Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2018-10-02 22:45:10 +0300
committerGitHub <noreply@github.com>2018-10-02 22:45:10 +0300
commit6b730b4c478bc4f55a89fd7d6a7c2715e2e5b829 (patch)
tree06218c0625e5ddc4045a7990347bcb8ca7fdc5ce /lib
parent19d552e00b16d8b5423b01755b5b1027df5a21ed (diff)
parent19f84f7b5485e204014671d0439e8af5693acbb1 (diff)
Merge pull request #11390 from nextcloud/feature/11043/apptoken_v3
Apptoken v3: imrpove token handling on external password change
Diffstat (limited to 'lib')
-rw-r--r--lib/composer/composer/autoload_classmap.php1
-rw-r--r--lib/composer/composer/autoload_static.php1
-rw-r--r--lib/private/Authentication/Token/DefaultTokenProvider.php12
-rw-r--r--lib/private/Authentication/Token/IProvider.php16
-rw-r--r--lib/private/Authentication/Token/Manager.php12
-rw-r--r--lib/private/Authentication/Token/PublicKeyToken.php9
-rw-r--r--lib/private/Authentication/Token/PublicKeyTokenMapper.php15
-rw-r--r--lib/private/Authentication/Token/PublicKeyTokenProvider.php26
-rw-r--r--lib/private/User/Session.php17
9 files changed, 106 insertions, 3 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 2522be9ec8f..7de8d3a4429 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -626,6 +626,7 @@ return array(
'OC\\Core\\Migrations\\Version14000Date20180626223656' => $baseDir . '/core/Migrations/Version14000Date20180626223656.php',
'OC\\Core\\Migrations\\Version14000Date20180710092004' => $baseDir . '/core/Migrations/Version14000Date20180710092004.php',
'OC\\Core\\Migrations\\Version14000Date20180712153140' => $baseDir . '/core/Migrations/Version14000Date20180712153140.php',
+ 'OC\\Core\\Migrations\\Version15000Date20180926101451' => $baseDir . '/core/Migrations/Version15000Date20180926101451.php',
'OC\\DB\\Adapter' => $baseDir . '/lib/private/DB/Adapter.php',
'OC\\DB\\AdapterMySQL' => $baseDir . '/lib/private/DB/AdapterMySQL.php',
'OC\\DB\\AdapterOCI8' => $baseDir . '/lib/private/DB/AdapterOCI8.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index e4e64ac1d55..8d92f623a09 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -656,6 +656,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Core\\Migrations\\Version14000Date20180626223656' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180626223656.php',
'OC\\Core\\Migrations\\Version14000Date20180710092004' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180710092004.php',
'OC\\Core\\Migrations\\Version14000Date20180712153140' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180712153140.php',
+ 'OC\\Core\\Migrations\\Version15000Date20180926101451' => __DIR__ . '/../../..' . '/core/Migrations/Version15000Date20180926101451.php',
'OC\\DB\\Adapter' => __DIR__ . '/../../..' . '/lib/private/DB/Adapter.php',
'OC\\DB\\AdapterMySQL' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterMySQL.php',
'OC\\DB\\AdapterOCI8' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterOCI8.php',
diff --git a/lib/private/Authentication/Token/DefaultTokenProvider.php b/lib/private/Authentication/Token/DefaultTokenProvider.php
index ad45303fa7c..a27a875a27f 100644
--- a/lib/private/Authentication/Token/DefaultTokenProvider.php
+++ b/lib/private/Authentication/Token/DefaultTokenProvider.php
@@ -338,4 +338,16 @@ class DefaultTokenProvider implements IProvider {
}
}
+ public function markPasswordInvalid(IToken $token, string $tokenId) {
+ if (!($token instanceof DefaultToken)) {
+ throw new InvalidTokenException();
+ }
+
+ //No need to mark as invalid. We just invalide default tokens
+ $this->invalidateToken($tokenId);
+ }
+
+ public function updatePasswords(string $uid, string $password) {
+ // Nothing to do here
+ }
}
diff --git a/lib/private/Authentication/Token/IProvider.php b/lib/private/Authentication/Token/IProvider.php
index ab46bd12126..7ee76b7b384 100644
--- a/lib/private/Authentication/Token/IProvider.php
+++ b/lib/private/Authentication/Token/IProvider.php
@@ -156,4 +156,20 @@ interface IProvider {
* @return IToken
*/
public function rotate(IToken $token, string $oldTokenId, string $newTokenId): IToken;
+
+ /**
+ * Marks a token as having an invalid password.
+ *
+ * @param IToken $token
+ * @param string $tokenId
+ */
+ public function markPasswordInvalid(IToken $token, string $tokenId);
+
+ /**
+ * Update all the passwords of $uid if required
+ *
+ * @param string $uid
+ * @param string $password
+ */
+ public function updatePasswords(string $uid, string $password);
}
diff --git a/lib/private/Authentication/Token/Manager.php b/lib/private/Authentication/Token/Manager.php
index 254a1598943..7c991eadea9 100644
--- a/lib/private/Authentication/Token/Manager.php
+++ b/lib/private/Authentication/Token/Manager.php
@@ -227,4 +227,16 @@ class Manager implements IProvider {
}
throw new InvalidTokenException();
}
+
+
+ public function markPasswordInvalid(IToken $token, string $tokenId) {
+ $this->getProvider($token)->markPasswordInvalid($token, $tokenId);
+ }
+
+ public function updatePasswords(string $uid, string $password) {
+ $this->defaultTokenProvider->updatePasswords($uid, $password);
+ $this->publicKeyTokenProvider->updatePasswords($uid, $password);
+ }
+
+
}
diff --git a/lib/private/Authentication/Token/PublicKeyToken.php b/lib/private/Authentication/Token/PublicKeyToken.php
index 0e793ce8c7c..b6f55146707 100644
--- a/lib/private/Authentication/Token/PublicKeyToken.php
+++ b/lib/private/Authentication/Token/PublicKeyToken.php
@@ -43,6 +43,7 @@ use OCP\AppFramework\Db\Entity;
* @method string getPublicKey()
* @method void setPublicKey(string $key)
* @method void setVersion(int $version)
+ * @method bool getPasswordInvalid()
*/
class PublicKeyToken extends Entity implements IToken {
@@ -90,6 +91,9 @@ class PublicKeyToken extends Entity implements IToken {
/** @var int */
protected $version;
+ /** @var bool */
+ protected $passwordInvalid;
+
public function __construct() {
$this->addType('uid', 'string');
$this->addType('loginName', 'string');
@@ -105,6 +109,7 @@ class PublicKeyToken extends Entity implements IToken {
$this->addType('publicKey', 'string');
$this->addType('privateKey', 'string');
$this->addType('version', 'int');
+ $this->addType('passwordInvalid', 'bool');
}
public function getId(): int {
@@ -214,4 +219,8 @@ class PublicKeyToken extends Entity implements IToken {
public function getExpires() {
return parent::getExpires();
}
+
+ public function setPasswordInvalid(bool $invalid) {
+ parent::setPasswordInvalid($invalid);
+ }
}
diff --git a/lib/private/Authentication/Token/PublicKeyTokenMapper.php b/lib/private/Authentication/Token/PublicKeyTokenMapper.php
index 5e5c69dbc46..df91066c44f 100644
--- a/lib/private/Authentication/Token/PublicKeyTokenMapper.php
+++ b/lib/private/Authentication/Token/PublicKeyTokenMapper.php
@@ -169,4 +169,19 @@ class PublicKeyTokenMapper extends QBMapper {
$qb->execute();
}
+
+ public function hasExpiredTokens(string $uid): bool {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from('authtoken')
+ ->where($qb->expr()->eq('uid', $qb->createNamedParameter($uid)))
+ ->andWhere($qb->expr()->eq('password_invalid', $qb->createNamedParameter(true), IQueryBuilder::PARAM_BOOL))
+ ->setMaxResults(1);
+
+ $cursor = $qb->execute();
+ $data = $cursor->fetchAll();
+ $cursor->closeCursor();
+
+ return count($data) === 1;
+ }
}
diff --git a/lib/private/Authentication/Token/PublicKeyTokenProvider.php b/lib/private/Authentication/Token/PublicKeyTokenProvider.php
index 7e98ee939ce..33c0b1d59eb 100644
--- a/lib/private/Authentication/Token/PublicKeyTokenProvider.php
+++ b/lib/private/Authentication/Token/PublicKeyTokenProvider.php
@@ -317,4 +317,30 @@ class PublicKeyTokenProvider implements IProvider {
return $dbToken;
}
+
+ public function markPasswordInvalid(IToken $token, string $tokenId) {
+ if (!($token instanceof PublicKeyToken)) {
+ throw new InvalidTokenException();
+ }
+
+ $token->setPasswordInvalid(true);
+ $this->mapper->update($token);
+ }
+
+ public function updatePasswords(string $uid, string $password) {
+ if (!$this->mapper->hasExpiredTokens($uid)) {
+ // Nothing to do here
+ return;
+ }
+
+ // Update the password for all tokens
+ $tokens = $this->mapper->getTokenByUser($uid);
+ foreach ($tokens as $t) {
+ $publicKey = $t->getPublicKey();
+ $t->setPassword($this->encryptPassword($password, $publicKey));
+ $this->updateToken($t);
+ }
+ }
+
+
}
diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php
index 5593e178ca3..a9c638dca93 100644
--- a/lib/private/User/Session.php
+++ b/lib/private/User/Session.php
@@ -694,12 +694,19 @@ class Session implements IUserSession, Emitter {
return true;
}
- if ($this->manager->checkPassword($dbToken->getLoginName(), $pwd) === false
- || (!is_null($this->activeUser) && !$this->activeUser->isEnabled())) {
+ // Invalidate token if the user is no longer active
+ if (!is_null($this->activeUser) && !$this->activeUser->isEnabled()) {
$this->tokenProvider->invalidateToken($token);
- // Password has changed or user was disabled -> log user out
return false;
}
+
+ // If the token password is no longer valid mark it as such
+ if ($this->manager->checkPassword($dbToken->getLoginName(), $pwd) === false) {
+ $this->tokenProvider->markPasswordInvalid($dbToken, $token);
+ // User is logged out
+ return false;
+ }
+
$dbToken->setLastCheck($now);
return true;
}
@@ -943,5 +950,9 @@ class Session implements IUserSession, Emitter {
}
}
+ public function updateTokens(string $uid, string $password) {
+ $this->tokenProvider->updatePasswords($uid, $password);
+ }
+
}