OATHUserRepository: add method to create and persist a key

This means that when keys will be ID-aware, a key object can be
immutable (instead of creating it without an ID and adding it in
persist()).

Change-Id: Ie1286ed71871dcedb2bd7d8d373f944be6691064
This commit is contained in:
Taavi Väänänen 2023-12-16 16:49:59 +02:00
parent 064308c1b9
commit 11d47134db
No known key found for this signature in database
GPG key ID: EF242F709F912FBE
3 changed files with 59 additions and 4 deletions

View file

@ -191,9 +191,12 @@ class TOTPEnableForm extends OATHAuthOOUIHTMLForm {
} }
$this->getRequest()->setSessionData( 'oathauth_totp_key', null ); $this->getRequest()->setSessionData( 'oathauth_totp_key', null );
$this->oathUser->setKeys( [ $key ] ); $this->oathRepo->createKey(
$this->oathUser->setModule( $this->module ); $this->oathUser,
$this->oathRepo->persist( $this->oathUser, $this->getRequest()->getIP() ); $this->module,
$key->jsonSerialize(),
$this->getRequest()->getIP()
);
return true; return true;
} }

View file

@ -9,7 +9,7 @@ use Message;
interface IModule { interface IModule {
/** /**
* Name of the module * Name of the module, as declared in the OATHAuth.Modules extension.json attribute.
* *
* @return string * @return string
*/ */

View file

@ -21,6 +21,7 @@ namespace MediaWiki\Extension\OATHAuth;
use BagOStuff; use BagOStuff;
use ConfigException; use ConfigException;
use FormatJson; use FormatJson;
use InvalidArgumentException;
use MediaWiki\Extension\OATHAuth\Notifications\Manager; use MediaWiki\Extension\OATHAuth\Notifications\Manager;
use MediaWiki\User\CentralId\CentralIdLookupFactory; use MediaWiki\User\CentralId\CentralIdLookupFactory;
use MWException; use MWException;
@ -176,6 +177,57 @@ class OATHUserRepository implements LoggerAwareInterface {
} }
} }
/**
* Persists the given OAuth key in the database.
*
* @param OATHUser $user
* @param IModule $module
* @param array $keyData
* @param string $clientInfo
* @return IAuthKey
*/
public function createKey( OATHUser $user, IModule $module, array $keyData, string $clientInfo ): IAuthKey {
if ( $user->getModule() && $user->getModule()->getName() !== $module->getName() ) {
throw new InvalidArgumentException(
"User already has a key from a different module enabled ({$user->getModule()->getName()})"
);
}
$userId = $this->centralIdLookupFactory->getLookup()->centralIdFromLocalUser( $user->getUser() );
$moduleId = $this->moduleRegistry->getModuleId( $module->getName() );
$dbw = $this->dbProvider->getPrimaryDatabase( 'virtual-oathauth' );
$dbw->newInsertQueryBuilder()
->insertInto( 'oathauth_devices' )
->row( [
'oad_user' => $userId,
'oad_type' => $moduleId,
'oad_data' => FormatJson::encode( $keyData ),
] )
->caller( __METHOD__ )
->execute();
$id = $dbw->insertId();
$hasExistingKey = $user->isTwoFactorAuthEnabled();
$key = $module->newKey( $keyData );
$user->addKey( $key );
$this->logger->info( 'OATHAuth {oathtype} key {key} added for {user} from {clientip}', [
'key' => $id,
'user' => $user->getUser()->getName(),
'clientip' => $clientInfo,
'oathtype' => $module->getName(),
] );
if ( !$hasExistingKey ) {
$user->setModule( $module );
Manager::notifyEnabled( $user );
}
return $key;
}
/** /**
* @param OATHUser $user * @param OATHUser $user
* @param string $clientInfo * @param string $clientInfo