Skip to content

Commit

Permalink
Role-based embargo exemption.
Browse files Browse the repository at this point in the history
  • Loading branch information
rosiel committed Jan 16, 2024
1 parent 52bf8d5 commit 88fad73
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 2 deletions.
31 changes: 31 additions & 0 deletions embargo.module
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\embargo\EmbargoStorage;

Expand Down Expand Up @@ -97,3 +99,32 @@ function embargo_theme($existing, $type, $theme, $path) {
],
];
}

/**
* Add exempt_roles field.
*/
function embargo_update_9101(&$sandbox) {
$exempt_roles = BaseFieldDefinition::create('entity_reference')
->setLabel(t('List of exempt roles'))
->setDescription(t('These roles will be able to bypass the embargo.'))
->setTranslatable(FALSE)
->setRevisionable(FALSE)
->setRequired(FALSE)
->setDisplayConfigurable('view', FALSE)
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
->setDisplayOptions('form', [
'type' => 'entity_reference_autocomplete',
])
->setDisplayOptions('view', [
'type' => 'entity_reference_label',
'label' => 'hidden',
])
->setSettings([
'target_type' => 'user_role',
'handler_settings' => [
'include_anonymous' => FALSE,
],
]);
\Drupal::entityDefinitionUpdateManager()->installFieldStorageDefinition(
'exempt_roles', 'embargo', 'embargo', $exempt_roles);
}
2 changes: 1 addition & 1 deletion src/Access/EmbargoAccessCheck.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class EmbargoAccessCheck implements EmbargoAccessCheckInterface {
protected $request;

/**
* Th current user.
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
Expand Down
4 changes: 4 additions & 0 deletions src/Access/QueryTagger.php
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ protected function buildAccessibleEmbargoesQuery($type) : SelectInterface {
$user_alias = $query->leftJoin('embargo__exempt_users', 'u', 'e.id = %alias.entity_id');
$group->condition("{$user_alias}.exempt_users_target_id", $this->user->id());

// ... the user has a role that is exempted from the embargo.
$role_alias = $query->leftJoin('embargo__exempt_roles', 'r', 'e.id = %alias.entity_id');
$group->condition("{$role_alias}.exempt_roles_target_id",$this->user->getRoles(), 'IN');

$query->condition($group);

return $query;
Expand Down
29 changes: 29 additions & 0 deletions src/EmbargoInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,24 @@ public function getExemptUsers(): array;
*/
public function setExemptUsers(array $users): EmbargoInterface;

/**
* Gets the list of exempt roles.
*
* @return \Drupal\user\RoleInterface[]
* A list of roles exempt from the embargo.
*/
public function getExemptRoles(): array;

/**
* Sets the list of roles exempt from this embargo.
*
* @param array $roles
* A list of role entities to exempt from this embargo.
*
* @return $this
*/
public function setExemptRoles(array $roles): EmbargoInterface;

/**
* Retrieves the node being embargoed.
*
Expand Down Expand Up @@ -238,6 +256,17 @@ public function expiresBefore(int $date): bool;
*/
public function isUserExempt(AccountInterface $user): bool;

/**
* Checks if any of the user's roles is exempt from this embargo.
*
* @param \Drupal\Core\Session\AccountInterface $user
* The user to check.
*
* @return bool
* TRUE if the user is exempt otherwise FALSE.
*/
public function isUserRoleExempt(AccountInterface $user): bool;

/**
* Checks if the given IP address is exempt from this embargo.
*
Expand Down
3 changes: 2 additions & 1 deletion src/EmbargoStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,9 @@ public function getApplicableNonExemptNonExpiredEmbargoes(EntityInterface $entit
$inactive = $embargo->expiresBefore($timestamp);
$type_exempt = ($entity instanceof NodeInterface && $embargo->getEmbargoType() !== EmbargoInterface::EMBARGO_TYPE_NODE);
$user_exempt = $embargo->isUserExempt($user);
$user_role_exempt = $embargo->isUserRoleExempt($user);
$ip_exempt = $embargo->ipIsExempt($ip);
return !($inactive || $type_exempt || $user_exempt || $ip_exempt);
return !($inactive || $type_exempt || $user_exempt || $user_role_exempt|| $ip_exempt);
});
}

Expand Down
49 changes: 49 additions & 0 deletions src/Entity/Embargo.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Drupal\embargo\EmbargoInterface;
use Drupal\embargo\IpRangeInterface;
use Drupal\node\NodeInterface;
use Drupal\user\RoleInterface;
use Drupal\user\UserInterface;

/**
Expand Down Expand Up @@ -174,6 +175,28 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
],
]);

$fields['exempt_roles'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('List of exempt roles'))
->setDescription(t('These roles will be able to bypass the embargo.'))
->setTranslatable(FALSE)
->setRevisionable(FALSE)
->setRequired(FALSE)
->setDisplayConfigurable('view', FALSE)
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
->setDisplayOptions('form', [
'type' => 'entity_reference_autocomplete',
])
->setDisplayOptions('view', [
'type' => 'entity_reference_label',
'label' => 'hidden',
])
->setSettings([
'target_type' => 'user_role',
'handler_settings' => [
'include_anonymous' => FALSE,
],
]);

$fields['additional_emails'] = BaseFieldDefinition::create('email')
->setLabel(t('Additional Emails'))
->setDescription(t('For contact changes to this embargo.'))
Expand Down Expand Up @@ -342,6 +365,23 @@ public function setExemptUsers(array $users): EmbargoInterface {
return $this;
}

/**
* {@inheritdoc}
*/
public function getExemptRoles(): array {
/** @var \Drupal\Core\Field\EntityReferenceFieldItemList $exempt_roles */
$exempt_roles = $this->get('exempt_roles');
return $exempt_roles->referencedEntities();
}

/**
* {@inheritdoc}
*/
public function setExemptRoles(array $roles): EmbargoInterface {
$this->set('exempt_roles', $roles);
return $this;
}

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -426,6 +466,15 @@ public function isUserExempt(AccountInterface $user): bool {
}, $exempt_users));
}

/**
* {@inheritdoc}
*/
public function isUserRoleExempt(AccountInterface $user): bool {
$exempt_role_ids = array_map(function (RoleInterface $role) {
return $role->id();
}, $this->getExemptRoles());
return count(array_intersect($exempt_role_ids, $user->getRoles())) > 0;
}
/**
* {@inheritdoc}
*/
Expand Down

0 comments on commit 88fad73

Please sign in to comment.