2013-06-07 17:30:18 +02:00
|
|
|
<?php
|
2015-02-04 10:46:36 +01:00
|
|
|
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
2013-06-07 17:30:18 +02:00
|
|
|
|
|
|
|
namespace Icinga\Authentication;
|
|
|
|
|
2014-02-14 17:28:11 +01:00
|
|
|
use Exception;
|
2015-05-06 12:18:57 +02:00
|
|
|
use Icinga\Authentication\UserGroup\UserGroupBackend;
|
2014-10-20 13:43:40 +02:00
|
|
|
use Icinga\Application\Config;
|
|
|
|
use Icinga\Exception\IcingaException;
|
2014-02-20 13:53:28 +01:00
|
|
|
use Icinga\Exception\NotReadableError;
|
2014-10-31 10:27:17 +01:00
|
|
|
use Icinga\Application\Logger;
|
2014-10-20 13:43:40 +02:00
|
|
|
use Icinga\User;
|
2014-02-14 17:28:11 +01:00
|
|
|
use Icinga\User\Preferences;
|
|
|
|
use Icinga\User\Preferences\PreferencesStore;
|
2014-10-20 13:43:40 +02:00
|
|
|
use Icinga\Web\Session;
|
2013-11-06 10:20:15 +01:00
|
|
|
|
2013-06-07 17:30:18 +02:00
|
|
|
class Manager
|
|
|
|
{
|
2013-08-28 10:16:18 +02:00
|
|
|
/**
|
|
|
|
* Singleton instance
|
|
|
|
*
|
|
|
|
* @var self
|
|
|
|
*/
|
2014-01-23 12:09:48 +01:00
|
|
|
private static $instance;
|
2013-06-10 13:28:54 +02:00
|
|
|
|
2014-02-26 17:36:20 +01:00
|
|
|
/**
|
2014-03-03 17:21:17 +01:00
|
|
|
* Authenticated user
|
2013-08-28 10:16:18 +02:00
|
|
|
*
|
2013-08-13 18:08:21 +02:00
|
|
|
* @var User
|
2014-07-16 09:33:49 +02:00
|
|
|
*/
|
2014-01-23 12:09:48 +01:00
|
|
|
private $user;
|
2013-07-12 15:37:36 +02:00
|
|
|
|
2014-01-22 12:50:17 +01:00
|
|
|
|
2014-03-03 17:21:17 +01:00
|
|
|
private function __construct()
|
2013-06-07 17:30:18 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-06-27 15:18:24 +02:00
|
|
|
/**
|
2014-02-14 12:11:49 +01:00
|
|
|
* Get the authentication manager
|
2013-08-28 10:16:18 +02:00
|
|
|
*
|
2014-03-03 17:21:17 +01:00
|
|
|
* @return self
|
2013-08-28 10:16:18 +02:00
|
|
|
*/
|
2014-03-03 17:21:17 +01:00
|
|
|
public static function getInstance()
|
2013-06-07 17:30:18 +02:00
|
|
|
{
|
|
|
|
if (self::$instance === null) {
|
2014-03-03 17:21:17 +01:00
|
|
|
self::$instance = new static();
|
2013-06-07 17:30:18 +02:00
|
|
|
}
|
|
|
|
return self::$instance;
|
|
|
|
}
|
|
|
|
|
2014-03-03 17:21:17 +01:00
|
|
|
public function setAuthenticated(User $user, $persist = true)
|
2013-08-13 18:08:21 +02:00
|
|
|
{
|
2014-03-03 17:21:17 +01:00
|
|
|
$username = $user->getUsername();
|
2013-08-13 18:08:21 +02:00
|
|
|
try {
|
2014-10-20 13:43:40 +02:00
|
|
|
$config = Config::app();
|
2014-03-03 17:21:17 +01:00
|
|
|
} catch (NotReadableError $e) {
|
2014-03-03 19:03:39 +01:00
|
|
|
Logger::error(
|
2014-08-27 16:03:15 +02:00
|
|
|
new IcingaException(
|
2015-05-13 10:46:34 +02:00
|
|
|
'Cannot load preferences for user "%s". An exception was thrown: %s',
|
2014-08-27 16:03:15 +02:00
|
|
|
$username,
|
|
|
|
$e
|
|
|
|
)
|
2014-02-21 10:16:16 +01:00
|
|
|
);
|
2014-11-07 13:53:03 +01:00
|
|
|
$config = new Config();
|
2013-08-13 18:08:21 +02:00
|
|
|
}
|
2015-01-23 16:07:38 +01:00
|
|
|
if ($config->get('preferences', 'store', 'ini') !== 'none') {
|
2015-01-23 15:23:43 +01:00
|
|
|
$preferencesConfig = $config->getSection('preferences');
|
2013-08-28 10:16:18 +02:00
|
|
|
try {
|
2014-03-03 17:21:17 +01:00
|
|
|
$preferencesStore = PreferencesStore::create(
|
2015-01-23 15:23:43 +01:00
|
|
|
$preferencesConfig,
|
2014-03-03 17:21:17 +01:00
|
|
|
$user
|
2013-08-28 10:16:18 +02:00
|
|
|
);
|
2014-03-03 17:21:17 +01:00
|
|
|
$preferences = new Preferences($preferencesStore->load());
|
2015-05-27 15:13:53 +02:00
|
|
|
} catch (Exception $e) {
|
2013-08-28 10:16:18 +02:00
|
|
|
Logger::error(
|
2014-08-27 16:03:15 +02:00
|
|
|
new IcingaException(
|
2015-05-13 10:46:34 +02:00
|
|
|
'Cannot load preferences for user "%s". An exception was thrown: %s',
|
2014-08-27 16:03:15 +02:00
|
|
|
$username,
|
|
|
|
$e
|
2014-03-03 17:21:17 +01:00
|
|
|
)
|
2013-08-28 10:16:18 +02:00
|
|
|
);
|
2014-03-03 17:21:17 +01:00
|
|
|
$preferences = new Preferences();
|
2013-08-28 10:16:18 +02:00
|
|
|
}
|
2014-03-03 17:21:17 +01:00
|
|
|
} else {
|
|
|
|
$preferences = new Preferences();
|
2013-08-28 10:16:18 +02:00
|
|
|
}
|
2014-03-03 17:21:17 +01:00
|
|
|
$user->setPreferences($preferences);
|
2015-02-09 15:27:50 +01:00
|
|
|
$groups = $user->getGroups();
|
2014-10-20 13:43:40 +02:00
|
|
|
foreach (Config::app('groups') as $name => $config) {
|
|
|
|
try {
|
|
|
|
$groupBackend = UserGroupBackend::create($name, $config);
|
|
|
|
$groupsFromBackend = $groupBackend->getMemberships($user);
|
|
|
|
} catch (Exception $e) {
|
|
|
|
Logger::error(
|
2015-05-13 10:46:34 +02:00
|
|
|
'Can\'t get group memberships for user \'%s\' from backend \'%s\'. An exception was thrown: %s',
|
2014-10-20 13:43:40 +02:00
|
|
|
$username,
|
|
|
|
$name,
|
|
|
|
$e
|
|
|
|
);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (empty($groupsFromBackend)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$groupsFromBackend = array_values($groupsFromBackend);
|
|
|
|
$groups = array_merge($groups, array_combine($groupsFromBackend, $groupsFromBackend));
|
|
|
|
}
|
2014-02-18 09:33:33 +01:00
|
|
|
$user->setGroups($groups);
|
2014-02-12 17:01:11 +01:00
|
|
|
$admissionLoader = new AdmissionLoader();
|
2014-11-19 15:11:14 +01:00
|
|
|
list($permissions, $restrictions) = $admissionLoader->getPermissionsAndRestrictions($user);
|
|
|
|
$user->setPermissions($permissions);
|
|
|
|
$user->setRestrictions($restrictions);
|
2014-02-18 09:33:33 +01:00
|
|
|
$this->user = $user;
|
2014-10-20 13:43:40 +02:00
|
|
|
if ($persist) {
|
2013-06-10 13:28:54 +02:00
|
|
|
$this->persistCurrentUser();
|
|
|
|
}
|
2013-06-07 17:30:18 +02:00
|
|
|
}
|
|
|
|
|
2013-06-27 15:18:24 +02:00
|
|
|
/**
|
2014-01-23 12:09:48 +01:00
|
|
|
* Writes the current user to the session
|
2014-07-16 09:33:49 +02:00
|
|
|
*/
|
2013-06-07 17:30:18 +02:00
|
|
|
public function persistCurrentUser()
|
|
|
|
{
|
2014-09-17 10:42:56 +02:00
|
|
|
Session::getSession()->set('user', $this->user)->refreshId();
|
2013-06-07 17:30:18 +02:00
|
|
|
}
|
2013-09-04 18:27:16 +02:00
|
|
|
|
2013-06-27 15:18:24 +02:00
|
|
|
/**
|
2014-09-18 15:20:46 +02:00
|
|
|
* 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
|
2014-07-16 09:33:49 +02:00
|
|
|
*/
|
2013-06-07 17:30:18 +02:00
|
|
|
public function authenticateFromSession()
|
|
|
|
{
|
2014-01-23 12:09:48 +01:00
|
|
|
$this->user = Session::getSession()->get('user');
|
2014-07-30 12:54:08 +02:00
|
|
|
if ($this->user !== null && $this->user->isRemoteUser() === true) {
|
|
|
|
list($originUsername, $field) = $this->user->getRemoteUserInformation();
|
2014-09-18 15:20:46 +02:00
|
|
|
if (! array_key_exists($field, $_SERVER) || $_SERVER[$field] !== $originUsername) {
|
2014-07-30 12:54:08 +02:00
|
|
|
$this->removeAuthorization();
|
|
|
|
}
|
|
|
|
}
|
2013-06-07 17:30:18 +02:00
|
|
|
}
|
|
|
|
|
2013-06-27 15:18:24 +02:00
|
|
|
/**
|
2014-09-18 15:20:46 +02:00
|
|
|
* Whether the user is authenticated
|
2013-08-13 18:08:21 +02:00
|
|
|
*
|
2014-09-18 15:20:46 +02:00
|
|
|
* @param bool $ignoreSession True to prevent session authentication
|
2013-08-13 18:08:21 +02:00
|
|
|
*
|
2013-08-28 10:16:18 +02:00
|
|
|
* @return bool
|
|
|
|
*/
|
2013-06-10 13:28:54 +02:00
|
|
|
public function isAuthenticated($ignoreSession = false)
|
2013-06-07 17:30:18 +02:00
|
|
|
{
|
2014-09-18 15:20:46 +02:00
|
|
|
if ($this->user === null && ! $ignoreSession) {
|
2013-06-07 17:30:18 +02:00
|
|
|
$this->authenticateFromSession();
|
|
|
|
}
|
2013-06-10 13:28:54 +02:00
|
|
|
return is_object($this->user);
|
2013-06-07 17:30:18 +02:00
|
|
|
}
|
|
|
|
|
2014-01-22 14:06:59 +01:00
|
|
|
/**
|
|
|
|
* Whether an authenticated user has a given permission
|
|
|
|
*
|
|
|
|
* @param string $permission Permission name
|
2014-09-18 14:57:24 +02:00
|
|
|
*
|
|
|
|
* @return bool True if the user owns the given permission, false if not or if not authenticated
|
2014-01-22 14:06:59 +01:00
|
|
|
*/
|
|
|
|
public function hasPermission($permission)
|
|
|
|
{
|
|
|
|
if (! $this->isAuthenticated()) {
|
|
|
|
return false;
|
|
|
|
}
|
2014-09-18 14:57:24 +02:00
|
|
|
return $this->user->can($permission);
|
2014-01-22 14:06:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
}
|
|
|
|
|
2013-06-27 15:18:24 +02:00
|
|
|
/**
|
2014-07-16 09:35:32 +02:00
|
|
|
* Purges the current authorization information and session
|
|
|
|
*/
|
2013-06-07 17:30:18 +02:00
|
|
|
public function removeAuthorization()
|
|
|
|
{
|
|
|
|
$this->user = null;
|
2014-07-16 09:35:32 +02:00
|
|
|
Session::getSession()->purge();
|
2013-06-07 17:30:18 +02:00
|
|
|
}
|
|
|
|
|
2013-06-27 15:18:24 +02:00
|
|
|
/**
|
2013-11-20 19:10:38 +01:00
|
|
|
* Returns the current user or null if no user is authenticated
|
2013-08-13 18:08:21 +02:00
|
|
|
*
|
2013-11-20 19:10:38 +01:00
|
|
|
* @return User
|
2014-07-16 09:33:49 +02:00
|
|
|
*/
|
2013-06-07 17:30:18 +02:00
|
|
|
public function getUser()
|
|
|
|
{
|
|
|
|
return $this->user;
|
|
|
|
}
|
|
|
|
|
2013-06-27 15:18:24 +02:00
|
|
|
/**
|
2014-01-23 12:09:48 +01:00
|
|
|
* Getter for groups belonged to authenticated user
|
2013-08-28 10:16:18 +02:00
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
* @see User::getGroups
|
2014-07-16 09:33:49 +02:00
|
|
|
*/
|
2013-06-07 17:30:18 +02:00
|
|
|
public function getGroups()
|
|
|
|
{
|
|
|
|
return $this->user->getGroups();
|
|
|
|
}
|
|
|
|
}
|