From d2f57e3fdc6cca96ba5ae3af7668e35cab8a70ce Mon Sep 17 00:00:00 2001 From: bohwaz Date: Thu, 11 May 2023 01:54:43 +0200 Subject: [PATCH] Implement auth callback fix #33 --- config.dist.php | 21 +++++++++++++++++++++ lib/KaraDAV/Users.php | 31 ++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/config.dist.php b/config.dist.php index b6a2300..4c90d7d 100644 --- a/config.dist.php +++ b/config.dist.php @@ -71,6 +71,27 @@ const ENABLE_XSENDFILE = false; */ const DISABLE_SLOW_OPERATIONS = false; +/** + * External authentication callback + * + * Use this to authenticate a user with a third-party service. + * Provide a valid PHP callback: either a function name, or a class name and method in an array. + * + * The callback will be passed the username and password as parameters, and must return + * TRUE if auth was successful, or FALSE otherwise. + * + * If the callback returned TRUE and the user does not exist in the database, + * it will be created with the default quota. + * + * @var string|array + */ +const AUTH_CALLBACK = null; +//const AUTH_CALLBACK = ['MyAuthClass', 'login']; +//const AUTH_CALLBACK = 'my_login'; +//function my_login(string $user, string $password) { +// return ($user == 'me' && $password == 'secret'); +//} + /** * LDAP server configuration * diff --git a/lib/KaraDAV/Users.php b/lib/KaraDAV/Users.php index d0073c5..27fc312 100644 --- a/lib/KaraDAV/Users.php +++ b/lib/KaraDAV/Users.php @@ -139,7 +139,7 @@ class Users return true; } - public function login(?string $login, ?string $password, ?string $app_password = null): ?stdClass + public function login(?string $login, ?string $password): ?stdClass { $login = null !== $login ? strtolower(trim($login)) : null; @@ -155,18 +155,35 @@ class Users } // If not, try to login - $user = $this->get($login); - - if (!$user) { - return null; - } + $ok = false; if (LDAP::enabled()) { if (!LDAP::checkPassword($login, $password)) { return null; } + + $ok = true; } - elseif (!password_verify(trim($password), $user->password)) { + elseif (AUTH_CALLBACK) { + $r = call_user_func(AUTH_CALLBACK, $login, $password); + if ($r !== true) { + return false; + } + + $ok = true; + } + + $user = $this->get($login); + + if (!$user && !$ok) { + return null; + } + elseif (!$user && $ok) { + $this->create($login, random_bytes(10)); + $user = $this->get($login); + } + + if (!$ok && !password_verify(trim($password), $user->password)) { return null; }