ReplicationAccessControlHandler.php in Deploy - Content Staging 8
File
src/ReplicationAccessControlHandler.php
View source
<?php
namespace Drupal\deploy;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\EntityAccessControlHandler;
use Drupal\Core\Entity\EntityHandlerInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Link;
use Drupal\Core\Messenger\MessengerTrait;
use Drupal\Core\Session\AccountInterface;
use Drupal\multiversion\Entity\Workspace;
use Drupal\multiversion\Workspace\WorkspaceManagerInterface;
use Drupal\workspace\Entity\Replication;
use Drupal\workspace\Entity\WorkspacePointer;
use Symfony\Component\DependencyInjection\ContainerInterface;
class ReplicationAccessControlHandler extends EntityAccessControlHandler implements EntityHandlerInterface {
use MessengerTrait;
protected $workspaceManager;
protected $entityTypeManager;
public function __construct(EntityTypeInterface $entity_type, WorkspaceManagerInterface $workspace_manager, EntityTypeManagerInterface $entity_type_manager) {
parent::__construct($entity_type);
$this->workspaceManager = $workspace_manager;
$this->entityTypeManager = $entity_type_manager;
}
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
return new static($entity_type, $container
->get('workspace.manager'), $container
->get('entity_type.manager'));
}
protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
$restricted_fields = [
'source',
'target',
];
if (in_array($field_definition
->getName(), $restricted_fields)) {
return AccessResult::forbidden();
}
return parent::checkFieldAccess($operation, $field_definition, $account, $items);
}
protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
$access = parent::checkCreateAccess($account, $context, $entity_bundle);
$active_workspace = $this->workspaceManager
->getActiveWorkspace();
$upstream_workspace_pointer = $active_workspace->upstream->entity;
if (!$upstream_workspace_pointer) {
return AccessResult::forbidden('No target is set for the active workspace.');
}
if (\Drupal::state()
->get('workspace.last_replication_failed', FALSE)) {
return AccessResult::forbidden('Replication is blocked.');
}
$replication_in_queue = $this->entityTypeManager
->getStorage('replication')
->getQuery()
->condition('source', WorkspacePointer::loadFromWorkspace($active_workspace)
->id())
->condition('target', $upstream_workspace_pointer
->id())
->condition('replication_status', [
Replication::QUEUED,
Replication::REPLICATING,
], 'IN')
->execute();
if (!empty($replication_in_queue)) {
$this
->messenger()
->addWarning(t('Users are only allowed to create one push and one pull deployment between the same source and target workspace. New deployments are only allowed after the currently queued deployment finish.'));
return AccessResult::forbidden('Replication queued or in progress.');
}
if ($account
->hasPermission('deploy to any workspace')) {
return AccessResult::allowed();
}
$upstream_workspace_id = $upstream_workspace_pointer->workspace_pointer->target_id;
$upstream_workspace = Workspace::load($upstream_workspace_id);
if ($upstream_workspace && $upstream_workspace
->getOwnerId() == $account
->id() && $account
->hasPermission('deploy to own workspace')) {
return AccessResult::allowed();
}
if (!$account
->hasPermission('Deploy to ' . $upstream_workspace_pointer
->label())) {
return AccessResult::forbidden('You do not have permission to deploy to the target.');
}
return $access;
}
}