1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 23:02:42 +01:00

Provide a basic detail view for user activity logs

Summary:
Depends on D20673. Ref T13343. Since we're now putting log IDs in email, make the UI a little better for working with log IDs.

Some day, this page might have actions like "report this as suspicious" or whatever, but I'm not planning to do any of that for now.

Test Plan: {F6608631}

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13343

Differential Revision: https://secure.phabricator.com/D20674
This commit is contained in:
epriestley 2019-07-19 15:24:37 -07:00
parent 60db658d52
commit 99c864f5e6
6 changed files with 167 additions and 29 deletions

View file

@ -4031,6 +4031,7 @@ phutil_register_library_map(array(
'PhabricatorPeopleListController' => 'applications/people/controller/PhabricatorPeopleListController.php', 'PhabricatorPeopleListController' => 'applications/people/controller/PhabricatorPeopleListController.php',
'PhabricatorPeopleLogQuery' => 'applications/people/query/PhabricatorPeopleLogQuery.php', 'PhabricatorPeopleLogQuery' => 'applications/people/query/PhabricatorPeopleLogQuery.php',
'PhabricatorPeopleLogSearchEngine' => 'applications/people/query/PhabricatorPeopleLogSearchEngine.php', 'PhabricatorPeopleLogSearchEngine' => 'applications/people/query/PhabricatorPeopleLogSearchEngine.php',
'PhabricatorPeopleLogViewController' => 'applications/people/controller/PhabricatorPeopleLogViewController.php',
'PhabricatorPeopleLogsController' => 'applications/people/controller/PhabricatorPeopleLogsController.php', 'PhabricatorPeopleLogsController' => 'applications/people/controller/PhabricatorPeopleLogsController.php',
'PhabricatorPeopleMailEngine' => 'applications/people/mail/PhabricatorPeopleMailEngine.php', 'PhabricatorPeopleMailEngine' => 'applications/people/mail/PhabricatorPeopleMailEngine.php',
'PhabricatorPeopleMailEngineException' => 'applications/people/mail/PhabricatorPeopleMailEngineException.php', 'PhabricatorPeopleMailEngineException' => 'applications/people/mail/PhabricatorPeopleMailEngineException.php',
@ -10291,6 +10292,7 @@ phutil_register_library_map(array(
'PhabricatorPeopleListController' => 'PhabricatorPeopleController', 'PhabricatorPeopleListController' => 'PhabricatorPeopleController',
'PhabricatorPeopleLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorPeopleLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorPeopleLogSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhabricatorPeopleLogSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorPeopleLogViewController' => 'PhabricatorPeopleController',
'PhabricatorPeopleLogsController' => 'PhabricatorPeopleController', 'PhabricatorPeopleLogsController' => 'PhabricatorPeopleController',
'PhabricatorPeopleMailEngine' => 'Phobject', 'PhabricatorPeopleMailEngine' => 'Phobject',
'PhabricatorPeopleMailEngineException' => 'Exception', 'PhabricatorPeopleMailEngineException' => 'Exception',

View file

@ -44,6 +44,7 @@ final class PhabricatorPeopleApplication extends PhabricatorApplication {
$this->getQueryRoutePattern() => 'PhabricatorPeopleListController', $this->getQueryRoutePattern() => 'PhabricatorPeopleListController',
'logs/' => array( 'logs/' => array(
$this->getQueryRoutePattern() => 'PhabricatorPeopleLogsController', $this->getQueryRoutePattern() => 'PhabricatorPeopleLogsController',
'(?P<id>\d+)/' => 'PhabricatorPeopleLogViewController',
), ),
'invite/' => array( 'invite/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?' '(?:query/(?P<queryKey>[^/]+)/)?'

View file

@ -0,0 +1,92 @@
<?php
final class PhabricatorPeopleLogViewController
extends PhabricatorPeopleController {
public function shouldRequireAdmin() {
return false;
}
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$id = $request->getURIData('id');
$log = id(new PhabricatorPeopleLogQuery())
->setViewer($viewer)
->withIDs(array($id))
->executeOne();
if (!$log) {
return new Aphront404Response();
}
$logs_uri = $this->getApplicationURI('logs/');
$crumbs = $this->buildApplicationCrumbs()
->addTextCrumb(pht('Activity Logs'), $logs_uri)
->addTextCrumb($log->getObjectName())
->setBorder(true);
$header = $this->buildHeaderView($log);
$properties = $this->buildPropertiesView($log);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->addPropertySection(pht('Details'), $properties);
return $this->newPage()
->setCrumbs($crumbs)
->setTitle($log->getObjectName())
->appendChild($view);
}
private function buildHeaderView(PhabricatorUserLog $log) {
$viewer = $this->getViewer();
$view = id(new PHUIHeaderView())
->setViewer($viewer)
->setHeader($log->getObjectName());
return $view;
}
private function buildPropertiesView(PhabricatorUserLog $log) {
$viewer = $this->getViewer();
$view = id(new PHUIPropertyListView())
->setViewer($viewer);
$type_map = PhabricatorUserLogType::getAllLogTypes();
$type_map = mpull($type_map, 'getLogTypeName', 'getLogTypeKey');
$action = $log->getAction();
$type_name = idx($type_map, $action, $action);
$view->addProperty(pht('Event Type'), $type_name);
$view->addProperty(
pht('Event Date'),
phabricator_datetime($log->getDateCreated(), $viewer));
$actor_phid = $log->getActorPHID();
if ($actor_phid) {
$view->addProperty(
pht('Acting User'),
$viewer->renderHandle($actor_phid));
}
$user_phid = $log->getUserPHID();
if ($user_phid) {
$view->addProperty(
pht('Affected User'),
$viewer->renderHandle($user_phid));
}
$remote_address = $log->getRemoteAddressForViewer($viewer);
if ($remote_address !== null) {
$view->addProperty(pht('Remote Address'), $remote_address);
}
return $view;
}
}

View file

@ -3,6 +3,7 @@
final class PhabricatorPeopleLogQuery final class PhabricatorPeopleLogQuery
extends PhabricatorCursorPagedPolicyAwareQuery { extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $actorPHIDs; private $actorPHIDs;
private $userPHIDs; private $userPHIDs;
private $relatedPHIDs; private $relatedPHIDs;
@ -12,6 +13,11 @@ final class PhabricatorPeopleLogQuery
private $dateCreatedMin; private $dateCreatedMin;
private $dateCreatedMax; private $dateCreatedMax;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withActorPHIDs(array $actor_phids) { public function withActorPHIDs(array $actor_phids) {
$this->actorPHIDs = $actor_phids; $this->actorPHIDs = $actor_phids;
return $this; return $this;
@ -59,6 +65,13 @@ final class PhabricatorPeopleLogQuery
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
$where = parent::buildWhereClauseParts($conn); $where = parent::buildWhereClauseParts($conn);
if ($this->ids !== null) {
$where[] = qsprintf(
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->actorPHIDs !== null) { if ($this->actorPHIDs !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn, $conn,

View file

@ -100,6 +100,43 @@ final class PhabricatorUserLog extends PhabricatorUserDAO
) + parent::getConfiguration(); ) + parent::getConfiguration();
} }
public function getURI() {
return urisprintf('/people/logs/%s/', $this->getID());
}
public function getObjectName() {
return pht('Activity Log %d', $this->getID());
}
public function getRemoteAddressForViewer(PhabricatorUser $viewer) {
$viewer_phid = $viewer->getPHID();
$actor_phid = $this->getActorPHID();
$user_phid = $this->getUserPHID();
if (!$viewer_phid) {
$can_see_ip = false;
} else if ($viewer->getIsAdmin()) {
$can_see_ip = true;
} else if ($viewer_phid == $actor_phid) {
// You can see the address if you took the action.
$can_see_ip = true;
} else if (!$actor_phid && ($viewer_phid == $user_phid)) {
// You can see the address if it wasn't authenticated and applied
// to you (partial login).
$can_see_ip = true;
} else {
// You can't see the address when an administrator disables your
// account, since it's their address.
$can_see_ip = false;
}
if (!$can_see_ip) {
return null;
}
return $this->getRemoteAddr();
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */ /* -( PhabricatorPolicyInterface )----------------------------------------- */

View file

@ -41,33 +41,16 @@ final class PhabricatorUserLogView extends AphrontView {
$actor_phid = $log->getActorPHID(); $actor_phid = $log->getActorPHID();
$user_phid = $log->getUserPHID(); $user_phid = $log->getUserPHID();
if ($viewer->getIsAdmin()) { $remote_address = $log->getRemoteAddressForViewer($viewer);
$can_see_ip = true; if ($remote_address !== null) {
} else if ($viewer_phid == $actor_phid) {
// You can see the address if you took the action.
$can_see_ip = true;
} else if (!$actor_phid && ($viewer_phid == $user_phid)) {
// You can see the address if it wasn't authenticated and applied
// to you (partial login).
$can_see_ip = true;
} else {
// You can't see the address when an administrator disables your
// account, since it's their address.
$can_see_ip = false;
}
if ($can_see_ip) {
$ip = $log->getRemoteAddr();
if ($base_uri) { if ($base_uri) {
$ip = phutil_tag( $remote_address = phutil_tag(
'a', 'a',
array( array(
'href' => $base_uri.'?ip='.$ip.'#R', 'href' => $base_uri.'?ip='.$remote_address.'#R',
), ),
$ip); $remote_address);
} }
} else {
$ip = null;
} }
$action = $log->getAction(); $action = $log->getAction();
@ -85,37 +68,47 @@ final class PhabricatorUserLogView extends AphrontView {
$user_name = null; $user_name = null;
} }
$action_link = phutil_tag(
'a',
array(
'href' => $log->getURI(),
),
$action_name);
$rows[] = array( $rows[] = array(
phabricator_date($log->getDateCreated(), $viewer), $log->getID(),
phabricator_time($log->getDateCreated(), $viewer), $action_link,
$action_name,
$actor_name, $actor_name,
$user_name, $user_name,
$ip, $remote_address,
$session, $session,
phabricator_date($log->getDateCreated(), $viewer),
phabricator_time($log->getDateCreated(), $viewer),
); );
} }
$table = new AphrontTableView($rows); $table = new AphrontTableView($rows);
$table->setHeaders( $table->setHeaders(
array( array(
pht('Date'), pht('ID'),
pht('Time'),
pht('Action'), pht('Action'),
pht('Actor'), pht('Actor'),
pht('User'), pht('User'),
pht('IP'), pht('IP'),
pht('Session'), pht('Session'),
pht('Date'),
pht('Time'),
)); ));
$table->setColumnClasses( $table->setColumnClasses(
array( array(
'', '',
'right',
'wide', 'wide',
'', '',
'', '',
'', '',
'n', 'n',
'',
'right',
)); ));
return $table; return $table;