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:
parent
a837c3d73e
commit
33a95d44bd
7 changed files with 81 additions and 4 deletions
|
@ -1843,10 +1843,12 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthSessionQuery' => 'applications/auth/query/PhabricatorAuthSessionQuery.php',
|
'PhabricatorAuthSessionQuery' => 'applications/auth/query/PhabricatorAuthSessionQuery.php',
|
||||||
'PhabricatorAuthSetupCheck' => 'applications/config/check/PhabricatorAuthSetupCheck.php',
|
'PhabricatorAuthSetupCheck' => 'applications/config/check/PhabricatorAuthSetupCheck.php',
|
||||||
'PhabricatorAuthStartController' => 'applications/auth/controller/PhabricatorAuthStartController.php',
|
'PhabricatorAuthStartController' => 'applications/auth/controller/PhabricatorAuthStartController.php',
|
||||||
|
'PhabricatorAuthTOTPKeyTemporaryTokenType' => 'applications/auth/factor/PhabricatorAuthTOTPKeyTemporaryTokenType.php',
|
||||||
'PhabricatorAuthTemporaryToken' => 'applications/auth/storage/PhabricatorAuthTemporaryToken.php',
|
'PhabricatorAuthTemporaryToken' => 'applications/auth/storage/PhabricatorAuthTemporaryToken.php',
|
||||||
'PhabricatorAuthTemporaryTokenGarbageCollector' => 'applications/auth/garbagecollector/PhabricatorAuthTemporaryTokenGarbageCollector.php',
|
'PhabricatorAuthTemporaryTokenGarbageCollector' => 'applications/auth/garbagecollector/PhabricatorAuthTemporaryTokenGarbageCollector.php',
|
||||||
'PhabricatorAuthTemporaryTokenQuery' => 'applications/auth/query/PhabricatorAuthTemporaryTokenQuery.php',
|
'PhabricatorAuthTemporaryTokenQuery' => 'applications/auth/query/PhabricatorAuthTemporaryTokenQuery.php',
|
||||||
'PhabricatorAuthTemporaryTokenType' => 'applications/auth/tokentype/PhabricatorAuthTemporaryTokenType.php',
|
'PhabricatorAuthTemporaryTokenType' => 'applications/auth/tokentype/PhabricatorAuthTemporaryTokenType.php',
|
||||||
|
'PhabricatorAuthTemporaryTokenTypeModule' => 'applications/auth/tokentype/PhabricatorAuthTemporaryTokenTypeModule.php',
|
||||||
'PhabricatorAuthTerminateSessionController' => 'applications/auth/controller/PhabricatorAuthTerminateSessionController.php',
|
'PhabricatorAuthTerminateSessionController' => 'applications/auth/controller/PhabricatorAuthTerminateSessionController.php',
|
||||||
'PhabricatorAuthTryFactorAction' => 'applications/auth/action/PhabricatorAuthTryFactorAction.php',
|
'PhabricatorAuthTryFactorAction' => 'applications/auth/action/PhabricatorAuthTryFactorAction.php',
|
||||||
'PhabricatorAuthUnlinkController' => 'applications/auth/controller/PhabricatorAuthUnlinkController.php',
|
'PhabricatorAuthUnlinkController' => 'applications/auth/controller/PhabricatorAuthUnlinkController.php',
|
||||||
|
@ -6164,6 +6166,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthSessionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorAuthSessionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'PhabricatorAuthSetupCheck' => 'PhabricatorSetupCheck',
|
'PhabricatorAuthSetupCheck' => 'PhabricatorSetupCheck',
|
||||||
'PhabricatorAuthStartController' => 'PhabricatorAuthController',
|
'PhabricatorAuthStartController' => 'PhabricatorAuthController',
|
||||||
|
'PhabricatorAuthTOTPKeyTemporaryTokenType' => 'PhabricatorAuthTemporaryTokenType',
|
||||||
'PhabricatorAuthTemporaryToken' => array(
|
'PhabricatorAuthTemporaryToken' => array(
|
||||||
'PhabricatorAuthDAO',
|
'PhabricatorAuthDAO',
|
||||||
'PhabricatorPolicyInterface',
|
'PhabricatorPolicyInterface',
|
||||||
|
@ -6171,6 +6174,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuthTemporaryTokenGarbageCollector' => 'PhabricatorGarbageCollector',
|
'PhabricatorAuthTemporaryTokenGarbageCollector' => 'PhabricatorGarbageCollector',
|
||||||
'PhabricatorAuthTemporaryTokenQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorAuthTemporaryTokenQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'PhabricatorAuthTemporaryTokenType' => 'Phobject',
|
'PhabricatorAuthTemporaryTokenType' => 'Phobject',
|
||||||
|
'PhabricatorAuthTemporaryTokenTypeModule' => 'PhabricatorConfigModule',
|
||||||
'PhabricatorAuthTerminateSessionController' => 'PhabricatorAuthController',
|
'PhabricatorAuthTerminateSessionController' => 'PhabricatorAuthController',
|
||||||
'PhabricatorAuthTryFactorAction' => 'PhabricatorSystemAction',
|
'PhabricatorAuthTryFactorAction' => 'PhabricatorSystemAction',
|
||||||
'PhabricatorAuthUnlinkController' => 'PhabricatorAuthController',
|
'PhabricatorAuthUnlinkController' => 'PhabricatorAuthController',
|
||||||
|
|
|
@ -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');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
final class PhabricatorTOTPAuthFactor extends PhabricatorAuthFactor {
|
final class PhabricatorTOTPAuthFactor extends PhabricatorAuthFactor {
|
||||||
|
|
||||||
const TEMPORARY_TOKEN_TYPE = 'mfa:totp:key';
|
|
||||||
|
|
||||||
public function getFactorKey() {
|
public function getFactorKey() {
|
||||||
return 'totp';
|
return 'totp';
|
||||||
}
|
}
|
||||||
|
@ -24,6 +22,8 @@ final class PhabricatorTOTPAuthFactor extends PhabricatorAuthFactor {
|
||||||
AphrontRequest $request,
|
AphrontRequest $request,
|
||||||
PhabricatorUser $user) {
|
PhabricatorUser $user) {
|
||||||
|
|
||||||
|
$totp_token_type = PhabricatorAuthTOTPKeyTemporaryTokenType::TOKENTYPE;
|
||||||
|
|
||||||
$key = $request->getStr('totpkey');
|
$key = $request->getStr('totpkey');
|
||||||
if (strlen($key)) {
|
if (strlen($key)) {
|
||||||
// If the user is providing a key, make sure it's a key we generated.
|
// 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())
|
$temporary_token = id(new PhabricatorAuthTemporaryTokenQuery())
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->withTokenResources(array($user->getPHID()))
|
->withTokenResources(array($user->getPHID()))
|
||||||
->withTokenTypes(array(self::TEMPORARY_TOKEN_TYPE))
|
->withTokenTypes(array($totp_token_type))
|
||||||
->withExpired(false)
|
->withExpired(false)
|
||||||
->withTokenCodes(array(PhabricatorHash::digest($key)))
|
->withTokenCodes(array(PhabricatorHash::digest($key)))
|
||||||
->executeOne();
|
->executeOne();
|
||||||
|
@ -56,7 +56,7 @@ final class PhabricatorTOTPAuthFactor extends PhabricatorAuthFactor {
|
||||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||||
id(new PhabricatorAuthTemporaryToken())
|
id(new PhabricatorAuthTemporaryToken())
|
||||||
->setTokenResource($user->getPHID())
|
->setTokenResource($user->getPHID())
|
||||||
->setTokenType(self::TEMPORARY_TOKEN_TYPE)
|
->setTokenType($totp_token_type)
|
||||||
->setTokenExpires(time() + phutil_units('1 hour in seconds'))
|
->setTokenExpires(time() + phutil_units('1 hour in seconds'))
|
||||||
->setTokenCode(PhabricatorHash::digest($key))
|
->setTokenCode(PhabricatorHash::digest($key))
|
||||||
->save();
|
->save();
|
||||||
|
|
|
@ -5,6 +5,10 @@ final class PhabricatorAuthOneTimeLoginTemporaryTokenType
|
||||||
|
|
||||||
const TOKENTYPE = 'login:onetime';
|
const TOKENTYPE = 'login:onetime';
|
||||||
|
|
||||||
|
public function getTokenTypeDisplayName() {
|
||||||
|
return pht('One-Time Login');
|
||||||
|
}
|
||||||
|
|
||||||
public function getTokenReadableTypeName(
|
public function getTokenReadableTypeName(
|
||||||
PhabricatorAuthTemporaryToken $token) {
|
PhabricatorAuthTemporaryToken $token) {
|
||||||
return pht('One-Time Login Token');
|
return pht('One-Time Login Token');
|
||||||
|
|
|
@ -5,6 +5,10 @@ final class PhabricatorAuthPasswordResetTemporaryTokenType
|
||||||
|
|
||||||
const TOKENTYPE = 'login:password';
|
const TOKENTYPE = 'login:password';
|
||||||
|
|
||||||
|
public function getTokenTypeDisplayName() {
|
||||||
|
return pht('Password Reset');
|
||||||
|
}
|
||||||
|
|
||||||
public function getTokenReadableTypeName(
|
public function getTokenReadableTypeName(
|
||||||
PhabricatorAuthTemporaryToken $token) {
|
PhabricatorAuthTemporaryToken $token) {
|
||||||
return pht('Password Reset Token');
|
return pht('Password Reset Token');
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
abstract class PhabricatorAuthTemporaryTokenType
|
abstract class PhabricatorAuthTemporaryTokenType
|
||||||
extends Phobject {
|
extends Phobject {
|
||||||
|
|
||||||
|
abstract public function getTokenTypeDisplayName();
|
||||||
abstract public function getTokenReadableTypeName(
|
abstract public function getTokenReadableTypeName(
|
||||||
PhabricatorAuthTemporaryToken $token);
|
PhabricatorAuthTemporaryToken $token);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue