AMBARI-7463. Admin Views: Changing password for a user does not work. (jaimin)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/b749dd53 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/b749dd53 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/b749dd53 Branch: refs/heads/branch-alerts-dev Commit: b749dd538b8f41c7ff2df8e40d93286f25032349 Parents: 4dec652 Author: Jaimin Jetly <[email protected]> Authored: Tue Sep 23 15:49:43 2014 -0700 Committer: Jaimin Jetly <[email protected]> Committed: Tue Sep 23 15:49:43 2014 -0700 ---------------------------------------------------------------------- .../ambari/server/orm/dao/PermissionDAO.java | 25 ++++- .../server/security/authorization/Users.java | 24 +++- .../security/authorization/TestUsers.java | 112 ++++++++++++++++--- 3 files changed, 135 insertions(+), 26 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/b749dd53/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/PermissionDAO.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/PermissionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/PermissionDAO.java index faa6b8c..97af522 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/PermissionDAO.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/PermissionDAO.java @@ -18,15 +18,18 @@ package org.apache.ambari.server.orm.dao; -import com.google.inject.Inject; -import com.google.inject.Provider; -import com.google.inject.Singleton; -import org.apache.ambari.server.orm.entities.PermissionEntity; -import org.apache.ambari.server.orm.entities.ResourceTypeEntity; +import java.util.List; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; -import java.util.List; + +import org.apache.ambari.server.orm.entities.PermissionEntity; +import org.apache.ambari.server.orm.entities.ResourceTypeEntity; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.google.inject.Singleton; +import com.google.inject.persist.Transactional; /** * Permission Data Access Object. @@ -44,6 +47,16 @@ public class PermissionDAO { DaoUtils daoUtils; /** + * Create permission. + * + * @param PermissionEntity entity to store + */ + @Transactional + public void create(PermissionEntity permissionEntity) { + entityManagerProvider.get().persist(permissionEntity); + } + + /** * Find a permission entity with the given id. * * @param id type id http://git-wip-us.apache.org/repos/asf/ambari/blob/b749dd53/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java index fd2f77b..26daa1b 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java @@ -46,6 +46,7 @@ import org.apache.ambari.server.orm.entities.PrivilegeEntity; import org.apache.ambari.server.orm.entities.UserEntity; import org.apache.ambari.server.security.ldap.LdapBatchDto; import org.apache.ambari.server.security.ldap.LdapUserGroupMemberDto; +import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.authentication.BadCredentialsException; @@ -152,28 +153,41 @@ public class Users { UserEntity currentUserEntity = userDAO.findLocalUserByName(currentUserName); - //Authenticate LDAP admin user - boolean isLdapAdmin = false; + //Authenticate LDAP user + boolean isLdapUser = false; if (currentUserEntity == null) { currentUserEntity = userDAO.findLdapUserByName(currentUserName); try { ldapAuthenticationProvider.authenticate( new UsernamePasswordAuthenticationToken(currentUserName, currentUserPassword)); - isLdapAdmin = true; + isLdapUser = true; } catch (BadCredentialsException ex) { throw new AmbariException("Incorrect password provided for LDAP user " + currentUserName); } } + boolean isCurrentUserAdmin = false; + for (PrivilegeEntity privilegeEntity: currentUserEntity.getPrincipal().getPrivileges()) { + if (privilegeEntity.getPermission().getPermissionName().equals(PermissionEntity.AMBARI_ADMIN_PERMISSION_NAME)) { + isCurrentUserAdmin = true; + break; + } + } + UserEntity userEntity = userDAO.findLocalUserByName(userName); if ((userEntity != null) && (currentUserEntity != null)) { - if (isLdapAdmin || passwordEncoder.matches(currentUserPassword, currentUserEntity.getUserPassword())) { + if (!isCurrentUserAdmin && !userName.equals(currentUserName)) { + throw new AmbariException("You can't change password of another user"); + } + + if ((isLdapUser && isCurrentUserAdmin) || (StringUtils.isNotEmpty(currentUserPassword) && + passwordEncoder.matches(currentUserPassword, currentUserEntity.getUserPassword()))) { userEntity.setUserPassword(passwordEncoder.encode(newPassword)); userDAO.merge(userEntity); } else { - throw new AmbariException("Wrong password provided"); + throw new AmbariException("Wrong current password provided"); } } else { http://git-wip-us.apache.org/repos/asf/ambari/blob/b749dd53/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/TestUsers.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/TestUsers.java b/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/TestUsers.java index d1e9a97..5487db8 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/TestUsers.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/TestUsers.java @@ -18,26 +18,31 @@ package org.apache.ambari.server.security.authorization; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import java.util.List; import java.util.Properties; +import junit.framework.Assert; + import org.apache.ambari.server.AmbariException; -import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.orm.GuiceJpaInitializer; import org.apache.ambari.server.orm.InMemoryDefaultTestModule; import org.apache.ambari.server.orm.dao.GroupDAO; import org.apache.ambari.server.orm.dao.MemberDAO; +import org.apache.ambari.server.orm.dao.PermissionDAO; import org.apache.ambari.server.orm.dao.PrincipalDAO; import org.apache.ambari.server.orm.dao.PrincipalTypeDAO; +import org.apache.ambari.server.orm.dao.ResourceDAO; +import org.apache.ambari.server.orm.dao.ResourceTypeDAO; import org.apache.ambari.server.orm.dao.UserDAO; +import org.apache.ambari.server.orm.entities.PermissionEntity; import org.apache.ambari.server.orm.entities.PrincipalEntity; import org.apache.ambari.server.orm.entities.PrincipalTypeEntity; +import org.apache.ambari.server.orm.entities.ResourceEntity; +import org.apache.ambari.server.orm.entities.ResourceTypeEntity; import org.apache.ambari.server.orm.entities.UserEntity; import org.junit.After; import org.junit.Before; @@ -64,6 +69,12 @@ public class TestUsers { @Inject protected MemberDAO memberDAO; @Inject + protected PermissionDAO permissionDAO; + @Inject + protected ResourceDAO resourceDAO; + @Inject + protected ResourceTypeDAO resourceTypeDAO; + @Inject protected PrincipalTypeDAO principalTypeDAO; @Inject protected PrincipalDAO principalDAO; @@ -89,6 +100,9 @@ public class TestUsers { @Test public void testGetAllUsers() throws Exception { + Authentication auth = new UsernamePasswordAuthenticationToken("user", null); + SecurityContextHolder.getContext().setAuthentication(auth); + users.createUser("user", "user"); users.createUser("admin", "admin"); @@ -105,7 +119,7 @@ public class TestUsers { UserEntity userEntity = userDAO.findLocalUserByName("user"); assertNotNull("user", userEntity.getUserPassword()); - users.modifyPassword("user", "admin", "resu"); + users.modifyPassword("user", "user", "resu"); assertNotSame(userEntity.getUserPassword(), userDAO.findLocalUserByName("user").getUserPassword()); } @@ -191,23 +205,91 @@ public class TestUsers { assertEquals(users.getGroupMembers("unexisting"), null); } - @Test(expected = AmbariException.class) - public void testModifyPassword() throws Exception { - users.createUser("user", "user"); + @Test + public void testModifyPassword_UserByHimselfPasswordOk() throws Exception { + Authentication auth = new UsernamePasswordAuthenticationToken("user", null); + SecurityContextHolder.getContext().setAuthentication(auth); - UserEntity userEntity = userDAO.findLocalUserByName("user"); + users.createUser("user", "user"); - assertNotSame("user", userEntity.getUserPassword()); - assertTrue(passwordEncoder.matches("user", userEntity.getUserPassword())); + UserEntity userEntity = userDAO.findLocalUserByName("user"); - users.modifyPassword("user", "admin", "user_new_password"); + assertNotSame("user", userEntity.getUserPassword()); + assertTrue(passwordEncoder.matches("user", userEntity.getUserPassword())); - assertTrue("user_new_password".equals(userDAO.findLocalUserByName("user").getUserPassword())); + users.modifyPassword("user", "user", "user_new_password"); - users.modifyPassword("user", "error", "new"); + assertTrue(passwordEncoder.matches("user_new_password", userDAO.findLocalUserByName("user").getUserPassword())); + } - fail("Exception was not thrown"); - } + @Test + public void testModifyPassword_UserByHimselfPasswordNotOk() throws Exception { + Authentication auth = new UsernamePasswordAuthenticationToken("user", null); + SecurityContextHolder.getContext().setAuthentication(auth); + + users.createUser("user", "user"); + + UserEntity userEntity = userDAO.findLocalUserByName("user"); + + assertNotSame("user", userEntity.getUserPassword()); + assertTrue(passwordEncoder.matches("user", userEntity.getUserPassword())); + + try { + users.modifyPassword("user", "admin", "user_new_password"); + Assert.fail("Exception should be thrown here as password is incorrect"); + } catch (AmbariException ex) { + } + } + + @Test + public void testModifyPassword_UserByNonAdmin() throws Exception { + Authentication auth = new UsernamePasswordAuthenticationToken("user2", null); + SecurityContextHolder.getContext().setAuthentication(auth); + + users.createUser("user", "user"); + users.createUser("user2", "user2"); + + UserEntity userEntity = userDAO.findLocalUserByName("user"); + + assertNotSame("user", userEntity.getUserPassword()); + assertTrue(passwordEncoder.matches("user", userEntity.getUserPassword())); + + try { + users.modifyPassword("user", "user2", "user_new_password"); + Assert.fail("Exception should be thrown here as user2 can't change password of user"); + } catch (AmbariException ex) { + } + } + + @Test + public void testModifyPassword_UserByAdmin() throws Exception { + ResourceTypeEntity resourceTypeEntity = new ResourceTypeEntity(); + resourceTypeEntity.setId(ResourceTypeEntity.AMBARI_RESOURCE_TYPE); + resourceTypeEntity.setName(ResourceTypeEntity.AMBARI_RESOURCE_TYPE_NAME); + resourceTypeDAO.create(resourceTypeEntity); + + ResourceEntity resourceEntity = new ResourceEntity(); + resourceEntity.setId(ResourceEntity.AMBARI_RESOURCE_ID); + resourceEntity.setResourceType(resourceTypeEntity); + resourceDAO.create(resourceEntity); + + PermissionEntity adminPermissionEntity = new PermissionEntity(); + adminPermissionEntity.setId(PermissionEntity.AMBARI_ADMIN_PERMISSION); + adminPermissionEntity.setPermissionName(PermissionEntity.AMBARI_ADMIN_PERMISSION_NAME); + adminPermissionEntity.setResourceType(resourceTypeEntity); + permissionDAO.create(adminPermissionEntity); + + users.createUser("admin", "admin", true, true, false); + users.createUser("user", "user"); + + UserEntity userEntity = userDAO.findLocalUserByName("user"); + + assertNotSame("user", userEntity.getUserPassword()); + assertTrue(passwordEncoder.matches("user", userEntity.getUserPassword())); + + users.modifyPassword("user", "admin", "user_new_password"); + assertTrue(passwordEncoder.matches("user_new_password", userDAO.findLocalUserByName("user").getUserPassword())); + } private void createLdapUser() {
