Actually convert the token
* When getting the token * When rotating the token * Also store the encrypted password as base64 to avoid weird binary stuff Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
This commit is contained in:
parent
d03d16a936
commit
f168ecfa7a
|
@ -121,8 +121,19 @@ class Manager implements IProvider {
|
|||
try {
|
||||
return $this->publicKeyTokenProvider->getToken($tokenId);
|
||||
} catch (InvalidTokenException $e) {
|
||||
return $this->defaultTokenProvider->getToken($tokenId);
|
||||
// No worries we try to convert it to a PublicKey Token
|
||||
}
|
||||
|
||||
//Convert!
|
||||
$token = $this->defaultTokenProvider->getToken($tokenId);
|
||||
|
||||
try {
|
||||
$password = $this->defaultTokenProvider->getPassword($token, $tokenId);
|
||||
} catch (PasswordlessTokenException $e) {
|
||||
$password = null;
|
||||
}
|
||||
|
||||
return $this->publicKeyTokenProvider->convertToken($token, $tokenId, $password);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,7 +160,6 @@ class Manager implements IProvider {
|
|||
try {
|
||||
$this->publicKeyTokenProvider->renewSessionToken($oldSessionId, $sessionId);
|
||||
} catch (InvalidTokenException $e) {
|
||||
//TODO: Move to new token
|
||||
$this->defaultTokenProvider->renewSessionToken($oldSessionId, $sessionId);
|
||||
}
|
||||
}
|
||||
|
@ -163,7 +173,6 @@ class Manager implements IProvider {
|
|||
*/
|
||||
public function getPassword(IToken $savedToken, string $tokenId): string {
|
||||
if ($savedToken instanceof DefaultToken) {
|
||||
//TODO convert to new token type
|
||||
return $this->defaultTokenProvider->getPassword($savedToken, $tokenId);
|
||||
}
|
||||
|
||||
|
@ -173,9 +182,7 @@ class Manager implements IProvider {
|
|||
}
|
||||
|
||||
public function setPassword(IToken $token, string $tokenId, string $password) {
|
||||
|
||||
if ($token instanceof DefaultToken) {
|
||||
//TODO conver to new token
|
||||
$this->defaultTokenProvider->setPassword($token, $tokenId, $password);
|
||||
}
|
||||
|
||||
|
@ -200,10 +207,14 @@ class Manager implements IProvider {
|
|||
}
|
||||
|
||||
public function rotate(IToken $token, string $oldTokenId, string $newTokenId): IToken {
|
||||
|
||||
if ($token instanceof DefaultToken) {
|
||||
//TODO Migrate to new token
|
||||
return $this->defaultTokenProvider->rotate($token, $oldTokenId, $newTokenId);
|
||||
try {
|
||||
$password = $this->defaultTokenProvider->getPassword($token, $oldTokenId);
|
||||
} catch (PasswordlessTokenException $e) {
|
||||
$password = null;
|
||||
}
|
||||
|
||||
return $this->publicKeyTokenProvider->convertToken($token, $newTokenId, $password);
|
||||
}
|
||||
|
||||
if ($token instanceof PublicKeyToken) {
|
||||
|
|
|
@ -159,4 +159,12 @@ class PublicKeyTokenMapper extends QBMapper {
|
|||
$qb->execute();
|
||||
}
|
||||
|
||||
public function deleteTempToken(PublicKeyToken $except) {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$qb->delete('authtoken')
|
||||
->where($qb->expr()->eq('type', $qb->createNamedParameter(IToken::TEMPORARY_TOKEN)))
|
||||
->andWhere($qb->expr()->neq('id', $qb->createNamedParameter($except->getId())))
|
||||
->andWhere($qb->expr()->eq('version', $qb->createNamedParameter(2, IQueryBuilder::PARAM_INT)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,36 +67,7 @@ class PublicKeyTokenProvider implements IProvider {
|
|||
string $name,
|
||||
int $type = IToken::TEMPORARY_TOKEN,
|
||||
int $remember = IToken::DO_NOT_REMEMBER): IToken {
|
||||
$dbToken = new PublicKeyToken();
|
||||
$dbToken->setUid($uid);
|
||||
$dbToken->setLoginName($loginName);
|
||||
|
||||
$config = [
|
||||
'digest_alg' => 'sha512',
|
||||
'private_key_bits' => 2048,
|
||||
];
|
||||
|
||||
// Generate new key
|
||||
$res = openssl_pkey_new($config);
|
||||
openssl_pkey_export($res, $privateKey);
|
||||
|
||||
// Extract the public key from $res to $pubKey
|
||||
$publicKey = openssl_pkey_get_details($res);
|
||||
$publicKey = $publicKey['key'];
|
||||
|
||||
$dbToken->setPublicKey($publicKey);
|
||||
$dbToken->setPrivateKey($this->encrypt($privateKey, $token));
|
||||
|
||||
if (!is_null($password)) {
|
||||
$dbToken->setPassword($this->encryptPassword($password, $publicKey));
|
||||
}
|
||||
|
||||
$dbToken->setName($name);
|
||||
$dbToken->setToken($this->hashToken($token));
|
||||
$dbToken->setType($type);
|
||||
$dbToken->setRemember($remember);
|
||||
$dbToken->setLastActivity($this->time->getTime());
|
||||
$dbToken->setLastCheck($this->time->getTime());
|
||||
$dbToken = $this->newToken($token, $uid, $loginName, $password, $name, $type, $remember);
|
||||
|
||||
$this->mapper->insert($dbToken);
|
||||
|
||||
|
@ -219,6 +190,9 @@ class PublicKeyTokenProvider implements IProvider {
|
|||
throw new InvalidTokenException();
|
||||
}
|
||||
|
||||
// When changeing passwords all temp tokens are deleted
|
||||
$this->mapper->deleteTempToken($token);
|
||||
|
||||
// Update the password for all tokens
|
||||
$tokens = $this->mapper->getTokenByUser($token->getUID());
|
||||
foreach ($tokens as $t) {
|
||||
|
@ -226,8 +200,6 @@ class PublicKeyTokenProvider implements IProvider {
|
|||
$t->setPassword($this->encryptPassword($password, $publicKey));
|
||||
$this->updateToken($t);
|
||||
}
|
||||
|
||||
//TODO: should we also do this for temp tokens?
|
||||
}
|
||||
|
||||
public function rotate(IToken $token, string $oldTokenId, string $newTokenId): IToken {
|
||||
|
@ -267,11 +239,13 @@ class PublicKeyTokenProvider implements IProvider {
|
|||
|
||||
private function encryptPassword(string $password, string $publicKey): string {
|
||||
openssl_public_encrypt($password, $encryptedPassword, $publicKey, OPENSSL_PKCS1_OAEP_PADDING);
|
||||
$encryptedPassword = base64_encode($encryptedPassword);
|
||||
|
||||
return $encryptedPassword;
|
||||
}
|
||||
|
||||
private function decryptPassword(string $encryptedPassword, string $privateKey): string {
|
||||
$encryptedPassword = base64_decode($encryptedPassword);
|
||||
openssl_private_decrypt($encryptedPassword, $password, $privateKey, OPENSSL_PKCS1_OAEP_PADDING);
|
||||
|
||||
return $password;
|
||||
|
@ -281,4 +255,65 @@ class PublicKeyTokenProvider implements IProvider {
|
|||
$secret = $this->config->getSystemValue('secret');
|
||||
return hash('sha512', $token . $secret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a DefaultToken to a publicKeyToken
|
||||
* This will also be updated directly in the Database
|
||||
*/
|
||||
public function convertToken(DefaultToken $defaultToken, string $token, $password): PublicKeyToken {
|
||||
$pkToken = $this->newToken(
|
||||
$token,
|
||||
$defaultToken->getUID(),
|
||||
$defaultToken->getLoginName(),
|
||||
$password,
|
||||
$defaultToken->getName(),
|
||||
$defaultToken->getType(),
|
||||
$defaultToken->getRemember()
|
||||
);
|
||||
|
||||
$pkToken->setId($defaultToken->getId());
|
||||
|
||||
return $this->mapper->update($pkToken);
|
||||
}
|
||||
|
||||
private function newToken(string $token,
|
||||
string $uid,
|
||||
string $loginName,
|
||||
$password,
|
||||
string $name,
|
||||
int $type,
|
||||
int $remember): PublicKeyToken {
|
||||
$dbToken = new PublicKeyToken();
|
||||
$dbToken->setUid($uid);
|
||||
$dbToken->setLoginName($loginName);
|
||||
|
||||
$config = [
|
||||
'digest_alg' => 'sha512',
|
||||
'private_key_bits' => 2048,
|
||||
];
|
||||
|
||||
// Generate new key
|
||||
$res = openssl_pkey_new($config);
|
||||
openssl_pkey_export($res, $privateKey);
|
||||
|
||||
// Extract the public key from $res to $pubKey
|
||||
$publicKey = openssl_pkey_get_details($res);
|
||||
$publicKey = $publicKey['key'];
|
||||
|
||||
$dbToken->setPublicKey($publicKey);
|
||||
$dbToken->setPrivateKey($this->encrypt($privateKey, $token));
|
||||
|
||||
if (!is_null($password)) {
|
||||
$dbToken->setPassword($this->encryptPassword($password, $publicKey));
|
||||
}
|
||||
|
||||
$dbToken->setName($name);
|
||||
$dbToken->setToken($this->hashToken($token));
|
||||
$dbToken->setType($type);
|
||||
$dbToken->setRemember($remember);
|
||||
$dbToken->setLastActivity($this->time->getTime());
|
||||
$dbToken->setLastCheck($this->time->getTime());
|
||||
|
||||
return $dbToken;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue