Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14033120
D8556.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
D8556.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Sun, Nov 10, 4:48 PM (2 d, 11 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6716275
Default Alt Text
D8556.diff (7 KB)
Attached To
Mode
D8556: Allow users to terminate login sessions
Attached
Detach File
Event Timeline
Log In to Comment