From f6d7f513fa0390e31ccf813cc89dc8d2c7e96dd8 Mon Sep 17 00:00:00 2001 From: Ioannis Igoumenos Date: Sat, 29 Nov 2025 17:35:17 +0200 Subject: [PATCH] Authenticators wrappers --- .../Transmogrify/config/schema/tables.json | 23 ++++++ .../src/Lib/Traits/TypeMapperTrait.php | 77 +++++++++++++------ 2 files changed, 76 insertions(+), 24 deletions(-) diff --git a/app/plugins/Transmogrify/config/schema/tables.json b/app/plugins/Transmogrify/config/schema/tables.json index 430c6c39..36200d00 100644 --- a/app/plugins/Transmogrify/config/schema/tables.json +++ b/app/plugins/Transmogrify/config/schema/tables.json @@ -356,6 +356,17 @@ }, "addChangelog": true }, + "authenticators": { + "source": "cm_authenticators", + "displayField": "description", + "cache": ["co_id"], + "fieldMap": { + "plugin": "&mapAuthenticatorPlugin", + "co_message_template_id": "message_template_id" + }, + "addChangelog": true + }, + "__NOTES__": "DATA MIGRATIONS", "authentication_events": { "source": "cm_authentication_events", @@ -371,6 +382,18 @@ "status": "&mapPersonStatus" } }, + "authenticator_statuses": { + "source": "cm_authenticator_statuses", + "displayField": "id", + "booleans": [ + "locked" + ], + "cache": ["person_id", "authenticator_id"], + "fieldMap": { + "co_person_id": "person_id" + }, + "addChangelog": true + }, "person_roles": { "source": "cm_co_person_roles", "sqlSelect": "roleSqlSelect", diff --git a/app/plugins/Transmogrify/src/Lib/Traits/TypeMapperTrait.php b/app/plugins/Transmogrify/src/Lib/Traits/TypeMapperTrait.php index 912917af..0688267f 100644 --- a/app/plugins/Transmogrify/src/Lib/Traits/TypeMapperTrait.php +++ b/app/plugins/Transmogrify/src/Lib/Traits/TypeMapperTrait.php @@ -256,25 +256,30 @@ protected function mapApiIdFromCache(array $row): ?int { /** - * Map v4 External Identity Source plugin name to v5 plugin model path. + * Generic mapper for v4 plugin names to v5 plugin model paths. * - * Generic logic: - * - If a plugin exists with the same name as the v4 Source (ends with "Source"), - * return "Plugin.PluralTable" (eg: EnvSource -> EnvSource.EnvSources). - * - Else, if a "Connector" plugin exists for a "BaseSource", return - * "BaseConnector.PluralTable" (eg: FileSource -> FileConnector.FileSources). + * Logic: + * - Only process plugin names that end with the given $suffix (eg, "Source" or "Authenticator") + * - If a plugin exists with the same name, return "Plugin.PluralTable" + * - Else, if a "Connector" plugin exists, return "BaseConnector.PluralTable" * - * @param array $row A row from cm_org_identity_sources containing 'plugin' - * @return string|null The v5 Plugin.Table string or null if unmapped/empty - * @since COmanage Registry v5.2.0 + * @param array $row Row data containing 'plugin' + * @param string $suffix Required suffix for the plugin name (eg, "Source", "Authenticator") + * @param string $context Human‑readable context for exception messages + * @return string|null */ - protected function mapExternalIdentitySourcePlugin(array $row): ?string + protected function mapPlugin(array $row, string $suffix, string $context): ?string { $v4 = $row['plugin'] ?? null; if (!$v4) { return null; } + // Only process names that end with the expected suffix + if (!str_ends_with($v4, $suffix)) { + return null; + } + $pluginsTable = TableRegistry::getTableLocator()->get('Plugins'); $pluginRows = $pluginsTable @@ -287,37 +292,61 @@ protected function mapExternalIdentitySourcePlugin(array $row): ?string $available = array_map(static fn(array $r) => (string)$r['plugin'], $pluginRows->toList()); - // Only process names that end with "Source" - if (!str_ends_with($v4, 'Source')) { - return null; - } - // Pluralized Table name for the model side (eg, EnvSource -> EnvSources) $pluralTable = Inflector::pluralize($v4); - // 1) Direct plugin exists with same name as the Source - // Example: EnvSource -> EnvSource.EnvSources + // 1) Direct plugin exists with the same name if (in_array($v4, $available, true)) { return $v4 . '.' . $pluralTable; } - // 2) If it's a "Source", check for "Connector" - // Example: FileSource -> FileConnector.FileSources - $base = substr($v4, 0, -strlen('Source')); + // 2) Check for "Connector" + $base = substr($v4, 0, -strlen($suffix)); $connector = $base . 'Connector'; - if (in_array($connector, $available, true)) { + if ($base !== '' && in_array($connector, $available, true)) { return $connector . '.' . $pluralTable; } // No mapping found -// return null; - throw new \InvalidArgumentException("Unable to map External Identity Source plugin: $v4. Plugin not implemented in COmanage Registry v5."); + throw new \InvalidArgumentException( + "Unable to map {$context} plugin: {$v4}. Plugin not implemented in COmanage Registry v5." + ); } + /** + * Map v4 External Identity Source plugin name to v5 plugin model path. + * + * Examples: + * EnvSource -> EnvSource.EnvSources + * FileSource -> FileConnector.FileSources + * + * @param array $row A row from cm_org_identity_sources containing 'plugin' + * @return string|null + */ + protected function mapExternalIdentitySourcePlugin(array $row): ?string + { + return $this->mapPlugin($row, 'Source', 'External Identity Source'); + } - /** + + /** + * Map v4 Authenticator plugin name to v5 plugin model path. + * + * Examples: + * SshKeyAuthenticator -> SshKeyAuthenticator.SshKeyAuthenticators + * + * @param array $row Row data containing 'plugin' + * @return string|null + */ + protected function mapAuthenticatorPlugin(array $row): ?string + { + return $this->mapPlugin($row, 'Authenticator', 'Authenticator'); + } + + + /** * Map email type to corresponding type ID * * @param array $row Row data containing email type