View source
<?php
namespace Drupal\administerusersbyrole\Services;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
class AccessManager implements AccessManagerInterface {
use StringTranslationTrait;
protected $configFactory;
protected $config;
const CONVERT_OP = [
'cancel' => 'cancel',
'delete' => 'cancel',
'edit' => 'edit',
'update' => 'edit',
'view' => 'view',
'role-assign' => 'role-assign',
];
public function __construct(ConfigFactoryInterface $config_factory) {
$this->configFactory = $config_factory;
$this->config = $config_factory
->get('administerusersbyrole.settings');
}
public function rolesChanged() {
$role_config = [];
foreach (array_keys($this
->managedRoles()) as $rid) {
$role_config[$rid] = $this->config
->get("roles.{$rid}") ?: self::UNSAFE;
}
$this->configFactory
->getEditable('administerusersbyrole.settings')
->set('roles', $role_config)
->save();
}
public function permissions() {
$op_titles = [
'edit' => $this
->t('Edit users with allowed roles'),
'cancel' => $this
->t('Cancel users with allowed roles'),
'view' => $this
->t('View users with allowed roles'),
'role-assign' => $this
->t('Assign allowed roles'),
];
foreach ($op_titles as $op => $title) {
$perm_string = $this
->buildPermString($op);
$perms[$perm_string] = [
'title' => $title,
];
}
$role_config = $this->config
->get('roles') ?: [];
$role_config = array_filter($role_config, function ($s) {
return $s == self::PERM;
});
$roles = array_intersect_key($this
->managedRoles(), $role_config);
foreach ($roles as $rid => $role) {
$op_role_titles = [
'edit' => $this
->t("Edit users includes role %role", [
'%role' => $role
->label(),
]),
'cancel' => $this
->t("Cancel users includes role %role", [
'%role' => $role
->label(),
]),
'view' => $this
->t("View users includes role %role", [
'%role' => $role
->label(),
]),
'role-assign' => $this
->t("Assign roles includes role %role", [
'%role' => $role
->label(),
]),
];
foreach ($op_role_titles as $op => $title) {
$perm_string = $this
->buildPermString($op, $rid);
$description = $this
->t('This permission only works when combined with %base', [
'%base' => $op_titles[$op],
]);
$perms[$perm_string] = [
'title' => $title,
'description' => $description,
];
}
}
return $perms;
}
public function access(array $roles, $operation, AccountInterface $account) {
if (!$this
->preAccess($operation, $account)) {
return AccessResult::neutral();
}
foreach ($roles as $rid) {
if (!$this
->roleAccess($operation, $account, $rid)) {
return AccessResult::neutral();
}
}
return AccessResult::allowed();
}
public function listRoles($operation, AccountInterface $account) {
if (!$this
->preAccess($operation, $account)) {
return [];
}
$roles = [
AccountInterface::AUTHENTICATED_ROLE,
];
foreach (array_keys($this
->managedRoles()) as $rid) {
if ($this
->roleAccess($operation, $account, $rid)) {
$roles[] = $rid;
}
}
return $roles;
}
public function managedRoles() {
$roles = array_filter(user_roles(TRUE), function ($role) {
return !$role
->hasPermission('administer users');
});
unset($roles[AccountInterface::AUTHENTICATED_ROLE]);
return $roles;
}
protected function preAccess(&$operation, AccountInterface $account) {
if ($account
->hasPermission('administer users')) {
return FALSE;
}
if (!array_key_exists($operation, self::CONVERT_OP)) {
return FALSE;
}
$operation = self::CONVERT_OP[$operation];
return $this
->hasPerm($operation, $account);
}
protected function roleAccess($operation, AccountInterface $account, $rid) {
if ($rid == AccountInterface::AUTHENTICATED_ROLE) {
return self::SAFE;
}
$setting = $this->config
->get("roles.{$rid}") ?: self::UNSAFE;
switch ($setting) {
case self::SAFE:
return TRUE;
case self::UNSAFE:
return FALSE;
case self::PERM:
return $this
->hasPerm($operation, $account, $rid);
}
}
protected function hasPerm($operation, AccountInterface $account, $rid = NULL) {
return $account
->hasPermission($this
->buildPermString($operation, $rid));
}
public function buildPermString($operation, $rid = NULL) {
return $rid ? "{$operation} users with role {$rid}" : "{$operation} users by role";
}
}