From b1e17079c1bfac7e15045326313ebbf29afaa758 Mon Sep 17 00:00:00 2001
From: Zan Vidmar <zan@getopensocial.com>
Date: Thu, 27 Jun 2024 12:52:49 +0200
Subject: [PATCH] IOSAP-457: Add external identifier field for user

Add an external identifier field to the user entity.
This field is locked, as it should not be managed
via the UI, but rather by modifying the configuration.
The field is provided without any settings and is,
therefore, unusable by default. At least one target
type needs to be specified by modifying the field
storage configuration to ensure the field can be
properly used.

Include hook update to ensure that field is created
also for existing installations.

Field usage example:
SCIM provides the concept of externalId which
can be used to identify a resource with an identifier
that is known to the SCIM client. This prevents the
SCIM client from having to store a mapping between
its internal data and our ID, instead putting that burden
on us as a service provider.
---
 ...ld.user.user.field_external_identifier.yml | 20 +++++++++++++++++++
 ...storage.user.field_external_identifier.yml | 19 ++++++++++++++++++
 .../update/social_user_update_13003.yml       |  4 ++++
 .../social_user/social_user.install           | 14 +++++++++++++
 4 files changed, 57 insertions(+)
 create mode 100644 modules/social_features/social_user/config/install/field.field.user.user.field_external_identifier.yml
 create mode 100644 modules/social_features/social_user/config/install/field.storage.user.field_external_identifier.yml
 create mode 100644 modules/social_features/social_user/config/update/social_user_update_13003.yml

diff --git a/modules/social_features/social_user/config/install/field.field.user.user.field_external_identifier.yml b/modules/social_features/social_user/config/install/field.field.user.user.field_external_identifier.yml
new file mode 100644
index 00000000000..9129e6be20f
--- /dev/null
+++ b/modules/social_features/social_user/config/install/field.field.user.user.field_external_identifier.yml
@@ -0,0 +1,20 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.storage.user.field_external_identifier
+  module:
+    - social_core
+    - user
+id: user.user.field_external_identifier
+field_name: field_external_identifier
+entity_type: user
+bundle: user
+label: 'External Identifier'
+description: ''
+required: false
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings: {  }
+field_type: social_external_identifier
diff --git a/modules/social_features/social_user/config/install/field.storage.user.field_external_identifier.yml b/modules/social_features/social_user/config/install/field.storage.user.field_external_identifier.yml
new file mode 100644
index 00000000000..8e35a7089f4
--- /dev/null
+++ b/modules/social_features/social_user/config/install/field.storage.user.field_external_identifier.yml
@@ -0,0 +1,19 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - social_core
+    - user
+id: user.field_external_identifier
+field_name: field_external_identifier
+entity_type: user
+type: social_external_identifier
+settings:
+  target_types: {  }
+module: social_core
+locked: true
+cardinality: 1
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
+custom_storage: false
diff --git a/modules/social_features/social_user/config/update/social_user_update_13003.yml b/modules/social_features/social_user/config/update/social_user_update_13003.yml
new file mode 100644
index 00000000000..35ff8ae1699
--- /dev/null
+++ b/modules/social_features/social_user/config/update/social_user_update_13003.yml
@@ -0,0 +1,4 @@
+__global_actions:
+  import_configs:
+    - field.storage.user.field_external_identifier
+    - field.field.user.user.field_external_identifier
diff --git a/modules/social_features/social_user/social_user.install b/modules/social_features/social_user/social_user.install
index 79885682f69..9298ab330ef 100644
--- a/modules/social_features/social_user/social_user.install
+++ b/modules/social_features/social_user/social_user.install
@@ -205,3 +205,17 @@ function social_user_update_13002(): void {
     ->clear('show_mail_in_messages')
     ->save();
 }
+
+/**
+ * Add an external identifier field to the user entity.
+ */
+function social_user_update_13003() : string {
+  /** @var \Drupal\update_helper\Updater $updater */
+  $updater = \Drupal::service('update_helper.updater');
+
+  // Execute configuration update definitions with logging of success.
+  $updater->executeUpdate('social_user', __FUNCTION__);
+
+  // Output logged messages to related channel of update execution.
+  return $updater->logger()->output();
+}
