From c1c1a8202b12cd9330048b86322124aa9ebea6b1 Mon Sep 17 00:00:00 2001 From: Siddhanttimeline Date: Mon, 9 Sep 2024 14:30:55 +0530 Subject: [PATCH 1/6] migrate userName to emailPrefix for ldap auth provider. --- .../service/OpenMetadataApplication.java | 1 + .../migration/api/MigrationProcessImpl.java | 3 ++ .../migration/api/MigrationWorkflow.java | 24 +++++++++++++--- .../migration/mysql/v153/Migration.java | 2 ++ .../migration/utils/MigrationFile.java | 5 ++++ .../migration/utils/v153/MigrationUtil.java | 28 +++++++++++++++++++ .../service/util/OpenMetadataOperations.java | 1 + .../service/OpenMetadataApplicationTest.java | 4 +++ .../service/util/MigrationWorkflowTest.java | 14 +++++++--- 9 files changed, 74 insertions(+), 8 deletions(-) diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/OpenMetadataApplication.java b/openmetadata-service/src/main/java/org/openmetadata/service/OpenMetadataApplication.java index 8cf9242a8d49..a9cf7133f0ae 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/OpenMetadataApplication.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/OpenMetadataApplication.java @@ -454,6 +454,7 @@ private void validateMigrations(Jdbi jdbi, OpenMetadataApplicationConfig conf) connectionType, conf.getMigrationConfiguration().getExtensionPath(), conf.getPipelineServiceClientConfiguration(), + conf.getAuthenticationConfiguration(), false); migrationWorkflow.loadMigrations(); migrationWorkflow.validateMigrationsForServer(); diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/migration/api/MigrationProcessImpl.java b/openmetadata-service/src/main/java/org/openmetadata/service/migration/api/MigrationProcessImpl.java index 98e06643f1fd..75897e005539 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/migration/api/MigrationProcessImpl.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/migration/api/MigrationProcessImpl.java @@ -9,6 +9,7 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.jdbi.v3.core.Handle; +import org.openmetadata.schema.api.security.AuthenticationConfiguration; import org.openmetadata.sdk.PipelineServiceClientInterface; import org.openmetadata.service.clients.pipeline.PipelineServiceClientFactory; import org.openmetadata.service.jdbi3.CollectionDAO; @@ -24,6 +25,7 @@ public class MigrationProcessImpl implements MigrationProcess { protected CollectionDAO collectionDAO; protected Handle handle; protected PipelineServiceClientInterface pipelineServiceClient; + protected AuthenticationConfiguration authenticationConfiguration; private final MigrationFile migrationFile; public @Getter MigrationContext context; @@ -40,6 +42,7 @@ public void initialize(Handle handle) { this.pipelineServiceClient = PipelineServiceClientFactory.createPipelineServiceClient( this.migrationFile.pipelineServiceClientConfiguration); + this.authenticationConfiguration = migrationFile.authenticationConfiguration; } @Override diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/migration/api/MigrationWorkflow.java b/openmetadata-service/src/main/java/org/openmetadata/service/migration/api/MigrationWorkflow.java index 7c2aba84781e..d40083b32da4 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/migration/api/MigrationWorkflow.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/migration/api/MigrationWorkflow.java @@ -18,6 +18,7 @@ import org.jdbi.v3.core.Jdbi; import org.json.JSONObject; import org.openmetadata.schema.api.configuration.pipelineServiceClient.PipelineServiceClientConfiguration; +import org.openmetadata.schema.api.security.AuthenticationConfiguration; import org.openmetadata.service.jdbi3.MigrationDAO; import org.openmetadata.service.jdbi3.locator.ConnectionType; import org.openmetadata.service.migration.QueryStatus; @@ -35,6 +36,7 @@ public class MigrationWorkflow { private final ConnectionType connectionType; private final String extensionSQLScriptRootPath; @Getter private final PipelineServiceClientConfiguration pipelineServiceClientConfiguration; + @Getter private final AuthenticationConfiguration authenticationConfiguration; private final MigrationDAO migrationDAO; private final Jdbi jdbi; private final boolean forceMigrations; @@ -47,6 +49,7 @@ public MigrationWorkflow( ConnectionType connectionType, String extensionSQLScriptRootPath, PipelineServiceClientConfiguration pipelineServiceClientConfiguration, + AuthenticationConfiguration authenticationConfiguration, boolean forceMigrations) { this.jdbi = jdbi; this.migrationDAO = jdbi.onDemand(MigrationDAO.class); @@ -55,6 +58,7 @@ public MigrationWorkflow( this.connectionType = connectionType; this.extensionSQLScriptRootPath = extensionSQLScriptRootPath; this.pipelineServiceClientConfiguration = pipelineServiceClientConfiguration; + this.authenticationConfiguration = authenticationConfiguration; } public void loadMigrations() { @@ -64,7 +68,8 @@ public void loadMigrations() { nativeSQLScriptRootPath, connectionType, extensionSQLScriptRootPath, - pipelineServiceClientConfiguration); + pipelineServiceClientConfiguration, + authenticationConfiguration); // Filter Migrations to Be Run this.migrations = filterAndGetMigrationsToRun(availableMigrations); } @@ -83,10 +88,15 @@ public List getMigrationFiles( String nativeSQLScriptRootPath, ConnectionType connectionType, String extensionSQLScriptRootPath, - PipelineServiceClientConfiguration pipelineServiceClientConfiguration) { + PipelineServiceClientConfiguration pipelineServiceClientConfiguration, + AuthenticationConfiguration authenticationConfiguration) { List availableOMNativeMigrations = getMigrationFilesFromPath( - nativeSQLScriptRootPath, connectionType, pipelineServiceClientConfiguration, false); + nativeSQLScriptRootPath, + connectionType, + pipelineServiceClientConfiguration, + authenticationConfiguration, + false); // If we only have OM migrations, return them if (extensionSQLScriptRootPath == null || extensionSQLScriptRootPath.isEmpty()) { @@ -96,7 +106,11 @@ public List getMigrationFiles( // Otherwise, fetch the extension migrations and sort the executions List availableExtensionMigrations = getMigrationFilesFromPath( - extensionSQLScriptRootPath, connectionType, pipelineServiceClientConfiguration, true); + extensionSQLScriptRootPath, + connectionType, + pipelineServiceClientConfiguration, + authenticationConfiguration, + true); /* If we create migrations version as: @@ -114,6 +128,7 @@ public List getMigrationFilesFromPath( String path, ConnectionType connectionType, PipelineServiceClientConfiguration pipelineServiceClientConfiguration, + AuthenticationConfiguration authenticationConfiguration, Boolean isExtension) { return Arrays.stream(Objects.requireNonNull(new File(path).listFiles(File::isDirectory))) .map( @@ -123,6 +138,7 @@ public List getMigrationFilesFromPath( migrationDAO, connectionType, pipelineServiceClientConfiguration, + authenticationConfiguration, isExtension)) .sorted() .toList(); diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v153/Migration.java b/openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v153/Migration.java index f42d5d6447a9..1e1bc60dcac9 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v153/Migration.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v153/Migration.java @@ -1,6 +1,7 @@ package org.openmetadata.service.migration.mysql.v153; import static org.openmetadata.service.migration.utils.v153.MigrationUtil.updateEmailTemplates; +import static org.openmetadata.service.migration.utils.v153.MigrationUtil.updateUserNameToEmailPrefixForLdapAuthProvider; import lombok.SneakyThrows; import org.openmetadata.service.migration.api.MigrationProcessImpl; @@ -16,5 +17,6 @@ public Migration(MigrationFile migrationFile) { @SneakyThrows public void runDataMigration() { updateEmailTemplates(collectionDAO); + updateUserNameToEmailPrefixForLdapAuthProvider(collectionDAO, authenticationConfiguration); } } diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/MigrationFile.java b/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/MigrationFile.java index 4a0248e885e1..66d834e94e61 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/MigrationFile.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/MigrationFile.java @@ -14,6 +14,7 @@ import org.flywaydb.core.internal.sqlscript.SqlStatementIterator; import org.flywaydb.database.mysql.MySQLParser; import org.openmetadata.schema.api.configuration.pipelineServiceClient.PipelineServiceClientConfiguration; +import org.openmetadata.schema.api.security.AuthenticationConfiguration; import org.openmetadata.service.jdbi3.MigrationDAO; import org.openmetadata.service.jdbi3.locator.ConnectionType; import org.openmetadata.service.util.EntityUtil; @@ -23,6 +24,8 @@ public class MigrationFile implements Comparable { public final String version; public final ConnectionType connectionType; public final PipelineServiceClientConfiguration pipelineServiceClientConfiguration; + public final AuthenticationConfiguration authenticationConfiguration; + public final File dir; public final Boolean isExtension; public final String dbPackageName; @@ -38,6 +41,7 @@ public MigrationFile( MigrationDAO migrationDAO, ConnectionType connectionType, PipelineServiceClientConfiguration pipelineServiceClientConfiguration, + AuthenticationConfiguration authenticationConfiguration, Boolean isExtension) { this.dir = dir; this.isExtension = isExtension; @@ -45,6 +49,7 @@ public MigrationFile( this.connectionType = connectionType; this.migrationDAO = migrationDAO; this.pipelineServiceClientConfiguration = pipelineServiceClientConfiguration; + this.authenticationConfiguration = authenticationConfiguration; this.dbPackageName = connectionType == ConnectionType.MYSQL ? "mysql" : "postgres"; versionNumbers = convertToNumber(version); schemaChanges = new ArrayList<>(); diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v153/MigrationUtil.java b/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v153/MigrationUtil.java index a89ed2cd749a..768e4df10cb1 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v153/MigrationUtil.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v153/MigrationUtil.java @@ -1,7 +1,12 @@ package org.openmetadata.service.migration.utils.v153; +import java.util.List; import lombok.extern.slf4j.Slf4j; +import org.openmetadata.schema.api.security.AuthenticationConfiguration; +import org.openmetadata.schema.entity.teams.User; +import org.openmetadata.schema.services.connections.metadata.AuthProvider; import org.openmetadata.service.jdbi3.CollectionDAO; +import org.openmetadata.service.util.JsonUtils; @Slf4j public class MigrationUtil { @@ -11,4 +16,27 @@ public static void updateEmailTemplates(CollectionDAO collectionDAO) { // delete emailTemplates, it will be loaded from initSeedData. dao.deleteEmailTemplates(); } + + public static void updateUserNameToEmailPrefixForLdapAuthProvider( + CollectionDAO daoCollection, AuthenticationConfiguration config) { + if (config.getProvider().equals(AuthProvider.LDAP)) { + LOG.info("Starting migration username -> email prefix"); + int total = daoCollection.userDAO().listTotalCount(); + int offset = 0; + int limit = 200; + while (offset < total) { + List userEntities = daoCollection.userDAO().listAfterWithOffset(limit, offset); + for (String json : userEntities) { + User userEntity = JsonUtils.readValue(json, User.class); + String email = userEntity.getEmail(); + String emailPrefix = email.substring(0, email.indexOf("@")); + userEntity.setFullyQualifiedName(emailPrefix); + + daoCollection.userDAO().update(userEntity); + } + offset = offset + limit; + } + LOG.info("Completed migrating username -> email prefix"); + } + } } diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/util/OpenMetadataOperations.java b/openmetadata-service/src/main/java/org/openmetadata/service/util/OpenMetadataOperations.java index cd81cb82752f..754867160730 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/util/OpenMetadataOperations.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/util/OpenMetadataOperations.java @@ -618,6 +618,7 @@ private void validateAndRunSystemDataMigrations(boolean force) { connType, extensionSQLScriptRootPath, config.getPipelineServiceClientConfiguration(), + config.getAuthenticationConfiguration(), force); workflow.loadMigrations(); workflow.printMigrationInfo(); diff --git a/openmetadata-service/src/test/java/org/openmetadata/service/OpenMetadataApplicationTest.java b/openmetadata-service/src/test/java/org/openmetadata/service/OpenMetadataApplicationTest.java index 897ee0af5197..14bd2bdd5e28 100644 --- a/openmetadata-service/src/test/java/org/openmetadata/service/OpenMetadataApplicationTest.java +++ b/openmetadata-service/src/test/java/org/openmetadata/service/OpenMetadataApplicationTest.java @@ -48,6 +48,7 @@ import org.junit.jupiter.api.TestInstance; import org.openmetadata.common.utils.CommonUtil; import org.openmetadata.schema.api.configuration.pipelineServiceClient.PipelineServiceClientConfiguration; +import org.openmetadata.schema.api.security.AuthenticationConfiguration; import org.openmetadata.schema.service.configuration.elasticsearch.ElasticSearchConfiguration; import org.openmetadata.schema.type.IndexMappingLanguage; import org.openmetadata.service.jdbi3.CollectionDAO; @@ -208,6 +209,7 @@ public void createApplication() throws Exception { nativeMigrationScriptsLocation, extensionMigrationScripsLocation, null, + null, false); createIndices(); APP.before(); @@ -221,6 +223,7 @@ public static void validateAndRunSystemDataMigrations( String nativeMigrationSQLPath, String extensionSQLScriptRootPath, PipelineServiceClientConfiguration pipelineServiceClientConfiguration, + AuthenticationConfiguration authenticationConfiguration, boolean forceMigrations) { DatasourceConfig.initialize(connType.label); MigrationWorkflow workflow = @@ -230,6 +233,7 @@ public static void validateAndRunSystemDataMigrations( connType, extensionSQLScriptRootPath, pipelineServiceClientConfiguration, + authenticationConfiguration, forceMigrations); // Initialize search repository SearchRepository searchRepository = diff --git a/openmetadata-service/src/test/java/org/openmetadata/service/util/MigrationWorkflowTest.java b/openmetadata-service/src/test/java/org/openmetadata/service/util/MigrationWorkflowTest.java index 9bf3699aa8d3..5b65dc330901 100644 --- a/openmetadata-service/src/test/java/org/openmetadata/service/util/MigrationWorkflowTest.java +++ b/openmetadata-service/src/test/java/org/openmetadata/service/util/MigrationWorkflowTest.java @@ -28,7 +28,7 @@ public static void setup() { migrationWorkflow = spy( new MigrationWorkflow( - jdbi, "nativePath", ConnectionType.MYSQL, "extensionPath", null, false)); + jdbi, "nativePath", ConnectionType.MYSQL, "extensionPath", null, null, false)); omMigrationList = List.of( @@ -37,18 +37,21 @@ public static void setup() { null, ConnectionType.MYSQL, migrationWorkflow.getPipelineServiceClientConfiguration(), + migrationWorkflow.getAuthenticationConfiguration(), false), new MigrationFile( new File("/bootstrap/sql/migrations/native/1.2.0"), null, ConnectionType.MYSQL, migrationWorkflow.getPipelineServiceClientConfiguration(), + migrationWorkflow.getAuthenticationConfiguration(), false), new MigrationFile( new File("/bootstrap/sql/migrations/native/1.2.1"), null, ConnectionType.MYSQL, migrationWorkflow.getPipelineServiceClientConfiguration(), + migrationWorkflow.getAuthenticationConfiguration(), false)); collateMigrationList = @@ -58,12 +61,14 @@ public static void setup() { null, ConnectionType.MYSQL, migrationWorkflow.getPipelineServiceClientConfiguration(), + migrationWorkflow.getAuthenticationConfiguration(), true), new MigrationFile( new File("/bootstrap-collate/sql/migrations/native/1.2.2-collate"), null, ConnectionType.MYSQL, migrationWorkflow.getPipelineServiceClientConfiguration(), + migrationWorkflow.getAuthenticationConfiguration(), true)); } @@ -72,18 +77,19 @@ void test_getMigrationFiles() { Mockito.doReturn(omMigrationList) .when(migrationWorkflow) .getMigrationFilesFromPath( - eq("nativePath"), any(ConnectionType.class), eq(null), eq(false)); + eq("nativePath"), any(ConnectionType.class), eq(null), eq(null), eq(false)); Mockito.doReturn(collateMigrationList) .when(migrationWorkflow) .getMigrationFilesFromPath( - eq("extensionPath"), any(ConnectionType.class), eq(null), eq(true)); + eq("extensionPath"), any(ConnectionType.class), eq(null), eq(null), eq(true)); List foundList = migrationWorkflow.getMigrationFiles( "nativePath", ConnectionType.MYSQL, "extensionPath", - migrationWorkflow.getPipelineServiceClientConfiguration()); + migrationWorkflow.getPipelineServiceClientConfiguration(), + migrationWorkflow.getAuthenticationConfiguration()); assertEquals( List.of("1.1.0", "1.1.0-collate", "1.2.0", "1.2.1", "1.2.2-collate"), From 389b4b67d892e29a8e24ab984a1155088699f855 Mon Sep 17 00:00:00 2001 From: Siddhanttimeline Date: Mon, 9 Sep 2024 14:31:36 +0530 Subject: [PATCH 2/6] migrate userName to emailPrefix for ldap auth provider. --- .../openmetadata/service/migration/postgres/v153/Migration.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v153/Migration.java b/openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v153/Migration.java index 85bf8181cbc8..17f71b3a3ac2 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v153/Migration.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v153/Migration.java @@ -1,6 +1,7 @@ package org.openmetadata.service.migration.postgres.v153; import static org.openmetadata.service.migration.utils.v153.MigrationUtil.updateEmailTemplates; +import static org.openmetadata.service.migration.utils.v153.MigrationUtil.updateUserNameToEmailPrefixForLdapAuthProvider; import lombok.SneakyThrows; import org.openmetadata.service.migration.api.MigrationProcessImpl; @@ -16,5 +17,6 @@ public Migration(MigrationFile migrationFile) { @SneakyThrows public void runDataMigration() { updateEmailTemplates(collectionDAO); + updateUserNameToEmailPrefixForLdapAuthProvider(collectionDAO, authenticationConfiguration); } } From 618f75f80daa39af6f05830dc2e5861b91868bdc Mon Sep 17 00:00:00 2001 From: Siddhanttimeline Date: Thu, 12 Sep 2024 19:53:09 +0530 Subject: [PATCH 3/6] fix migration. --- .../migration/mysql/v153/Migration.java | 2 - .../migration/mysql/v154/Migration.java | 21 +++++++ .../migration/postgres/v153/Migration.java | 2 - .../migration/postgres/v154/Migration.java | 21 +++++++ .../migration/utils/v153/MigrationUtil.java | 28 --------- .../migration/utils/v154/MigrationUtil.java | 60 +++++++++++++++++++ 6 files changed, 102 insertions(+), 32 deletions(-) create mode 100644 openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v154/Migration.java create mode 100644 openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v154/Migration.java create mode 100644 openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v154/MigrationUtil.java diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v153/Migration.java b/openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v153/Migration.java index 1e1bc60dcac9..f42d5d6447a9 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v153/Migration.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v153/Migration.java @@ -1,7 +1,6 @@ package org.openmetadata.service.migration.mysql.v153; import static org.openmetadata.service.migration.utils.v153.MigrationUtil.updateEmailTemplates; -import static org.openmetadata.service.migration.utils.v153.MigrationUtil.updateUserNameToEmailPrefixForLdapAuthProvider; import lombok.SneakyThrows; import org.openmetadata.service.migration.api.MigrationProcessImpl; @@ -17,6 +16,5 @@ public Migration(MigrationFile migrationFile) { @SneakyThrows public void runDataMigration() { updateEmailTemplates(collectionDAO); - updateUserNameToEmailPrefixForLdapAuthProvider(collectionDAO, authenticationConfiguration); } } diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v154/Migration.java b/openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v154/Migration.java new file mode 100644 index 000000000000..55ea9bc5206d --- /dev/null +++ b/openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v154/Migration.java @@ -0,0 +1,21 @@ +package org.openmetadata.service.migration.mysql.v154; + +import static org.openmetadata.service.migration.utils.v154.MigrationUtil.updateUserNameToEmailPrefixForLdapAuthProvider; + +import lombok.SneakyThrows; +import org.openmetadata.service.migration.api.MigrationProcessImpl; +import org.openmetadata.service.migration.utils.MigrationFile; + +public class Migration extends MigrationProcessImpl { + + public Migration(MigrationFile migrationFile) { + super(migrationFile); + } + + @Override + @SneakyThrows + public void runDataMigration() { + updateUserNameToEmailPrefixForLdapAuthProvider( + handle, collectionDAO, authenticationConfiguration, false); + } +} diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v153/Migration.java b/openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v153/Migration.java index 17f71b3a3ac2..85bf8181cbc8 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v153/Migration.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v153/Migration.java @@ -1,7 +1,6 @@ package org.openmetadata.service.migration.postgres.v153; import static org.openmetadata.service.migration.utils.v153.MigrationUtil.updateEmailTemplates; -import static org.openmetadata.service.migration.utils.v153.MigrationUtil.updateUserNameToEmailPrefixForLdapAuthProvider; import lombok.SneakyThrows; import org.openmetadata.service.migration.api.MigrationProcessImpl; @@ -17,6 +16,5 @@ public Migration(MigrationFile migrationFile) { @SneakyThrows public void runDataMigration() { updateEmailTemplates(collectionDAO); - updateUserNameToEmailPrefixForLdapAuthProvider(collectionDAO, authenticationConfiguration); } } diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v154/Migration.java b/openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v154/Migration.java new file mode 100644 index 000000000000..c32def9e8a4c --- /dev/null +++ b/openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v154/Migration.java @@ -0,0 +1,21 @@ +package org.openmetadata.service.migration.postgres.v154; + +import static org.openmetadata.service.migration.utils.v154.MigrationUtil.updateUserNameToEmailPrefixForLdapAuthProvider; + +import lombok.SneakyThrows; +import org.openmetadata.service.migration.api.MigrationProcessImpl; +import org.openmetadata.service.migration.utils.MigrationFile; + +public class Migration extends MigrationProcessImpl { + + public Migration(MigrationFile migrationFile) { + super(migrationFile); + } + + @Override + @SneakyThrows + public void runDataMigration() { + updateUserNameToEmailPrefixForLdapAuthProvider( + handle, collectionDAO, authenticationConfiguration, true); + } +} diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v153/MigrationUtil.java b/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v153/MigrationUtil.java index 768e4df10cb1..a89ed2cd749a 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v153/MigrationUtil.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v153/MigrationUtil.java @@ -1,12 +1,7 @@ package org.openmetadata.service.migration.utils.v153; -import java.util.List; import lombok.extern.slf4j.Slf4j; -import org.openmetadata.schema.api.security.AuthenticationConfiguration; -import org.openmetadata.schema.entity.teams.User; -import org.openmetadata.schema.services.connections.metadata.AuthProvider; import org.openmetadata.service.jdbi3.CollectionDAO; -import org.openmetadata.service.util.JsonUtils; @Slf4j public class MigrationUtil { @@ -16,27 +11,4 @@ public static void updateEmailTemplates(CollectionDAO collectionDAO) { // delete emailTemplates, it will be loaded from initSeedData. dao.deleteEmailTemplates(); } - - public static void updateUserNameToEmailPrefixForLdapAuthProvider( - CollectionDAO daoCollection, AuthenticationConfiguration config) { - if (config.getProvider().equals(AuthProvider.LDAP)) { - LOG.info("Starting migration username -> email prefix"); - int total = daoCollection.userDAO().listTotalCount(); - int offset = 0; - int limit = 200; - while (offset < total) { - List userEntities = daoCollection.userDAO().listAfterWithOffset(limit, offset); - for (String json : userEntities) { - User userEntity = JsonUtils.readValue(json, User.class); - String email = userEntity.getEmail(); - String emailPrefix = email.substring(0, email.indexOf("@")); - userEntity.setFullyQualifiedName(emailPrefix); - - daoCollection.userDAO().update(userEntity); - } - offset = offset + limit; - } - LOG.info("Completed migrating username -> email prefix"); - } - } } diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v154/MigrationUtil.java b/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v154/MigrationUtil.java new file mode 100644 index 000000000000..0ad786917434 --- /dev/null +++ b/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v154/MigrationUtil.java @@ -0,0 +1,60 @@ +package org.openmetadata.service.migration.utils.v154; + +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.jdbi.v3.core.Handle; +import org.openmetadata.schema.api.security.AuthenticationConfiguration; +import org.openmetadata.schema.entity.teams.User; +import org.openmetadata.schema.services.connections.metadata.AuthProvider; +import org.openmetadata.schema.utils.EntityInterfaceUtil; +import org.openmetadata.service.jdbi3.CollectionDAO; +import org.openmetadata.service.util.JsonUtils; + +@Slf4j +public class MigrationUtil { + public static void updateUserNameToEmailPrefixForLdapAuthProvider( + Handle handle, + CollectionDAO daoCollection, + AuthenticationConfiguration config, + boolean postgres) { + if (config.getProvider().equals(AuthProvider.LDAP)) { + LOG.info("Starting migration username -> email prefix"); + int total = daoCollection.userDAO().listTotalCount(); + int offset = 0; + int limit = 200; + while (offset < total) { + List userEntities = daoCollection.userDAO().listAfterWithOffset(limit, offset); + for (String json : userEntities) { + User userEntity = JsonUtils.readValue(json, User.class); + String email = userEntity.getEmail(); + String emailPrefix = email.substring(0, email.indexOf("@")); + userEntity.setFullyQualifiedName(EntityInterfaceUtil.quoteName(emailPrefix)); + userEntity.setName(emailPrefix); + + daoCollection.userDAO().update(userEntity); + } + offset = offset + limit; + } + + updateUserEntityNameHash(handle, postgres); + LOG.info("Completed migrating username -> email prefix"); + } + } + + public static void updateUserEntityNameHash(Handle handle, boolean postgres) { + String updateNameHashSql; + if (postgres) { + updateNameHashSql = "UPDATE user_entity SET nameHash = MD5(json ->> 'fullyQualifiedName');"; + } else { + updateNameHashSql = + "UPDATE user_entity SET nameHash = MD5(JSON_UNQUOTE(JSON_EXTRACT(json, '$.fullyQualifiedName')));"; + } + + try { + handle.execute(updateNameHashSql); + LOG.info("Successfully updated nameHash for all user entities."); + } catch (Exception e) { + LOG.error("Error updating nameHash field", e); + } + } +} From 5b2e63403dd7724c6b5c84ea1adbcc1f5453b959 Mon Sep 17 00:00:00 2001 From: Siddhanttimeline Date: Thu, 19 Sep 2024 15:51:09 +0530 Subject: [PATCH 4/6] move migration to v155 --- .../service/migration/mysql/{v154 => v155}/Migration.java | 4 ++-- .../service/migration/postgres/{v154 => v155}/Migration.java | 4 ++-- .../service/migration/utils/{v154 => v155}/MigrationUtil.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/{v154 => v155}/Migration.java (82%) rename openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/{v154 => v155}/Migration.java (81%) rename openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/{v154 => v155}/MigrationUtil.java (97%) diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v154/Migration.java b/openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v155/Migration.java similarity index 82% rename from openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v154/Migration.java rename to openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v155/Migration.java index 55ea9bc5206d..b3dce3d71e30 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v154/Migration.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/migration/mysql/v155/Migration.java @@ -1,6 +1,6 @@ -package org.openmetadata.service.migration.mysql.v154; +package org.openmetadata.service.migration.mysql.v155; -import static org.openmetadata.service.migration.utils.v154.MigrationUtil.updateUserNameToEmailPrefixForLdapAuthProvider; +import static org.openmetadata.service.migration.utils.v155.MigrationUtil.updateUserNameToEmailPrefixForLdapAuthProvider; import lombok.SneakyThrows; import org.openmetadata.service.migration.api.MigrationProcessImpl; diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v154/Migration.java b/openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v155/Migration.java similarity index 81% rename from openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v154/Migration.java rename to openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v155/Migration.java index c32def9e8a4c..5b470da547b4 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v154/Migration.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/migration/postgres/v155/Migration.java @@ -1,6 +1,6 @@ -package org.openmetadata.service.migration.postgres.v154; +package org.openmetadata.service.migration.postgres.v155; -import static org.openmetadata.service.migration.utils.v154.MigrationUtil.updateUserNameToEmailPrefixForLdapAuthProvider; +import static org.openmetadata.service.migration.utils.v155.MigrationUtil.updateUserNameToEmailPrefixForLdapAuthProvider; import lombok.SneakyThrows; import org.openmetadata.service.migration.api.MigrationProcessImpl; diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v154/MigrationUtil.java b/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v155/MigrationUtil.java similarity index 97% rename from openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v154/MigrationUtil.java rename to openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v155/MigrationUtil.java index 0ad786917434..28967d860bfe 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v154/MigrationUtil.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/migration/utils/v155/MigrationUtil.java @@ -1,4 +1,4 @@ -package org.openmetadata.service.migration.utils.v154; +package org.openmetadata.service.migration.utils.v155; import java.util.List; import lombok.extern.slf4j.Slf4j; From f96255893a17338f2ee5ecb6ecdc83c88cf31469 Mon Sep 17 00:00:00 2001 From: mohitdeuex Date: Sat, 21 Sep 2024 00:30:19 +0530 Subject: [PATCH 5/6] Update Ldap Authenticator --- .../service/security/auth/LdapAuthenticator.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/LdapAuthenticator.java b/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/LdapAuthenticator.java index 005910e0de45..f0a42832d21f 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/LdapAuthenticator.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/LdapAuthenticator.java @@ -139,9 +139,9 @@ private LDAPConnectionPool getLdapConnectionPool(LdapConfiguration ldapConfigura @Override public JwtResponse loginUser(LoginRequest loginRequest) throws IOException, TemplateException { checkIfLoginBlocked(loginRequest.getEmail()); - User storedUser = lookUserInProvider(loginRequest.getEmail()); - validatePassword(storedUser.getEmail(), storedUser, loginRequest.getPassword()); - User omUser = checkAndCreateUser(storedUser.getEmail(), storedUser.getName()); + User storedUserInLdap = lookUserInProvider(loginRequest.getEmail()); + validatePassword(storedUserInLdap.getEmail(), storedUserInLdap, loginRequest.getPassword()); + User omUser = checkAndCreateUser(storedUserInLdap.getEmail(), storedUserInLdap.getName()); return getJwtResponse(omUser, SecurityUtil.getLoginConfiguration().getJwtTokenExpiryTime()); } @@ -237,8 +237,10 @@ public User lookUserInProvider(String email) { Attribute emailAttr = searchResultEntry.getAttribute(ldapConfiguration.getMailAttributeName()); - if (!CommonUtil.nullOrEmpty(userDN) && emailAttr != null) { - return getUserForLdap(email).withName(userDN.toLowerCase()); + if (!CommonUtil.nullOrEmpty(userDN) + && emailAttr != null + && email.equalsIgnoreCase(emailAttr.getValue())) { + return getUserForLdap(email); } else { throw new CustomExceptionMessage(FORBIDDEN, INVALID_USER_OR_PASSWORD, LDAP_MISSING_ATTR); } From 3c42a2d21632d4974e87b6f0383289d0b3f2154c Mon Sep 17 00:00:00 2001 From: mohitdeuex Date: Sat, 21 Sep 2024 16:42:20 +0530 Subject: [PATCH 6/6] Fix Ldap Issue on Login --- .../security/auth/AuthenticatorHandler.java | 6 +- .../security/auth/BasicAuthenticator.java | 38 +++++----- .../security/auth/LdapAuthenticator.java | 73 ++++++++++++------- .../security/auth/NoopAuthenticator.java | 6 +- .../service/util/email/EmailUtil.java | 8 +- 5 files changed, 77 insertions(+), 54 deletions(-) diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/AuthenticatorHandler.java b/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/AuthenticatorHandler.java index b514b264e68a..7c77a0e88fc6 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/AuthenticatorHandler.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/AuthenticatorHandler.java @@ -33,13 +33,13 @@ public interface AuthenticatorHandler { void checkIfLoginBlocked(String userName); - void recordFailedLoginAttempt(String providedIdentity, User user) + void recordFailedLoginAttempt(String email, String userName) throws TemplateException, IOException; - void validatePassword(String providedIdentity, User storedUser, String reqPassword) + void validatePassword(String providedIdentity, String reqPassword, User omUser) throws TemplateException, IOException; - User lookUserInProvider(String userName); + User lookUserInProvider(String email, String pwd) throws TemplateException, IOException; default User registerUser(RegistrationRequest registrationRequest) { throw new CustomExceptionMessage( diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/BasicAuthenticator.java b/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/BasicAuthenticator.java index e6c2041c5f60..a99a7eeab87a 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/BasicAuthenticator.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/BasicAuthenticator.java @@ -261,7 +261,8 @@ public void resetUserPasswordWithToken(UriInfo uriInfo, PasswordResetRequest req // Update user about Password Change try { - sendAccountStatus(storedUser, "Update Password", "Change Successful"); + sendAccountStatus( + storedUser.getName(), storedUser.getEmail(), "Update Password", "Change Successful"); } catch (TemplateException ex) { LOG.error("Error in sending Password Change Mail to User. Reason : " + ex.getMessage(), ex); throw new CustomExceptionMessage(424, FAILED_SEND_EMAIL, EMAIL_SENDING_ISSUE); @@ -466,28 +467,29 @@ public void validateEmailAlreadyExists(String email) { @Override public JwtResponse loginUser(LoginRequest loginRequest) throws IOException, TemplateException { - String userName = loginRequest.getEmail(); - checkIfLoginBlocked(userName); - User storedUser = lookUserInProvider(userName); - validatePassword(userName, storedUser, loginRequest.getPassword()); + String email = loginRequest.getEmail(); + checkIfLoginBlocked(email); + User storedUser = lookUserInProvider(email, loginRequest.getPassword()); + validatePassword(email, loginRequest.getPassword(), storedUser); return getJwtResponse(storedUser, SecurityUtil.getLoginConfiguration().getJwtTokenExpiryTime()); } @Override - public void checkIfLoginBlocked(String userName) { - if (loginAttemptCache.isLoginBlocked(userName)) { + public void checkIfLoginBlocked(String email) { + if (loginAttemptCache.isLoginBlocked(email)) { throw new AuthenticationException(MAX_FAILED_LOGIN_ATTEMPT); } } @Override - public void recordFailedLoginAttempt(String providedIdentity, User storedUser) + public void recordFailedLoginAttempt(String email, String userName) throws TemplateException, IOException { - loginAttemptCache.recordFailedLogin(providedIdentity); - int failedLoginAttempt = loginAttemptCache.getUserFailedLoginCount(providedIdentity); + loginAttemptCache.recordFailedLogin(email); + int failedLoginAttempt = loginAttemptCache.getUserFailedLoginCount(email); if (failedLoginAttempt == SecurityUtil.getLoginConfiguration().getMaxLoginFailAttempts()) { sendAccountStatus( - storedUser, + userName, + email, "Multiple Failed Login Attempts.", String.format( "Someone is trying to access your account. Login is Blocked for %s minutes. Please change your password.", @@ -495,35 +497,35 @@ public void recordFailedLoginAttempt(String providedIdentity, User storedUser) } } - public void validatePassword(String providedIdentity, User storedUser, String reqPassword) + public void validatePassword(String providedIdentity, String reqPassword, User omUser) throws TemplateException, IOException { // when basic auth is enabled and the user is created through the API without password, the // stored auth mechanism // for the user is null - if (storedUser.getAuthenticationMechanism() == null) { + if (omUser.getAuthenticationMechanism() == null) { throw new AuthenticationException(INVALID_USERNAME_PASSWORD); } @SuppressWarnings("unchecked") LinkedHashMap storedData = - (LinkedHashMap) storedUser.getAuthenticationMechanism().getConfig(); + (LinkedHashMap) omUser.getAuthenticationMechanism().getConfig(); String storedHashPassword = storedData.get("password"); if (!BCrypt.verifyer().verify(reqPassword.toCharArray(), storedHashPassword).verified) { // record Failed Login Attempts - recordFailedLoginAttempt(providedIdentity, storedUser); + recordFailedLoginAttempt(omUser.getEmail(), omUser.getName()); throw new AuthenticationException(INVALID_USERNAME_PASSWORD); } } @Override - public User lookUserInProvider(String userName) { + public User lookUserInProvider(String email, String pwd) { User storedUser = null; try { - if (userName.contains("@")) { + if (email.contains("@")) { // lookup by User Email storedUser = userRepository.getByEmail( null, - userName, + email, new EntityUtil.Fields( Set.of(USER_PROTECTED_FIELDS, "roles"), "authenticationMechanism,roles")); } diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/LdapAuthenticator.java b/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/LdapAuthenticator.java index f0a42832d21f..9531d76c1f97 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/LdapAuthenticator.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/LdapAuthenticator.java @@ -12,6 +12,8 @@ import static org.openmetadata.service.exception.CatalogExceptionMessage.MAX_FAILED_LOGIN_ATTEMPT; import static org.openmetadata.service.exception.CatalogExceptionMessage.MULTIPLE_EMAIL_ENTRIES; import static org.openmetadata.service.exception.CatalogExceptionMessage.PASSWORD_RESET_TOKEN_EXPIRED; +import static org.openmetadata.service.exception.CatalogExceptionMessage.SELF_SIGNUP_DISABLED_MESSAGE; +import static org.openmetadata.service.exception.CatalogExceptionMessage.SELF_SIGNUP_NOT_ENABLED; import static org.openmetadata.service.util.UserUtil.getRoleListFromUser; import com.fasterxml.jackson.core.JsonProcessingException; @@ -85,6 +87,7 @@ public class LdapAuthenticator implements AuthenticatorHandler { private LoginAttemptCache loginAttemptCache; private LdapConfiguration ldapConfiguration; private LDAPConnectionPool ldapLookupConnectionPool; + private boolean isSelfSignUpEnabled; @Override public void init(OpenMetadataApplicationConfig config) { @@ -100,6 +103,7 @@ public void init(OpenMetadataApplicationConfig config) { this.tokenRepository = Entity.getTokenRepository(); this.ldapConfiguration = config.getAuthenticationConfiguration().getLdapConfiguration(); this.loginAttemptCache = new LoginAttemptCache(); + this.isSelfSignUpEnabled = config.getAuthenticationConfiguration().getEnableSelfSignup(); } private LDAPConnectionPool getLdapConnectionPool(LdapConfiguration ldapConfiguration) { @@ -138,10 +142,9 @@ private LDAPConnectionPool getLdapConnectionPool(LdapConfiguration ldapConfigura @Override public JwtResponse loginUser(LoginRequest loginRequest) throws IOException, TemplateException { - checkIfLoginBlocked(loginRequest.getEmail()); - User storedUserInLdap = lookUserInProvider(loginRequest.getEmail()); - validatePassword(storedUserInLdap.getEmail(), storedUserInLdap, loginRequest.getPassword()); - User omUser = checkAndCreateUser(storedUserInLdap.getEmail(), storedUserInLdap.getName()); + String email = loginRequest.getEmail(); + checkIfLoginBlocked(email); + User omUser = lookUserInProvider(email, loginRequest.getPassword()); return getJwtResponse(omUser, SecurityUtil.getLoginConfiguration().getJwtTokenExpiryTime()); } @@ -149,21 +152,25 @@ public JwtResponse loginUser(LoginRequest loginRequest) throws IOException, Temp * Check if the user exists in database by userName, if user exist, reassign roles for user according to it's ldap * group else, create a new user and assign roles according to it's ldap group * - * @param email email address of user - * @param name userName of user + * @param userDn userDn from LDAP + * @param email Email of the User * @return user info * @author Eric Wen@2023-07-16 17:06:43 */ - private User checkAndCreateUser(String email, String name) throws IOException { + private User checkAndCreateUser(String userDn, String email, String userName) throws IOException { // Check if the user exists in OM Database try { User omUser = - userRepository.getByName(null, name, userRepository.getFields("id,name,email,roles")); - getRoleForLdap(omUser, Boolean.TRUE); + userRepository.getByEmail(null, email, userRepository.getFields("id,name,email,roles")); + getRoleForLdap(userDn, omUser, Boolean.TRUE); return omUser; } catch (EntityNotFoundException ex) { - // User does not exist - return userRepository.create(null, getUserForLdap(email, name)); + if (isSelfSignUpEnabled) { + return userRepository.create(null, getUserForLdap(userDn, email, userName)); + } else { + throw new CustomExceptionMessage( + INTERNAL_SERVER_ERROR, SELF_SIGNUP_NOT_ENABLED, SELF_SIGNUP_DISABLED_MESSAGE); + } } } @@ -175,13 +182,14 @@ public void checkIfLoginBlocked(String email) { } @Override - public void recordFailedLoginAttempt(String providedIdentity, User storedUser) + public void recordFailedLoginAttempt(String email, String userName) throws TemplateException, IOException { - loginAttemptCache.recordFailedLogin(providedIdentity); - int failedLoginAttempt = loginAttemptCache.getUserFailedLoginCount(providedIdentity); + loginAttemptCache.recordFailedLogin(email); + int failedLoginAttempt = loginAttemptCache.getUserFailedLoginCount(email); if (failedLoginAttempt == SecurityUtil.getLoginConfiguration().getMaxLoginFailAttempts()) { EmailUtil.sendAccountStatus( - storedUser, + userName, + email, "Multiple Failed Login Attempts.", String.format( "Someone is tried accessing your account. Login is Blocked for %s seconds.", @@ -190,12 +198,12 @@ public void recordFailedLoginAttempt(String providedIdentity, User storedUser) } @Override - public void validatePassword(String providedIdentity, User storedUser, String reqPassword) + public void validatePassword(String userDn, String reqPassword, User dummy) throws TemplateException, IOException { // performed in LDAP , the storedUser's name set as DN of the User in Ldap BindResult bindingResult = null; try { - bindingResult = ldapLookupConnectionPool.bind(storedUser.getName(), reqPassword); + bindingResult = ldapLookupConnectionPool.bind(userDn, reqPassword); if (Objects.equals(bindingResult.getResultCode().getName(), ResultCode.SUCCESS.getName())) { return; } @@ -203,7 +211,7 @@ public void validatePassword(String providedIdentity, User storedUser, String re if (bindingResult != null && Objects.equals( bindingResult.getResultCode().getName(), ResultCode.INVALID_CREDENTIALS.getName())) { - recordFailedLoginAttempt(providedIdentity, storedUser); + recordFailedLoginAttempt(dummy.getEmail(), dummy.getName()); throw new CustomExceptionMessage( UNAUTHORIZED, INVALID_USER_OR_PASSWORD, INVALID_EMAIL_PASSWORD); } @@ -218,7 +226,20 @@ public void validatePassword(String providedIdentity, User storedUser, String re } @Override - public User lookUserInProvider(String email) { + public User lookUserInProvider(String email, String pwd) throws TemplateException, IOException { + String userDN = getUserDnFromLdap(email); + + if (!nullOrEmpty(userDN)) { + User dummy = getUserForLdap(email); + validatePassword(userDN, pwd, dummy); + return checkAndCreateUser(userDN, email, dummy.getName()); + } + + throw new CustomExceptionMessage( + INTERNAL_SERVER_ERROR, INVALID_USER_OR_PASSWORD, INVALID_EMAIL_PASSWORD); + } + + private String getUserDnFromLdap(String email) { try { Filter emailFilter = Filter.createEqualityFilter(ldapConfiguration.getMailAttributeName(), email); @@ -240,7 +261,7 @@ public User lookUserInProvider(String email) { if (!CommonUtil.nullOrEmpty(userDN) && emailAttr != null && email.equalsIgnoreCase(emailAttr.getValue())) { - return getUserForLdap(email); + return userDN; } else { throw new CustomExceptionMessage(FORBIDDEN, INVALID_USER_OR_PASSWORD, LDAP_MISSING_ATTR); } @@ -249,7 +270,7 @@ public User lookUserInProvider(String email) { INTERNAL_SERVER_ERROR, MULTIPLE_EMAIL_ENTRIES, MULTIPLE_EMAIL_ENTRIES); } else { throw new CustomExceptionMessage( - INTERNAL_SERVER_ERROR, MULTIPLE_EMAIL_ENTRIES, INVALID_EMAIL_PASSWORD); + INTERNAL_SERVER_ERROR, INVALID_USER_OR_PASSWORD, INVALID_EMAIL_PASSWORD); } } catch (LDAPException ex) { throw new CustomExceptionMessage(INTERNAL_SERVER_ERROR, "LDAP_ERROR", ex.getMessage()); @@ -264,14 +285,14 @@ userName, new CreateUser().withName(userName).withEmail(email).withIsBot(false)) .withAuthenticationMechanism(null); } - private User getUserForLdap(String email, String userName) { + private User getUserForLdap(String ldapUserDn, String email, String userName) { User user = UserUtil.getUser( userName, new CreateUser().withName(userName).withEmail(email).withIsBot(false)) .withIsEmailVerified(false) .withAuthenticationMechanism(null); try { - getRoleForLdap(user, false); + getRoleForLdap(ldapUserDn, user, false); } catch (JsonProcessingException e) { LOG.error( "Failed to assign roles from LDAP to OpenMetadata for the user {} due to {}", @@ -288,7 +309,8 @@ userName, new CreateUser().withName(userName).withEmail(email).withIsBot(false)) * @param reAssign flag to decide whether to reassign roles * @author Eric Wen@2023-07-16 17:23:57 */ - private void getRoleForLdap(User user, Boolean reAssign) throws JsonProcessingException { + private void getRoleForLdap(String userDn, User user, Boolean reAssign) + throws JsonProcessingException { // Get user's groups from LDAP server using the DN of the user try { Filter groupFilter = @@ -296,8 +318,7 @@ private void getRoleForLdap(User user, Boolean reAssign) throws JsonProcessingEx ldapConfiguration.getGroupAttributeName(), ldapConfiguration.getGroupAttributeValue()); Filter groupMemberAttr = - Filter.createEqualityFilter( - ldapConfiguration.getGroupMemberAttributeName(), user.getName()); + Filter.createEqualityFilter(ldapConfiguration.getGroupMemberAttributeName(), userDn); Filter groupAndMemberFilter = Filter.createANDFilter(groupFilter, groupMemberAttr); SearchRequest searchRequest = new SearchRequest( diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/NoopAuthenticator.java b/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/NoopAuthenticator.java index de5be6cd5b9e..bd3826de0eb2 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/NoopAuthenticator.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/security/auth/NoopAuthenticator.java @@ -33,7 +33,7 @@ public void checkIfLoginBlocked(String userName) { } @Override - public void recordFailedLoginAttempt(String providedIdentity, User user) { + public void recordFailedLoginAttempt(String providedIdentity, String userName) { throw new CustomExceptionMessage( Response.Status.FORBIDDEN, AUTHENTICATOR_OPERATION_NOT_SUPPORTED, @@ -41,7 +41,7 @@ public void recordFailedLoginAttempt(String providedIdentity, User user) { } @Override - public void validatePassword(String providedIdentity, User storedUser, String reqPassword) { + public void validatePassword(String providedIdentity, String reqPassword, User storedUser) { throw new CustomExceptionMessage( Response.Status.FORBIDDEN, AUTHENTICATOR_OPERATION_NOT_SUPPORTED, @@ -49,7 +49,7 @@ public void validatePassword(String providedIdentity, User storedUser, String re } @Override - public User lookUserInProvider(String userName) { + public User lookUserInProvider(String email, String pwd) { throw new CustomExceptionMessage( Response.Status.FORBIDDEN, AUTHENTICATOR_OPERATION_NOT_SUPPORTED, diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/util/email/EmailUtil.java b/openmetadata-service/src/main/java/org/openmetadata/service/util/email/EmailUtil.java index a87018d79810..ee3ab278f213 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/util/email/EmailUtil.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/util/email/EmailUtil.java @@ -121,7 +121,7 @@ private static Mailer createMailer(SmtpSettings smtpServerSettings) { return null; } - public static void sendAccountStatus(User user, String action, String status) + public static void sendAccountStatus(String userName, String email, String action, String status) throws IOException, TemplateException { if (Boolean.TRUE.equals(getSmtpSettings().getEnableSmtpServer())) { @@ -129,7 +129,7 @@ public static void sendAccountStatus(User user, String action, String status) new TemplatePopulatorBuilder() .add(ENTITY, getSmtpSettings().getEmailingEntity()) .add(SUPPORT_URL, getSmtpSettings().getSupportUrl()) - .add(USERNAME, user.getName()) + .add(USERNAME, userName) .add(ACTION_KEY, action) .add(ACTION_STATUS_KEY, status) .build(); @@ -137,11 +137,11 @@ public static void sendAccountStatus(User user, String action, String status) sendMail( getAccountStatusChangeSubject(), templatePopulator, - user.getEmail(), + email, ACCOUNT_ACTIVITY_CHANGE_TEMPLATE, true); } else { - LOG.warn(EMAIL_IGNORE_MSG, user.getEmail()); + LOG.warn(EMAIL_IGNORE_MSG, userName); } }