Casuser auth backend: add user access filters feature
This commit is contained in:
parent
82122089f9
commit
57aedc4869
8 changed files with 183 additions and 32 deletions
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -1,7 +1,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"POT-Creation-Date: 2024-01-23 18:15+0000\n"
|
"POT-Creation-Date: 2024-02-21 09:12+0000\n"
|
||||||
"PO-Revision-Date: \n"
|
"PO-Revision-Date: \n"
|
||||||
"Last-Translator: Benjamin Renard <brenard@easter-eggs.com>\n"
|
"Last-Translator: Benjamin Renard <brenard@easter-eggs.com>\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
|
@ -30,7 +30,7 @@ msgstr ""
|
||||||
msgid "Unknown"
|
msgid "Unknown"
|
||||||
msgstr "Inconnu"
|
msgstr "Inconnu"
|
||||||
|
|
||||||
#: Db.php:78
|
#: Db.php:93
|
||||||
msgid "Unable to connect to the database."
|
msgid "Unable to connect to the database."
|
||||||
msgstr "Impossible de se connecter à la base de données."
|
msgstr "Impossible de se connecter à la base de données."
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ msgstr "Connection"
|
||||||
msgid "Authentication required"
|
msgid "Authentication required"
|
||||||
msgstr "Authentication requise"
|
msgstr "Authentication requise"
|
||||||
|
|
||||||
#: Auth/Http.php:124 Auth/Http.php:127 Url.php:185
|
#: Auth/Http.php:124 Auth/Http.php:127 Url.php:185 Auth.php:340 Auth.php:343
|
||||||
msgid "Access denied"
|
msgid "Access denied"
|
||||||
msgstr "Accès interdit"
|
msgstr "Accès interdit"
|
||||||
|
|
||||||
|
@ -54,6 +54,10 @@ msgstr "Accès interdit"
|
||||||
msgid "You must login to access this page."
|
msgid "You must login to access this page."
|
||||||
msgstr "Vous devez vous connecter pour accéder à cette page."
|
msgstr "Vous devez vous connecter pour accéder à cette page."
|
||||||
|
|
||||||
|
#: Auth/Casuser.php:88 Auth/Casuser.php:112
|
||||||
|
msgid "Configuration error in CAS auth backend."
|
||||||
|
msgstr "Erreur de configuration dans le backend d'authentification CAS."
|
||||||
|
|
||||||
#: Url.php:177
|
#: Url.php:177
|
||||||
msgid "Bad request"
|
msgid "Bad request"
|
||||||
msgstr "Mauvaise requête"
|
msgstr "Mauvaise requête"
|
||||||
|
@ -120,6 +124,14 @@ msgstr "Authentication requise mais impossible pour vous authentifier."
|
||||||
msgid "This request could not be processed correctly."
|
msgid "This request could not be processed correctly."
|
||||||
msgstr "Cette requête n'a put être traitée correctement."
|
msgstr "Cette requête n'a put être traitée correctement."
|
||||||
|
|
||||||
|
#: Auth.php:344
|
||||||
|
msgid "You do not have access to this application."
|
||||||
|
msgstr "Vous n'avez pas accès à cette application."
|
||||||
|
|
||||||
|
#: Auth.php:348
|
||||||
|
msgid "Details:"
|
||||||
|
msgstr "Détails :"
|
||||||
|
|
||||||
#: Cli.php:44
|
#: Cli.php:44
|
||||||
msgid "Create a new project using EesyPHP framework"
|
msgid "Create a new project using EesyPHP framework"
|
||||||
msgstr "Créer un nouveau project utilisant le framework EesyPHP"
|
msgstr "Créer un nouveau project utilisant le framework EesyPHP"
|
||||||
|
@ -261,13 +273,7 @@ msgstr ""
|
||||||
"Port d'écoute spécifié invalid. Il doit s'agir d'un entier positif entre 1 "
|
"Port d'écoute spécifié invalid. Il doit s'agir d'un entier positif entre 1 "
|
||||||
"et 65535."
|
"et 65535."
|
||||||
|
|
||||||
#: Cli.php:418
|
#: Cli.php:415
|
||||||
msgid "Can't invoke bash. Can't ask password prompt."
|
|
||||||
msgstr ""
|
|
||||||
"Impossible d'utiliser bash. Impossible de demander à l'utilisateur de saisir "
|
|
||||||
"un not de passe."
|
|
||||||
|
|
||||||
#: Cli.php:421
|
|
||||||
msgid "Please enter password:"
|
msgid "Please enter password:"
|
||||||
msgstr "Merci de saisir le not de passe :"
|
msgstr "Merci de saisir le not de passe :"
|
||||||
|
|
||||||
|
@ -300,19 +306,19 @@ msgstr "ns"
|
||||||
msgid "Less than 1%s"
|
msgid "Less than 1%s"
|
||||||
msgstr "Moins de 1%s"
|
msgstr "Moins de 1%s"
|
||||||
|
|
||||||
#: App.php:239 I18n.php:119
|
#: App.php:242 I18n.php:119
|
||||||
msgid "Hello world !"
|
msgid "Hello world !"
|
||||||
msgstr "Bonjour tout le monde !"
|
msgstr "Bonjour tout le monde !"
|
||||||
|
|
||||||
#: App.php:241
|
#: App.php:244
|
||||||
msgid "Hello world!"
|
msgid "Hello world!"
|
||||||
msgstr "Salut tout le monde !"
|
msgstr "Salut tout le monde !"
|
||||||
|
|
||||||
#: App.php:252
|
#: App.php:255
|
||||||
msgid "Disconnected"
|
msgid "Disconnected"
|
||||||
msgstr "Déconnecté"
|
msgstr "Déconnecté"
|
||||||
|
|
||||||
#: App.php:254
|
#: App.php:257
|
||||||
msgid "You are now disconnected."
|
msgid "You are now disconnected."
|
||||||
msgstr "Vous êtes maintenant déconnecté."
|
msgstr "Vous êtes maintenant déconnecté."
|
||||||
|
|
||||||
|
@ -606,12 +612,12 @@ msgstr ""
|
||||||
"\n"
|
"\n"
|
||||||
"Mail originalement destiné à %s."
|
"Mail originalement destiné à %s."
|
||||||
|
|
||||||
#: Email.php:139
|
#: Email.php:137
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "<p><small>%s: %s</small></p>"
|
msgid "<p><small>%s: %s</small></p>"
|
||||||
msgstr "<p><small>%s: %s</small></p>"
|
msgstr "<p><small>%s: %s</small></p>"
|
||||||
|
|
||||||
#: Email.php:140
|
#: Email.php:138
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -657,6 +663,10 @@ msgstr "Erreur : %1"
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "Retour"
|
msgstr "Retour"
|
||||||
|
|
||||||
|
#: templates/access_denied.tpl:12
|
||||||
|
msgid "Details: %1"
|
||||||
|
msgstr "Détails : %1"
|
||||||
|
|
||||||
#: templates/empty.tpl:74
|
#: templates/empty.tpl:74
|
||||||
msgid "Sign out"
|
msgid "Sign out"
|
||||||
msgstr "Déconnexion"
|
msgstr "Déconnexion"
|
||||||
|
@ -701,6 +711,11 @@ msgstr ""
|
||||||
"fichier <em>homepage.tpl</em> pour l'écraser. Vous pouvez également écraser "
|
"fichier <em>homepage.tpl</em> pour l'écraser. Vous pouvez également écraser "
|
||||||
"le gestionnaire de l'URL racine de l'application web."
|
"le gestionnaire de l'URL racine de l'application web."
|
||||||
|
|
||||||
|
#~ msgid "Can't invoke bash. Can't ask password prompt."
|
||||||
|
#~ msgstr ""
|
||||||
|
#~ "Impossible d'utiliser bash. Impossible de demander à l'utilisateur de "
|
||||||
|
#~ "saisir un not de passe."
|
||||||
|
|
||||||
#~ msgid "Confirmation"
|
#~ msgid "Confirmation"
|
||||||
#~ msgstr "Confirmation"
|
#~ msgstr "Confirmation"
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"POT-Creation-Date: 2024-01-23 18:19+0000\n"
|
"POT-Creation-Date: 2024-02-21 09:12+0000\n"
|
||||||
"PO-Revision-Date: 2024-01-23 18:19+0000\n"
|
"PO-Revision-Date: 2024-02-21 09:12+0000\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
@ -22,7 +22,7 @@ msgstr ""
|
||||||
msgid "Unknown"
|
msgid "Unknown"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: Db.php:78
|
#: Db.php:93
|
||||||
msgid "Unable to connect to the database."
|
msgid "Unable to connect to the database."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ msgstr ""
|
||||||
msgid "Authentication required"
|
msgid "Authentication required"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: Auth/Http.php:124 Auth/Http.php:127 Url.php:185
|
#: Auth/Http.php:124 Auth/Http.php:127 Url.php:185 Auth.php:340 Auth.php:343
|
||||||
msgid "Access denied"
|
msgid "Access denied"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -46,6 +46,10 @@ msgstr ""
|
||||||
msgid "You must login to access this page."
|
msgid "You must login to access this page."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: Auth/Casuser.php:88 Auth/Casuser.php:112
|
||||||
|
msgid "Configuration error in CAS auth backend."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: Url.php:177
|
#: Url.php:177
|
||||||
msgid "Bad request"
|
msgid "Bad request"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -104,6 +108,14 @@ msgstr ""
|
||||||
msgid "This request could not be processed correctly."
|
msgid "This request could not be processed correctly."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: Auth.php:344
|
||||||
|
msgid "You do not have access to this application."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: Auth.php:348
|
||||||
|
msgid "Details:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: Cli.php:44
|
#: Cli.php:44
|
||||||
msgid "Create a new project using EesyPHP framework"
|
msgid "Create a new project using EesyPHP framework"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -223,11 +235,7 @@ msgid ""
|
||||||
"65535."
|
"65535."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: Cli.php:418
|
#: Cli.php:415
|
||||||
msgid "Can't invoke bash. Can't ask password prompt."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: Cli.php:421
|
|
||||||
msgid "Please enter password:"
|
msgid "Please enter password:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -260,19 +268,19 @@ msgstr ""
|
||||||
msgid "Less than 1%s"
|
msgid "Less than 1%s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: App.php:239 I18n.php:119
|
#: App.php:242 I18n.php:119
|
||||||
msgid "Hello world !"
|
msgid "Hello world !"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: App.php:241
|
#: App.php:244
|
||||||
msgid "Hello world!"
|
msgid "Hello world!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: App.php:252
|
#: App.php:255
|
||||||
msgid "Disconnected"
|
msgid "Disconnected"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: App.php:254
|
#: App.php:257
|
||||||
msgid "You are now disconnected."
|
msgid "You are now disconnected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -523,12 +531,12 @@ msgid ""
|
||||||
"Mail initially intended for %s."
|
"Mail initially intended for %s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: Email.php:139
|
#: Email.php:137
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid "<p><small>%s: %s</small></p>"
|
msgid "<p><small>%s: %s</small></p>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: Email.php:140
|
#: Email.php:138
|
||||||
#, php-format
|
#, php-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -569,6 +577,10 @@ msgstr ""
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/access_denied.tpl:12
|
||||||
|
msgid "Details: %1"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: templates/empty.tpl:74
|
#: templates/empty.tpl:74
|
||||||
msgid "Sign out"
|
msgid "Sign out"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
23
src/Auth.php
23
src/Auth.php
|
@ -328,4 +328,27 @@ class Auth {
|
||||||
public static function user() {
|
public static function user() {
|
||||||
return self :: $user;
|
return self :: $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to trigger access denied error
|
||||||
|
* @param string|null $details Reason or details about this error
|
||||||
|
* @return never
|
||||||
|
*/
|
||||||
|
public static function access_denied($details=null) {
|
||||||
|
if (Tpl::initialized()) {
|
||||||
|
Tpl :: assign("details", $details);
|
||||||
|
Tpl :: display("access_denied.tpl", I18n::_("Access denied"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("<h1>%s</h1>", I18n::_("Access denied"));
|
||||||
|
printf("<p>%s</p>", I18n::_("You do not have access to this application."));
|
||||||
|
if ($details)
|
||||||
|
printf(
|
||||||
|
"<p><small>%s%s</small></p>",
|
||||||
|
I18n::_("Details:"),
|
||||||
|
$details
|
||||||
|
);
|
||||||
|
}
|
||||||
|
exit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,16 @@ class Cas extends Method {
|
||||||
'default' => null,
|
'default' => null,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
/*
|
||||||
|
* CAS user backend access filters:
|
||||||
|
* [
|
||||||
|
* attr => regex,
|
||||||
|
* attr => callable (will receive the username and the attr value as parameters),
|
||||||
|
* callable, (will receive the username and an associative array of all attrs values as
|
||||||
|
* parameters)
|
||||||
|
* ]
|
||||||
|
*/
|
||||||
|
'user_filters' => array(),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
self :: $fake_authenticated_user = App :: get(
|
self :: $fake_authenticated_user = App :: get(
|
||||||
|
|
|
@ -3,10 +3,14 @@
|
||||||
namespace EesyPHP\Auth;
|
namespace EesyPHP\Auth;
|
||||||
|
|
||||||
use EesyPHP\App;
|
use EesyPHP\App;
|
||||||
|
use EesyPHP\Auth;
|
||||||
use EesyPHP\Auth\User;
|
use EesyPHP\Auth\User;
|
||||||
|
use EesyPHP\Check;
|
||||||
use EesyPHP\Config;
|
use EesyPHP\Config;
|
||||||
|
use EesyPHP\I18n;
|
||||||
use EesyPHP\Log;
|
use EesyPHP\Log;
|
||||||
use function EesyPHP\cast;
|
use function EesyPHP\cast;
|
||||||
|
use function EesyPHP\format_callable;
|
||||||
use function EesyPHP\vardump;
|
use function EesyPHP\vardump;
|
||||||
|
|
||||||
use phpCAS;
|
use phpCAS;
|
||||||
|
@ -37,6 +41,9 @@ class Casuser extends Backend {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check user filters and denied access if not match
|
||||||
|
self :: check_user_filters($username);
|
||||||
|
|
||||||
$info = array();
|
$info = array();
|
||||||
foreach(Config::get('auth.cas.user_attributes') as $name => $attr_config) {
|
foreach(Config::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);
|
||||||
|
@ -52,4 +59,68 @@ class Casuser extends Backend {
|
||||||
return new User($username, '\\EesyPHP\\Auth\\Casuser', $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."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
20
templates/access_denied.tpl
Normal file
20
templates/access_denied.tpl
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{extends file='Tpl:empty.tpl'}
|
||||||
|
{block name="pagetitle"}{/block}
|
||||||
|
{block name="content"}
|
||||||
|
<div class="p-5 mb-4 bg-light rounded-3">
|
||||||
|
<div class="container-fluid py-5">
|
||||||
|
<h1 class="display-5 fw-bold">{t domain=$CORE_TEXT_DOMAIN}Access denied{/t}</h1>
|
||||||
|
<p class="col-md-8 fs-4">
|
||||||
|
{t escape=off domain=$CORE_TEXT_DOMAIN}You do not have access to this application.{/t}
|
||||||
|
</p>
|
||||||
|
{if $details}
|
||||||
|
<p class="col-md-8 fs-6 fw-lighter fst-italic">
|
||||||
|
{t 1=$details domain=$CORE_TEXT_DOMAIN}Details: %1{/t}
|
||||||
|
</p>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/block}
|
||||||
|
{*
|
||||||
|
# vim: autoindent expandtab tabstop=2 shiftwidth=2 softtabstop=2
|
||||||
|
*}
|
Loading…
Reference in a new issue