From f50bf5ec7045e8d20de9ca31c2c2393c220936b5 Mon Sep 17 00:00:00 2001 From: Mohit Yadav <105265192+mohityadav766@users.noreply.github.com> Date: Mon, 8 May 2023 23:52:55 +0530 Subject: [PATCH] Bootstrap users fix + Ldap Fix error message (#11463) * Fix issues in Bootstrapping Admin Users * Fix Ldap Binding Message * Remove delete * do not remove the user on own * failing tests fix * null should also add auth-mechanism --- .../service/jdbi3/UserRepository.java | 13 ++- .../security/auth/LdapAuthenticator.java | 2 +- .../openmetadata/service/util/UserUtil.java | 81 ++++++++++--------- 3 files changed, 49 insertions(+), 47 deletions(-) diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/UserRepository.java b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/UserRepository.java index dd6c249db6d..7c09cb39b0d 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/UserRepository.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/UserRepository.java @@ -36,7 +36,6 @@ import org.apache.commons.csv.CSVPrinter; import org.apache.commons.csv.CSVRecord; import org.openmetadata.csv.EntityCsv; import org.openmetadata.schema.api.teams.CreateTeam.TeamType; -import org.openmetadata.schema.auth.SSOAuthMechanism; import org.openmetadata.schema.entity.teams.AuthenticationMechanism; import org.openmetadata.schema.entity.teams.Team; import org.openmetadata.schema.entity.teams.User; @@ -222,19 +221,17 @@ public class UserRepository extends EntityRepository { } public void initializeUsers(OpenMetadataApplicationConfig config) { + String providerType = config.getAuthenticationConfiguration().getProvider(); + // Create Admins Set adminUsers = new HashSet<>(config.getAuthorizerConfiguration().getAdminPrincipals()); LOG.debug("Checking user entries for admin users {}", adminUsers); String domain = SecurityUtil.getDomain(config); - String providerType = config.getAuthenticationConfiguration().getProvider(); - if (providerType.equals(SSOAuthMechanism.SsoServiceType.BASIC.value())) { - UserUtil.handleBasicAuth(adminUsers, domain); - } else { - UserUtil.addUsers(adminUsers, domain, true); - } + UserUtil.addUsers(providerType, adminUsers, domain, true); + // Create Test Users LOG.debug("Checking user entries for test users"); Set testUsers = new HashSet<>(config.getAuthorizerConfiguration().getTestPrincipals()); - UserUtil.addUsers(testUsers, domain, null); + UserUtil.addUsers(providerType, testUsers, domain, null); } private List getOwns(User user) throws IOException { 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 998c34754ab..82684cd28ba 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 @@ -171,7 +171,7 @@ public class LdapAuthenticator implements AuthenticatorHandler { if (bindingResult != null) { throw new CustomExceptionMessage(INTERNAL_SERVER_ERROR, bindingResult.getResultCode().getName()); } else { - throw new CustomExceptionMessage(INTERNAL_SERVER_ERROR, "Binding for User in LDAP Failed."); + throw new CustomExceptionMessage(INTERNAL_SERVER_ERROR, INVALID_EMAIL_PASSWORD); } } diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/util/UserUtil.java b/openmetadata-service/src/main/java/org/openmetadata/service/util/UserUtil.java index e8323e35a3d..5c61f9d1efe 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/util/UserUtil.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/util/UserUtil.java @@ -26,6 +26,7 @@ import static org.openmetadata.service.Entity.ADMIN_USER_NAME; import at.favre.lib.crypto.bcrypt.BCrypt; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Set; @@ -51,46 +52,57 @@ import org.openmetadata.service.security.jwt.JWTTokenGenerator; @Slf4j public final class UserUtil { - private static final String COLON_DELIMITER = ":"; - public static void handleBasicAuth(Set adminUsers, String domain) { + public static void addUsers(String providerType, Set adminUsers, String domain, Boolean isAdmin) { try { - for (String adminUser : adminUsers) { - if (adminUser.contains(COLON_DELIMITER)) { - String[] tokens = adminUser.split(COLON_DELIMITER); - addUserForBasicAuth(tokens[0], tokens[1], domain); - } else { - boolean isDefaultAdmin = adminUser.equals(ADMIN_USER_NAME); - String token = PasswordUtil.generateRandomPassword(); - if (isDefaultAdmin) { - token = ADMIN_USER_NAME; - } - addUserForBasicAuth(adminUser, token, domain); - } + for (String username : adminUsers) { + createOrUpdateUser(providerType, username, domain, isAdmin); } - } catch (IOException e) { - LOG.error("Failed in Basic Auth Setup. Reason : {}", e.getMessage()); + } catch (Exception ex) { + LOG.error("[BootstrapUser] Encountered Exception while bootstrapping admin user", ex); } } - public static void addUserForBasicAuth(String username, String pwd, String domain) throws IOException { + private static void createOrUpdateUser(String providerType, String username, String domain, Boolean isAdmin) + throws IOException { UserRepository userRepository = (UserRepository) Entity.getEntityRepository(Entity.USER); + User updatedUser; try { - List fields = List.of("profile", "roles", "teams", "authenticationMechanism", "isEmailVerified"); - User originalUser = userRepository.getByName(null, username, new EntityUtil.Fields(fields)); - if (originalUser.getAuthenticationMechanism() == null) { - updateBasicAuthUser(originalUser, pwd); - } - } catch (EntityNotFoundException e) { - User user = user(username, domain, username).withIsAdmin(true).withIsEmailVerified(true); - updateBasicAuthUser(user, pwd); - } - } + // Create Required Fields List + List fieldList = new ArrayList<>(userRepository.getPatchFields().getFieldList()); + fieldList.add("authenticationMechanism"); - private static void updateBasicAuthUser(User user, String pwd) { - updateUserWithHashedPwd(user, pwd); - addOrUpdateUser(user); - EmailUtil.sendInviteMailToAdmin(user, pwd); + // Fetch Original User, is available + User originalUser = userRepository.getByName(null, username, new EntityUtil.Fields(fieldList)); + updatedUser = originalUser; + + // Update Auth Mechanism if not present, and send mail to the user + if (providerType.equals(SSOAuthMechanism.SsoServiceType.BASIC.value())) { + if (originalUser.getAuthenticationMechanism() == null + || originalUser.getAuthenticationMechanism().equals(new AuthenticationMechanism())) { + updateUserWithHashedPwd(updatedUser, ADMIN_USER_NAME); + EmailUtil.sendInviteMailToAdmin(updatedUser, ADMIN_USER_NAME); + } + } else { + updatedUser.setAuthenticationMechanism(new AuthenticationMechanism()); + } + + // Update the specific fields isAdmin + updatedUser.setIsAdmin(isAdmin); + + // user email + updatedUser.setEmail(String.format("%s@%s", username, domain)); + } catch (EntityNotFoundException e) { + updatedUser = user(username, domain, username).withIsAdmin(isAdmin).withIsEmailVerified(true); + // Update Auth Mechanism if not present, and send mail to the user + if (providerType.equals(SSOAuthMechanism.SsoServiceType.BASIC.value())) { + updateUserWithHashedPwd(updatedUser, ADMIN_USER_NAME); + EmailUtil.sendInviteMailToAdmin(updatedUser, ADMIN_USER_NAME); + } + } + + // Update the user + addOrUpdateUser(updatedUser); } public static void updateUserWithHashedPwd(User user, String pwd) { @@ -101,13 +113,6 @@ public final class UserUtil { .withConfig(new BasicAuthMechanism().withPassword(hashedPwd))); } - public static void addUsers(Set users, String domain, Boolean isAdmin) { - for (String userName : users) { - User user = user(userName, domain, userName).withIsAdmin(isAdmin); - addOrUpdateUser(user); - } - } - public static User addOrUpdateUser(User user) { UserRepository userRepository = (UserRepository) Entity.getEntityRepository(Entity.USER); try {