Skip to content

Commit

Permalink
Merge pull request #46123 from nextcloud/feat/user-password-hash
Browse files Browse the repository at this point in the history
feat: Allow getting/setting the password hash of a user
  • Loading branch information
Pytal authored Jul 9, 2024
2 parents 025a784 + c390ae9 commit 3a97dbf
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 1 deletion.
1 change: 1 addition & 0 deletions lib/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,7 @@
'OCP\\User\\Backend\\IGetHomeBackend' => $baseDir . '/lib/public/User/Backend/IGetHomeBackend.php',
'OCP\\User\\Backend\\IGetRealUIDBackend' => $baseDir . '/lib/public/User/Backend/IGetRealUIDBackend.php',
'OCP\\User\\Backend\\IPasswordConfirmationBackend' => $baseDir . '/lib/public/User/Backend/IPasswordConfirmationBackend.php',
'OCP\\User\\Backend\\IPasswordHashBackend' => $baseDir . '/lib/public/User/Backend/IPasswordHashBackend.php',
'OCP\\User\\Backend\\IProvideAvatarBackend' => $baseDir . '/lib/public/User/Backend/IProvideAvatarBackend.php',
'OCP\\User\\Backend\\IProvideEnabledStateBackend' => $baseDir . '/lib/public/User/Backend/IProvideEnabledStateBackend.php',
'OCP\\User\\Backend\\ISearchKnownUsersBackend' => $baseDir . '/lib/public/User/Backend/ISearchKnownUsersBackend.php',
Expand Down
1 change: 1 addition & 0 deletions lib/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\User\\Backend\\IGetHomeBackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/IGetHomeBackend.php',
'OCP\\User\\Backend\\IGetRealUIDBackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/IGetRealUIDBackend.php',
'OCP\\User\\Backend\\IPasswordConfirmationBackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/IPasswordConfirmationBackend.php',
'OCP\\User\\Backend\\IPasswordHashBackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/IPasswordHashBackend.php',
'OCP\\User\\Backend\\IProvideAvatarBackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/IProvideAvatarBackend.php',
'OCP\\User\\Backend\\IProvideEnabledStateBackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/IProvideEnabledStateBackend.php',
'OCP\\User\\Backend\\ISearchKnownUsersBackend' => __DIR__ . '/../../..' . '/lib/public/User/Backend/ISearchKnownUsersBackend.php',
Expand Down
39 changes: 38 additions & 1 deletion lib/private/User/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/
namespace OC\User;

use InvalidArgumentException;
use OCP\AppFramework\Db\TTransactional;
use OCP\Cache\CappedMemoryCache;
use OCP\EventDispatcher\IEventDispatcher;
Expand All @@ -21,6 +22,7 @@
use OCP\User\Backend\IGetDisplayNameBackend;
use OCP\User\Backend\IGetHomeBackend;
use OCP\User\Backend\IGetRealUIDBackend;
use OCP\User\Backend\IPasswordHashBackend;
use OCP\User\Backend\ISearchKnownUsersBackend;
use OCP\User\Backend\ISetDisplayNameBackend;
use OCP\User\Backend\ISetPasswordBackend;
Expand All @@ -37,7 +39,8 @@ class Database extends ABackend implements
IGetHomeBackend,
ICountUsersBackend,
ISearchKnownUsersBackend,
IGetRealUIDBackend {
IGetRealUIDBackend,
IPasswordHashBackend {
/** @var CappedMemoryCache */
private $cache;

Expand Down Expand Up @@ -176,6 +179,40 @@ public function setPassword(string $uid, string $password): bool {
return false;
}

public function getPasswordHash(string $userId): ?string {
$this->fixDI();
if (!$this->userExists($userId)) {
return null;
}
if (!empty($this->cache[$userId]['password'])) {
return $this->cache[$userId]['password'];
}
$qb = $this->dbConn->getQueryBuilder();
$qb->select('password')
->from($this->table)
->where($qb->expr()->eq('uid_lower', $qb->createNamedParameter(mb_strtolower($userId))));
/** @var false|string $hash */
$hash = $qb->executeQuery()->fetchOne();
if ($hash === false) {
return null;
}
$this->cache[$userId]['password'] = $hash;
return $hash;
}

public function setPasswordHash(string $userId, string $passwordHash): bool {
if (!\OCP\Server::get(IHasher::class)->validate($passwordHash)) {
throw new InvalidArgumentException();
}
$this->fixDI();
$result = $this->updatePassword($userId, $passwordHash);
if (!$result) {
return false;
}
$this->cache[$userId]['password'] = $passwordHash;
return true;
}

/**
* Set display name
*
Expand Down
8 changes: 8 additions & 0 deletions lib/private/User/LazyUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ public function setPassword($password, $recoveryPassword = null) {
return $this->getUser()->setPassword($password, $recoveryPassword);
}

public function getPasswordHash(): ?string {
return $this->getUser()->getPasswordHash();
}

public function setPasswordHash(string $passwordHash): bool {
return $this->getUser()->setPasswordHash($passwordHash);
}

public function getHome() {
return $this->getUser()->getHome();
}
Expand Down
15 changes: 15 additions & 0 deletions lib/private/User/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use OCP\IUserBackend;
use OCP\Notification\IManager as INotificationManager;
use OCP\User\Backend\IGetHomeBackend;
use OCP\User\Backend\IPasswordHashBackend;
use OCP\User\Backend\IProvideAvatarBackend;
use OCP\User\Backend\IProvideEnabledStateBackend;
use OCP\User\Backend\ISetDisplayNameBackend;
Expand Down Expand Up @@ -319,6 +320,20 @@ public function setPassword($password, $recoveryPassword = null) {
}
}

public function getPasswordHash(): ?string {
if (!($this->backend instanceof IPasswordHashBackend)) {
return null;
}
return $this->backend->getPasswordHash($this->uid);
}

public function setPasswordHash(string $passwordHash): bool {
if (!($this->backend instanceof IPasswordHashBackend)) {
return false;
}
return $this->backend->setPasswordHash($this->uid, $passwordHash);
}

/**
* get the users home folder to mount
*
Expand Down
17 changes: 17 additions & 0 deletions lib/public/IUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,23 @@ public function delete();
*/
public function setPassword($password, $recoveryPassword = null);

/**
* Get the password hash of the user
*
* @return ?string the password hash hashed by `\OCP\Security\IHasher::hash()`
* @since 30.0.0
*/
public function getPasswordHash(): ?string;

/**
* Set the password hash of the user
*
* @param string $passwordHash the password hash hashed by `\OCP\Security\IHasher::hash()`
* @throws InvalidArgumentException when `$passwordHash` is not a valid hash
* @since 30.0.0
*/
public function setPasswordHash(string $passwordHash): bool;

/**
* get the users home folder to mount
*
Expand Down
30 changes: 30 additions & 0 deletions lib/public/User/Backend/IPasswordHashBackend.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCP\User\Backend;

use InvalidArgumentException;

/**
* @since 30.0.0
*/
interface IPasswordHashBackend {
/**
* @return ?string the password hash hashed by `\OCP\Security\IHasher::hash()`
* @since 30.0.0
*/
public function getPasswordHash(string $userId): ?string;

/**
* @param string $passwordHash the password hash hashed by `\OCP\Security\IHasher::hash()`
* @throws InvalidArgumentException when `$passwordHash` is not a valid hash
* @since 30.0.0
*/
public function setPasswordHash(string $userId, string $passwordHash): bool;
}

0 comments on commit 3a97dbf

Please sign in to comment.