127 lines
3.9 KiB
PHP
127 lines
3.9 KiB
PHP
<?php
|
|
|
|
namespace EesyPHP\Auth;
|
|
|
|
use EesyPHP\App;
|
|
use EesyPHP\Auth;
|
|
use EesyPHP\Auth\User;
|
|
use EesyPHP\Check;
|
|
use EesyPHP\Config;
|
|
use EesyPHP\I18n;
|
|
use EesyPHP\Log;
|
|
use function EesyPHP\cast;
|
|
use function EesyPHP\format_callable;
|
|
use function EesyPHP\vardump;
|
|
|
|
use phpCAS;
|
|
|
|
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
|
|
* @param string $username
|
|
* @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) {
|
|
if (!phpCAS :: isAuthenticated()) {
|
|
Log::error("get_user(%s): phpCAS not authenticated, can't compute user");
|
|
return null;
|
|
}
|
|
|
|
// Check user filters and denied access if not match
|
|
self :: check_user_filters($username);
|
|
|
|
$info = array();
|
|
foreach(Config::get('auth.cas.user_attributes') as $name => $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);
|
|
if (!$cas_name || is_null(self :: get_attr($cas_name)))
|
|
$cas_name = $alt_cas_name;
|
|
$info[$name] = self :: get_attr(
|
|
$cas_name?$cas_name:$name,
|
|
Config::get("default", null, null, false, $attr_config)
|
|
);
|
|
}
|
|
Log::debug('User "%s" info computed from CAS attributes:\n%s', $username, vardump($info));
|
|
return new User($username, '\\EesyPHP\\Auth\\Casuser', $info);
|
|
}
|
|
|
|
/**
|
|
* Check authenticated user match with configured filters and denied access if not
|
|
* @param string $username
|
|
* @return void|never
|
|
*/
|
|
public static function check_user_filters($username) {
|
|
foreach(Config::get('auth.cas.user_filters', [], 'array') as $attr => $filter) {
|
|
if (is_callable($filter)) {
|
|
if (
|
|
!$filter(
|
|
$username,
|
|
is_string($attr)?phpCAS::getAttribute($attr):phpCAS::getAttributes()
|
|
)
|
|
)
|
|
{
|
|
Log::warning("get_user(%s): filter out by %s", $username, format_callable($filter));
|
|
Auth::access_denied();
|
|
}
|
|
}
|
|
else if (is_string($attr)) {
|
|
$regex_valid = Check :: regex($filter, true);
|
|
if ($regex_valid !== true) {
|
|
Log::error(
|
|
"Casuser auth backend: Invalid regex provided for attribute %s: %s (%s)",
|
|
$attr, $regex_valid, $filter
|
|
);
|
|
Log::fatal(I18n::_("Configuration error in CAS auth backend."));
|
|
}
|
|
|
|
$attr_values = self :: get_attr($attr, [], 'array');
|
|
if (!$attr_values) {
|
|
Log::warning(
|
|
"get_user(%s): filter out by attribute %s (not defined)",
|
|
$username, $attr
|
|
);
|
|
Auth::access_denied();
|
|
}
|
|
|
|
$match = false;
|
|
foreach ($attr_values as $attr_value) {
|
|
if (preg_match($filter, $attr_value)) {
|
|
$match = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!$match) {
|
|
Log::warning(
|
|
"get_user(%s): filter out by attribute %s (not match with '%s')",
|
|
$username, $attr, $filter
|
|
);
|
|
Auth::access_denied();
|
|
}
|
|
}
|
|
else {
|
|
Log::error(
|
|
"Casuser auth backend: Invalid filter rule configured (%s => %s)",
|
|
vardump($attr), vardump($filter)
|
|
);
|
|
Log::fatal(I18n::_("Configuration error in CAS auth backend."));
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|