Access policy updates get ignored when not using default language

Created on 4 April 2024, 3 months ago
Updated 15 April 2024, 2 months ago

Hi! First off, thanks for all the hard work you've done on this module -- it's an impressive piece of work and an excellent contribution to the community.

One issue I've been having concerns the application of Access Policy to sub-page (paragraph) components. I'm working on a bilingual site that uses an access policy with the 'taxonomy with depth' option on paragraph entities against a user's term reference field. This has worked well on initial entity creation for both languages but once I try to change the relevant access controlled term reference field from either unset (i.e. public) to set (i.e. controlled access) the non-English, translated, version of the component fails to update the change. Now, I should add that we're also using the Paragraph Assymetric Translation Widgets module so the translated paragraphs are separate entities that have to be updated in the UI separately, which we've done. However, the translated component still fails to update its access policy even after manually updating in the UI.

Using xdebug I've been able to ascertain that the 'access_policy' field value is not being updated on the translated component. When it starts with the string machine name of the policy on creation it's not being removed on update; when it starts empty, it's not being added. I believe the issue is due to this conditional in src/EntityOperations.php (line 155):

if (!$this->storage->isPolicyUpdated($entity) && $this->information->hasEnabledForEntitiesOfEntityType($entity->getEntityType()) && $entity->language()->isDefault()) {

That method appears to ignore any entity not using the default language. Removing the final condition appears to resolve our problem but I wanted to know what's the purpose of that condition, in case there's something I'm missing here and it will require a more complicated fix than I'm proposing.

πŸ› Bug report
Status

Active

Version

1.0

Component

Code

Created by

πŸ‡¨πŸ‡¦Canada gmarus

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @gmarus
  • πŸ‡ΊπŸ‡ΈUnited States partdigital

    Hi gmarus, thanks for reaching out!

    There a few assumptions that access policy makes:

    • The access_policy field is not translatable.
    • It will only determine the policy based on the Default translation.

    This is to prevent translations from having different policies.

    The condition $entity->language()->isDefault() was added to prevent selecting a policy against translated field values. For example, let's say the original language has the "Sales" department, but the French translation doesn't have a department. Because the access_policy field is not translatable that would remove the policy entirely.

    You can see a test case here covering this use case: https://git.drupalcode.org/project/access_policy/-/blob/1.0.x/tests/src/...

    To use access policy predictably I recommend only using non-translatable fields with selection rules. I'm definitely open to investigating language specific policies in future versions.

  • πŸ‡¨πŸ‡¦Canada gmarus

    Thanks for the quick response! We're not using a translatable field for the check against the policy and there's only one access policy to apply on those paragraph entities, though I think the use of the PATW module is probably complicating things here. Our access control works across both EN and FR entities at creation but then due to that conditional in entityPresave() fails badly on updates if it involves setting/un-setting our access control field (i.e. applying a new policy). Anyway, something for me to mull over while I consider next steps. Thanks for sharing the rationale behind that decision.

  • πŸ‡ΊπŸ‡ΈUnited States partdigital

    Would you be willing to share some more details about your policy and steps to reproduce? I'd like to see if I can reproduce it as well.

    One thing I should mention is the way that access policy handles assignment. The "Dynamic" selection mode will only assign the policy if the field value has changed between revisions. Do you think that could be a factor as well?

    If so, in the latest dev version I've added the ability assign policies "on save" instead of "on change", to try it out do the following:

    1. Update to the latest dev version.
    2. Create a new selection strategy plugin (see below).
    3. Enable that Selection mode for paragraphs

    <?php
    namespace Drupal\access_policy\Plugin\access_policy\SelectionStrategy;

    use Drupal\Core\Entity\EntityTypeInterface;

    /**
    * On save selection strategy.
    *
    * @SelectionStrategy(
    * id = "on_save",
    * label = @Translation("On save"),
    * description = @Translation("On save, access policies are dynamically assigned to entities based on selection rules."),
    * weight = 0,
    * )
    */
    class OnSaveSelection extends SelectionStrategyBase {

    /**
    * {@inheritdoc}
    */
    public function defaultOptions() {
    return [
    'dynamic_assignment' => 'on_save',
    'enable_selection_page' => FALSE,
    'show_operations_link' => FALSE,
    'enable_policy_field' => FALSE,
    'allow_empty' => FALSE,
    ];
    }

    /**
    * {@inheritdoc}
    */
    public static function isApplicable(EntityTypeInterface $entity_type) {
    return TRUE;
    }

    }

  • πŸ‡ΊπŸ‡ΈUnited States partdigital

    I spent some more time investigating this I noticed is that, in some cases, the field controlling access can still be visible on translated pages, even if that field isn't translatable. When authors change the value of that field that can cause that field and access policy to become out of sync.

    For example:

    1. Create a new paragraph
    2. Click the "Private" checkbox, this will make the content private. The "Private" field is not translatable.
    3. Create a new French version of that paragraph.
    4. The "Private" checkbox is still visible on the translation.
    5. When an author clicks the checkbox the access policy is not updated.

    Does this sound similar to the issue that you're running in to?

    I'll add a change so that fields controlling access are only visisble on the default language. In the meantime, a quick fix for this is to make sure that "Hide non translatable fields on translation forms" is checked.

    1. Go to /admin/config/regional/content-language
    2. Scroll down until you see translation settings for paragraphs.
    3. Click "Hide non translatable fields on translation forms"
Production build 0.69.0 2024