diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2055,6 +2055,7 @@ 'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php', 'PhabricatorSettingsPanel' => 'applications/settings/panel/PhabricatorSettingsPanel.php', 'PhabricatorSettingsPanelAccount' => 'applications/settings/panel/PhabricatorSettingsPanelAccount.php', + 'PhabricatorSettingsPanelActivity' => 'applications/settings/panel/PhabricatorSettingsPanelActivity.php', 'PhabricatorSettingsPanelConduit' => 'applications/settings/panel/PhabricatorSettingsPanelConduit.php', 'PhabricatorSettingsPanelConpherencePreferences' => 'applications/settings/panel/PhabricatorSettingsPanelConpherencePreferences.php', 'PhabricatorSettingsPanelDeveloperPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelDeveloperPreferences.php', @@ -2221,6 +2222,7 @@ 'PhabricatorUserEmail' => 'applications/people/storage/PhabricatorUserEmail.php', 'PhabricatorUserEmailTestCase' => 'applications/people/storage/__tests__/PhabricatorUserEmailTestCase.php', 'PhabricatorUserLog' => 'applications/people/storage/PhabricatorUserLog.php', + 'PhabricatorUserLogView' => 'applications/people/view/PhabricatorUserLogView.php', 'PhabricatorUserPreferences' => 'applications/settings/storage/PhabricatorUserPreferences.php', 'PhabricatorUserProfile' => 'applications/people/storage/PhabricatorUserProfile.php', 'PhabricatorUserProfileEditor' => 'applications/people/editor/PhabricatorUserProfileEditor.php', @@ -4950,6 +4952,7 @@ 'PhabricatorSettingsAdjustController' => 'PhabricatorController', 'PhabricatorSettingsMainController' => 'PhabricatorController', 'PhabricatorSettingsPanelAccount' => 'PhabricatorSettingsPanel', + 'PhabricatorSettingsPanelActivity' => 'PhabricatorSettingsPanel', 'PhabricatorSettingsPanelConduit' => 'PhabricatorSettingsPanel', 'PhabricatorSettingsPanelConpherencePreferences' => 'PhabricatorSettingsPanel', 'PhabricatorSettingsPanelDeveloperPreferences' => 'PhabricatorSettingsPanel', @@ -5131,6 +5134,7 @@ 0 => 'PhabricatorUserDAO', 1 => 'PhabricatorPolicyInterface', ), + 'PhabricatorUserLogView' => 'AphrontView', 'PhabricatorUserPreferences' => 'PhabricatorUserDAO', 'PhabricatorUserProfile' => 'PhabricatorUserDAO', 'PhabricatorUserProfileEditor' => 'PhabricatorApplicationTransactionEditor', diff --git a/src/applications/auth/controller/PhabricatorAuthDowngradeSessionController.php b/src/applications/auth/controller/PhabricatorAuthDowngradeSessionController.php --- a/src/applications/auth/controller/PhabricatorAuthDowngradeSessionController.php +++ b/src/applications/auth/controller/PhabricatorAuthDowngradeSessionController.php @@ -20,11 +20,8 @@ if ($request->isFormPost()) { - queryfx( - $session->establishConnection('w'), - 'UPDATE %T SET highSecurityUntil = NULL WHERE id = %d', - $session->getTableName(), - $session->getID()); + id(new PhabricatorAuthSessionEngine()) + ->exitHighSecurity($viewer, $session); return id(new AphrontRedirectResponse()) ->setURI($this->getApplicationURI('session/downgrade/')); diff --git a/src/applications/auth/engine/PhabricatorAuthSessionEngine.php b/src/applications/auth/engine/PhabricatorAuthSessionEngine.php --- a/src/applications/auth/engine/PhabricatorAuthSessionEngine.php +++ b/src/applications/auth/engine/PhabricatorAuthSessionEngine.php @@ -249,6 +249,12 @@ $session->getTableName(), $until, $session->getID()); + + $log = PhabricatorUserLog::initializeNewLog( + $viewer, + $viewer->getPHID(), + PhabricatorUserLog::ACTION_ENTER_HISEC); + $log->save(); } } @@ -302,4 +308,21 @@ } + public function exitHighSecurity( + PhabricatorUser $viewer, + PhabricatorAuthSession $session) { + + queryfx( + $session->establishConnection('w'), + 'UPDATE %T SET highSecurityUntil = NULL WHERE id = %d', + $session->getTableName(), + $session->getID()); + + $log = PhabricatorUserLog::initializeNewLog( + $viewer, + $viewer->getPHID(), + PhabricatorUserLog::ACTION_EXIT_HISEC); + $log->save(); + } + } diff --git a/src/applications/oauthserver/panel/PhabricatorOAuthServerAuthorizationsSettingsPanel.php b/src/applications/oauthserver/panel/PhabricatorOAuthServerAuthorizationsSettingsPanel.php --- a/src/applications/oauthserver/panel/PhabricatorOAuthServerAuthorizationsSettingsPanel.php +++ b/src/applications/oauthserver/panel/PhabricatorOAuthServerAuthorizationsSettingsPanel.php @@ -12,7 +12,7 @@ } public function getPanelGroup() { - return pht('Authentication'); + return pht('Sessions and Logs'); } public function isEnabled() { diff --git a/src/applications/people/controller/PhabricatorPeopleLogsController.php b/src/applications/people/controller/PhabricatorPeopleLogsController.php --- a/src/applications/people/controller/PhabricatorPeopleLogsController.php +++ b/src/applications/people/controller/PhabricatorPeopleLogsController.php @@ -35,64 +35,11 @@ $phids = array_keys($phids); $handles = $this->loadViewerHandles($phids); - $action_map = PhabricatorUserLog::getActionTypeMap(); - - $rows = array(); - foreach ($logs as $log) { - - $ip_href = $this->getApplicationURI( - 'logs/?ip='.$log->getRemoteAddr()); - - $session_href = $this->getApplicationURI( - 'logs/?sessions='.$log->getSession()); - - $action = $log->getAction(); - $action_name = idx($action_map, $action, $action); - - $rows[] = array( - phabricator_date($log->getDateCreated(), $viewer), - phabricator_time($log->getDateCreated(), $viewer), - $action_name, - $log->getActorPHID() - ? $handles[$log->getActorPHID()]->getName() - : null, - $handles[$log->getUserPHID()]->getName(), - phutil_tag( - 'a', - array( - 'href' => $ip_href, - ), - $log->getRemoteAddr()), - phutil_tag( - 'a', - array( - 'href' => $session_href, - ), - substr($log->getSession(), 0, 6)), - ); - } - - $table = new AphrontTableView($rows); - $table->setHeaders( - array( - pht('Date'), - pht('Time'), - pht('Action'), - pht('Actor'), - pht('User'), - pht('IP'), - pht('Session'), - )); - $table->setColumnClasses( - array( - '', - 'right', - 'wide', - '', - '', - '', - 'n', - )); + $table = id(new PhabricatorUserLogView()) + ->setUser($viewer) + ->setLogs($logs) + ->setSearchBaseURI($this->getApplicationURI('logs/')) + ->setHandles($handles); return id(new PHUIObjectBoxView()) ->setHeaderText(pht('User Activity Logs')) diff --git a/src/applications/people/query/PhabricatorPeopleLogQuery.php b/src/applications/people/query/PhabricatorPeopleLogQuery.php --- a/src/applications/people/query/PhabricatorPeopleLogQuery.php +++ b/src/applications/people/query/PhabricatorPeopleLogQuery.php @@ -76,6 +76,7 @@ $where[] = qsprintf( $conn_r, 'actorPHID IN (%Ls) OR userPHID IN (%Ls)', + $this->relatedPHIDs, $this->relatedPHIDs); } diff --git a/src/applications/people/storage/PhabricatorUserLog.php b/src/applications/people/storage/PhabricatorUserLog.php --- a/src/applications/people/storage/PhabricatorUserLog.php +++ b/src/applications/people/storage/PhabricatorUserLog.php @@ -27,6 +27,9 @@ const ACTION_CHANGE_PASSWORD = 'change-password'; const ACTION_CHANGE_USERNAME = 'change-username'; + const ACTION_ENTER_HISEC = 'hisec-enter'; + const ACTION_EXIT_HISEC = 'hisec-exit'; + protected $actorPHID; protected $userPHID; protected $action; @@ -58,6 +61,8 @@ self::ACTION_EMAIL_REMOVE => pht('Email: Remove Address'), self::ACTION_CHANGE_PASSWORD => pht('Change Password'), self::ACTION_CHANGE_USERNAME => pht('Change Username'), + self::ACTION_ENTER_HISEC => pht('Hisec: Enter'), + self::ACTION_EXIT_HISEC => pht('Hisec: Exit'), ); } diff --git a/src/applications/people/view/PhabricatorUserLogView.php b/src/applications/people/view/PhabricatorUserLogView.php new file mode 100644 --- /dev/null +++ b/src/applications/people/view/PhabricatorUserLogView.php @@ -0,0 +1,95 @@ +searchBaseURI = $search_base_uri; + return $this; + } + + public function setLogs(array $logs) { + assert_instances_of($logs, 'PhabricatorUserLog'); + $this->logs = $logs; + return $this; + } + + public function setHandles(array $handles) { + assert_instances_of($handles, 'PhabricatorObjectHandle'); + $this->handles = $handles; + return $this; + } + + public function render() { + $logs = $this->logs; + $handles = $this->handles; + $viewer = $this->getUser(); + + $action_map = PhabricatorUserLog::getActionTypeMap(); + $base_uri = $this->searchBaseURI; + + $rows = array(); + foreach ($logs as $log) { + + $ip = $log->getRemoteAddr(); + $session = substr($log->getSession(), 0, 6); + + if ($base_uri) { + $ip = phutil_tag( + 'a', + array( + 'href' => $base_uri.'?ip='.$log->getRemoteAddr().'#R', + ), + $ip); + $session = phutil_tag( + 'a', + array( + 'href' => $base_uri.'?sessions='.$log->getSession().'#R', + ), + $session); + } + + $action = $log->getAction(); + $action_name = idx($action_map, $action, $action); + + $rows[] = array( + phabricator_date($log->getDateCreated(), $viewer), + phabricator_time($log->getDateCreated(), $viewer), + $action_name, + $log->getActorPHID() + ? $handles[$log->getActorPHID()]->getName() + : null, + $handles[$log->getUserPHID()]->getName(), + $ip, + $session, + ); + } + + $table = new AphrontTableView($rows); + $table->setHeaders( + array( + pht('Date'), + pht('Time'), + pht('Action'), + pht('Actor'), + pht('User'), + pht('IP'), + pht('Session'), + )); + $table->setColumnClasses( + array( + '', + 'right', + 'wide', + '', + '', + '', + 'n', + )); + + return $table; + } +} diff --git a/src/applications/settings/panel/PhabricatorSettingsPanelActivity.php b/src/applications/settings/panel/PhabricatorSettingsPanelActivity.php new file mode 100644 --- /dev/null +++ b/src/applications/settings/panel/PhabricatorSettingsPanelActivity.php @@ -0,0 +1,58 @@ +getUser(); + $user = $this->getUser(); + + $logs = id(new PhabricatorPeopleLogQuery()) + ->setViewer($viewer) + ->withRelatedPHIDs(array($user->getPHID())) + ->execute(); + + $phids = array(); + foreach ($logs as $log) { + $phids[] = $log->getUserPHID(); + $phids[] = $log->getActorPHID(); + } + + if ($phids) { + $handles = id(new PhabricatorHandleQuery()) + ->setViewer($viewer) + ->withPHIDs($phids) + ->execute(); + } else { + $handles = array(); + } + + $table = id(new PhabricatorUserLogView()) + ->setUser($viewer) + ->setLogs($logs) + ->setHandles($handles); + + $panel = id(new PHUIObjectBoxView()) + ->setHeaderText(pht('Account Activity Logs')) + ->appendChild($table); + + return $panel; + } + +} diff --git a/src/applications/settings/panel/PhabricatorSettingsPanelSessions.php b/src/applications/settings/panel/PhabricatorSettingsPanelSessions.php --- a/src/applications/settings/panel/PhabricatorSettingsPanelSessions.php +++ b/src/applications/settings/panel/PhabricatorSettingsPanelSessions.php @@ -12,7 +12,7 @@ } public function getPanelGroup() { - return pht('Authentication'); + return pht('Sessions and Logs'); } public function isEnabled() {