Page MenuHomePhabricator

D10133.diff
No OneTemporary

D10133.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
@@ -1192,6 +1192,7 @@
'PhabricatorAuthProviderConfigTransaction' => 'applications/auth/storage/PhabricatorAuthProviderConfigTransaction.php',
'PhabricatorAuthProviderConfigTransactionQuery' => 'applications/auth/query/PhabricatorAuthProviderConfigTransactionQuery.php',
'PhabricatorAuthRegisterController' => 'applications/auth/controller/PhabricatorAuthRegisterController.php',
+ 'PhabricatorAuthRevokeTokenController' => 'applications/auth/controller/PhabricatorAuthRevokeTokenController.php',
'PhabricatorAuthSession' => 'applications/auth/storage/PhabricatorAuthSession.php',
'PhabricatorAuthSessionEngine' => 'applications/auth/engine/PhabricatorAuthSessionEngine.php',
'PhabricatorAuthSessionGarbageCollector' => 'applications/auth/garbagecollector/PhabricatorAuthSessionGarbageCollector.php',
@@ -2146,6 +2147,7 @@
'PhabricatorSettingsPanelSSHKeys' => 'applications/settings/panel/PhabricatorSettingsPanelSSHKeys.php',
'PhabricatorSettingsPanelSearchPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelSearchPreferences.php',
'PhabricatorSettingsPanelSessions' => 'applications/settings/panel/PhabricatorSettingsPanelSessions.php',
+ 'PhabricatorSettingsPanelTokens' => 'applications/settings/panel/PhabricatorSettingsPanelTokens.php',
'PhabricatorSetupCheck' => 'applications/config/check/PhabricatorSetupCheck.php',
'PhabricatorSetupCheckAPC' => 'applications/config/check/PhabricatorSetupCheckAPC.php',
'PhabricatorSetupCheckAphlict' => 'applications/notification/setup/PhabricatorSetupCheckAphlict.php',
@@ -3986,6 +3988,7 @@
'PhabricatorAuthProviderConfigTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorAuthProviderConfigTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorAuthRegisterController' => 'PhabricatorAuthController',
+ 'PhabricatorAuthRevokeTokenController' => 'PhabricatorAuthController',
'PhabricatorAuthSession' => array(
'PhabricatorAuthDAO',
'PhabricatorPolicyInterface',
@@ -4999,6 +5002,7 @@
'PhabricatorSettingsPanelSSHKeys' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelSearchPreferences' => 'PhabricatorSettingsPanel',
'PhabricatorSettingsPanelSessions' => 'PhabricatorSettingsPanel',
+ 'PhabricatorSettingsPanelTokens' => 'PhabricatorSettingsPanel',
'PhabricatorSetupCheckAPC' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckAphlict' => 'PhabricatorSetupCheck',
'PhabricatorSetupCheckAuth' => 'PhabricatorSetupCheck',
diff --git a/src/applications/auth/application/PhabricatorAuthApplication.php b/src/applications/auth/application/PhabricatorAuthApplication.php
--- a/src/applications/auth/application/PhabricatorAuthApplication.php
+++ b/src/applications/auth/application/PhabricatorAuthApplication.php
@@ -103,6 +103,8 @@
=> 'PhabricatorAuthConfirmLinkController',
'session/terminate/(?P<id>[^/]+)/'
=> 'PhabricatorAuthTerminateSessionController',
+ 'token/revoke/(?P<id>[^/]+)/'
+ => 'PhabricatorAuthRevokeTokenController',
'session/downgrade/'
=> 'PhabricatorAuthDowngradeSessionController',
'multifactor/'
diff --git a/src/applications/auth/controller/PhabricatorAuthRevokeTokenController.php b/src/applications/auth/controller/PhabricatorAuthRevokeTokenController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/auth/controller/PhabricatorAuthRevokeTokenController.php
@@ -0,0 +1,78 @@
+<?php
+
+final class PhabricatorAuthRevokeTokenController
+ 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 PhabricatorAuthTemporaryTokenQuery())
+ ->setViewer($viewer)
+ ->withObjectPHIDs(array($viewer->getPHID()));
+ if (!$is_all) {
+ $query->withIDs(array($this->id));
+ }
+
+ $tokens = $query->execute();
+ foreach ($tokens as $key => $token) {
+ if (!$token->isRevocable()) {
+ // Don't revoke unrevocable tokens.
+ unset($tokens[$key]);
+ }
+ }
+
+ $panel_uri = '/settings/panel/tokens/';
+
+ if (!$tokens) {
+ return $this->newDialog()
+ ->setTitle(pht('No Matching Tokens'))
+ ->appendParagraph(
+ pht('There are no matching tokens to revoke.'))
+ ->appendParagraph(
+ pht(
+ '(Some types of token can not be revoked, and you can not revoke '.
+ 'tokens which have already expired.)'))
+ ->addCancelButton($panel_uri);
+ }
+
+ if ($request->isDialogFormPost()) {
+ foreach ($tokens as $token) {
+ $token->setTokenExpires(PhabricatorTime::getNow() - 1)->save();
+ }
+ return id(new AphrontRedirectResponse())->setURI($panel_uri);
+ }
+
+ if ($is_all) {
+ $title = pht('Revoke Tokens?');
+ $short = pht('Revoke Tokens');
+ $body = pht(
+ 'Really revoke all tokens? Among other temporary authorizations, '.
+ 'this will disable any outstanding password reset or account '.
+ 'recovery links.');
+ } else {
+ $title = pht('Revoke Token?');
+ $short = pht('Revoke Token');
+ $body = pht(
+ 'Really revoke this token? Any temporary authorization it enables '.
+ 'will be disabled.');
+ }
+
+ return $this->newDialog()
+ ->setTitle($title)
+ ->setShortTitle($short)
+ ->appendParagraph($body)
+ ->addSubmitButton(pht('Revoke'))
+ ->addCancelButton($panel_uri);
+ }
+
+
+}
diff --git a/src/applications/auth/storage/PhabricatorAuthTemporaryToken.php b/src/applications/auth/storage/PhabricatorAuthTemporaryToken.php
--- a/src/applications/auth/storage/PhabricatorAuthTemporaryToken.php
+++ b/src/applications/auth/storage/PhabricatorAuthTemporaryToken.php
@@ -17,6 +17,33 @@
) + parent::getConfiguration();
}
+ public function getTokenReadableTypeName() {
+ // Eventually, it would be nice to let applications implement token types
+ // so we can put this in modular subclasses.
+ switch ($this->tokenType) {
+ case PhabricatorAuthSessionEngine::ONETIME_TEMPORARY_TOKEN_TYPE:
+ return pht('One-Time Login Token');
+ case PhabricatorAuthSessionEngine::PASSWORD_TEMPORARY_TOKEN_TYPE:
+ return pht('Password Reset Token');
+ }
+
+ return $this->tokenType;
+ }
+
+ public function isRevocable() {
+ if ($this->tokenExpires < time()) {
+ return false;
+ }
+
+ switch ($this->tokenType) {
+ case PhabricatorAuthSessionEngine::ONETIME_TEMPORARY_TOKEN_TYPE:
+ case PhabricatorAuthSessionEngine::PASSWORD_TEMPORARY_TOKEN_TYPE:
+ return true;
+ }
+
+ return false;
+ }
+
/* -( PhabricatorPolicyInterface )----------------------------------------- */
@@ -40,5 +67,4 @@
return null;
}
-
}
diff --git a/src/applications/settings/panel/PhabricatorSettingsPanelTokens.php b/src/applications/settings/panel/PhabricatorSettingsPanelTokens.php
new file mode 100644
--- /dev/null
+++ b/src/applications/settings/panel/PhabricatorSettingsPanelTokens.php
@@ -0,0 +1,100 @@
+<?php
+
+final class PhabricatorSettingsPanelTokens
+ extends PhabricatorSettingsPanel {
+
+ public function getPanelKey() {
+ return 'tokens';
+ }
+
+ public function getPanelName() {
+ return pht('Temporary Tokens');
+ }
+
+ public function getPanelGroup() {
+ return pht('Sessions and Logs');
+ }
+
+ public function isEnabled() {
+ return true;
+ }
+
+ public function processRequest(AphrontRequest $request) {
+ $viewer = $request->getUser();
+
+ $tokens = id(new PhabricatorAuthTemporaryTokenQuery())
+ ->setViewer($viewer)
+ ->withObjectPHIDs(array($viewer->getPHID()))
+ ->execute();
+
+ $rows = array();
+ foreach ($tokens as $token) {
+
+ if ($token->isRevocable()) {
+ $button = javelin_tag(
+ 'a',
+ array(
+ 'href' => '/auth/token/revoke/'.$token->getID().'/',
+ 'class' => 'small grey button',
+ 'sigil' => 'workflow',
+ ),
+ pht('Revoke'));
+ } else {
+ $button = javelin_tag(
+ 'a',
+ array(
+ 'class' => 'small grey button disabled',
+ ),
+ pht('Revoke'));
+ }
+
+ if ($token->getTokenExpires() >= time()) {
+ $expiry = phabricator_datetime($token->getTokenExpires(), $viewer);
+ } else {
+ $expiry = pht('Expired');
+ }
+
+ $rows[] = array(
+ $token->getTokenReadableTypeName(),
+ $expiry,
+ $button,
+ );
+ }
+
+ $table = new AphrontTableView($rows);
+ $table->setNoDataString(pht("You don't have any active tokens."));
+ $table->setHeaders(
+ array(
+ pht('Type'),
+ pht('Expires'),
+ pht(''),
+ ));
+ $table->setColumnClasses(
+ array(
+ 'wide',
+ 'right',
+ 'action',
+ ));
+
+
+ $terminate_icon = id(new PHUIIconView())
+ ->setIconFont('fa-exclamation-triangle');
+ $terminate_button = id(new PHUIButtonView())
+ ->setText(pht('Revoke All'))
+ ->setHref('/auth/token/revoke/all/')
+ ->setTag('a')
+ ->setWorkflow(true)
+ ->setIcon($terminate_icon);
+
+ $header = id(new PHUIHeaderView())
+ ->setHeader(pht('Temporary Tokens'))
+ ->addActionLink($terminate_button);
+
+ $panel = id(new PHUIObjectBoxView())
+ ->setHeader($header)
+ ->appendChild($table);
+
+ return $panel;
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Wed, Dec 25, 8:59 AM (10 h, 16 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6925720
Default Alt Text
D10133.diff (9 KB)

Event Timeline