Make sure that external identifier id is correctly unique

Created on 11 July 2024, 4 months ago
Updated 8 August 2024, 4 months ago

Problem/Motivation

This is FUP of https://www.drupal.org/project/social/issues/3457487

We need to make sure that external identifier id is correctly unique

Apply this rules by using constraint.

  • External ID should be unique per entity type (for example: external ID can be used only once per user entity).
  • External ID should be unique per all “social_external_identifier” fields (Unlimited amount of fields of type social_external_identifier can be added per one entity and even among all those fields External ID should be unique).
  • External ID should be unique per external owner (External owner entity is defined by "external_owner_target_type" and external_owner_id". External ID can be used as many times per entity type, until each external ID is connected to different external owner).

Note:
The purpose of the external identifier field is to point to single entity with a unique External ID per entity type. If the same External ID is used multiple times in the same field or across different fields for the same entity, it is not an issue from a relationship perspective. We will always find the correct (and only one) entity associated with the given external ID, even if multiple values point to it. Currently, there is no requirement to limit identical External IDs on the same entity. If such a requirement arises in the future, we will need to update the external ID field constraint and the related kernel test scenarios accordingly. The only known downside of the current development approach is that it allows redundant data in the system. However, this "issue" is not unique to this particular field, as there is no existing system to prevent such redundancy across other fields either.

Roadmap Note:
In the future, we plan to limit unique External IDs to one per platform (currently, it is limited per entity type). However, this requires development considerations to ensure performance efficiency, as searching for duplicated values across all entity types and fields of type "social_external_identifier" can be resource-intensive. Ideally, we aim to restrict External IDs to be unique per entity, so each ID is stored only once in the database. Currently, it is possible to have redundant unique External IDs for the same entity.

 * Example 1: This situation is allowed as External ID is unique per entity type
 *            (User 1).
 *
 *   | Entity | Field                       | External ID | External owner |
 *   | ------ | --------------------------- | ----------- | -------------- |
 *   | User:1 | field_external_identifier_1 | 123         | consumer:1     |
 *   | User:1 | field_external_identifier_1 | 123         | consumer:1     |
 *
 *  Example 2: This situation is forbidden as two users can not have same
 *             External ID.
 *
 *    | Entity | Field               | External ID | External owner |
 *    | ------ | ------------------- | ----------- | -------------- |
 *    | User:1 | field_external_id_1 | 123         | consumer:1     |
 *    | User:2 | field_external_id_1 | 123         | consumer:1     |
 *
 * Example 3: This situation is forbidden as same External ID is not allowed
 *            even within two different fields within same entity type (User).
 *
 *   | Entity | Field               | External ID | External owner |
 *   | ------ | ------------------- | ----------- | -------------- |
 *   | User:1 | field_external_id_1 | 123         | consumer:1     |
 *   | User:2 | field_external_id_2 | 123         | consumer:1     |
 *
 * Example 4: This situation is forbidden as same External ID is not allowed
 *            even within two different entity bundles within same entity
 *            type (Group).
 *
 *   | Entity  | Bundle   | Field               | External ID | External owner |
 *   | ------- | -------- | ------------------- | ----------- | -------------- |
 *   | Group:1 | course   | field_external_id_1 | 123         | consumer:1     |
 *   | Group:2 | flexible | field_external_id_2 | 123         | consumer:1     |
 *
 * Example 5: This situation is allowed as External ID is unique per entity
 *            type.
 *
 *   | Entity  | Field               | External ID | External owner |
 *   | ------- | ------------------- | ----------- | -------------- |
 *   | User:1  | field_external_id_1 | 123         | consumer:1     |
 *   | Group:1 | field_external_id_1 | 123         | consumer:1     |
 *
 * Example 6: This situation is allowed as External ID is unique per external
 *            owner.
 *
 *   | Entity | Field               | External ID | External owner |
 *   | ------ | ------------------- | ----------- | -------------- |
 *   | User:1 | field_external_id_1 | 123         | consumer:1     |
 *   | User:1 | field_external_id_1 | 123         | consumer:2     |
 *   | User:1 | field_external_id_1 | 123         | owner:1        |

Steps to reproduce

See https://github.com/goalgorilla/open_social/pull/3978

Proposed resolution

Provide constraint to handle correctly unique external identifier id

Remaining tasks

See Roadmap Note:

User interface changes

N/A

API changes

N/A

Data model changes

N/A

Feature request
Status

Fixed

Version

13.0

Component

Code (back-end)

Created by

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

Comments & Activities

Production build 0.71.5 2024