winter/modules/backend/classes/AuthManager.php

230 lines
6.2 KiB
PHP
Raw Normal View History

2014-05-14 23:24:20 +10:00
<?php namespace Backend\Classes;
use System\Classes\PluginManager;
2014-05-14 23:24:20 +10:00
use October\Rain\Auth\Manager as RainAuthManager;
/**
* Back-end authentication manager.
*
* @package october\backend
* @author Alexey Bobkov, Samuel Georges
*/
class AuthManager extends RainAuthManager
{
protected static $instance;
protected $sessionKey = 'admin_auth';
protected $userModel = 'Backend\Models\User';
protected $groupModel = 'Backend\Models\UserGroup';
protected $throttleModel = 'Backend\Models\UserThrottle';
protected $requireActivation = false;
//
// Permission management
//
protected static $permissionDefaults = [
2014-05-14 23:24:20 +10:00
'code' => null,
'label' => null,
'comment' => null,
'roles' => null,
2015-05-21 22:54:44 +10:00
'order' => 500
2014-05-14 23:24:20 +10:00
];
/**
* @var array Cache of registration callbacks.
*/
2014-08-01 18:20:55 +10:00
protected $callbacks = [];
2014-05-14 23:24:20 +10:00
/**
* @var array List of registered permissions.
*/
2014-08-01 18:20:55 +10:00
protected $permissions = [];
2014-05-14 23:24:20 +10:00
/**
* @var array List of registered permission roles.
*/
protected $permissionRoles = false;
2014-05-14 23:24:20 +10:00
/**
* @var array Cache of registered permissions.
*/
2014-08-01 18:20:55 +10:00
protected $permissionCache = false;
2014-05-14 23:24:20 +10:00
/**
* Registers a callback function that defines authentication permissions.
* The callback function should register permissions by calling the manager's
* registerPermissions() function. The manager instance is passed to the
* callback function as an argument. Usage:
*
* BackendAuth::registerCallback(function($manager){
* $manager->registerPermissions([...]);
* });
*
2014-05-14 23:24:20 +10:00
* @param callable $callback A callable function.
*/
public function registerCallback(callable $callback)
{
$this->callbacks[] = $callback;
}
/**
* Registers the back-end permission items.
* The argument is an array of the permissions. The array keys represent the
* permission codes, specific for the plugin/module. Each element in the
2014-05-14 23:24:20 +10:00
* array should be an associative array with the following keys:
* - label - specifies the menu label localization string key, required.
* - order - a position of the item in the menu, optional.
* - comment - a brief comment that describes the permission, optional.
* - tab - assign this permission to a tabbed group, optional.
* @param string $owner Specifies the menu items owner plugin or module in the format Vendor/Module.
* @param array $definitions An array of the menu item definitions.
*/
2014-10-10 23:12:50 +02:00
public function registerPermissions($owner, array $definitions)
2014-05-14 23:24:20 +10:00
{
2014-10-10 23:12:50 +02:00
foreach ($definitions as $code => $definition) {
2014-05-14 23:24:20 +10:00
$permission = (object)array_merge(self::$permissionDefaults, array_merge($definition, [
2014-10-10 23:12:50 +02:00
'code' => $code,
'owner' => $owner
2014-05-14 23:24:20 +10:00
]));
$this->permissions[] = $permission;
}
}
/**
2015-05-21 22:54:44 +10:00
* Returns a list of the registered permissions items.
* @return array
2014-05-14 23:24:20 +10:00
*/
public function listPermissions()
{
2014-10-10 23:12:50 +02:00
if ($this->permissionCache !== false) {
2014-05-14 23:24:20 +10:00
return $this->permissionCache;
2014-10-10 23:12:50 +02:00
}
2014-05-14 23:24:20 +10:00
/*
* Load module items
*/
2014-05-14 23:24:20 +10:00
foreach ($this->callbacks as $callback) {
$callback($this);
}
/*
* Load plugin items
*/
$plugins = PluginManager::instance()->getPlugins();
foreach ($plugins as $id => $plugin) {
$items = $plugin->registerPermissions();
2014-10-10 23:12:50 +02:00
if (!is_array($items)) {
continue;
2014-10-10 23:12:50 +02:00
}
$this->registerPermissions($id, $items);
}
/*
* Sort permission items
*/
2014-10-10 23:12:50 +02:00
usort($this->permissions, function ($a, $b) {
if ($a->order == $b->order) {
2014-05-14 23:24:20 +10:00
return 0;
2014-10-10 23:12:50 +02:00
}
2014-05-14 23:24:20 +10:00
return $a->order > $b->order ? 1 : -1;
});
return $this->permissionCache = $this->permissions;
}
2015-05-21 22:54:44 +10:00
/**
* Returns an array of registered permissions, grouped by tabs.
* @return array
*/
public function listTabbedPermissions()
{
$tabs = [];
foreach ($this->listPermissions() as $permission) {
$tab = $permission->tab ?? 'backend::lang.form.undefined_tab';
2015-05-21 22:54:44 +10:00
if (!array_key_exists($tab, $tabs)) {
$tabs[$tab] = [];
}
$tabs[$tab][] = $permission;
}
return $tabs;
}
/**
* {@inheritdoc}
*/
protected function createUserModelQuery()
{
return parent::createUserModelQuery()->withTrashed();
}
/**
* {@inheritdoc}
*/
protected function validateUserModel($user)
{
if ( ! $user instanceof $this->userModel) {
return false;
}
// Perform the deleted_at check manually since the relevant migrations
// might not have been run yet during the update to build 444.
// @see https://github.com/octobercms/october/issues/3999
if (array_key_exists('deleted_at', $user->getAttributes()) && $user->deleted_at !== null) {
return false;
}
return $user;
}
/**
* Returns an array of registered permissions belonging to a given role code
* @param string $role
2019-01-03 16:26:30 -06:00
* @param bool $includeOrphans
* @return array
*/
public function listPermissionsForRole($role, $includeOrphans = true)
{
if ($this->permissionRoles === false) {
$this->permissionRoles = [];
foreach ($this->listPermissions() as $permission) {
if ($permission->roles) {
foreach ((array) $permission->roles as $_role) {
$this->permissionRoles[$_role][$permission->code] = 1;
}
}
else {
$this->permissionRoles['*'][$permission->code] = 1;
}
}
}
$result = $this->permissionRoles[$role] ?? [];
if ($includeOrphans) {
$result += $this->permissionRoles['*'] ?? [];
}
return $result;
}
public function hasPermissionsForRole($role)
{
return !!$this->listPermissionsForRole($role, false);
}
2014-10-10 23:12:50 +02:00
}