Problem/Motivation

The method DomainAccessManager::getAccessValues() uses a static cache keyed only by entity type ID, entity ID, and field name. It does not take the entity's language into account.

When called on translated nodes, the first translation cached is reused for all subsequent translations. This results in incorrect domain values being returned for translations. As a result, hook_node_access_records() writes incorrect entries into the node_access table, which leads to access being denied for otherwise published and properly domain-assigned translations.

Steps to reproduce

  1. Enable Domain and Domain Access submodule.
  2. Create a node in language A, assign it to Domain X.
  3. Add a translation in language B, assign it to Domain Y.
  4. Inspect the node_access table or attempt to view the translation as an anonymous user.
  5. The translation is either inaccessible (403) or the node_access rows show the wrong domain assignment (Domain X instead of Domain Y).

Proposed resolution

  • Extend the static cache key in getAccessValues() to include the entity language code.
  • Example change:
        $langcode = $entity->language()->getId();
        if (isset(self::$staticCache[$entity->getEntityTypeId()][$entity->id()][$field_name][$langcode])) {
          return self::$staticCache[$entity->getEntityTypeId()][$entity->id()][$field_name][$langcode];
        }
        ...
        self::$staticCache[$entity->getEntityTypeId()][$entity->id()][$field_name][$langcode] = $list;
        
  • This ensures each translation stores and returns its own domain access values correctly.

Remaining tasks

  • Provide patch and rerun test suite.
  • Add test coverage for multilingual nodes with different domain assignments per translation.

User interface changes

None.

Introduced terminology

None.

API changes

DomainAccessManager::getAccessValues() static cache structure changes (adds a langcode key). Existing callers are unaffected.

Data model changes

None.

Release notes snippet

Fixed a bug where multilingual nodes could receive incorrect domain access grants because getAccessValues() ignored translation language when caching. Sites using multilingual content should run node_access_rebuild() after updating.

Issue fork domain-3547422

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

xavier.masson created an issue. See original summary.

mably made their first commit to this issue’s fork.

mably’s picture

Hi @xavier.masson, by default, the domain access field doesn't seem to be translatable from what I can read from the domain_access_confirm_fields function.

Are you using some custom domain access field that you made translatable?

EDIT: Looks like you can simply enabled it in the content translation configuration.

I'll merge your MR in the 3.x dev branch so people can start playing with it.

mably’s picture

mably’s picture

Status: Active » Needs review

While working on the related functional tests, I found that we were using the wrong hooks to clear the access values static cache.

We must use presave/predelete instead of update/delete.

I have updated my 3.x MR accordingly.

Any feedback welcome.

@xavier.masson are there any other tests you think we should add?

  • mably committed e9786821 on 3.x
    Issue #3547422 by xavier.masson: getAccessValues() static cache ignores...

  • mably committed bfcbc73e on 2.0.x
    Issue #3547422 by xavier.masson: getAccessValues() static cache ignores...
mably’s picture

Status: Needs review » Fixed

Now that this issue is closed, please review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, please credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.