Auth/Cas: add fake_authenticated_user_attributes config parameter

This commit is contained in:
Benjamin Renard 2024-12-03 02:55:50 +01:00
parent f85e7392b9
commit 1f927b2487
Signed by: bn8
GPG key ID: 3E2E1CE1907115BC
4 changed files with 57 additions and 25 deletions

View file

@ -230,6 +230,9 @@ auth:
# CAS Fake authenticated user # CAS Fake authenticated user
#fake_authenticated_user: 'myusername' #fake_authenticated_user: 'myusername'
#fake_authenticated_user_attributes:
# attr1: value1
# attr2: value2
# CAS user attributes to retrieve with their properties: # CAS user attributes to retrieve with their properties:
# [attr name]: # [attr name]:

View file

@ -230,6 +230,9 @@ auth:
# CAS Fake authenticated user # CAS Fake authenticated user
#fake_authenticated_user: 'myusername' #fake_authenticated_user: 'myusername'
#fake_authenticated_user_attributes:
# attr1: value1
# attr2: value2
# CAS user attributes to retrieve with their properties: # CAS user attributes to retrieve with their properties:
# [attr name]: # [attr name]:

View file

@ -9,6 +9,8 @@ use EesyPHP\Url;
use phpCAS; use phpCAS;
use function EesyPHP\cast;
class Cas extends Method { class Cas extends Method {
/** /**
@ -39,6 +41,7 @@ class Cas extends Method {
'version' => '2.0', 'version' => '2.0',
'logout' => true, 'logout' => true,
'fake_authenticated_user' => null, 'fake_authenticated_user' => null,
'fake_authenticated_user_attributes' => [],
'debug_log_file' => null, 'debug_log_file' => null,
'ca_cert_certificate_path' => null, 'ca_cert_certificate_path' => null,
'user_attributes' => array( 'user_attributes' => array(
@ -182,4 +185,42 @@ class Cas extends Method {
Url :: redirect(isset($_REQUEST['next'])?urldecode($_REQUEST['next']):null); Url :: redirect(isset($_REQUEST['next'])?urldecode($_REQUEST['next']):null);
Log :: fatal('No CAS ticket or fail to authenticate you'); Log :: fatal('No CAS ticket or fail to authenticate you');
} }
/**
* Check if user is authenticated using CAS backend
* @return bool
*/
public static function is_authenticated() {
return self :: $fake_authenticated_user || phpCAS :: isAuthenticated();
}
/**
* Retrieve CAS attribute value(s) from CAS authenticated user
* @param string $attr The CAS attribute name
* @param mixed $default The default value to return if the CAS attribute is undefined
* (optional, default: null)
* @param string|null $cast The expected type of value (optional, default: string)
* @return mixed
*/
public static function get_attr($attr, $default=null, $cast=null) {
if (self :: $fake_authenticated_user)
return App::get(
"auth.cas.fake_authenticated_user_attributes.$attr",
$default,
$cast ?? "string"
);
if (!phpCAS::hasAttribute($attr))
return $default;
return cast(phpCAS::getAttribute($attr), $cast?$cast:'string');
}
/**
* Retrieve CAS attributes's value(s) from CAS authenticated user
* @return array<string,mixed>
*/
public static function get_attrs() {
if (self :: $fake_authenticated_user)
return App::get("auth.cas.fake_authenticated_user_attributes", [], "array");
return phpCAS::getAttributes();
}
} }

View file

@ -4,40 +4,25 @@ namespace EesyPHP\Auth;
use EesyPHP\App; use EesyPHP\App;
use EesyPHP\Auth; use EesyPHP\Auth;
use EesyPHP\Auth\Cas;
use EesyPHP\Auth\User; use EesyPHP\Auth\User;
use EesyPHP\Check; use EesyPHP\Check;
use EesyPHP\Config; use EesyPHP\Config;
use EesyPHP\I18n; use EesyPHP\I18n;
use EesyPHP\Log; use EesyPHP\Log;
use function EesyPHP\cast;
use function EesyPHP\format_callable; use function EesyPHP\format_callable;
use function EesyPHP\vardump; use function EesyPHP\vardump;
use phpCAS;
class Casuser extends Backend { class Casuser extends Backend {
/**
* Retrieve CAS attribute value(s) from CAS authenticated user
* @param string $attr The CAS attribute name
* @param mixed $default The default value to return if the CAS attribute is undefined
* (optional, default: null)
* @param string|null $cast The expected type of value (optional, default: string)
*/
public static function get_attr($attr, $default=null, $cast=null) {
if (!phpCAS::hasAttribute($attr))
return $default;
return cast(phpCAS::getAttribute($attr), $cast?$cast:'string');
}
/** /**
* Retrieve a user by its username * Retrieve a user by its username
* @param string $username * @param string $username
* @return \EesyPHP\Auth\User|null|false The user object if found, null it not, false in case of error * @return \EesyPHP\Auth\User|null|false The user object if found, null it not, false in case of error
*/ */
public static function get_user($username) { public static function get_user($username) {
if (!phpCAS :: isAuthenticated()) { if (!Cas :: is_authenticated()) {
Log::error("get_user(%s): phpCAS not authenticated, can't compute user"); Log::error("get_user(%s): CAS backend not authenticated, can't compute user");
return null; return null;
} }
@ -45,14 +30,14 @@ class Casuser extends Backend {
self :: check_user_filters($username); self :: check_user_filters($username);
$info = array(); $info = array();
foreach(Config::get('auth.cas.user_attributes') as $name => $attr_config) { foreach(App::get('auth.cas.user_attributes') as $name => $attr_config) {
$cas_name = Config::get("cas_name", null, 'string', false, $attr_config); $cas_name = Config::get("cas_name", null, 'string', false, $attr_config);
$alt_cas_name = Config::get("alt_cas_name", $name, 'string', false, $attr_config); $alt_cas_name = Config::get("alt_cas_name", $name, 'string', false, $attr_config);
if (!$cas_name || is_null(self :: get_attr($cas_name))) if (!$cas_name || is_null(Cas :: get_attr($cas_name)))
$cas_name = $alt_cas_name; $cas_name = $alt_cas_name;
$info[$name] = self :: get_attr( $info[$name] = Cas :: get_attr(
$cas_name?$cas_name:$name, $cas_name?$cas_name:$name,
Config::get("default", null, null, false, $attr_config) default: Config::get("default", null, null, false, $attr_config)
); );
} }
Log::debug('User "%s" info computed from CAS attributes:\n%s', $username, vardump($info)); Log::debug('User "%s" info computed from CAS attributes:\n%s', $username, vardump($info));
@ -65,12 +50,12 @@ class Casuser extends Backend {
* @return void|never * @return void|never
*/ */
public static function check_user_filters($username) { public static function check_user_filters($username) {
foreach(Config::get('auth.cas.user_filters', [], 'array') as $attr => $filter) { foreach(App::get('auth.cas.user_filters', [], 'array') as $attr => $filter) {
if (is_callable($filter)) { if (is_callable($filter)) {
if ( if (
!$filter( !$filter(
$username, $username,
is_string($attr)?phpCAS::getAttribute($attr):phpCAS::getAttributes() is_string($attr)?Cas::get_attr($attr):Cas::get_attrs()
) )
) )
{ {
@ -88,7 +73,7 @@ class Casuser extends Backend {
Log::fatal(I18n::_("Configuration error in CAS auth backend.")); Log::fatal(I18n::_("Configuration error in CAS auth backend."));
} }
$attr_values = self :: get_attr($attr, [], 'array'); $attr_values = Cas :: get_attr($attr, [], 'array');
if (!$attr_values) { if (!$attr_values) {
Log::warning( Log::warning(
"get_user(%s): filter out by attribute %s (not defined)", "get_user(%s): filter out by attribute %s (not defined)",