diff --git a/js/settings.js b/js/settings.js index da1f8b7..18a3d4d 100644 --- a/js/settings.js +++ b/js/settings.js @@ -119,7 +119,7 @@ user_sql.adminSettingsUI = function () { ); autocomplete( - "#db-table-user-column-uid, #db-table-user-column-email, #db-table-user-column-quota, #db-table-user-column-home, #db-table-user-column-password, #db-table-user-column-name, #db-table-user-column-active, #db-table-user-column-disabled, #db-table-user-column-avatar, #db-table-user-column-salt", + "#db-table-user-column-uid, #db-table-user-column-username, #db-table-user-column-email, #db-table-user-column-quota, #db-table-user-column-home, #db-table-user-column-password, #db-table-user-column-name, #db-table-user-column-active, #db-table-user-column-disabled, #db-table-user-column-avatar, #db-table-user-column-salt", "/apps/user_sql/settings/autocomplete/table/user" ); diff --git a/lib/Backend/UserBackend.php b/lib/Backend/UserBackend.php index 22dc213..6656fdb 100644 --- a/lib/Backend/UserBackend.php +++ b/lib/Backend/UserBackend.php @@ -301,15 +301,15 @@ final class UserBackend extends ABackend implements * Check if the user's password is correct then return its ID or * FALSE on failure. * - * @param string $uid The user ID. + * @param string $username The user ID. * @param string $password The password. * * @return string|bool The user ID on success, false otherwise. */ - public function checkPassword(string $uid, string $password) + public function checkPassword(string $username, string $password) { $this->logger->debug( - "Entering checkPassword($uid, *)", ["app" => $this->appName] + "Entering checkPassword($username, *)", ["app" => $this->appName] ); $passwordAlgorithm = $this->getPasswordAlgorithm(); @@ -318,8 +318,8 @@ final class UserBackend extends ABackend implements } $caseSensitive = empty($this->properties[Opt::CASE_INSENSITIVE_USERNAME]); - $user = $this->userRepository->findByUid($uid, $caseSensitive); - if (!($user instanceof User) || ($caseSensitive && $user->uid !== $uid)) { + $user = $this->userRepository->findByUsername($username, $caseSensitive); + if (!($user instanceof User) || ($caseSensitive && $user->username !== $username)) { return false; } diff --git a/lib/Constant/DB.php b/lib/Constant/DB.php index 0442b13..e7f751d 100644 --- a/lib/Constant/DB.php +++ b/lib/Constant/DB.php @@ -55,4 +55,5 @@ final class DB const USER_QUOTA_COLUMN = "db.table.user.column.quota"; const USER_SALT_COLUMN = "db.table.user.column.salt"; const USER_UID_COLUMN = "db.table.user.column.uid"; + const USER_USERNAME_COLUMN = "db.table.user.column.username"; } diff --git a/lib/Constant/Query.php b/lib/Constant/Query.php index 8cbff2c..cad6ba9 100644 --- a/lib/Constant/Query.php +++ b/lib/Constant/Query.php @@ -36,6 +36,8 @@ final class Query const FIND_GROUPS = "find_groups"; const FIND_USER = "find_user"; const FIND_USER_CASE_INSENSITIVE = "find_user_case_insensitive"; + const FIND_USER_BY_USERNAME = "find_user_by_username"; + const FIND_USER_BY_USERNAME_CASE_INSENSITIVE = "find_user_by_username_case_insensitive"; const FIND_USER_GROUPS = "find_user_groups"; const FIND_USERS = "find_users"; const UPDATE_DISPLAY_NAME = "update_display_name"; @@ -50,4 +52,5 @@ final class Query const QUOTA_PARAM = "quota"; const SEARCH_PARAM = "search"; const UID_PARAM = "uid"; + const USERNAME_PARAM = "username"; } diff --git a/lib/Model/User.php b/lib/Model/User.php index 40ebf1c..0349f67 100644 --- a/lib/Model/User.php +++ b/lib/Model/User.php @@ -29,9 +29,13 @@ namespace OCA\UserSQL\Model; class User { /** - * @var string The UID (username). + * @var string The UID (uid). */ public $uid; + /** + * @var string The user's username for login. + */ + public $username; /** * @var string The user's email address. */ diff --git a/lib/Query/QueryProvider.php b/lib/Query/QueryProvider.php index 81ff994..8e16148 100644 --- a/lib/Query/QueryProvider.php +++ b/lib/Query/QueryProvider.php @@ -76,6 +76,7 @@ class QueryProvider implements \ArrayAccess $uQuota = $this->properties[DB::USER_QUOTA_COLUMN]; $uSalt = $this->properties[DB::USER_SALT_COLUMN]; $uUID = $this->properties[DB::USER_UID_COLUMN]; + $uUsername = $this->properties[DB::USER_USERNAME_COLUMN]; $ugGID = $this->properties[DB::USER_GROUP_GID_COLUMN]; $ugUID = $this->properties[DB::USER_GROUP_UID_COLUMN]; @@ -87,6 +88,7 @@ class QueryProvider implements \ArrayAccess $quotaParam = Query::QUOTA_PARAM; $searchParam = Query::SEARCH_PARAM; $uidParam = Query::UID_PARAM; + $usernameParam = Query::USERNAME_PARAM; $reverseActiveOpt = $this->properties[Opt::REVERSE_ACTIVE]; @@ -95,7 +97,7 @@ class QueryProvider implements \ArrayAccess (empty($gName) ? "g." . $gGID : "g." . $gName) . " AS name, " . (empty($gAdmin) ? "false" : "g." . $gAdmin) . " AS admin"; $userColumns - = "u.$uUID AS uid, " . + = "u.$uUID AS uid, u.$uUsername AS username, " . (empty($uName) ? "u." . $uUID : "u." . $uName) . " AS name, " . (empty($uEmail) ? "null" : "u." . $uEmail) . " AS email, " . (empty($uQuota) ? "null" : "u." . $uQuota) . " AS quota, " . @@ -156,6 +158,18 @@ class QueryProvider implements \ArrayAccess "FROM $user u " . "WHERE lower(u.$uUID) = lower(:$uidParam) " . (empty($uDisabled) ? "" : "AND NOT u.$uDisabled"), + + Query::FIND_USER_BY_USERNAME => + "SELECT $userColumns, u.$uPassword AS password " . + "FROM $user u " . + "WHERE u.$uUsername = :$usernameParam " . + (empty($uDisabled) ? "" : "AND NOT u.$uDisabled"), + + Query::FIND_USER_BY_USERNAME_CASE_INSENSITIVE => + "SELECT $userColumns, u.$uPassword AS password " . + "FROM $user u " . + "WHERE lower(u.$uUsername) = lower(:$usernameParam) " . + (empty($uDisabled) ? "" : "AND NOT u.$uDisabled"), Query::FIND_USER_GROUPS => "SELECT $groupColumns " . diff --git a/lib/Repository/UserRepository.php b/lib/Repository/UserRepository.php index 9841cf0..2f2eeec 100644 --- a/lib/Repository/UserRepository.php +++ b/lib/Repository/UserRepository.php @@ -74,6 +74,29 @@ class UserRepository ); } } + + /** + * Get an user entity object. + * + * @param string $username The username. + * @param bool $caseSensitive TRUE for case sensitive search, + * FALSE for case insensitive search. + * + * @return User The user entity, NULL if it does not exists or + * FALSE on failure. + */ + public function findByUsername($username, $caseSensitive = true) + { + if ($caseSensitive) { + return $this->dataQuery->queryEntity( + Query::FIND_USER_BY_USERNAME, User::class, [Query::USERNAME_PARAM => $username] + ); + } else { + return $this->dataQuery->queryEntity( + Query::FIND_USER_BY_USERNAME_CASE_INSENSITIVE, User::class, [Query::USERNAME_PARAM => $username] + ); + } + } /** * Get an array of user entity objects.