From 953dae293e754431fd540832c602a398a13dac93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20=C5=81ojewski?= Date: Sun, 29 Mar 2020 22:08:35 +0200 Subject: [PATCH] issue#135 Allow email login --- CHANGELOG.md | 1 + README.md | 1 + lib/Backend/UserBackend.php | 12 +++++++++--- lib/Constant/Opt.php | 1 + lib/Constant/Query.php | 4 +++- lib/Properties.php | 2 +- lib/Query/QueryProvider.php | 14 +++++++++++++- lib/Repository/UserRepository.php | 27 ++++++++++++++++++++++++++- templates/admin.php | 1 + 9 files changed, 56 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e95f021..66cfb78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Support for Nextcloud 19 - Argon2id support - System wide values option +- Allow email login option ## [4.4.1] - 2020-02-02 ### Fixed diff --git a/README.md b/README.md index c0931f1..34acacc 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ Here are all currently supported options. Name | Description | Details --- | --- | --- **Allow display name change** | With this option enabled user can change its display name. The display name change is propagated to the database. | Optional.
Default: *false*.
Requires: user *Display name* column. +**Allow email login** | User input at login is considered to be either UID or email. | Optional.
Default: *false*.
Requires: user *Email* column. **Allow password change** | Can user change its password. The password change is propagated to the database. See [Hash algorithms](#hash-algorithms). | Optional.
Default: *false*. **Allow providing avatar** | Can user provide its avatar. The value is used when column *Provide avatar* is not set. | Optional.
Default: *false*. **Case-insensitive username** | Whether user query should be case-sensitive or case-insensitive. | Optional.
Default: *false*. diff --git a/lib/Backend/UserBackend.php b/lib/Backend/UserBackend.php index a97e095..9693ff0 100644 --- a/lib/Backend/UserBackend.php +++ b/lib/Backend/UserBackend.php @@ -2,7 +2,7 @@ /** * Nextcloud - user_sql * - * @copyright 2018 Marcin Łojewski + * @copyright 2020 Marcin Łojewski * @author Marcin Łojewski * * This program is free software: you can redistribute it and/or modify @@ -318,8 +318,14 @@ 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)) { + $emailLogin = !empty($this->properties[Opt::EMAIL_LOGIN]); + if ($emailLogin) { + $user = $this->userRepository->findByUidOrEmail($uid, $caseSensitive); + } else { + $user = $this->userRepository->findByUid($uid, $caseSensitive); + } + + if (!($user instanceof User)) { return false; } diff --git a/lib/Constant/Opt.php b/lib/Constant/Opt.php index b07b87c..52583fb 100644 --- a/lib/Constant/Opt.php +++ b/lib/Constant/Opt.php @@ -34,6 +34,7 @@ final class Opt const CRYPTO_PARAM_0 = "opt.crypto_param_0"; const CRYPTO_PARAM_1 = "opt.crypto_param_1"; const CRYPTO_PARAM_2 = "opt.crypto_param_2"; + const EMAIL_LOGIN = "opt.email_login"; const EMAIL_SYNC = "opt.email_sync"; const HOME_LOCATION = "opt.home_location"; const HOME_MODE = "opt.home_mode"; diff --git a/lib/Constant/Query.php b/lib/Constant/Query.php index 8cbff2c..de95984 100644 --- a/lib/Constant/Query.php +++ b/lib/Constant/Query.php @@ -2,7 +2,7 @@ /** * Nextcloud - user_sql * - * @copyright 2018 Marcin Łojewski + * @copyright 2020 Marcin Łojewski * @author Marcin Łojewski * * This program is free software: you can redistribute it and/or modify @@ -35,6 +35,8 @@ final class Query const FIND_GROUP_USERS = "find_group_users"; const FIND_GROUPS = "find_groups"; const FIND_USER = "find_user"; + const FIND_USER_BY_UID_OR_EMAIL = "find_user_by_uid_or_email"; + const FIND_USER_BY_UID_OR_EMAIL_CASE_INSENSITIVE = "find_user_by_uid_or_email_case_insensitive"; const FIND_USER_CASE_INSENSITIVE = "find_user_case_insensitive"; const FIND_USER_GROUPS = "find_user_groups"; const FIND_USERS = "find_users"; diff --git a/lib/Properties.php b/lib/Properties.php index a5712bf..bd97d2c 100644 --- a/lib/Properties.php +++ b/lib/Properties.php @@ -174,7 +174,7 @@ class Properties implements \ArrayAccess { return in_array( $param, [ - Opt::APPEND_SALT, Opt::CASE_INSENSITIVE_USERNAME, + Opt::APPEND_SALT, Opt::CASE_INSENSITIVE_USERNAME, Opt::EMAIL_LOGIN, Opt::NAME_CHANGE, Opt::PASSWORD_CHANGE, Opt::PREPEND_SALT, Opt::PROVIDE_AVATAR, Opt::REVERSE_ACTIVE, Opt::SAFE_STORE, Opt::USE_CACHE diff --git a/lib/Query/QueryProvider.php b/lib/Query/QueryProvider.php index 81ff994..0ddf0b2 100644 --- a/lib/Query/QueryProvider.php +++ b/lib/Query/QueryProvider.php @@ -2,7 +2,7 @@ /** * Nextcloud - user_sql * - * @copyright 2018 Marcin Łojewski + * @copyright 2020 Marcin Łojewski * @author Marcin Łojewski * * This program is free software: you can redistribute it and/or modify @@ -151,6 +151,18 @@ class QueryProvider implements \ArrayAccess "WHERE u.$uUID = :$uidParam " . (empty($uDisabled) ? "" : "AND NOT u.$uDisabled"), + Query::FIND_USER_BY_UID_OR_EMAIL => + "SELECT $userColumns, u.$uPassword AS password " . + "FROM $user u " . + "WHERE u.$uUID = :$uidParam OR u.$uEmail = :$emailParam " . + (empty($uDisabled) ? "" : "AND NOT u.$uDisabled"), + + Query::FIND_USER_BY_UID_OR_EMAIL_CASE_INSENSITIVE => + "SELECT $userColumns, u.$uPassword AS password " . + "FROM $user u " . + "WHERE lower(u.$uUID) = lower(:$uidParam) OR lower(u.$uEmail) = lower(:$emailParam) " . + (empty($uDisabled) ? "" : "AND NOT u.$uDisabled"), + Query::FIND_USER_CASE_INSENSITIVE => "SELECT $userColumns, u.$uPassword AS password " . "FROM $user u " . diff --git a/lib/Repository/UserRepository.php b/lib/Repository/UserRepository.php index 9841cf0..f3e3fbb 100644 --- a/lib/Repository/UserRepository.php +++ b/lib/Repository/UserRepository.php @@ -2,7 +2,7 @@ /** * Nextcloud - user_sql * - * @copyright 2018 Marcin Łojewski + * @copyright 2020 Marcin Łojewski * @author Marcin Łojewski * * This program is free software: you can redistribute it and/or modify @@ -75,6 +75,31 @@ class UserRepository } } + /** + * Get an user entity object. + * + * @param string $query The user ID or email address. + * @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 findByUidOrEmail($query, $caseSensitive = true) + { + if ($caseSensitive) { + return $this->dataQuery->queryEntity( + Query::FIND_USER_BY_UID_OR_EMAIL, User::class, + [Query::UID_PARAM => $query, Query::EMAIL_PARAM => $query] + ); + } else { + return $this->dataQuery->queryEntity( + Query::FIND_USER_BY_UID_OR_EMAIL_CASE_INSENSITIVE, User::class, + [Query::UID_PARAM => $query, Query::EMAIL_PARAM => $query] + ); + } + } + /** * Get an array of user entity objects. * diff --git a/templates/admin.php b/templates/admin.php index 7678830..add76e1 100644 --- a/templates/admin.php +++ b/templates/admin.php @@ -110,6 +110,7 @@ function print_select_options(

t("Here are all currently supported options.")); ?>