From 0ae716a7914978b4c4cef7d84c9c5fd6b38d02a3 Mon Sep 17 00:00:00 2001 From: Mohit Yadav <105265192+mohityadav766@users.noreply.github.com> Date: Wed, 5 Jul 2023 10:41:23 +0530 Subject: [PATCH] =?UTF-8?q?fix=20lookup=20issue=20in=20case=20the=20provid?= =?UTF-8?q?ed=20username=20with=20email=20does=20not=20ex=E2=80=A6=20(#122?= =?UTF-8?q?83)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix lookup issue in case the provided username with email does not exist in the system * typo --- .../service/jdbi3/CollectionDAO.java | 3 ++ .../service/jdbi3/UserRepository.java | 9 ++++++ .../security/auth/AuthenticatorHandler.java | 5 +-- .../security/auth/BasicAuthenticator.java | 32 ++++++++++++------- .../security/auth/LdapAuthenticator.java | 13 ++++---- .../security/auth/NoopAuthenticator.java | 4 +-- 6 files changed, 44 insertions(+), 22 deletions(-) diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java index 967dcb92d5d..d84d1796efa 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java @@ -2775,6 +2775,9 @@ public interface CollectionDAO { @ConnectionAwareSqlQuery(value = "SELECT count(*) FROM user_entity WHERE email = :email", connectionType = MYSQL) @ConnectionAwareSqlQuery(value = "SELECT count(*) FROM user_entity WHERE email = :email", connectionType = POSTGRES) int checkEmailExists(@Bind("email") String email); + + @SqlQuery("SELECT json FROM user_entity WHERE email = :email") + String findUserByEmail(@Bind("email") String email); } interface ChangeEventDAO { 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 33e0348ba1a..ce9916c5220 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 @@ -49,6 +49,7 @@ import org.openmetadata.schema.utils.EntityInterfaceUtil; import org.openmetadata.service.Entity; import org.openmetadata.service.OpenMetadataApplicationConfig; import org.openmetadata.service.exception.CatalogExceptionMessage; +import org.openmetadata.service.exception.EntityNotFoundException; import org.openmetadata.service.jdbi3.CollectionDAO.EntityRelationshipRecord; import org.openmetadata.service.resources.teams.UserResource; import org.openmetadata.service.secrets.SecretsManager; @@ -87,6 +88,14 @@ public class UserRepository extends EntityRepository { return super.getByName(uriInfo, EntityInterfaceUtil.quoteName(name), fields); } + public User getByEmail(UriInfo uriInfo, String email, Fields fields) throws IOException { + String userString = ((CollectionDAO.UserDAO) dao).findUserByEmail(email); + if (userString == null) { + throw EntityNotFoundException.byMessage(CatalogExceptionMessage.entityNotFound(USER, email)); + } + return withHref(uriInfo, setFieldsInternal(JsonUtils.readValue(userString, User.class), fields)); + } + /** Ensures that the default roles are added for POST, PUT and PATCH operations. */ @Override public void prepare(User user) throws IOException { 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 903d4780846..02d7726b5bb 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 @@ -31,9 +31,10 @@ public interface AuthenticatorHandler { void checkIfLoginBlocked(String userName); - void recordFailedLoginAttempt(User user) throws TemplateException, IOException; + void recordFailedLoginAttempt(String providedIdentity, User user) throws TemplateException, IOException; - void validatePassword(User storedUser, String reqPassword) throws TemplateException, IOException; + void validatePassword(String providedIdentity, User storedUser, String reqPassword) + throws TemplateException, IOException; User lookUserInProvider(String userName); 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 02e9547f405..d4850caf6a8 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 @@ -422,11 +422,10 @@ public class BasicAuthenticator implements AuthenticatorHandler { @Override public JwtResponse loginUser(LoginRequest loginRequest) throws IOException, TemplateException { - String userName = - loginRequest.getEmail().contains("@") ? loginRequest.getEmail().split("@")[0] : loginRequest.getEmail(); + String userName = loginRequest.getEmail(); checkIfLoginBlocked(userName); User storedUser = lookUserInProvider(userName); - validatePassword(storedUser, loginRequest.getPassword()); + validatePassword(userName, storedUser, loginRequest.getPassword()); return getJwtResponse(storedUser, loginConfiguration.getJwtTokenExpiryTime()); } @@ -438,9 +437,9 @@ public class BasicAuthenticator implements AuthenticatorHandler { } @Override - public void recordFailedLoginAttempt(User storedUser) throws TemplateException, IOException { - loginAttemptCache.recordFailedLogin(storedUser.getName()); - int failedLoginAttempt = loginAttemptCache.getUserFailedLoginCount(storedUser.getName()); + public void recordFailedLoginAttempt(String providedIdentity, User storedUser) throws TemplateException, IOException { + loginAttemptCache.recordFailedLogin(providedIdentity); + int failedLoginAttempt = loginAttemptCache.getUserFailedLoginCount(providedIdentity); if (failedLoginAttempt == loginConfiguration.getMaxLoginFailAttempts()) { EmailUtil.getInstance() .sendAccountStatus( @@ -452,7 +451,8 @@ public class BasicAuthenticator implements AuthenticatorHandler { } } - public void validatePassword(User storedUser, String reqPassword) throws TemplateException, IOException { + public void validatePassword(String providedIdentity, User storedUser, String reqPassword) + 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) { @@ -464,18 +464,26 @@ public class BasicAuthenticator implements AuthenticatorHandler { String storedHashPassword = storedData.get("password"); if (!BCrypt.verifyer().verify(reqPassword.toCharArray(), storedHashPassword).verified) { // record Failed Login Attempts - recordFailedLoginAttempt(storedUser); + recordFailedLoginAttempt(providedIdentity, storedUser); throw new AuthenticationException(INVALID_USERNAME_PASSWORD); } } @Override public User lookUserInProvider(String userName) { - User storedUser; + User storedUser = null; try { - storedUser = - userRepository.getByName( - null, userName, new EntityUtil.Fields(List.of(USER_PROTECTED_FIELDS), USER_PROTECTED_FIELDS)); + if (userName.contains("@")) { + // lookup by User Email + storedUser = + userRepository.getByEmail( + null, userName, new EntityUtil.Fields(List.of(USER_PROTECTED_FIELDS), USER_PROTECTED_FIELDS)); + } else { + storedUser = + userRepository.getByName( + null, userName, new EntityUtil.Fields(List.of(USER_PROTECTED_FIELDS), USER_PROTECTED_FIELDS)); + } + if (storedUser != null && Boolean.TRUE.equals(storedUser.getIsBot())) { throw new CustomExceptionMessage(BAD_REQUEST, INVALID_USERNAME_PASSWORD); } 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 6761cec107a..2928d66b5d3 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 @@ -116,7 +116,7 @@ public class LdapAuthenticator implements AuthenticatorHandler { public JwtResponse loginUser(LoginRequest loginRequest) throws IOException, TemplateException { checkIfLoginBlocked(loginRequest.getEmail()); User storedUser = lookUserInProvider(loginRequest.getEmail()); - validatePassword(storedUser, loginRequest.getPassword()); + validatePassword(loginRequest.getEmail(), storedUser, loginRequest.getPassword()); User omUser = checkAndCreateUser(loginRequest.getEmail()); return getJwtResponse(omUser, loginConfiguration.getJwtTokenExpiryTime()); } @@ -139,9 +139,9 @@ public class LdapAuthenticator implements AuthenticatorHandler { } @Override - public void recordFailedLoginAttempt(User storedUser) throws TemplateException, IOException { - loginAttemptCache.recordFailedLogin(storedUser.getName()); - int failedLoginAttempt = loginAttemptCache.getUserFailedLoginCount(storedUser.getName()); + public void recordFailedLoginAttempt(String providedIdentity, User storedUser) throws TemplateException, IOException { + loginAttemptCache.recordFailedLogin(providedIdentity); + int failedLoginAttempt = loginAttemptCache.getUserFailedLoginCount(providedIdentity); if (failedLoginAttempt == loginConfiguration.getMaxLoginFailAttempts()) { EmailUtil.getInstance() .sendAccountStatus( @@ -154,7 +154,8 @@ public class LdapAuthenticator implements AuthenticatorHandler { } @Override - public void validatePassword(User storedUser, String reqPassword) throws TemplateException, IOException { + public void validatePassword(String providedIdentity, User storedUser, String reqPassword) + throws TemplateException, IOException { // performed in LDAP , the storedUser's name set as DN of the User in Ldap BindResult bindingResult = null; try { @@ -165,7 +166,7 @@ public class LdapAuthenticator implements AuthenticatorHandler { } catch (Exception ex) { if (bindingResult != null && Objects.equals(bindingResult.getResultCode().getName(), ResultCode.INVALID_CREDENTIALS.getName())) { - recordFailedLoginAttempt(storedUser); + recordFailedLoginAttempt(providedIdentity, storedUser); throw new CustomExceptionMessage(UNAUTHORIZED, INVALID_EMAIL_PASSWORD); } } 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 f772e8e0737..7f26560e2cc 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 @@ -27,12 +27,12 @@ public class NoopAuthenticator implements AuthenticatorHandler { } @Override - public void recordFailedLoginAttempt(User user) { + public void recordFailedLoginAttempt(String providedIdentity, User user) { throw new CustomExceptionMessage(Response.Status.FORBIDDEN, FORBIDDEN_AUTHENTICATOR_OP); } @Override - public void validatePassword(User storedUser, String reqPassword) { + public void validatePassword(String providedIdentity, User storedUser, String reqPassword) { throw new CustomExceptionMessage(Response.Status.FORBIDDEN, FORBIDDEN_AUTHENTICATOR_OP); }