diff options
author | Christoph Wurst <christoph@owncloud.com> | 2016-06-21 10:23:50 +0200 |
---|---|---|
committer | Christoph Wurst <christoph@owncloud.com> | 2016-06-21 10:24:25 +0200 |
commit | b805908dca5cd4daf9f56bc140bbed48e067d573 (patch) | |
tree | 9c9bee8639d269b80985621c873163b5803a6a8b | |
parent | 0e575c7eeadc6c8eb11b0be2ed1d39cdcf6cfcb8 (diff) | |
download | nextcloud-server-b805908dca5cd4daf9f56bc140bbed48e067d573.tar.gz nextcloud-server-b805908dca5cd4daf9f56bc140bbed48e067d573.zip |
update session token password on user password change
-rw-r--r-- | lib/private/Authentication/Token/DefaultTokenProvider.php | 17 | ||||
-rw-r--r-- | lib/private/Authentication/Token/IProvider.php | 10 | ||||
-rw-r--r-- | lib/private/User/Session.php | 17 | ||||
-rw-r--r-- | settings/ChangePassword/Controller.php | 1 | ||||
-rw-r--r-- | tests/lib/Authentication/Token/DefaultTokenProviderTest.php | 33 | ||||
-rw-r--r-- | tests/lib/User/SessionTest.php | 65 |
6 files changed, 143 insertions, 0 deletions
diff --git a/lib/private/Authentication/Token/DefaultTokenProvider.php b/lib/private/Authentication/Token/DefaultTokenProvider.php index 84effc5f875..75f0fb10ba6 100644 --- a/lib/private/Authentication/Token/DefaultTokenProvider.php +++ b/lib/private/Authentication/Token/DefaultTokenProvider.php @@ -151,6 +151,23 @@ class DefaultTokenProvider implements IProvider { } /** + * Encrypt and set the password of the given token + * + * @param IToken $token + * @param string $tokenId + * @param string $password + * @throws InvalidTokenException + */ + public function setPassword(IToken $token, $tokenId, $password) { + if (!($token instanceof DefaultToken)) { + throw new InvalidTokenException(); + } + /** @var DefaultToken $token */ + $token->setPassword($this->encryptPassword($password, $tokenId)); + $this->mapper->update($token); + } + + /** * Invalidate (delete) the given session token * * @param string $token diff --git a/lib/private/Authentication/Token/IProvider.php b/lib/private/Authentication/Token/IProvider.php index fece7dcb567..a9950dfaa4b 100644 --- a/lib/private/Authentication/Token/IProvider.php +++ b/lib/private/Authentication/Token/IProvider.php @@ -99,4 +99,14 @@ interface IProvider { * @return string */ public function getPassword(IToken $token, $tokenId); + + /** + * Encrypt and set the password of the given token + * + * @param IToken $token + * @param string $tokenId + * @param string $password + * @throws InvalidTokenException + */ + public function setPassword(IToken $token, $tokenId, $password); } diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php index 4e9c827448d..fe1835b3e55 100644 --- a/lib/private/User/Session.php +++ b/lib/private/User/Session.php @@ -676,4 +676,21 @@ class Session implements IUserSession, Emitter { setcookie('oc_remember_login', '', time() - 3600, OC::$WEBROOT . '/', '', $secureCookie, true); } + /** + * Update password of the browser session token if there is one + * + * @param string $password + */ + public function updateSessionTokenPassword($password) { + try { + $sessionId = $this->session->getId(); + $token = $this->tokenProvider->getToken($sessionId); + $this->tokenProvider->setPassword($token, $sessionId, $password); + } catch (SessionNotAvailableException $ex) { + // Nothing to do + } catch (InvalidTokenException $ex) { + // Nothing to do + } + } + } diff --git a/settings/ChangePassword/Controller.php b/settings/ChangePassword/Controller.php index 5a6c985f181..2bf743575b0 100644 --- a/settings/ChangePassword/Controller.php +++ b/settings/ChangePassword/Controller.php @@ -46,6 +46,7 @@ class Controller { exit(); } if (!is_null($password) && \OC_User::setPassword($username, $password)) { + \OC::$server->getUserSession()->updateSessionTokenPassword($username, $password); \OC_JSON::success(); } else { \OC_JSON::error(); diff --git a/tests/lib/Authentication/Token/DefaultTokenProviderTest.php b/tests/lib/Authentication/Token/DefaultTokenProviderTest.php index 98cee208065..d4117d877ea 100644 --- a/tests/lib/Authentication/Token/DefaultTokenProviderTest.php +++ b/tests/lib/Authentication/Token/DefaultTokenProviderTest.php @@ -175,6 +175,39 @@ class DefaultTokenProviderTest extends TestCase { $tokenProvider->getPassword($tk, $token); } + public function testSetPassword() { + $token = new DefaultToken(); + $tokenId = 'token123'; + $password = '123456'; + + $this->config->expects($this->once()) + ->method('getSystemValue') + ->with('secret') + ->will($this->returnValue('ocsecret')); + $this->crypto->expects($this->once()) + ->method('encrypt') + ->with($password, $tokenId . 'ocsecret') + ->will($this->returnValue('encryptedpassword')); + $this->mapper->expects($this->once()) + ->method('update') + ->with($token); + + $this->tokenProvider->setPassword($token, $tokenId, $password); + + $this->assertEquals('encryptedpassword', $token->getPassword()); + } + + /** + * @expectedException \OC\Authentication\Exceptions\InvalidTokenException + */ + public function testSetPasswordInvalidToken() { + $token = $this->getMock('\OC\Authentication\Token\IToken'); + $tokenId = 'token123'; + $password = '123456'; + + $this->tokenProvider->setPassword($token, $tokenId, $password); + } + public function testInvalidateToken() { $this->mapper->expects($this->once()) ->method('invalidate') diff --git a/tests/lib/User/SessionTest.php b/tests/lib/User/SessionTest.php index 7a34d42a2bc..4dcdc7c1348 100644 --- a/tests/lib/User/SessionTest.php +++ b/tests/lib/User/SessionTest.php @@ -818,4 +818,69 @@ class SessionTest extends \Test\TestCase { $this->invokePrivate($userSession, 'validateSession', [$user]); } + public function testUpdateSessionTokenPassword() { + $userManager = $this->getMock('\OCP\IUserManager'); + $session = $this->getMock('\OCP\ISession'); + $timeFactory = $this->getMock('\OCP\AppFramework\Utility\ITimeFactory'); + $tokenProvider = $this->getMock('\OC\Authentication\Token\IProvider'); + $userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config); + + $password = '123456'; + $sessionId ='session1234'; + $token = new \OC\Authentication\Token\DefaultToken(); + + $session->expects($this->once()) + ->method('getId') + ->will($this->returnValue($sessionId)); + $tokenProvider->expects($this->once()) + ->method('getToken') + ->with($sessionId) + ->will($this->returnValue($token)); + $tokenProvider->expects($this->once()) + ->method('setPassword') + ->with($token, $sessionId, $password); + + $userSession->updateSessionTokenPassword($password); + } + + public function testUpdateSessionTokenPasswordNoSessionAvailable() { + $userManager = $this->getMock('\OCP\IUserManager'); + $session = $this->getMock('\OCP\ISession'); + $timeFactory = $this->getMock('\OCP\AppFramework\Utility\ITimeFactory'); + $tokenProvider = $this->getMock('\OC\Authentication\Token\IProvider'); + $userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config); + + $session->expects($this->once()) + ->method('getId') + ->will($this->throwException(new \OCP\Session\Exceptions\SessionNotAvailableException())); + + $userSession->updateSessionTokenPassword('1234'); + } + + public function testUpdateSessionTokenPasswordInvalidTokenException() { + $userManager = $this->getMock('\OCP\IUserManager'); + $session = $this->getMock('\OCP\ISession'); + $timeFactory = $this->getMock('\OCP\AppFramework\Utility\ITimeFactory'); + $tokenProvider = $this->getMock('\OC\Authentication\Token\IProvider'); + $userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config); + + $password = '123456'; + $sessionId ='session1234'; + $token = new \OC\Authentication\Token\DefaultToken(); + + $session->expects($this->once()) + ->method('getId') + ->will($this->returnValue($sessionId)); + $tokenProvider->expects($this->once()) + ->method('getToken') + ->with($sessionId) + ->will($this->returnValue($token)); + $tokenProvider->expects($this->once()) + ->method('setPassword') + ->with($token, $sessionId, $password) + ->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException())); + + $userSession->updateSessionTokenPassword($password); + } + } |