Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support setting the uid from the query #60

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ This app has no user interface. All configuration is done via Nextcloud's system
//'db_password' => 'thePasswordForTheDatabaseUser',
//'db_password_file' => '/path/to/file/ContainingThePasswordForTheDatabaseUser',
'queries' => array(
'get_password_hash_for_user' => 'SELECT password_hash FROM users_fqda WHERE fqda = :username',
'get_password_hash_for_user' => 'SELECT password_hash, fqda FROM users_fqda WHERE fqda = :username OR email = :username',
'user_exists' => 'SELECT EXISTS(SELECT 1 FROM users_fqda WHERE fqda = :username)',
'get_users' => 'SELECT fqda FROM users_fqda WHERE (fqda ILIKE :search) OR (display_name ILIKE :search)',
//'set_password_hash_for_user' => 'UPDATE users SET password_hash = :new_password_hash WHERE local = split_part(:username, \'@\', 1) AND domain = split_part(:username, \'@\', 2)',
Expand Down Expand Up @@ -130,15 +130,19 @@ that will be used to read/write data.
* queries use named parameters. You have to use the exact names as shown in the examples. For
example, to retrieve the hash for a user, the query named `get_password_hash_for_user` will be
used. Write your custom SQL query and simply put `:username` where you are referring to the
username (aka uid) of the user trying to login.
username (aka uid) of the user trying to login. Optionally the query may return a second column
with the uid as nexcloud should use it. This allows you to accept multiple usernames (e.g.
username and email, case insensitive usernames, etc) for a single account. This uid will then
also be used in subsequent queries .If not present the username as entered will be used.
* You don't need to supply all queries. For example, if you use the default user home simply leave
the query `get_home` commented. This app will recognize this and
[communicate](https://github.com/nextcloud/server/blob/316acc3cc313f4333fe29d136f9124f163b40dec/lib/public/UserInterface.php#L47)
to Nextcloud that this feature is not available.
* `user_exists` and `get_users` are required, the rest is optional.
* For user authentication (i.e. login) you need at least `get_password_hash_for_user`,
`user_exists` and `get_users`.
* For all queries that read data, only the first column is interpreted.
* For all queries that read data except get_password_hash_for_user (see above), only the first
column is interpreted.
* Two queries require a little bit of attention:
1. `user_exists` should return a boolean. See the example on how to do this properly.
2. `get_users` is a query that searches for usernames (e.g. *bob*) and display names (e.g. *Bob
Expand Down
16 changes: 11 additions & 5 deletions lib/UserBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

use OC\User\Backend;
use Psr\Log\LoggerInterface;
use \PDO;

class UserBackend implements \OCP\IUserBackend, \OCP\UserInterface

Expand Down Expand Up @@ -67,7 +68,7 @@ public function implementsActions($actions)
* Nextcloud if Backend::CHECK_PASSWORD is set.
* @param $providedUsername
* @param $providedPassword
* @return bool whether the provided password was correct for provided user
* @return string|false The uid on success false on failure
*/
public function checkPassword($providedUsername, $providedPassword)
{
Expand All @@ -80,14 +81,19 @@ public function checkPassword($providedUsername, $providedPassword)

$statement = $dbHandle->prepare($this->config->getQueryGetPasswordHashForUser());
$statement->execute(['username' => $providedUsername]);
$retrievedPasswordHash = $statement->fetchColumn();

if ($retrievedPasswordHash === false) {
$retrievedRow = $statement->fetch(PDO::FETCH_NUM);
if ($retrievedRow === false || count($retrievedRow) == 0) {
return false;
}

$retrievedPasswordHash = $retrievedRow[0];

if (password_verify($providedPassword, $retrievedPasswordHash)) {
return $providedUsername;
if (count($retrievedRow) > 1) {
return $retrievedRow[1];
} else {
return $providedUsername;
}
} else {
return false;
}
Expand Down