Skip to content

Commit

Permalink
WS-504: Paragraphs patch to fix editting of content that was pubished…
Browse files Browse the repository at this point in the history
… then unpublished.
  • Loading branch information
rgristroph-usdoj committed Nov 12, 2024
1 parent 7511e92 commit 28f7117
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 5 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@
"Config install issues": "https://www.drupal.org/files/issues/2022-10-04/password_policy_field_last_password_reset_unknown_error_2771129-134.patch"
},
"drupal/paragraphs": {
"Inline Paragraphs widget performance update": "./patches/paragraphs-improve-performance-2935134.patch"
"Inline Paragraphs widget performance update": "./patches/paragraphs-improve-performance-2935134.patch",
"Paragraph access check using incorrect revision of its parent https://www.drupal.org/project/paragraphs/issues/3090200#comment-14762651": "./patches/3084934-13_combine_3090200-22.patch"
},
"drupal/simplesamlphp_auth": {
"Masquerade and Logout Fix": "./patches/FOIA-78964-simplesamlphp-logout.patch"
Expand Down
8 changes: 4 additions & 4 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

97 changes: 97 additions & 0 deletions patches/3084934-13_combine_3090200-22.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
diff --git a/src/ParagraphAccessControlHandler.php b/src/ParagraphAccessControlHandler.php
index 2946808..ba06541 100644
--- a/src/ParagraphAccessControlHandler.php
+++ b/src/ParagraphAccessControlHandler.php
@@ -7,6 +7,8 @@ use Drupal\Core\Entity\EntityAccessControlHandler;
use Drupal\Core\Entity\EntityHandlerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Entity\TranslatableRevisionableStorageInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Access\AccessResult;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -25,6 +27,13 @@ class ParagraphAccessControlHandler extends EntityAccessControlHandler implement
*/
protected $configFactory;

+ /**
+ * The entity type manager.
+ *
+ * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+ */
+ protected $entityTypeManager;
+
/**
* Constructs a TranslatorAccessControlHandler object.
*
@@ -32,10 +41,13 @@ class ParagraphAccessControlHandler extends EntityAccessControlHandler implement
* The entity type definition.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config object factory.
+ * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+ * The entity type manager.
*/
- public function __construct(EntityTypeInterface $entity_type, ConfigFactoryInterface $config_factory) {
+ public function __construct(EntityTypeInterface $entity_type, ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager) {
parent::__construct($entity_type);
$this->configFactory = $config_factory;
+ $this->entityTypeManager = $entity_type_manager;
}

/**
@@ -44,7 +56,8 @@ class ParagraphAccessControlHandler extends EntityAccessControlHandler implement
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
return new static(
$entity_type,
- $container->get('config.factory')
+ $container->get('config.factory'),
+ $container->get('entity_type.manager')
);
}

@@ -61,15 +74,40 @@ class ParagraphAccessControlHandler extends EntityAccessControlHandler implement
else {
$access_result = AccessResult::allowed();
}
+ $parent_entity = $paragraph->getParentEntity();
if ($paragraph->getParentEntity() != NULL) {
// Delete permission on the paragraph, should just depend on 'update'
// access permissions on the parent.
- $operation = ($operation == 'delete') ? 'update' : $operation;
+ $operation = ($operation === 'delete') ? 'update' : $operation;
// Library items have no support for parent entity access checking.
- if ($paragraph->getParentEntity()->getEntityTypeId() != 'paragraphs_library_item') {
- $parent_access = $paragraph->getParentEntity()->access($operation, $account, TRUE);
- $access_result = $access_result->andIf($parent_access);
+ if ($parent_entity->getEntityTypeId() == 'paragraphs_library_item') {
+ return $access_result;
+ }
+ // Paragraphs on blocks and paragraphs can get into a state that makes it
+ // difficult to find the correct revision of the parent to check access
+ // against, so return the current access result in that case.
+ $skip_types = ['block_content', 'paragraph'];
+ if (($operation == 'view' || $operation == 'update') && in_array($parent_entity->getEntityTypeId(), $skip_types)) {
+ return $access_result;
+ }
+ if ($operation !== 'view') {
+ $storage = $this->entityTypeManager->getStorage($parent_entity->getEntityTypeId());
+ // Load the latest revision if the parent entity is not new and is revisionable.
+ if ($storage instanceof TranslatableRevisionableStorageInterface && !$parent_entity->isNew()) {
+ $parent_entity_langcode = $parent_entity->language()->getId();
+ $parent_entity_id = $storage->getLatestTranslationAffectedRevisionId($parent_entity->id(),
+ $parent_entity_langcode);
+ if ($parent_entity_id) {
+ $parent_entity = $storage->loadRevision($parent_entity_id);
+ if ($parent_entity && $parent_entity->hasTranslation($parent_entity_langcode)) {
+ $parent_entity = $parent_entity->getTranslation($parent_entity_langcode);
+ }
+ }
+ }
}
+ // Now check access on the paragraph's parent.
+ $parent_access = $parent_entity->access($operation, $account, TRUE);
+ $access_result = $access_result->andIf($parent_access);
}
return $access_result;
}

0 comments on commit 28f7117

Please sign in to comment.