user === null && ! $this->authHttp() && ! $this->authExternal() && ! $ignoreSession ) { $this->authenticateFromSession(); } return $this->user !== null; } public function setAuthenticated(User $user, $persist = true) { $username = $user->getUsername(); try { $config = Config::app(); } catch (NotReadableError $e) { Logger::error( new IcingaException( 'Cannot load preferences for user "%s". An exception was thrown: %s', $username, $e ) ); $config = new Config(); } if ($config->get('global', 'config_backend', 'ini') !== 'none') { $preferencesConfig = new ConfigObject(array( 'store' => $config->get('global', 'config_backend', 'ini'), 'resource' => $config->get('global', 'config_resource') )); try { $preferencesStore = PreferencesStore::create( $preferencesConfig, $user ); $preferences = new Preferences($preferencesStore->load()); } catch (Exception $e) { Logger::error( new IcingaException( 'Cannot load preferences for user "%s". An exception was thrown: %s', $username, $e ) ); $preferences = new Preferences(); } } else { $preferences = new Preferences(); } $user->setPreferences($preferences); $groups = $user->getGroups(); foreach (Config::app('groups') as $name => $config) { try { $groupBackend = UserGroupBackend::create($name, $config); $groupsFromBackend = $groupBackend->getMemberships($user); } catch (Exception $e) { Logger::error( 'Can\'t get group memberships for user \'%s\' from backend \'%s\'. An exception was thrown: %s', $username, $name, $e ); continue; } if (empty($groupsFromBackend)) { continue; } $groupsFromBackend = array_values($groupsFromBackend); $groups = array_merge($groups, array_combine($groupsFromBackend, $groupsFromBackend)); } $user->setGroups($groups); $admissionLoader = new AdmissionLoader(); list($permissions, $restrictions) = $admissionLoader->getPermissionsAndRestrictions($user); $user->setPermissions($permissions); $user->setRestrictions($restrictions); $this->user = $user; if ($persist) { $this->persistCurrentUser(); } } /** * Getter for groups belonged to authenticated user * * @return array * @see User::getGroups */ public function getGroups() { return $this->user->getGroups(); } /** * Get the request * * @return \Icinga\Web\Request */ public function getRequest() { if ($this->request === null) { $this->request = Icinga::app()->getRequest(); } return $this->request; } /** * Get applied restrictions matching a given restriction name * * Returns a list of applied restrictions, empty if no user is * authenticated * * @param string $restriction Restriction name * @return array */ public function getRestrictions($restriction) { if (! $this->isAuthenticated()) { return array(); } return $this->user->getRestrictions($restriction); } /** * Returns the current user or null if no user is authenticated * * @return User */ public function getUser() { return $this->user; } /** * Try to authenticate the user with the current session * * Authentication for externally-authenticated users will be revoked if the username changed or external * authentication is no longer in effect */ public function authenticateFromSession() { $this->user = Session::getSession()->get('user'); if ($this->user !== null && $this->user->isExternalUser() === true) { list($originUsername, $field) = $this->user->getExternalUserInformation(); if (! array_key_exists($field, $_SERVER) || $_SERVER[$field] !== $originUsername) { $this->removeAuthorization(); } } } /** * Attempt to authenticate a user from external user backends * * @return bool */ protected function authExternal() { $user = new User(''); foreach ($this->getAuthChain() as $userBackend) { if ($userBackend instanceof ExternalBackend) { if ($userBackend->authenticate($user)) { $this->setAuthenticated($user); return true; } } } return false; } /** * Attempt to authenticate a user using HTTP authentication * * Supports only the Basic HTTP authentication scheme. This will not challenge the client if authorization is * missing or invalid yet. XHR will be ignored. * * @return bool */ protected function authHttp() { if ($this->getRequest()->isXmlHttpRequest()) { return false; } $header = $this->getRequest()->getHeader('Authorization'); if (empty($header)) { return false; } list($scheme) = explode(' ', $header, 2); if ($scheme !== 'Basic') { return false; } $authorization = substr($header, strlen('Basic ')); $credentials = base64_decode($authorization); $credentials = array_filter(explode(':', $credentials)); if (count($credentials) !== 2) { // Deny empty username and/or password return false; } $user = new User($credentials[0]); $password = $credentials[1]; if ($this->getAuthChain()->setSkipExternalBackends(true)->authenticate($user, $password)) { $this->setAuthenticated($user, false); $user->setIsHttpUser(true); return true; } else { return false; } } /** * Whether an authenticated user has a given permission * * @param string $permission Permission name * * @return bool True if the user owns the given permission, false if not or if not authenticated */ public function hasPermission($permission) { if (! $this->isAuthenticated()) { return false; } return $this->user->can($permission); } /** * Writes the current user to the session */ public function persistCurrentUser() { Session::getSession()->set('user', $this->user)->refreshId(); } /** * Purges the current authorization information and session */ public function removeAuthorization() { $this->user = null; Session::getSession()->purge(); } }