Problem/Motivation

After crm_membership represents roster membership through crm_relationship (see the related refactor issue), sites still need a clean way to turn CRM membership state into runtime authorization for the Drupal user: roles, group membership, and other consumers already supported by the ecosystem.

The Authorization module is built for this: Provider plugins supply facts about the user (typically at login), and Consumer plugins map those facts into Drupal (roles via authorization_drupal_roles, groups via authorization_group, and future or custom consumers).

Without a dedicated Provider, each site would reimplement ad hoc “load contact, load memberships, sync roles” logic. A CRM Membership Provider centralizes discovery of memberships for the logged-in account by chaining crm_user_contact_mapping → contact → membership relationships, and exposes normalized data for any configured Consumer.

Dependency: This work assumes the membership refactor is in place so “who has which membership” is defined through CRM relationships (and membership references on those relationships), not a bulk contacts field on the membership entity.

Steps to reproduce

Proposed resolution

Add an Authorization Provider plugin to crm_membership that:

  • Resolves the CRM contact for the current user via the
    crm_user_contact_mapping entity.
  • From that contact, discovers one or many relevant
    crm_membership records according to the post-refactor data model
    (relationships linking the contact to the appropriate organization or target, with
    current membership references on those relationships).
  • Emits structured data for the Authorization pipeline (for example membership
    IDs, types, statuses, labels — exact shape defined during implementation) so
    that site builders can configure Authorization profiles that
    wire this Provider to any installed Consumer.

At login (and whenever Authorization runs for that user), Consumers can then map those facts to Drupal roles, group membership, or other targets without crm_membership needing to know about each Consumer. That yields reuse of an existing feature set (roles, groups, config UI) and future flexibility as new Consumers appear.

Optional configuration on the Provider or profile might control which relationship types / membership types participate, or how multiple simultaneous memberships are labeled for mapping rules.

Remaining tasks

  • Confirm dependency order and branch with the CRM relationship membership issue.
  • Implement the Provider plugin; align with
    ProviderInterface / ProviderPluginBase from the
    Authorization module.
  • Define the Provider output schema (keys exposed to profile conditions / Consumer
    input) and document examples for Drupal Roles and Group Consumers.
  • Handle edge cases: no mapping, no contact, inactive relationships, multiple
    memberships, anonymous users.
  • Declare crm_membership dependency on Authorization (and document
    optional sub-modules such as authorization_drupal_roles for
    examples, not necessarily hard requirements).
  • Add automated tests (kernel or functional) covering mapping → membership
    resolution → Provider output.
  • Update module documentation (README / Drush if applicable).

User interface changes

No mandatory new entity forms in crm_membership; site builders configure behavior through existing Authorization profile UI by selecting this Provider and choosing Consumers. Any minimal Provider settings (if needed) can live on the profile subform pattern used by other Providers.

API changes

New plugin class(es) and possibly a small service to resolve “memberships for user” reused by the Provider. Existing public APIs on Membership may be consumed but need not change for this issue alone (unless the refactor issue changes method names — the Provider should target the post-refactor API).

Data model changes

None required for this issue beyond what the membership–relationship refactor delivers. This issue only adds integration code and configuration, not new entity fields.

Comments

bluegeek9 created an issue.