class WebformEntityAccessControlHandler in Webform 6.x
Same name and namespace in other branches
- 8.5 src/WebformEntityAccessControlHandler.php \Drupal\webform\WebformEntityAccessControlHandler
Defines the access control handler for the webform entity type.
Hierarchy
- class \Drupal\Core\Entity\EntityHandlerBase uses DependencySerializationTrait, StringTranslationTrait
- class \Drupal\Core\Entity\EntityAccessControlHandler implements EntityAccessControlHandlerInterface
- class \Drupal\webform\WebformEntityAccessControlHandler implements EntityHandlerInterface uses WebformEntityStorageTrait
- class \Drupal\Core\Entity\EntityAccessControlHandler implements EntityAccessControlHandlerInterface
Expanded class hierarchy of WebformEntityAccessControlHandler
See also
\Drupal\webform\Entity\Webform.
1 file declares its use of WebformEntityAccessControlHandler
File
- src/
WebformEntityAccessControlHandler.php, line 20
Namespace
Drupal\webformView source
class WebformEntityAccessControlHandler extends EntityAccessControlHandler implements EntityHandlerInterface {
use WebformEntityStorageTrait;
/**
* The request stack.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* The webform source entity plugin manager.
*
* @var \Drupal\webform\Plugin\WebformSourceEntityManagerInterface
*/
protected $webformSourceEntityManager;
/**
* The webform access rules manager service.
*
* @var \Drupal\webform\WebformAccessRulesManagerInterface
*/
protected $accessRulesManager;
/**
* {@inheritdoc}
*/
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
$instance = new static($entity_type);
$instance->requestStack = $container
->get('request_stack');
$instance->entityTypeManager = $container
->get('entity_type.manager');
$instance->webformSourceEntityManager = $container
->get('plugin.manager.webform.source_entity');
$instance->accessRulesManager = $container
->get('webform.access_rules_manager');
return $instance;
}
/**
* {@inheritdoc}
*/
protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
// Check 'administer webform' and 'create webform' permissions.
if ($account
->hasPermission('administer webform')) {
return WebformAccessResult::allowed();
}
elseif ($account
->hasPermission('create webform')) {
return WebformAccessResult::allowed();
}
else {
return WebformAccessResult::neutral();
}
}
/**
* {@inheritdoc}
*/
public function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
/** @var \Drupal\webform\WebformInterface $entity */
// Check 'administer webform' permission.
if ($account
->hasPermission('administer webform')) {
return WebformAccessResult::allowed();
}
// Check 'administer' access rule.
if ($account
->isAuthenticated()) {
$administer_access_result = $this->accessRulesManager
->checkWebformAccess('administer', $account, $entity);
if ($administer_access_result
->isAllowed()) {
return $administer_access_result;
}
}
$is_owner = (int) $account
->id() === (int) $entity
->getOwnerId();
// Check 'view' operation use 'submission_create' when viewing rendered
// HTML webform or use access 'configuration' when requesting a
// webform's configuration via REST or JSON API.
// @see https://www.drupal.org/project/webform/issues/2956771
if ($operation === 'view') {
// Check is current request if for HTML.
$is_html = $this->requestStack
->getCurrentRequest()
->getRequestFormat() === 'html';
// Make sure JSON API 1.x requests format which is 'html' is
// detected properly.
// @see https://www.drupal.org/project/jsonapi/issues/2877584
$is_jsonapi = strpos($this->requestStack
->getCurrentRequest()
->getPathInfo(), '/jsonapi/') === 0 ? TRUE : FALSE;
if ($is_html && !$is_jsonapi) {
$access_result = $this->accessRulesManager
->checkWebformAccess('create', $account, $entity);
}
else {
if ($account
->hasPermission('access any webform configuration') || $account
->hasPermission('access own webform configuration') && $is_owner) {
$access_result = WebformAccessResult::allowed($entity, TRUE);
}
else {
$access_result = $this->accessRulesManager
->checkWebformAccess('configuration', $account, $entity);
}
}
if ($access_result instanceof AccessResultReasonInterface) {
$access_result
->setReason('Access to webform configuration is required.');
}
return $access_result
->addCacheContexts([
'url.path',
'request_format',
]);
}
// Check if 'update', or 'delete' of 'own' or 'any' webform is allowed.
if ($account
->isAuthenticated()) {
switch ($operation) {
case 'test':
case 'update':
if ($account
->hasPermission('edit any webform') || $account
->hasPermission('edit own webform') && $is_owner) {
return WebformAccessResult::allowed($entity, TRUE);
}
break;
case 'duplicate':
if ($account
->hasPermission('create webform') && ($entity
->isTemplate() || ($account
->hasPermission('edit any webform') || $account
->hasPermission('edit own webform') && $is_owner))) {
return WebformAccessResult::allowed($entity, TRUE);
}
break;
case 'delete':
if ($account
->hasPermission('delete any webform') || $account
->hasPermission('delete own webform') && $is_owner) {
return WebformAccessResult::allowed($entity, TRUE);
}
break;
}
}
// Check webform access rules.
$rules_access_result = $this->accessRulesManager
->checkWebformAccess($operation, $account, $entity);
if ($rules_access_result
->isAllowed()) {
return $rules_access_result;
}
// Check submission_* operation.
if (strpos($operation, 'submission_') === 0) {
// Grant user with administer webform submission access to do whatever he
// likes on the submission operations.
if ($account
->hasPermission('administer webform submission')) {
return WebformAccessResult::allowed();
}
// Allow users with 'view any webform submission' or
// 'administer webform submission' to view all submissions.
if ($operation === 'submission_view_any' && ($account
->hasPermission('view any webform submission') || $account
->hasPermission('administer webform submission'))) {
return WebformAccessResult::allowed();
}
// Allow users with 'view own webform submission' to view own submissions.
if ($operation === 'submission_view_own' && $account
->hasPermission('view own webform submission')) {
return WebformAccessResult::allowed();
}
// Allow users with 'edit any webform submission' to update any submissions.
if ($operation === 'submission_update_any' && $account
->hasPermission('edit any webform submission')) {
return WebformAccessResult::allowed();
}
// Allow users with 'edit own webform submission' to update own submissions.
if ($operation === 'submission_update_own' && $account
->hasPermission('edit own webform submission')) {
return WebformAccessResult::allowed();
}
if (in_array($operation, [
'submission_page',
'submission_create',
])) {
// Check limit total unique access.
// @see \Drupal\webform\WebformSubmissionForm::setEntity
if ($entity
->getSetting('limit_total_unique')) {
$source_entity = $this->webformSourceEntityManager
->getSourceEntity('webform');
$last_submission = $this
->getSubmissionStorage()
->getLastSubmission($entity, $source_entity, NULL, [
'in_draft' => FALSE,
]);
if ($last_submission && $last_submission
->access('update')) {
return WebformAccessResult::allowed($last_submission);
}
}
// Check limit user unique access.
// @see \Drupal\webform\WebformSubmissionForm::setEntity
if ($entity
->getSetting('limit_user_unique')) {
// Require user to be authenticated to access a unique submission.
if (!$account
->isAuthenticated()) {
return WebformAccessResult::forbidden($entity);
}
$source_entity = $this->webformSourceEntityManager
->getSourceEntity('webform');
$last_submission = $this
->getSubmissionStorage()
->getLastSubmission($entity, $source_entity, $account, [
'in_draft' => FALSE,
]);
if ($last_submission && $last_submission
->access('update')) {
return WebformAccessResult::allowed($last_submission);
}
}
// Allow (secure) token to bypass submission page and create access controls.
$token = $this->requestStack
->getCurrentRequest()->query
->get('token');
if ($token && $entity
->isOpen()) {
$source_entity = $this->webformSourceEntityManager
->getSourceEntity('webform');
if ($submission = $this
->getSubmissionStorage()
->loadFromToken($token, $entity, $source_entity)) {
return WebformAccessResult::allowed($submission)
->addCacheContexts([
'url',
]);
}
}
}
// The "page" operation is the same as "create" but requires that the
// Webform is allowed to be displayed as dedicated page.
// Used by the 'entity.webform.canonical' route.
if ($operation === 'submission_page') {
// Completely block access to a template if the user can't create new
// Webforms.
$create_access = $entity
->access('create', $account, TRUE);
if ($entity
->isTemplate() && !$create_access
->isAllowed()) {
return WebformAccessResult::forbidden($entity)
->addCacheableDependency($create_access);
}
// Block access if the webform does not have a page URL.
if (!$entity
->getSetting('page')) {
$source_entity = $this->webformSourceEntityManager
->getSourceEntity('webform');
if (!$source_entity) {
return WebformAccessResult::forbidden($entity);
}
}
}
// Convert submission 'page' to corresponding 'create' access rule.
$submission_operation = str_replace('submission_page', 'submission_create', $operation);
// Remove 'submission_*' prefix.
$submission_operation = str_replace('submission_', '', $submission_operation);
// Check webform submission access rules.
$submission_access_result = $this->accessRulesManager
->checkWebformAccess($submission_operation, $account, $entity);
if ($submission_access_result
->isAllowed()) {
return $submission_access_result;
}
// Check webform 'update' access.
$update_access_result = $this
->checkAccess($entity, 'update', $account);
if ($update_access_result
->isAllowed()) {
return $update_access_result;
}
}
// NOTE: Not calling parent::checkAccess().
// @see \Drupal\Core\Entity\EntityAccessControlHandler::checkAccess
if ($operation === 'delete' && $entity
->isNew()) {
return WebformAccessResult::forbidden($entity);
}
else {
return WebformAccessResult::neutral($entity);
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DependencySerializationTrait:: |
protected | property | ||
DependencySerializationTrait:: |
protected | property | ||
DependencySerializationTrait:: |
public | function | 2 | |
DependencySerializationTrait:: |
public | function | 2 | |
EntityAccessControlHandler:: |
protected | property | Stores calculated access check results. | |
EntityAccessControlHandler:: |
protected | property | Information about the entity type. | |
EntityAccessControlHandler:: |
protected | property | The entity type ID of the access control handler instance. | |
EntityAccessControlHandler:: |
protected | property | Allows to grant access to just the labels. | 5 |
EntityAccessControlHandler:: |
public | function |
Checks access to an operation on a given entity or entity translation. Overrides EntityAccessControlHandlerInterface:: |
1 |
EntityAccessControlHandler:: |
protected | function | Default field access as determined by this access control handler. | 4 |
EntityAccessControlHandler:: |
public | function |
Checks access to create an entity. Overrides EntityAccessControlHandlerInterface:: |
1 |
EntityAccessControlHandler:: |
public | function |
Checks access to an operation on a given entity field. Overrides EntityAccessControlHandlerInterface:: |
|
EntityAccessControlHandler:: |
protected | function | Tries to retrieve a previously cached access value from the static cache. | |
EntityAccessControlHandler:: |
protected | function | Loads the current account object, if it does not exist yet. | |
EntityAccessControlHandler:: |
protected | function | We grant access to the entity if both of these conditions are met: | |
EntityAccessControlHandler:: |
public | function |
Clears all cached access checks. Overrides EntityAccessControlHandlerInterface:: |
|
EntityAccessControlHandler:: |
protected | function | Statically caches whether the given user has access. | |
EntityAccessControlHandler:: |
public | function | Constructs an access control handler instance. | 6 |
EntityHandlerBase:: |
protected | property | The module handler to invoke hooks on. | 5 |
EntityHandlerBase:: |
protected | function | Gets the module handler. | 5 |
EntityHandlerBase:: |
public | function | Sets the module handler for this handler. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 4 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
WebformEntityAccessControlHandler:: |
protected | property | The webform access rules manager service. | |
WebformEntityAccessControlHandler:: |
protected | property | The request stack. | |
WebformEntityAccessControlHandler:: |
protected | property | The webform source entity plugin manager. | |
WebformEntityAccessControlHandler:: |
public | function |
Performs access checks. Overrides EntityAccessControlHandler:: |
|
WebformEntityAccessControlHandler:: |
protected | function |
Performs create access checks. Overrides EntityAccessControlHandler:: |
|
WebformEntityAccessControlHandler:: |
public static | function |
Instantiates a new instance of this entity handler. Overrides EntityHandlerInterface:: |
|
WebformEntityStorageTrait:: |
protected | property | An associate array of entity type storage aliases. | |
WebformEntityStorageTrait:: |
protected | property | The entity type manager. | 5 |
WebformEntityStorageTrait:: |
protected | function | Retrieves the entity storage. | |
WebformEntityStorageTrait:: |
protected | function | Retrieves the webform submission storage. | |
WebformEntityStorageTrait:: |
protected | function | Retrieves the webform storage. | |
WebformEntityStorageTrait:: |
public | function | Implements the magic __get() method. |