grant-1.x-dev/modules/grant_base/grant_base.module
modules/grant_base/grant_base.module
<?php
/**
* @file
* Primary module hooks for Grant base module.
*/
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Site\Settings;
use Drupal\user\Entity\User;
use Drupal\user\UserInterface;
/**
* Implements hook_entity_access().
*/
function grant_base_entity_access(EntityInterface $entity, $operation, AccountInterface $account) {
$access_result = NULL;
$access_operation = FALSE;
// @todo Check if we need also operate on new entity/preview.
if ($entity->isNew()) {
return $access_result;
}
// Grant is currently only for content entities.
if ($entity instanceof ConfigEntityBase) {
return $access_result;
}
$grant_config = Settings::get('grant', []);
$e_type = $entity->getEntityTypeId();
$grant_config_entity = $grant_config['entities'][$e_type] ?? [];
if ($grant_config_entity == []) {
return $access_result;
}
$bundle = $entity->bundle();
$config = $grant_config_entity[$bundle] ?? [];
if ($config == []) {
return $access_result;
}
$allowed_if = $config['access_allowed_if'] ?? FALSE;
$check_perm_array = $config['entity_access_perm'][$operation] ?? [];
$entity_access_perm_base = $config['entity_access_perm_base'] ?? TRUE;
if ($entity_access_perm_base) {
$check_perm_array[] = ['grant-base entity access ' . $operation];
}
$check_perm = (string) implode('+', $check_perm_array);
$check_roles = $config['entity_access_role'][$operation] ?? [];
$user_global_roles = $account->getRoles();
if ($check_roles) {
$access_operation = !empty(array_intersect(array_filter($check_roles), $user_global_roles));
}
if (!$access_operation && $check_perm_array != []) {
$access_operation = $account->hasPermission($check_perm);
}
$access_ops_direct = $config['access_ops_direct'] ?? [];
$uid = $account->id();
if (!$access_operation && $access_ops_direct != []) {
$type_manager = \Drupal::service('entity_type.manager');
$role_storage = $type_manager->getStorage('user_role');
$fields = $entity->getFields();
foreach ($access_ops_direct as $parent_field => $parent_config) {
$parent_ops = $parent_config['ops'] ?? [];
if ((in_array($operation, $parent_ops)) && (isset($fields[$parent_field]))) {
$field = $fields[$parent_field];
if ($target_type = $field->getSetting('target_type')) {
switch ($target_type) {
case 'user_role':
$access_operation_roles = [];
$values = $field->getValue();
foreach ($values as $value) {
$target_role = '';
if (isset($value['target_id'])) {
$target_role = $value['target_id'];
}
else {
if (isset($value['target_uuid'])) {
$target = $role_storage->load($value['target_uuid']);
if ($target) {
$target_role = $target->id();
}
}
}
if (!in_array($target_role, $access_operation_roles)) {
$access_operation_roles[] = $target_role;
}
}
foreach ($access_operation_roles as $access_operation_role) {
if (in_array($access_operation_role, $user_global_roles)) {
$access_operation = TRUE;
break;
}
}
break;
case 'user':
$values = $field->getValue();
foreach ($values as $value) {
$target_id = 0;
if (isset($value['target_id'])) {
$target_id = $value['target_id'];
}
else {
if (isset($value['target_uuid'])) {
$target_user = $type_manager->getStorage('user')->load($value['target_uuid']);
if ($target_user instanceof UserInterface) {
$target_id = $target_user->id();
}
}
}
if ($target_id == $uid) {
$access_operation = TRUE;
break;
}
}
break;
default:
$parent_entities = $entity->get($parent_field)->referencedEntities();
foreach ($parent_entities as $parent_entity) {
if ($parent_entity->access($operation, $account)) {
$access_operation = TRUE;
break;
}
}
break;
}
}
}
if ($access_operation) {
break;
}
}
}
$assign_access = $config['assign_access'] ?? FALSE;
if (!$access_operation && $assign_access && ($uid > 0)) {
if (\Drupal::moduleHandler()->moduleExists('grant')) {
$e_uuid = $entity->uuid();
$u3id = User::load($uid)->uuid();
$uag_roles = [];
if ($check_roles) {
$uag_roles = \Drupal::service('grant.main')->getUserAssignedGrantRoles($u3id, $e_type, $e_uuid);
$access_operation = !empty(array_intersect(array_filter($check_roles), $uag_roles));
}
if (!$access_operation && $check_perm_array != []) {
$access_operation = \Drupal::service('grant.main')->userAssignedGrantHasPermission($u3id, $check_perm, $e_type, $e_uuid, [], $uag_roles);
}
}
}
if ($allowed_if == FALSE) {
if ($access_operation) {
$access_result = AccessResult::allowed();
}
else {
$access_result = AccessResult::forbidden();
}
}
else {
$access_result = AccessResult::allowedIf($access_operation);
}
return $access_result;
}
