Select Git revision
user.class.php 9.23 KiB
<?php
/**
* user class contains username and its roles
* This class is used in the base class
*
* @author hahn
*
* Axel <axel.hahn@unibe.ch>
* 2024-08-29 Axel php8 only; added variable types; use short array syntax
*/
class user
{
/**
* login name of the current user
* @var string
*/
private string $_sUsername = '';
/**
* list of groups of the current user
* @var array
*/
private array $_aUserGroups = [];
/**
* list of roles based on the groups
* @var array
*/
private array $_aUserPermmissions = [];
/**
* list of projects the current user is involved in
* @var array
*/
private $_aProjects = [];
/**
* name of the last checked role
* @var string
*/
private $_sLastCheckedPermission = false;
/**
* Constructor
* init user with optional given user
*
* @param string $sUser username to set
*/
public function __construct(string $sUser = '')
{
$this->setUser($sUser);
}
// ----------------------------------------------------------------------
// private functions
// ----------------------------------------------------------------------
/**
* Get string with detected user from current session / basic auth / cli access
*
* @return string
*/
private function _autoDetectUser(): string
{
$sUser = '';
if (isset($_SESSION) && isset($_SESSION["PHP_AUTH_USER"])) {
$sUser = $_SESSION["PHP_AUTH_USER"];
}
if (!$sUser && isset($_SERVER["PHP_AUTH_USER"])) {
$sUser = $_SERVER["PHP_AUTH_USER"];
}
if (php_sapi_name() == "cli") {
$sUser = "cliadmin";
}
return $sUser;
}
/**
* UNUSED SO FAR
* Idea: limit user access to a set of projects
*/
private function _getUser2Projects()
{
$sFile = __DIR__ . '/../../../config/inc_user2projects.php';
return file_exists($sFile)
? require $sFile
: []
;
}
/**
* Load roles per user from config
* @return array
*/
private function _getUser2Roles(): array
{
$sFile = __DIR__ . '/../../../config/inc_user2roles.php';
return file_exists($sFile)
? require $sFile
: ['admin' => ['admin']]
;
}
/**
* TODO: reimplement
* get the user groups of the current user from an internal source.
* The function returns a flat aray with names of the groups
* @return array
*/
private function _getUserGroups(): array
{
$aGroups = [];
if ($this->_sUsername) {
$aGroups[] = "authenticated";
// $aGroups[]='#'.$this->_sUsername;
$aUserDefinitions = $this->_getUser2Roles();
foreach (array_keys($aUserDefinitions) as $sGroup) {
if (array_search($this->_sUsername, $aUserDefinitions[$sGroup]) !== false) {
$aGroups[] = $sGroup;
}
}
}
$this->_aUserGroups = $aGroups;
return $this->_aUserGroups;
}
/**
* TODO: reimplement
* get the user roles of the current user from an internal source.
* The function returns a flat aray with names of the roles
* @return array
*/
private function _getUserPermission(): array
{
$aRoles = [];
$aRolesDefinitions = require(__DIR__ . '/../../../config/inc_roles.php');
// anonymous roles:
$aRoles = array_merge($aRoles, $aRolesDefinitions['all']);
foreach (array_keys($aRolesDefinitions) as $sGroup) {
if ($this->hasGroup($sGroup)) {
$aRoles = array_merge($aRoles, $aRolesDefinitions[$sGroup]);
}
}
$this->_aUserPermmissions = array_unique($aRoles);
return $this->_aUserPermmissions;
}
// ----------------------------------------------------------------------
// public ACTIONS
// ----------------------------------------------------------------------
/**
* authenticate a user with the configured methods
*
* @global array $aConfig global config
* @global array $aParams params (i.e. GET and POST)
*
* @return boolean
*/
public function authenticate(): bool
{
global $aConfig, $aParams;
if (!isset($aConfig['auth']) || !is_array($aConfig['auth']) || !count($aConfig['auth']) || !isset($aParams['user'])) {
return false;
}
$sUser = $aParams['user'];
$sPassword = isset($aParams['password']) ? $aParams['password'] : false;
foreach (array_keys($aConfig['auth']) as $sAuthMethod) {
$oUserAuth = false;
switch ($sAuthMethod) {
case 'ldap':
require_once("userauth.ldap.class.php");
$oUserAuth = new userauthLdap($aConfig['auth']['ldap']);
break;
// implement other methods here
// see userauth.ldap.class.php as simple example
default:
echo 'WARNING: authmethod ' . $sAuthMethod . ' in your config is not implemented in ' . basename(__FILE__) . ' and is useless so far.<br>';
}
// if authentication fails then continue and try next method
if ($oUserAuth && $oUserAuth->authenticate($sUser, $sPassword)) {
// set a session - it must correspondent with _autoDetectUser()
// $_SESSION["PHP_AUTH_USER"]=$sUser;
$this->setUser($sUser);
return true;
}
// if authentication fails then continue and try next method
if (!$oUserAuth) {
echo "DEBUG: ERROR oUserAuth waasn't initialized for [$sAuthMethod].<br>";
}
}
return false;
}
/**
* logoff user
* @return boolean
*/
public function logoff(): bool
{
unset($_SESSION["PHP_AUTH_USER"]);
$this->setUser();
return true;
}
/**
* set an authenticated user and get its roles
* @param string $sUser optional: set a given username
* @return void
*/
public function setUser(string $sUser = ''): void
{
if ($sUser) {
$this->_sUsername = $sUser;
$_SESSION["PHP_AUTH_USER"] = $sUser;
} else {
// check user from basic auth or cli
$this->_sUsername = $this->_autoDetectUser();
}
$this->_getUserGroups();
$this->_getUserPermission();
}
/**
* Get html code to display a denied message
* @return string
*/
public function showDenied(): string
{
return '<div class="alert alert-danger" role="alert">'
. ($this->_sUsername
? t("class-user-error-deny-no-role") . '<br>' . $this->_sUsername . ' --> (' . $this->_sLastCheckedPermission . ')<br>'
: t("class-user-error-login-required")
)
. '</div><br>'
. '<a href="/deployment/all/login/" class="btn btn-primary">' . t('menu-login') . '</a>'
;
}
// ----------------------------------------------------------------------
// public GETTER
// ----------------------------------------------------------------------
/**
* UNUSED SO FAR
* Idea: limit user access to a set of projects
*/
public function getUser2Projects()
{
return $this->_getUser2Projects();
}
/**
* Get a list of all roles for the current user
* @return array
*/
public function getUser2Roles(): array
{
return $this->_getUser2Roles();
}
/**
* Get the current username
* @return string
*/
public function getUsername(): string
{
return $this->_sUsername;
}
/**
* Get a flat array with roles of the current user
* @return array
*/
public function getUserGroups(): array
{
return $this->_aUserGroups;
}
/**
* Get a flat array with roles of the current user
* @return array
*/
public function getUserPermission(): array
{
return $this->_aUserPermmissions;
}
/**
* check if the current user has a given role name
* @param string $sGroupname name of the role to check
* @return bool
*/
public function hasGroup($sGroupname)
{
return !!(array_search($sGroupname, $this->_aUserGroups) !== false);
}
/**
* check if the current user has a given role name
* @param string $sPermission name of the role to check
* @return boolean
*/
public function hasPermission($sPermission): bool
{
$this->_sLastCheckedPermission = $sPermission;
$bReturn = !!(array_search($sPermission, $this->_aUserPermmissions) !== false);
// $this->log(__FUNCTION__ . "($sRolename) -> " . $bReturn ? 'true' : 'false');
return $bReturn;
}
}