Page MenuHomePhabricator

D8556.id20302.diff
No OneTemporary

D8556.id20302.diff

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
@@ -1226,6 +1226,7 @@
'PhabricatorAuthSessionGarbageCollector' => 'applications/auth/garbagecollector/PhabricatorAuthSessionGarbageCollector.php',
'PhabricatorAuthSessionQuery' => 'applications/auth/query/PhabricatorAuthSessionQuery.php',
'PhabricatorAuthStartController' => 'applications/auth/controller/PhabricatorAuthStartController.php',
+ 'PhabricatorAuthTerminateSessionController' => 'applications/auth/controller/PhabricatorAuthTerminateSessionController.php',
'PhabricatorAuthUnlinkController' => 'applications/auth/controller/PhabricatorAuthUnlinkController.php',
'PhabricatorAuthValidateController' => 'applications/auth/controller/PhabricatorAuthValidateController.php',
'PhabricatorAuthenticationConfigOptions' => 'applications/config/option/PhabricatorAuthenticationConfigOptions.php',
@@ -3910,6 +3911,7 @@
'PhabricatorAuthSessionGarbageCollector' => 'PhabricatorGarbageCollector',
'PhabricatorAuthSessionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorAuthStartController' => 'PhabricatorAuthController',
+ 'PhabricatorAuthTerminateSessionController' => 'PhabricatorAuthController',
'PhabricatorAuthUnlinkController' => 'PhabricatorAuthController',
'PhabricatorAuthValidateController' => 'PhabricatorAuthController',
'PhabricatorAuthenticationConfigOptions' => 'PhabricatorApplicationConfigOptions',
diff --git a/src/applications/auth/application/PhabricatorApplicationAuth.php b/src/applications/auth/application/PhabricatorApplicationAuth.php
--- a/src/applications/auth/application/PhabricatorApplicationAuth.php
+++ b/src/applications/auth/application/PhabricatorApplicationAuth.php
@@ -86,6 +86,8 @@
=> 'PhabricatorAuthLinkController',
'confirmlink/(?P<akey>[^/]+)/'
=> 'PhabricatorAuthConfirmLinkController',
+ 'session/terminate/(?P<id>[^/]+)/'
+ => 'PhabricatorAuthTerminateSessionController',
),
'/oauth/(?P<provider>\w+)/login/'
diff --git a/src/applications/auth/controller/PhabricatorAuthTerminateSessionController.php b/src/applications/auth/controller/PhabricatorAuthTerminateSessionController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/auth/controller/PhabricatorAuthTerminateSessionController.php
@@ -0,0 +1,83 @@
+<?php
+
+final class PhabricatorAuthTerminateSessionController
+ extends PhabricatorAuthController {
+
+ private $id;
+
+ public function willProcessRequest(array $data) {
+ $this->id = $data['id'];
+ }
+
+ public function processRequest() {
+ $request = $this->getRequest();
+ $viewer = $request->getUser();
+
+ $is_all = ($this->id === 'all');
+
+ $query = id(new PhabricatorAuthSessionQuery())
+ ->setViewer($viewer)
+ ->withIdentityPHIDs(array($viewer->getPHID()));
+ if (!$is_all) {
+ $query->withIDs(array($this->id));
+ }
+
+ $current_key = PhabricatorHash::digest(
+ $request->getCookie(PhabricatorCookies::COOKIE_SESSION));
+
+ $sessions = $query->execute();
+ foreach ($sessions as $key => $session) {
+ if ($session->getSessionKey() == $current_key) {
+ // Don't terminate the current login session.
+ unset($sessions[$key]);
+ }
+ }
+
+ $panel_uri = '/settings/panel/sessions/';
+
+ if (!$sessions) {
+ $dialog = id(new AphrontDialogView())
+ ->setUser($viewer)
+ ->setTitle(pht('No Matching Sessions'))
+ ->appendParagraph(
+ pht('There are no matching sessions to terminate.'))
+ ->appendParagraph(
+ pht(
+ '(You can not terminate your current login session. To '.
+ 'terminate it, log out.)'))
+ ->addCancelButton($panel_uri);
+
+ return id(new AphrontDialogResponse())->setDialog($dialog);
+ }
+
+ if ($request->isDialogFormPost()) {
+ foreach ($sessions as $session) {
+ $session->delete();
+ }
+ return id(new AphrontRedirectResponse())->setURI($panel_uri);
+ }
+
+ if ($is_all) {
+ $title = pht('Terminate Sessions?');
+ $body = pht(
+ 'Really terminate all sessions? (Your current login session will '.
+ 'not be terminated.)');
+ } else {
+ $title = pht('Terminate Session?');
+ $body = pht(
+ 'Really terminate session %s?',
+ phutil_tag('strong', array(), substr($session->getSessionKey(), 0, 6)));
+ }
+
+ $dialog = id(new AphrontDialogView())
+ ->setUser($viewer)
+ ->setTitle($title)
+ ->appendParagraph($body)
+ ->addSubmitButton(pht('Terminate'))
+ ->addCancelButton($panel_uri);
+
+ return id(new AphrontDialogResponse())->setDialog($dialog);
+ }
+
+
+}
diff --git a/src/applications/auth/query/PhabricatorAuthSessionQuery.php b/src/applications/auth/query/PhabricatorAuthSessionQuery.php
--- a/src/applications/auth/query/PhabricatorAuthSessionQuery.php
+++ b/src/applications/auth/query/PhabricatorAuthSessionQuery.php
@@ -3,6 +3,7 @@
final class PhabricatorAuthSessionQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
+ private $ids;
private $identityPHIDs;
private $sessionKeys;
private $sessionTypes;
@@ -22,6 +23,11 @@
return $this;
}
+ public function withIDs(array $ids) {
+ $this->ids = $ids;
+ return $this;
+ }
+
protected function loadPage() {
$table = new PhabricatorAuthSession();
$conn_r = $table->establishConnection('r');
@@ -62,6 +68,13 @@
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
+ if ($this->ids) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'id IN (%Ld)',
+ $this->ids);
+ }
+
if ($this->identityPHIDs) {
$where[] = qsprintf(
$conn_r,
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
@@ -48,16 +48,31 @@
foreach ($sessions as $session) {
if ($session->getSessionKey() == $current_key) {
$rowc[] = 'highlighted';
+ $button = phutil_tag(
+ 'a',
+ array(
+ 'class' => 'small grey button disabled',
+ ),
+ pht('Current'));
} else {
$rowc[] = null;
+ $button = javelin_tag(
+ 'a',
+ array(
+ 'href' => '/auth/session/terminate/'.$session->getID().'/',
+ 'class' => 'small grey button',
+ 'sigil' => 'workflow',
+ ),
+ pht('Terminate'));
}
$rows[] = array(
$handles[$session->getUserPHID()]->renderLink(),
- substr($session->getSessionKey(), 0, 12),
+ substr($session->getSessionKey(), 0, 6),
$session->getType(),
phabricator_datetime($session->getSessionStart(), $viewer),
- phabricator_datetime($session->getSessionExpires(), $viewer),
+ phabricator_date($session->getSessionExpires(), $viewer),
+ $button,
);
}
@@ -71,6 +86,7 @@
pht('Type'),
pht('Created'),
pht('Expires'),
+ pht(''),
));
$table->setColumnClasses(
array(
@@ -79,11 +95,23 @@
'',
'right',
'right',
+ 'action',
));
+ $terminate_icon = id(new PHUIIconView())
+ ->setSpriteSheet(PHUIIconView::SPRITE_ICONS)
+ ->setSpriteIcon('warning');
+ $terminate_button = id(new PHUIButtonView())
+ ->setText(pht('Terminate All Sessions'))
+ ->setHref('/auth/session/terminate/all/')
+ ->setTag('a')
+ ->setWorkflow(true)
+ ->setIcon($terminate_icon);
+
$header = id(new PHUIHeaderView())
- ->setHeader(pht('Active Login Sessions'));
+ ->setHeader(pht('Active Login Sessions'))
+ ->addActionLink($terminate_button);
$panel = id(new PHUIObjectBoxView())
->setHeader($header)

File Metadata

Mime Type
text/plain
Expires
Wed, Oct 16, 1:49 PM (3 w, 6 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6716275
Default Alt Text
D8556.id20302.diff (7 KB)

Event Timeline