* @owner University of Latvia * @version 3.0 * @since 09.04.2018 * * @package Lu\LuAuth\Services */ class LUFEAuthService extends AbstractService { /** * Extension configuration * * @array */ public $conf; /** * Remote identity provider * * @var string */ private $remoteIdentityProvider; /** * Remote IDP * * @var string */ private $remoteIDP; /** * Remote Session ID * * @var string */ private $remoteSessionId; /** * Remote user * * @var string */ private $username; /** * Define used login provider. `default: 1433416747` * * @var string */ public $loginProviderID = '1522914815'; /** * Reads and initializes extension configuration * * @return bool */ public function init():bool { // Set config value $this->conf = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Configuration\ExtensionConfiguration::class)->get('lu_auth'); // Set identify provider $this->remoteIdentityProvider = $_SERVER[$this->conf['remoteIdentityProvider']]; // Set Required IDP $this->remoteIDP = $this->conf['remoteIDP']; // Set Session ID $this->remoteSessionId = $_SERVER[$this->conf['remoteSessionId']]; // Set remove user parameter $this->username = $_SERVER[$this->conf['remoteUser']]; // Check if logout is requested $logintype = GeneralUtility::_GP('logintype'); if ($logintype == 'logout') { return $this->setLogout(); } return parent::init(); } /** * Initializes authentication for this service. * * @param string $subType : Subtype for authentication (either "getUserFE" or "getUserBE") * @param array $loginData : Login data submitted by user and preprocessed by AbstractUserAuthentication * @param array $authenticationInformation : Additional TYPO3 information for authentication services (unused here) * @param AbstractUserAuthentication $parentObject Calling object * * @return void */ public function initAuth($subType, array $loginData, array $authenticationInformation, AbstractUserAuthentication &$parentObject) { // Store login and authentication data $this->loginData = $loginData; $this->authenticationInformation = $authenticationInformation; $this->parentObject = $parentObject; } /** * Get user data and redirect to auth site, if login successful * * @return array|null */ public function getUser() { // Set initial authenticated value un false $user = [ 'authenticated' => false, ]; if (!empty($this->remoteSessionId) && preg_match("/{$this->remoteIDP}/", $this->remoteIdentityProvider)) { // Check user. If saved in our system - login, else - create one and then, login $user = $this->syncSingleUserData(); // Check if user is allowed to use system! if (!empty($user)) { $user['authenticated'] = true; } else { return null; } } // Return user data return $user; } /** * Authenticates the user * * @param array $user * * @return bool|int|mixed */ public function authUser(array $user) { // Sets initial to 100 $OK = 100; if ($this->username) { $OK = @$user['authenticated']; // Failed login attempt (wrong password) - write that to the log! if (!$OK) { if ($this->writeAttemptLog) { $this->writelog( 255, 3, 3, 1, "Login-attempt from %s (%s), username '%s', password not accepted!", [ $this->info['REMOTE_ADDR'], $this->info['REMOTE_HOST'], $this->username, ] ); } } // Set 200, if authenticated $OK = $OK ? 200 : 100; } // Check domain lock if ($OK && $user['lockToDomain'] && $user['lockToDomain'] != $this->authInfo['HTTP_HOST']) { if ($this->writeAttemptLog) { $this->writelog( 255, 3, 3, 1, "Login-attempt from %s (%s), username '%s', locked domain '%s' did not match '%s'!", [ $this->authInfo['REMOTE_ADDR'], $this->authInfo['REMOTE_HOST'], $user[$this->authInfo['db_user']['username_column']], $user['lockToDomain'], $this->authInfo['HTTP_HOST'], ] ); } $OK = false; } return $OK; } /** * Retrieve user data or create one, if none present * * @return array|bool */ private function syncSingleUserData() { // Pre-set used models $UserModel = new Users('fe'); $LuisLib = new LuisLibrary(); // Get user date and reactivate if disabled $user = $UserModel->getUserData($this->username, 'activate'); // If still no user, try to catch a new user if (empty($user)) { $user = $LuisLib->getUserData($this->username); $userData = json_decode($user, true); if ($userData['code'] == 200) { $user = $userData['data']; } $user = $UserModel->insertUser($user); } else { $user = $LuisLib->getUserData($this->username); $userData = json_decode($user, true); if ($userData['code'] == 200) { $user = $userData['data']; } $user = $UserModel->updateUser($user); } // Return user return $user; } /** * Set logout and redirect to provided url * * @return null */ private function setLogout() { // Destroy session $SessionsModel = new Sessions('fe'); $SessionsModel->destroy(); // Redirect if logoutHandler is set. if (!empty($this->conf['logoutInfoUrl'])) { $redirectUrl = GeneralUtility::sanitizeLocalUrl($this->conf['logoutInfoUrl']); HttpUtility::redirect($redirectUrl); } return null; } }