Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Role-based embargo exemption. #28

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
50 changes: 50 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,16 @@ 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
Loading