From aefd2102733508134d92432c5021c2579e4aa01b Mon Sep 17 00:00:00 2001 From: Paolo Date: Tue, 12 Mar 2019 11:33:01 +0100 Subject: [PATCH] - Added new configuration file auth.php for authentication - Added new configuration file ldap.php for LDAP connection - Added new controller system/Login to manage logins - Added new controller system/Logout to manage logout - Added new core model LDAP_Model to manage LDAP connections - Added new constants in config/constants for authentication - Added new function getCode to hlp_message_helper - Now core/Auth_Controller loads the AuthLib as first step - Now PermissionLib does NOT load anymore the AuthLib - Removed old logic from PermissionLib - Now function getAuthUID (hlp_authentication_helper) does not load anymore the AuthLib - Now REST_Controller loads hlp_message_helper and hlp_common_helper - core/APIv1_Controller does NOT load anymore hlp_message_helper and hlp_common_helper - Added new constants to AuthLib - AuthLib constructor now accept a parameter to enable the authentication immediatly (default) - AuthLib loads configuration file auth.php and Person_model by default - Added public methods getAuthObj and logout to AuthLib - Renamed CheckUserAuthByUsernamePassword to checkUserAuthByUsernamePassword, CheckUserAuthByCode to checkUserAuthByCode and CheckUserAuthByCodeEmail to checkUserAuthByCodeEmail in AuthLib - Added private methods _createAuthObj, _isLogged, _showInvalidAuthentication, _showError, _checkBTAuthentication, _checkHBALDAPAuthentication, _checkLDAPAuthentication, _checkForeignAuthentication, _storeAuthObj and _authenticate to AuthLib --- application/config/auth.php | 24 ++ application/config/constants.php | 34 +- application/config/ldap.php | 63 +++ application/controllers/system/Login.php | 41 ++ application/controllers/system/Logout.php | 31 ++ application/core/APIv1_Controller.php | 9 +- application/core/Auth_Controller.php | 3 + application/core/LDAP_Model.php | 222 ++++++++++ application/core/REST_Controller.php | 5 + .../helpers/hlp_authentication_helper.php | 1 - application/helpers/hlp_message_helper.php | 27 +- application/libraries/AuthLib.php | 400 ++++++++++++++++-- application/libraries/PermissionLib.php | 22 - 13 files changed, 792 insertions(+), 90 deletions(-) create mode 100644 application/config/auth.php create mode 100644 application/config/ldap.php create mode 100644 application/controllers/system/Login.php create mode 100644 application/controllers/system/Logout.php create mode 100644 application/core/LDAP_Model.php diff --git a/application/config/auth.php b/application/config/auth.php new file mode 100644 index 000000000..b1947d2c7 --- /dev/null +++ b/application/config/auth.php @@ -0,0 +1,24 @@ + 'system/Login/emailCode', + AUTH_LDAP => 'system/Login/usernamePassword', + AUTH_SSO => 'system/Login/sso' +); + +// List of permissions that are allowed to perform loginAs +$config['authentication_loginas_perms'] = array('admin', 'infocenter'); + +// List of permissions that cannot be gained with loginAs +$config['authentication_loginas_blacklist'] = array('admin'); diff --git a/application/config/constants.php b/application/config/constants.php index 5e0c9e66e..2901080f3 100644 --- a/application/config/constants.php +++ b/application/config/constants.php @@ -11,14 +11,14 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); | and translated in the language files. | */ -define('FHC_SUCCESS', 0); // General Success Message -define('FHC_ERROR', 1); // General Error Message -define('FHC_MODEL_ERROR', 2); // Model Error -define('FHC_DB_ERROR', 3); // Database Error -define('FHC_NODBTABLE', 4); // No DB-Table is set -define('FHC_NORIGHT', 5); // No rights -define('FHC_INVALIDID', 6); // Invalid or no ID (key) -define('FHC_NOPK', 7); // No primary key +define('FHC_SUCCESS', 0); // General Success Message +define('FHC_ERROR', 1); // General Error Message +define('FHC_MODEL_ERROR', 2); // Model Error +define('FHC_DB_ERROR', 3); // Database Error +define('FHC_NODBTABLE', 4); // No DB-Table is set +define('FHC_NORIGHT', 5); // No rights +define('FHC_INVALIDID', 6); // Invalid or no ID (key) +define('FHC_NOPK', 7); // No primary key /* |-------------------------------------------------------------------------- @@ -60,11 +60,19 @@ define('EXIT_AUTO_MAX', 2000); // highest automatically-assigned error code | Authentication constants |-------------------------------------------------------------------------- */ -// Authentication methods -define('AUTH_SESSION', 'session'); -define('AUTH_LDAP', 'ldap'); -define('AUTH_DB', 'database'); -define('AUTH_SSO', 'sso'); +// Foreign authentication methods +define('AUTH_HBALDAP', 'httpBasicAuthLDAP'); +define('AUTH_BT', 'bewerbung'); + +// Login methods +define('AUTH_LDAP', 'ldap'); +define('AUTH_DB', 'database'); +define('AUTH_SSO', 'sso'); + +// Authentication return codes +define('AUTH_SUCCESS', 0); +define('AUTH_NOT_AUTHENTICATED', 1); +define('AUTH_INVALID_CREDENTIALS', 2); /* |-------------------------------------------------------------------------- diff --git a/application/config/ldap.php b/application/config/ldap.php new file mode 100644 index 000000000..b7134e3ce --- /dev/null +++ b/application/config/ldap.php @@ -0,0 +1,63 @@ + LDAP_SERVER, + 'port' => LDAP_PORT, + 'starttls' => LDAP_STARTTLS, + 'basedn' => LDAP_BASE_DN, + 'username' => LDAP_BIND_USER, + 'password' => LDAP_BIND_PASSWORD, + 'usf' => LDAP_USER_SEARCH_FILTER + ); +} + +if (defined('LDAP2_SERVER')) // 2nd LDAP server +{ + $ldap['development'][] = array( + 'server' => LDAP2_SERVER, + 'port' => LDAP2_PORT, + 'starttls' => LDAP2_STARTTLS, + 'basedn' => LDAP2_BASE_DN, + 'username' => LDAP2_BIND_USER, + 'password' => LDAP2_BIND_PASSWORD, + 'usf' => LDAP2_USER_SEARCH_FILTER + ); +} + +$ldap['production'] = array(); // Live LDAP configs + +if (defined('LDAP_SERVER')) // 1st LDAP server +{ + $ldap['production'][] = array( + 'server' => LDAP_SERVER, + 'port' => LDAP_PORT, + 'starttls' => LDAP_STARTTLS, + 'basedn' => LDAP_BASE_DN, + 'username' => LDAP_BIND_USER, + 'password' => LDAP_BIND_PASSWORD, + 'usf' => LDAP_USER_SEARCH_FILTER + ); +} + +if (defined('LDAP2_SERVER')) // 2nd LDAP server +{ + $ldap['production'][] = array( + 'server' => LDAP2_SERVER, + 'port' => LDAP2_PORT, + 'starttls' => LDAP2_STARTTLS, + 'basedn' => LDAP2_BASE_DN, + 'username' => LDAP2_BIND_USER, + 'password' => LDAP2_BIND_PASSWORD, + 'usf' => LDAP2_USER_SEARCH_FILTER + ); +} diff --git a/application/controllers/system/Login.php b/application/controllers/system/Login.php new file mode 100644 index 000000000..09e9de294 --- /dev/null +++ b/application/controllers/system/Login.php @@ -0,0 +1,41 @@ +load->library('AuthLib'); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Logout the current logged user + */ + public function index() + { + $this->authlib->logout(); + } +} diff --git a/application/core/APIv1_Controller.php b/application/core/APIv1_Controller.php index 1efbe5600..9dd7b4ae8 100644 --- a/application/core/APIv1_Controller.php +++ b/application/core/APIv1_Controller.php @@ -1,5 +1,8 @@ load->helper('hlp_message'); - - // Loads helper with generic utility function - $this->load->helper('hlp_common'); - // Loads permission lib $this->load->library('PermissionLib'); diff --git a/application/core/Auth_Controller.php b/application/core/Auth_Controller.php index 5a3986c90..dfddc5d30 100644 --- a/application/core/Auth_Controller.php +++ b/application/core/Auth_Controller.php @@ -11,6 +11,9 @@ class Auth_Controller extends FHC_Controller { parent::__construct(); + // Loads authentication library and starts authentication + $this->load->library('AuthLib'); + // Loads authentication helper $this->load->helper('hlp_authentication'); diff --git a/application/core/LDAP_Model.php b/application/core/LDAP_Model.php new file mode 100644 index 000000000..bf8b80625 --- /dev/null +++ b/application/core/LDAP_Model.php @@ -0,0 +1,222 @@ +_connection = null; + $this->_workingConfigArray = null; + $this->_ldapConfigArray = null; + + $this->_loadConfig(); // NOTE: always the last to be called! + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Tries to connect to LDAP using configurations in property _ldapConfigArray + * The first that works is used and stored in property _workingConfigArray + * The LDAP connection link is stored in _connection + */ + public function connect() + { + $connect = error('Did not found a working LDAP configuration'); + + // Loops through LDAP configurations + foreach ($this->_ldapConfigArray as $ldapConfigs) + { + // Tries to establish a connection + $connect = $this->_connect($ldapConfigs); + if (isSuccess($connect)) + { + break; // found a working LDAP configuration and successfully connected! + } + else + { + $this->close(); // close the eventually established connection + } + } + + return $connect; + } + + /** + * Tries to reconnect using the given username and password and the last working configuration + */ + public function connectUsernamePassword($username, $password) + { + return $this->_connect($this->_workingConfigArray, $username, $password); + } + + /** + * Close the current connection to LDAP if present + */ + public function close() + { + if ($this->_connection != null) @ldap_unbind($this->_connection); + } + + /** + * Get the user DN from LDAP using the given username + */ + public function getUserDN($username) + { + $userDN = error('No user DN were found'); + + // Tries to search for a user DN using the given username + $searchResultIdentifier = @ldap_search( + $this->_connection, + $this->_workingConfigArray[self::BASEDN], + $this->_workingConfigArray[self::USF].'='.$username + ); + if (!$searchResultIdentifier) // Error + { + $userDN = error(ldap_error($this->_connection)); + } + + // Counts the number of found entries + $countEntries = @ldap_count_entries($this->_connection, $searchResultIdentifier); + if ($countEntries === false) // Error + { + $userDN = error(ldap_error($this->_connection)); + } + elseif ($countEntries != 1) // 0 or > 1 + { + $userDN = error('None or too many user DN were found'); + } + else // One entry was found + { + $entries = @ldap_get_entries($this->_connection, $searchResultIdentifier); + if (!$entries) // Error + { + $userDN = error(ldap_error($this->_connection)); + } + else + { + $userDN = success($entries[0][self::DN]); + } + } + + return $userDN; + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + /** + * Loads the LDAP configuration file and store the LDAP configuration array into _ldapConfigArray property + */ + private function _loadConfig() + { + // Tries to require the LDAP configuration file... + // ...first in the ENVIRONMENT subdirectory... + if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/'.self::LDAP_CONF_FILE.'.php')) + { + require_once(APPPATH.'config/'.ENVIRONMENT.'/'.self::LDAP_CONF_FILE.'.php'); + } + else // ...then in the default config directory + { + require_once(APPPATH.'config/'.self::LDAP_CONF_FILE.'.php'); + } + + $this->_ldapConfigArray = $ldap[$ldap_active_group]; // store the active LDAP configuration array + } + + /** + * Establish a connection to LDAP with the given LDAP configuration array and eventually with + * with a given username and password + */ + private function _connect($ldapConfigs, $username = null, $password = null) + { + // Checks if the LDAP configuraion is empty + if (isEmptyArray($ldapConfigs)) + { + return error('Wrong parameters given'); + } + + // LDAP connection + $ldapConnection = @ldap_connect($ldapConfigs[self::SERVER], $ldapConfigs[self::PORT]); + if ($ldapConnection) // if success + { + // Sets the LDAP protocol version + if (!@ldap_set_option($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, self::LDAP_PROTOCOL_VERSION)) + { + return error(ldap_error($ldapConnection)); + } + + // Enable/disable the LDAP referrals + if (!@ldap_set_option($ldapConnection, LDAP_OPT_REFERRALS, self::LDAP_REFERRALS)) + { + return error(ldap_error($ldapConnection)); + } + + // Starts TLS if required + if ($ldapConfigs[self::STARTTLS] === true) + { + if (!@ldap_start_tls($ldapConnection)) + { + return error(ldap_error($ldapConnection)); + } + } + + // If username and password are not provided... + if ($username == null || $password == null) + { + // ...uses those provided by the configuration + $username = $ldapConfigs[self::USERNAME]; + $password = $ldapConfigs[self::PASSWORD]; + } + + // Binds to LDAP directory + if (!@ldap_bind($ldapConnection, $username, $password)) + { + // Wrong username and/or password + if (ldap_errno($ldapConnection) == self::LDAP_INVALID_CREDENTIALS) + { + return error('Invalid credentials', AUTH_INVALID_CREDENTIALS); + } + else // Error + { + return error(ldap_error($ldapConnection)); + } + } + + $this->_connection = $ldapConnection; // save the connection into _connection property + $this->_workingConfigArray = $ldapConfigs; // save the working LDAP configuration into _workingConfigArray property + + return success('Connected'); // connected!!! + } + else // Connection error + { + return error(ldap_error($ldapConnection)); + } + } +} diff --git a/application/core/REST_Controller.php b/application/core/REST_Controller.php index 0e4ef7266..488892b60 100644 --- a/application/core/REST_Controller.php +++ b/application/core/REST_Controller.php @@ -360,6 +360,11 @@ abstract class REST_Controller extends CI_Controller { */ protected function early_checks() { + // Loads helper message to manage returning messages + $this->load->helper('hlp_message'); + + // Loads helper with generic utility function + $this->load->helper('hlp_common'); } /** diff --git a/application/helpers/hlp_authentication_helper.php b/application/helpers/hlp_authentication_helper.php index abf85a7a3..1c2e3603d 100644 --- a/application/helpers/hlp_authentication_helper.php +++ b/application/helpers/hlp_authentication_helper.php @@ -16,7 +16,6 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); function getAuthUID() { $ci =& get_instance(); // get CI instance - $ci->load->library('AuthLib'); // load authentication library return ($ci->authlib->getAuthObj())->{AuthLib::AO_USERNAME}; } diff --git a/application/helpers/hlp_message_helper.php b/application/helpers/hlp_message_helper.php index f9ff758f3..4470929df 100644 --- a/application/helpers/hlp_message_helper.php +++ b/application/helpers/hlp_message_helper.php @@ -68,6 +68,16 @@ function isSuccess($result) return false; } +/** + * Checks if the result represents an error + * Wrapper function of isSuccess, more readable code + * Bob Dylan: ...there's no success like failure. And that failure's no success at all. + */ +function isError($result) +{ + return !isSuccess($result); +} + /** * Checks if the result represents a success and also if it contains valid data */ @@ -86,7 +96,7 @@ function hasData($result) } /** - * Returns the property retval if $result contains data + * Returns the property retval if $result contains data, otherwise null */ function getData($result) { @@ -101,11 +111,16 @@ function getData($result) } /** - * Checks if the result represents an error - * Wrapper function of isSuccess, more readable code - * Bob Dylan: ...there's no success like failure. And that failure's no success at all. + * Returns the property fhcCode if present, otherwise null */ -function isError($result) +function getCode($result) { - return !isSuccess($result); + $code = null; + + if (isset($result->fhcCode)) + { + $code = $result->fhcCode; + } + + return $code; } diff --git a/application/libraries/AuthLib.php b/application/libraries/AuthLib.php index f686eca4a..65ec5d71f 100644 --- a/application/libraries/AuthLib.php +++ b/application/libraries/AuthLib.php @@ -1,43 +1,58 @@ _ci =& get_instance(); + + // Loads auth configuration + $this->_ci->config->load('auth'); + + // Load model PersonModel + $this->_ci->load->model('person/person_model', 'PersonModel'); + + if ($authenticate === true) $this->_authenticate(); // if required -> authenticate the current user + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Returns the authentication object stored in the session + * if the user is not logged then returns null + */ + public function getAuthObj() + { + return getSessionElement(self::SESSION_NAME, self::SESSION_AUTH_OBJ); } /** @@ -46,19 +61,19 @@ class AuthLib extends authentication */ public function basicAuthentication($username, $password) { - return $this->checkpassword($username, $password); + return isSuccess($this->_checkLDAPAuthentication($username, $password)); } /** * Checks if the given username and password of a final user are valid */ - public function CheckUserAuthByUsernamePassword($username, $password, $keys = false) + public function checkUserAuthByUsernamePassword($username, $password, $keys = false) { $result = error(false); if (isset($username) && isset($password)) { - if ($this->checkpassword($username, $password) === true) + if (isSuccess($this->_checkLDAPAuthentication($username, $password))) { if ($keys === true) { @@ -77,15 +92,11 @@ class AuthLib extends authentication /** * Checks if the given code of a final user is valid */ - public function CheckUserAuthByCode($code) + public function checkUserAuthByCode($code) { $result = error(false); - // Load model PersonModel - $this->_ci->load->model('person/person_model', 'PersonModel'); - $person = $this->_ci->PersonModel->loadWhere(array('zugangscode' => $code)); - if (hasData($person)) { $result = $this->_getFinalUserBasicDataByPersonID($person->retval[0]->person_id); @@ -97,15 +108,11 @@ class AuthLib extends authentication /** * Checks if the given code and email of a final user are valid */ - public function CheckUserAuthByCodeEmail($code, $email) + public function checkUserAuthByCodeEmail($code, $email) { $result = error(false); - // Load model PersonModel - $this->_ci->load->model('person/person_model', 'PersonModel'); - $person = $this->_ci->PersonModel->getPersonKontaktByZugangscode($code, $email); - if (hasData($person)) { $result = $this->_getFinalUserBasicDataByPersonID($person->retval[0]->person_id); @@ -114,6 +121,316 @@ class AuthLib extends authentication return $result; } + /** + * Logs out the current logged user + * If the user is using the LoginAs functionality then it is logged out from the acquired user + * and its original one is restored + */ + public function logout() + { + $authObj = getSessionElement(AuthLib::SESSION_NAME, AuthLib::SESSION_AUTH_OBJ); + $authObjOrigin =getSessionElement(AuthLib::SESSION_NAME, AuthLib::SESSION_AUTH_OBJ_ORIGIN); + + // NOT logged in + if ($authObj == null || $authObjOrigin == null) return; + + // LoginAs functionality NOT in use + if ($authObj->{AuthLib::AO_PERSON_ID} == $authObjOrigin->{AuthLib::AO_PERSON_ID}) + { + // Clean the entire session -> fully logged out + cleanSession(AuthLib::SESSION_NAME); + } + else // LoginAs functionality in use + { + // Copy the origin authentication object as the authentication object in session + // The LoginAs account is logged out + // The user is again connected with its real account + setSessionElement( + AuthLib::SESSION_NAME, + AuthLib::SESSION_AUTH_OBJ, + getSessionElement(self::SESSION_NAME, self::SESSION_AUTH_OBJ_ORIGIN) + ); + } + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + /** + * Create an authentication object with all the information about the logged user + * The minimum information required is the person_id + * Username should be null only if the user is authenticated with a foreign authentication method + */ + private function _createAuthObj($person_id, $name = null, $surname = null, $username = null) + { + $authObj = null; + + if (is_numeric($person_id)) + { + $authObj = new stdClass(); + + $authObj->{self::AO_PERSON_ID} = $person_id; + $authObj->{self::AO_NAME} = $name; + $authObj->{self::AO_SURNAME} = $surname; + $authObj->{self::AO_USERNAME} = $username; + } + + return $authObj; + } + + /** + * If the object store in $_SESSIOn['AUTH']['AUTH_OBJ'] + * is NOT null (logged) then returns true otherwise false (NOT logged) + */ + private function _isLogged() + { + return $this->getAuthObj() != null; + } + + /** + * Display an invalid credentials error + * Used only by HTTP basic authentication! + */ + private function _showInvalidAuthentication() + { + header('HTTP/1.0 401 Unauthorized'); // set the HTTP header as unauthorized + unset($_SERVER['PHP_AUTH_USER']); + + $this->_ci->load->library('EPrintfLib'); // loads the EPrintfLib to format the output + + // Prints the main error message + $this->_ci->eprintflib->printError('The provided authentication credentials are invalid'); + // Prints the called controller name + $this->_ci->eprintflib->printInfo('Controller name: '.$this->_ci->router->class); + // Prints the called controller method name + $this->_ci->eprintflib->printInfo('Method name: '.$this->_ci->router->method); + + exit; // immediately terminate the execution + } + + /** + * Display a generic blocking error occurred while authenticating the user + */ + private function _showError($errorMessage) + { + $this->_ci->load->library('EPrintfLib'); // loads the EPrintfLib to format the output + $this->_ci->load->library('LogLib'); // Loads the logs library + + // Prints the main error message + $this->_ci->eprintflib->printError('An error occurred while checking the provided credentials'); + $this->_ci->eprintflib->printError('Please contact the system administrator'); + // Prints the called controller name + $this->_ci->eprintflib->printInfo('Controller name: '.$this->_ci->router->class); + // Prints the called controller method name + $this->_ci->eprintflib->printInfo('Method name: '.$this->_ci->router->method); + // Prints date and time + $this->_ci->eprintflib->printInfo('Date and time: '.date('Y.m.d H:i:s')); + + $this->_ci->loglib->logError($errorMessage); + + exit; // immediately terminate the execution + } + + /** + * Checks if the user is already authenticated with the Bewerbung Tool + * NOTE: this method does NOT set the username in the authentication object + */ + private function _checkBTAuthentication() + { + $bt = error('Not authenticated', AUTH_NOT_AUTHENTICATED); // by default is NOT authenticated + + // Checks if an authentication were performed via BT + if (isset($_SESSION['bewerbung/personId']) && is_numeric($_SESSION['bewerbung/personId']) && isset($_SESSION['bewerbung/user'])) + { + $this->_ci->PersonModel->resetQuery(); // Reset an eventually already built query + + // Then retrieves the person data from DB using the person_id + $this->_ci->PersonModel->addSelect('vorname, nachname'); + + // Retrieves user data using its own person_id + $personResult = $this->_ci->PersonModel->load($_SESSION['bewerbung/personId']); + if (hasData($personResult)) // Found! + { + $person = getData($personResult)[0]; + + // Stores used data into the authentication object and then into a success object + $bt = success( + $this->_createAuthObj($_SESSION['bewerbung/personId'], $person->vorname, $person->nachname), + AUTH_SUCCESS + ); + } + elseif (isError($person)) // Blocking error + { + $bt = $person; // return it! + } + } + + return $bt; + } + + /** + * Checks if the user is already authenticated with HTTP basic authentication + LDAP + * NOTE: this method also display a login, not possible to be avoided due HTTP basic authentication limitations + */ + private function _checkHBALDAPAuthentication() + { + $hta = error('Not authenticated', AUTH_NOT_AUTHENTICATED); // by default is NOT authenticated + + // Checks if an HTTP basic authentication is active and checks credentials using LDAP + if (!isset($_SERVER['PHP_AUTH_USER']) || isError($hta = $this->_checkLDAPAuthentication($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']))) + { + // If NOT send the header to perform an HTTP basic authentication + header('WWW-Authenticate: Basic realm="'.AUTH_NAME.'"'); + } + else // otherwise + { + $this->_ci->PersonModel->resetQuery(); // Reset an eventually already built query + + // Retrieves user data from DB using the UID + $personResult = $this->_ci->PersonModel->getByUid($_SERVER['PHP_AUTH_USER']); + if (hasData($personResult)) + { + $person = getData($personResult)[0]; + + // Stores used data into the authentication object and then into a success object + $hta = success( + $this->_createAuthObj($person->person_id, $person->vorname, $person->nachname, $_SERVER['PHP_AUTH_USER']), + AUTH_SUCCESS + ); + } + elseif (isError($personResult)) // Blocking error + { + $hta = $personResult; // return it! + } + } + + return $hta; + } + + /** + * Checks the provided username and password with LDAP + */ + private function _checkLDAPAuthentication($username, $password) + { + $ldap = error('Not authenticated', AUTH_NOT_AUTHENTICATED); // by default is NOT authenticated + $ldapModel = new LDAP_Model(); // LDAP model handles the LDAP connection + + $ldapConnection = $ldapModel->connect(); // connect! + if (isSuccess($ldapConnection)) // connected!! + { + // Get the user DN from LDAP + $userDN = $ldapModel->getUserDN($username); + if (isSuccess($userDN)) // got it! + { + $ldapModel->close(); // close the previous LDAP connection + + // Connects to LDAP using the last working configuration + the retrieved user DN + the provided password + $ldapConnection = $ldapModel->connectUsernamePassword(getData($userDN), $password); + if (isSuccess($ldapConnection)) // connected! + { + $ldapModel->close(); // close the previous connection + $ldap = success('Authenticated'); // authenticated! + } + else // Error + { + $ldap = $ldapConnection; + } + } + else // Error + { + $ldap = $userDN; + } + } + else // Error + { + $ldap = $ldapConnection; + } + + return $ldap; + } + + /** + * Tries to find if the user is already logged via a foreign authentication method + * using a list of foreign authentication methods provided with the configurations + * If the user is logged via a foreign authentication method then an authentication object is returned + */ + private function _checkForeignAuthentication() + { + $auth = error('Not authenticated', AUTH_NOT_AUTHENTICATED); // by default is NOT authenticated + $am = $this->_ci->config->item(self::AUTHENTICATION_FOREIGN_METHODS); // foreign authentication methods array + + // Loops through the foreign authentication methods + foreach ($am as $method) + { + // Performs a different action for each foreign authentication method + switch ($method) + { + case AUTH_BT: // Bewerbung tool + $auth = $this->_checkBTAuthentication(); + break; + case AUTH_HBALDAP: // HTTP basic authentication + LDAP + $auth = $this->_checkHBALDAPAuthentication(); + break; + } + + // Invalid credentials + // NOTE: this is a corner case because of the HTTP basic authentication + if (getCode($auth) == AUTH_INVALID_CREDENTIALS) + { + $this->_showInvalidAuthentication(); // this also stop the execution + } + + // If not authenticated with this method... + if (getCode($auth) == AUTH_NOT_AUTHENTICATED) + { + // ...then continue to the next one + } + // If generic error or a foreign authentication was found stop checking + elseif (isError($auth) || (hasData($auth) && is_object(getData($auth)))) + { + break; + } + } + + return $auth; + } + + /** + * Stores the authentication object into the authentication session + */ + private function _storeAuthObj($authObj) + { + setSessionElement(self::SESSION_NAME, self::SESSION_AUTH_OBJ, $authObj); + setSessionElement(self::SESSION_NAME, self::SESSION_AUTH_OBJ_ORIGIN, $authObj); + } + + /** + * Starts the user authentication! + */ + private function _authenticate() + { + // If NOT logged + if (!$this->_isLogged()) + { + // Checks if already logged with a foreign authentication method + $auth = $this->_checkForeignAuthentication(); + if (hasData($auth)) // Authenticated with a foreign authentication method + { + $this->_storeAuthObj(getData($auth)); // Store the session authentication object + } + elseif (getCode($auth) == AUTH_NOT_AUTHENTICATED) // If no foreign authentication was found + { + // TODO: ask for a login + exit; + } + elseif (isError($auth)) // If an error occurred + { + $this->_showError(getData($auth)); // display the occurred error + } + } + // else the user is already logged, then continue with the execution + } + /** * Returns all the keys with which is possible to obtain personal data about a final user * using the given username (uid) @@ -126,7 +443,6 @@ class AuthLib extends authentication $this->_ci->load->model('person/Benutzer_model', 'BenutzerModel'); $benutzer = $this->_ci->BenutzerModel->load($uid); - if (hasData($benutzer)) { $finalUserBasicDataByUID = $this->_getFinalUserBasicDataByPersonID($benutzer->retval[0]->person_id); diff --git a/application/libraries/PermissionLib.php b/application/libraries/PermissionLib.php index ae68837f8..172be27ff 100644 --- a/application/libraries/PermissionLib.php +++ b/application/libraries/PermissionLib.php @@ -42,7 +42,6 @@ class PermissionLib const WRITE_HTTP_METHOD = 'POST'; private $_ci; // CI instance - private $acl; // conversion array from a source to a permission private static $bb; // benutzerberechtigung /** @@ -54,12 +53,6 @@ class PermissionLib // Loads CI instance $this->_ci =& get_instance(); - // Loads the array of resources - $this->acl = $this->_ci->config->item('fhc_acl'); - - // Loads authentication library - $this->_ci->load->library('AuthLib'); - // If it's NOT called from command line if (!is_cli()) { @@ -69,21 +62,6 @@ class PermissionLib } } - /** - * Get a permission by a given source - */ - public function getBerechtigungKurzbz($sourceName) - { - $returnValue = null; - - if (isset($this->acl[$sourceName])) - { - $returnValue = $this->acl[$sourceName]; - } - - return $returnValue; - } - /** * Checks user's (API caller) rights */