Browse Source

Allow the rotation of tokens

This for example will allow rotating the apptoken for oauth

Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
tags/v14.0.0beta1
Roeland Jago Douma 6 years ago
parent
commit
aba255997a
No account linked to committer's email address

+ 8
- 2
lib/private/Authentication/Token/DefaultToken.php View File

@@ -30,9 +30,7 @@ use OCP\AppFramework\Db\Entity;
* @method void setId(int $id)
* @method void setUid(string $uid);
* @method void setLoginName(string $loginname)
* @method void setPassword(string $password)
* @method void setName(string $name)
* @method void setToken(string $token)
* @method string getToken()
* @method void setType(int $type)
* @method int getType()
@@ -173,4 +171,12 @@ class DefaultToken extends Entity implements IToken {
public function getRemember(): int {
return parent::getRemember();
}

public function setToken(string $token) {
parent::setToken($token);
}

public function setPassword(string $password = null) {
parent::setPassword($password);
}
}

+ 22
- 0
lib/private/Authentication/Token/DefaultTokenProvider.php View File

@@ -273,6 +273,28 @@ class DefaultTokenProvider implements IProvider {
$this->mapper->invalidateOld($rememberThreshold, IToken::REMEMBER);
}

/**
* Rotate the token. Usefull for for example oauth tokens
*
* @param IToken $token
* @param string $oldTokenId
* @param string $newTokenId
* @return IToken
*/
public function rotate(IToken $token, string $oldTokenId, string $newTokenId): IToken {
try {
$password = $this->getPassword($token, $oldTokenId);
$token->setPassword($this->encryptPassword($password, $newTokenId));
} catch (PasswordlessTokenException $e) {

}

$token->setToken($this->hashToken($newTokenId));
$this->updateToken($token);

return $token;
}

/**
* @param string $token
* @return string

+ 10
- 0
lib/private/Authentication/Token/IProvider.php View File

@@ -145,4 +145,14 @@ interface IProvider {
* @throws InvalidTokenException
*/
public function setPassword(IToken $token, string $tokenId, string $password);

/**
* Rotate the token. Usefull for for example oauth tokens
*
* @param IToken $token
* @param string $oldTokenId
* @param string $newTokenId
* @return IToken
*/
public function rotate(IToken $token, string $oldTokenId, string $newTokenId): IToken;
}

+ 23
- 0
lib/private/Authentication/Token/IToken.php View File

@@ -96,7 +96,30 @@ interface IToken extends JsonSerializable {
*/
public function setScope($scope);

/**
* Get the name of the token
* @return string
*/
public function getName(): string;

/**
* Get the remember state of the token
*
* @return int
*/
public function getRemember(): int;

/**
* Set the token
*
* @param string $token
*/
public function setToken(string $token);

/**
* Set the password
*
* @param string $password
*/
public function setPassword(string $password);
}

+ 42
- 0
tests/lib/Authentication/Token/DefaultTokenProviderTest.php View File

@@ -416,4 +416,46 @@ class DefaultTokenProviderTest extends TestCase {

$this->tokenProvider->getTokenById(42);
}

public function testRotate() {
$token = new DefaultToken();
$token->setPassword('oldencryptedpassword');

$this->config->method('getSystemValue')
->with('secret')
->willReturn('mysecret');

$this->crypto->method('decrypt')
->with('oldencryptedpassword', 'oldtokenmysecret')
->willReturn('mypassword');
$this->crypto->method('encrypt')
->with('mypassword', 'newtokenmysecret')
->willReturn('newencryptedpassword');

$this->mapper->expects($this->once())
->method('update')
->with($this->callback(function (DefaultToken $token) {
return $token->getPassword() === 'newencryptedpassword' &&
$token->getToken() === hash('sha512', 'newtokenmysecret');
}));

$this->tokenProvider->rotate($token, 'oldtoken', 'newtoken');
}

public function testRotateNoPassword() {
$token = new DefaultToken();

$this->config->method('getSystemValue')
->with('secret')
->willReturn('mysecret');

$this->mapper->expects($this->once())
->method('update')
->with($this->callback(function (DefaultToken $token) {
return $token->getPassword() === null &&
$token->getToken() === hash('sha512', 'newtokenmysecret');
}));

$this->tokenProvider->rotate($token, 'oldtoken', 'newtoken');
}
}

Loading…
Cancel
Save