Problem/Motivation

tft.module implements hook_ENTITY_TYPE_create_access() for taxonomy_term via tft_taxonomy_term_create_access(). The hook is intended to allow users with the tft add child terms permission to create new TFT folders (terms in the tft_tree vocabulary). However, the function does not check the $entity_bundle parameter before granting access:

// tft.module, tft_taxonomy_term_create_access()
function tft_taxonomy_term_create_access(
  AccountInterface $account,
  array $context,
  $entity_bundle
) {
  if ($account->hasPermission(TFT_ADD_TERMS)) {
    // Allow platform-level content managers to create folders.
    return AccessResult::allowed();  // ← no bundle check!
  }
  // ...
}

Because hook_ENTITY_TYPE_create_access fires for every taxonomy term creation regardless of vocabulary, any user holding the tft add child terms permission can create terms in any vocabulary — not just tft_tree.

This is inconsistent with tft_taxonomy_term_access() in the same file, which correctly guards its logic with a bundle check:

function tft_taxonomy_term_access(TermInterface $entity, $operation, AccountInterface $account) {
  if ($entity->bundle() !== 'tft_tree') {
    return AccessResult::neutral();  // ← bundle check present
  }
  // ...
}

Steps to reproduce

  1. Install TFT and opigno_class (the latter adds tft add child terms to the content_manager role via its config rewrite).
    Log in as a user with the content_manager role (has tft add child terms, but does not have create terms in other_taxonomy_bundle or administer taxonomy).
  2. Navigate directly to /admin/structure/taxonomy/manage/{other_taxonomy_bundle}/add
  3. Observe: access is granted and the form is fully functional — the user can create a new term.
  4. Expected behaviour: access is denied (403) because the user holds no create terms in {other_taxonomy_bundle} or administer taxonomy permission.

Proposed resolution

Add a bundle guard at the top of tft_taxonomy_term_create_access(), consistent with the existing guard in tft_taxonomy_term_access():

function tft_taxonomy_term_create_access(
  AccountInterface $account,
  array $context,
  $entity_bundle
) {
  // -------- Only apply TFT access logic to the tft_tree vocabulary. ----------
  if ($entity_bundle !== 'tft_tree') {
    return AccessResult::neutral();
  }
  if ($account->hasPermission(TFT_ADD_TERMS)) {
    // Allow platform-level content managers to create folders.
    return AccessResult::allowed();
  }
  // ...
}

Issue fork tft-3589874

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

paladyn created an issue. See original summary.

paladyn’s picture

Status: Active » Needs review
paladyn’s picture

Issue summary: View changes