1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-18 21:02:41 +01:00

Formally modularize MFA/TOTP tokens, provide a module panel for temporary tokens

Summary:
Ref T10603. We have a couple of sort of ad-hoc tokens, so start formalizing them. First up is MFA tokens.

Also adds a new config module panel for these.

Test Plan:
  - Added MFA.
  - Added MFA, intentionally fumbled the input, completed the workflow.
  - Removed MFA.
  - Viewed tokens, saw MFA sync tokens.
  - Viewed new module config panel.

{F1177014}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10603

Differential Revision: https://secure.phabricator.com/D15479
This commit is contained in:
epriestley 2016-03-16 06:17:31 -07:00
parent a837c3d73e
commit 33a95d44bd
7 changed files with 81 additions and 4 deletions

View file

@ -1843,10 +1843,12 @@ phutil_register_library_map(array(
'PhabricatorAuthSessionQuery' => 'applications/auth/query/PhabricatorAuthSessionQuery.php',
'PhabricatorAuthSetupCheck' => 'applications/config/check/PhabricatorAuthSetupCheck.php',
'PhabricatorAuthStartController' => 'applications/auth/controller/PhabricatorAuthStartController.php',
'PhabricatorAuthTOTPKeyTemporaryTokenType' => 'applications/auth/factor/PhabricatorAuthTOTPKeyTemporaryTokenType.php',
'PhabricatorAuthTemporaryToken' => 'applications/auth/storage/PhabricatorAuthTemporaryToken.php',
'PhabricatorAuthTemporaryTokenGarbageCollector' => 'applications/auth/garbagecollector/PhabricatorAuthTemporaryTokenGarbageCollector.php',
'PhabricatorAuthTemporaryTokenQuery' => 'applications/auth/query/PhabricatorAuthTemporaryTokenQuery.php',
'PhabricatorAuthTemporaryTokenType' => 'applications/auth/tokentype/PhabricatorAuthTemporaryTokenType.php',
'PhabricatorAuthTemporaryTokenTypeModule' => 'applications/auth/tokentype/PhabricatorAuthTemporaryTokenTypeModule.php',
'PhabricatorAuthTerminateSessionController' => 'applications/auth/controller/PhabricatorAuthTerminateSessionController.php',
'PhabricatorAuthTryFactorAction' => 'applications/auth/action/PhabricatorAuthTryFactorAction.php',
'PhabricatorAuthUnlinkController' => 'applications/auth/controller/PhabricatorAuthUnlinkController.php',
@ -6164,6 +6166,7 @@ phutil_register_library_map(array(
'PhabricatorAuthSessionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorAuthSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorAuthStartController' => 'PhabricatorAuthController',
'PhabricatorAuthTOTPKeyTemporaryTokenType' => 'PhabricatorAuthTemporaryTokenType',
'PhabricatorAuthTemporaryToken' => array(
'PhabricatorAuthDAO',
'PhabricatorPolicyInterface',
@ -6171,6 +6174,7 @@ phutil_register_library_map(array(
'PhabricatorAuthTemporaryTokenGarbageCollector' => 'PhabricatorGarbageCollector',
'PhabricatorAuthTemporaryTokenQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorAuthTemporaryTokenType' => 'Phobject',
'PhabricatorAuthTemporaryTokenTypeModule' => 'PhabricatorConfigModule',
'PhabricatorAuthTerminateSessionController' => 'PhabricatorAuthController',
'PhabricatorAuthTryFactorAction' => 'PhabricatorSystemAction',
'PhabricatorAuthUnlinkController' => 'PhabricatorAuthController',

View file

@ -0,0 +1,17 @@
<?php
final class PhabricatorAuthTOTPKeyTemporaryTokenType
extends PhabricatorAuthTemporaryTokenType {
const TOKENTYPE = 'mfa:totp:key';
public function getTokenTypeDisplayName() {
return pht('TOTP Synchronization');
}
public function getTokenReadableTypeName(
PhabricatorAuthTemporaryToken $token) {
return pht('TOTP Sync Token');
}
}

View file

@ -2,8 +2,6 @@
final class PhabricatorTOTPAuthFactor extends PhabricatorAuthFactor {
const TEMPORARY_TOKEN_TYPE = 'mfa:totp:key';
public function getFactorKey() {
return 'totp';
}
@ -24,6 +22,8 @@ final class PhabricatorTOTPAuthFactor extends PhabricatorAuthFactor {
AphrontRequest $request,
PhabricatorUser $user) {
$totp_token_type = PhabricatorAuthTOTPKeyTemporaryTokenType::TOKENTYPE;
$key = $request->getStr('totpkey');
if (strlen($key)) {
// If the user is providing a key, make sure it's a key we generated.
@ -37,7 +37,7 @@ final class PhabricatorTOTPAuthFactor extends PhabricatorAuthFactor {
$temporary_token = id(new PhabricatorAuthTemporaryTokenQuery())
->setViewer($user)
->withTokenResources(array($user->getPHID()))
->withTokenTypes(array(self::TEMPORARY_TOKEN_TYPE))
->withTokenTypes(array($totp_token_type))
->withExpired(false)
->withTokenCodes(array(PhabricatorHash::digest($key)))
->executeOne();
@ -56,7 +56,7 @@ final class PhabricatorTOTPAuthFactor extends PhabricatorAuthFactor {
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
id(new PhabricatorAuthTemporaryToken())
->setTokenResource($user->getPHID())
->setTokenType(self::TEMPORARY_TOKEN_TYPE)
->setTokenType($totp_token_type)
->setTokenExpires(time() + phutil_units('1 hour in seconds'))
->setTokenCode(PhabricatorHash::digest($key))
->save();

View file

@ -5,6 +5,10 @@ final class PhabricatorAuthOneTimeLoginTemporaryTokenType
const TOKENTYPE = 'login:onetime';
public function getTokenTypeDisplayName() {
return pht('One-Time Login');
}
public function getTokenReadableTypeName(
PhabricatorAuthTemporaryToken $token) {
return pht('One-Time Login Token');

View file

@ -5,6 +5,10 @@ final class PhabricatorAuthPasswordResetTemporaryTokenType
const TOKENTYPE = 'login:password';
public function getTokenTypeDisplayName() {
return pht('Password Reset');
}
public function getTokenReadableTypeName(
PhabricatorAuthTemporaryToken $token) {
return pht('Password Reset Token');

View file

@ -3,6 +3,7 @@
abstract class PhabricatorAuthTemporaryTokenType
extends Phobject {
abstract public function getTokenTypeDisplayName();
abstract public function getTokenReadableTypeName(
PhabricatorAuthTemporaryToken $token);

View file

@ -0,0 +1,47 @@
<?php
final class PhabricatorAuthTemporaryTokenTypeModule
extends PhabricatorConfigModule {
public function getModuleKey() {
return 'temporarytoken';
}
public function getModuleName() {
return pht('Temporary Tokens');
}
public function renderModuleStatus(AphrontRequest $request) {
$viewer = $request->getViewer();
$types = PhabricatorAuthTemporaryTokenType::getAllTypes();
$rows = array();
foreach ($types as $type) {
$rows[] = array(
get_class($type),
$type->getTokenTypeConstant(),
$type->getTokenTypeDisplayName(),
);
}
$table = id(new AphrontTableView($rows))
->setHeaders(
array(
pht('Class'),
pht('Key'),
pht('Name'),
))
->setColumnClasses(
array(
null,
null,
'wide pri',
));
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Temporary Token Types'))
->setTable($table);
}
}