From bf7e1d30eca31f71d879ad945d67600e6d00555b Mon Sep 17 00:00:00 2001 From: Matthias Hunstock Date: Fri, 16 Jun 2023 12:41:03 +0200 Subject: [PATCH] Web: add optional external auth mechanism, fixes #245 --- src/Application/Model/User.php | 49 ++++++++++++++++++++++++++++++++-- src/Config/Config.Default.php | 9 +++++-- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/Application/Model/User.php b/src/Application/Model/User.php index 38e98fe..57c7df3 100644 --- a/src/Application/Model/User.php +++ b/src/Application/Model/User.php @@ -21,6 +21,10 @@ class User extends Model_Authentication_User { const FIELD_ACTIVE = false; const FIELD_LOGIN_COUNT = false; + + private static $externalUser = false; + private static $externalUserHeader = ''; + private static $externalAuthInProgress = false; public $hasAndBelongsToMany = [ 'Project' => [ @@ -35,12 +39,53 @@ class User extends Model_Authentication_User { 'Project' => true ]; + public static function isLoggedIn() { + if (parent::isLoggedIn()) + return true; + + if (static::$externalAuthInProgress) + return false; + + $external = @$_SERVER[static::$externalUserHeader]; + if (static::$externalUserHeader == '' || $external == '') + return false; + + // try auto-login by external mechanism + static::$externalAuthInProgress = true; + $result = parent::login($external, '', false); + static::$externalAuthInProgress = false; + return $result; + } + public static function isRestricted() { - if (!static::isLoggedIn()) { + if (!parent::isLoggedIn()) { return false; } - return self::$Session->get()['restrict_project_access']; + return static::$Session->get()['restrict_project_access']; + } + + public static function setExternalUserHeader($headerName) { + if (static::$externalUserHeader == '') { + static::$externalUserHeader = $headerName; + } + } + + public function verifyPassword($password) { + if (static::$externalUserHeader != '' + && $_SERVER[self::$externalUserHeader] === $this[static::FIELD_USER]) { + $this->unsetRememberCookie(); + return static::$externalUser = true; + } + + // allow fallback to database credentials even with external auth enabled + return password_verify($password, $this[static::FIELD_PASSWORD]); + } + + public function shouldRehashPassword() { + return (static::$externalAuthInProgress) + ? false + : password_needs_rehash($this[static::FIELD_PASSWORD], PASSWORD_DEFAULT); } } diff --git a/src/Config/Config.Default.php b/src/Config/Config.Default.php index 9181182..4682107 100644 --- a/src/Config/Config.Default.php +++ b/src/Config/Config.Default.php @@ -22,5 +22,10 @@ session_set_cookie_params(0, '/', null, false, true); libxml_disable_entity_loader(true); - -?> \ No newline at end of file + + // Use settings like these to enable external auth mechanisms + // like OIDC or SAML, but don't forget to exclude RPC URLs + // from access control + #User::setExternalUserHeader('REMOTE_USER'); + #User::setExternalUserHeader('HTTP_X_USER'); +?>