Contact access granularity

Created on 22 February 2025, 3 months ago

Problem/Motivation

Access to each contact needs to have granular controls, like noode_access

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

✨ Feature request
Status

Active

Version

1.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States bluegeek9

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

Comments & Activities

  • Issue created by @bluegeek9
  • πŸ‡ΊπŸ‡ΈUnited States bluegeek9
  • πŸ‡ΊπŸ‡ΈUnited States jdleonard Austin, TX, USA

    This is great. It took me a few reads to fully understand the intent so I'm updating the IS to be more explicit.

    Is it possible to have a

    crm_user</code linking a User to their Contact without granting the User access to their Contact? For example, a CRM might be internal-facing and have a customer log in and be tracked by the CRM without the customer knowing that there's a Contact record linked to them.
    
    How is it determined whether a User with a <code>crm_user

    linking them to a Contact is permitted to issue grants to other Contacts? In addition to "view", "update", and "delete", should there be a "grant" grant?

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

    Any permissions for a user to view/update/delete their own contact should not be done with crm_contact_access.

    We need to add permissions the allow a user to view/update/delete own contact. Then update Drupal\crm\ContactAccessControlHandler

    So, yes a user could have a contact and not have access.

    I think grants will be given via relationships. There could be other ways, but relationship are the only current use case.

    The Group module handles access differently.

    ContactAccessControlHandler needs to be update to check the grant table.

      /**
       * Checks access to a contact via crm_contact_access table.
       *
       * @param int $user_contact_id
       *   The ID of the contact trying to access.
       * @param int $contact_id
       *   The ID of the contact being accessed.
       * @param string $operation
       *   The operation being checked: view, update, delete.
       *
       * @return bool
       *   TRUE if access is granted, FALSE otherwise.
       */
      public function checkContactAccess(int $user_contact_id, int $contact_id, string $operation): bool {
        if (!isset(self::SUPPORTED_OPERATIONS[$operation])) {
          return FALSE;
        }
    
        $grant_field = self::SUPPORTED_OPERATIONS[$operation];
    
        // Query crm_contact_access table for a matching grant.
        $query = $this->database->select('crm_contact_access', 'a')
          ->fields('a', [$grant_field])
          ->condition('a.contact_id', $contact_id)
          ->condition('a.gid', $user_contact_id)
          ->condition('a.'.$grant_field, 1);
    
        $result = $query->execute()->fetchAssoc();
    
        return !empty($result[$grant_field]);
      }
    }
    
  • πŸ‡ΊπŸ‡ΈUnited States jdleonard Austin, TX, USA

    Adding πŸ“Œ Determine which Relationship Types (if any) should be locked Active as related if grants might rely on specific Relationship Types, which would thus presumably need to be locked.

Production build 0.71.5 2024