Repository: ambari Updated Branches: refs/heads/branch-feature-AMBARI-20859 903cd1a06 -> 317905e40
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserResourceProviderTest.java index 4530d40..aaddda2 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserResourceProviderTest.java @@ -18,14 +18,21 @@ package org.apache.ambari.server.controller.internal; +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.getCurrentArguments; +import static org.easymock.EasyMock.newCapture; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Calendar; import java.util.Collections; +import java.util.Date; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; -import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -41,27 +48,46 @@ import org.apache.ambari.server.actionmanager.StageFactory; import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.controller.AbstractRootServiceResponseFactory; import org.apache.ambari.server.controller.AmbariManagementController; -import org.apache.ambari.server.controller.AmbariManagementControllerImpl; import org.apache.ambari.server.controller.KerberosHelper; +import org.apache.ambari.server.controller.ResourceProviderFactory; +import org.apache.ambari.server.controller.predicate.AndPredicate; +import org.apache.ambari.server.controller.predicate.EqualsPredicate; import org.apache.ambari.server.controller.spi.Predicate; import org.apache.ambari.server.controller.spi.Request; +import org.apache.ambari.server.controller.spi.RequestStatus; import org.apache.ambari.server.controller.spi.Resource; import org.apache.ambari.server.controller.spi.ResourceProvider; import org.apache.ambari.server.controller.utilities.PredicateBuilder; import org.apache.ambari.server.controller.utilities.PropertyHelper; +import org.apache.ambari.server.events.publishers.AmbariEventPublisher; +import org.apache.ambari.server.hooks.HookContext; import org.apache.ambari.server.hooks.HookContextFactory; import org.apache.ambari.server.hooks.HookService; import org.apache.ambari.server.metadata.CachedRoleCommandOrderProvider; import org.apache.ambari.server.metadata.RoleCommandOrderProvider; import org.apache.ambari.server.orm.DBAccessor; +import org.apache.ambari.server.orm.dao.GroupDAO; import org.apache.ambari.server.orm.dao.HostRoleCommandDAO; +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.PrivilegeDAO; +import org.apache.ambari.server.orm.dao.ResourceDAO; +import org.apache.ambari.server.orm.dao.UserAuthenticationDAO; +import org.apache.ambari.server.orm.dao.UserDAO; import org.apache.ambari.server.orm.entities.MemberEntity; +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.PrivilegeEntity; +import org.apache.ambari.server.orm.entities.ResourceEntity; import org.apache.ambari.server.orm.entities.UserAuthenticationEntity; import org.apache.ambari.server.orm.entities.UserEntity; import org.apache.ambari.server.scheduler.ExecutionScheduler; import org.apache.ambari.server.security.TestAuthenticationFactory; import org.apache.ambari.server.security.authorization.AuthorizationException; -import org.apache.ambari.server.security.authorization.Users; +import org.apache.ambari.server.security.authorization.UserAuthenticationType; import org.apache.ambari.server.security.encryption.CredentialStoreService; import org.apache.ambari.server.security.encryption.CredentialStoreServiceImpl; import org.apache.ambari.server.stack.StackManagerFactory; @@ -75,7 +101,12 @@ import org.apache.ambari.server.state.UpgradeContextFactory; import org.apache.ambari.server.state.configgroup.ConfigGroupFactory; import org.apache.ambari.server.state.scheduler.RequestExecutionFactory; import org.apache.ambari.server.state.stack.OsFamily; +import org.apache.ambari.server.view.ViewRegistry; +import org.apache.commons.lang.StringUtils; +import org.easymock.Capture; +import org.easymock.CaptureType; import org.easymock.EasyMockSupport; +import org.easymock.IAnswer; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -87,6 +118,7 @@ import org.springframework.security.crypto.password.PasswordEncoder; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; +import com.google.inject.Provider; import com.google.inject.assistedinject.FactoryModuleBuilder; /** @@ -94,6 +126,8 @@ import com.google.inject.assistedinject.FactoryModuleBuilder; */ public class UserResourceProviderTest extends EasyMockSupport { + private static final Date CREATE_TIME = Calendar.getInstance().getTime(); + @Before public void resetMocks() { resetAll(); @@ -106,107 +140,226 @@ public class UserResourceProviderTest extends EasyMockSupport { @Test public void testCreateResources_Administrator() throws Exception { - createResourcesTest(TestAuthenticationFactory.createAdministrator("admin")); + Map<String, Object> resource = new HashMap<>(); + resource.put(UserResourceProvider.USER_USERNAME_PROPERTY_ID, "User100"); + resource.put(UserResourceProvider.USER_LOCAL_USERNAME_PROPERTY_ID, "user100"); + resource.put(UserResourceProvider.USER_DISPLAY_NAME_PROPERTY_ID, "User 100"); + + createResourcesTest(TestAuthenticationFactory.createAdministrator(), Collections.singleton(resource)); } @Test(expected = AuthorizationException.class) public void testCreateResources_NonAdministrator() throws Exception { - createResourcesTest(TestAuthenticationFactory.createClusterAdministrator("User1", 2L)); + Map<String, Object> resource = new HashMap<>(); + resource.put(UserResourceProvider.USER_USERNAME_PROPERTY_ID, "User100"); + resource.put(UserResourceProvider.USER_LOCAL_USERNAME_PROPERTY_ID, "user100"); + resource.put(UserResourceProvider.USER_DISPLAY_NAME_PROPERTY_ID, "User 100"); + + createResourcesTest(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), Collections.singleton(resource)); + } + + @Test + public void testCreateResources_Multiple() throws Exception { + Map<String, Object> resource1 = new HashMap<>(); + resource1.put(UserResourceProvider.USER_USERNAME_PROPERTY_ID, "User100"); + Map<String, Object> resource2 = new HashMap<>(); + resource2.put(UserResourceProvider.USER_USERNAME_PROPERTY_ID, "User200"); + + HashSet<Map<String, Object>> resourceProperties = new HashSet<>(); + resourceProperties.add(resource1); + resourceProperties.add(resource2); + + createResourcesTest(TestAuthenticationFactory.createAdministrator("admin"), resourceProperties); + } + + /** + * Test setting a user's local password when creating the account. This is for backward compatibility + * to maintain the REST API V1 contract. + */ + @Test + public void testCreateResources_SetPassword() throws Exception { + Map<String, Object> resource = new HashMap<>(); + resource.put(UserResourceProvider.USER_USERNAME_PROPERTY_ID, "User100"); + resource.put(UserResourceProvider.USER_PASSWORD_PROPERTY_ID, "password100"); + + createResourcesTest(TestAuthenticationFactory.createAdministrator("admin"), Collections.singleton(resource)); + } + + /** + * Test give a user Ambari administrative rights by assigning the user to the AMBARI.ADMINISTRATOR role + * when creating the account. This is for backward compatibility to maintain the REST API V1 contract. + */ + @Test + public void testCreateResources_SetAdmin() throws Exception { + Map<String, Object> resource = new HashMap<>(); + resource.put(UserResourceProvider.USER_USERNAME_PROPERTY_ID, "User100"); + resource.put(UserResourceProvider.USER_ADMIN_PROPERTY_ID, true); + + createResourcesTest(TestAuthenticationFactory.createAdministrator("admin"), Collections.singleton(resource)); + } + + @Test + public void testCreateResources_SetInactive() throws Exception { + Map<String, Object> resource = new HashMap<>(); + resource.put(UserResourceProvider.USER_USERNAME_PROPERTY_ID, "User100"); + resource.put(UserResourceProvider.USER_ACTIVE_PROPERTY_ID, false); + + createResourcesTest(TestAuthenticationFactory.createAdministrator("admin"), Collections.singleton(resource)); } @Test public void testGetResources_Administrator() throws Exception { - getResourcesTest(TestAuthenticationFactory.createAdministrator("admin")); + getResourcesTest(TestAuthenticationFactory.createAdministrator("admin"), null); } @Test public void testGetResources_NonAdministrator() throws Exception { - getResourcesTest(TestAuthenticationFactory.createClusterAdministrator("User1", 2L)); + getResourcesTest(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), null); } @Test public void testGetResource_Administrator_Self() throws Exception { - getResourceTest(TestAuthenticationFactory.createAdministrator("admin"), "admin"); + getResourcesTest(TestAuthenticationFactory.createAdministrator("admin"), "admin"); } @Test public void testGetResource_Administrator_Other() throws Exception { - getResourceTest(TestAuthenticationFactory.createAdministrator("admin"), "User1"); + getResourcesTest(TestAuthenticationFactory.createAdministrator("admin"), "User1"); } @Test public void testGetResource_NonAdministrator_Self() throws Exception { - getResourceTest(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User1"); + getResourcesTest(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User1"); } @Test(expected = AuthorizationException.class) public void testGetResource_NonAdministrator_Other() throws Exception { - getResourceTest(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User100"); + getResourcesTest(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User100"); } @Test - public void testUpdateResources_SetAdmin_Administrator_Self() throws Exception { - updateResources_SetAdmin(TestAuthenticationFactory.createAdministrator("admin"), "User100"); + public void testUpdateResources_UpdateAdmin_Administrator_Self() throws Exception { + testUpdateResources_UpdateAdmin(TestAuthenticationFactory.createAdministrator("admin"), "admin"); } @Test - public void testUpdateResources_SetAdmin_Administrator_Other() throws Exception { - updateResources_SetAdmin(TestAuthenticationFactory.createAdministrator("admin"), "User100"); + public void testUpdateResources_UpdateAdmin_Administrator_Other() throws Exception { + testUpdateResources_UpdateAdmin(TestAuthenticationFactory.createAdministrator("admin"), "User100"); } @Test(expected = AuthorizationException.class) - public void testUpdateResources_SetAdmin_NonAdministrator_Self() throws Exception { - updateResources_SetAdmin(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User1"); + public void testUpdateResources_UpdateAdmin_NonAdministrator_Self() throws Exception { + testUpdateResources_UpdateAdmin(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User1"); } @Test(expected = AuthorizationException.class) - public void testUpdateResources_SetAdmin_NonAdministrator_Other() throws Exception { - updateResources_SetAdmin(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User100"); + public void testUpdateResources_UpdateAdmin_NonAdministrator_Other() throws Exception { + testUpdateResources_UpdateAdmin(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User100"); } @Test - public void testUpdateResources_SetActive_Administrator_Self() throws Exception { - updateResources_SetActive(TestAuthenticationFactory.createAdministrator("admin"), "User100"); + public void testUpdateResources_UpdateActive_Administrator_Self() throws Exception { + testUpdateResources_UpdateActive(TestAuthenticationFactory.createAdministrator("admin"), "admin"); } @Test - public void testUpdateResources_SetActive_Administrator_Other() throws Exception { - updateResources_SetActive(TestAuthenticationFactory.createAdministrator("admin"), "User100"); + public void testUpdateResources_UpdateActive_Administrator_Other() throws Exception { + testUpdateResources_UpdateActive(TestAuthenticationFactory.createAdministrator("admin"), "User100"); } @Test(expected = AuthorizationException.class) - public void testUpdateResources_SetActive_NonAdministrator_Self() throws Exception { - updateResources_SetActive(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User1"); + public void testUpdateResources_UpdateActive_NonAdministrator_Self() throws Exception { + testUpdateResources_UpdateActive(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User1"); } @Test(expected = AuthorizationException.class) - public void testUpdateResources_SetActive_NonAdministrator_Other() throws Exception { - updateResources_SetActive(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User100"); + public void testUpdateResources_UpdateActive_NonAdministrator_Other() throws Exception { + testUpdateResources_UpdateActive(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User100"); } @Test - public void testUpdateResources_SetPassword_Administrator_Self() throws Exception { - updateResources_SetPassword(TestAuthenticationFactory.createAdministrator("admin"), "User100"); + public void testUpdateResources_UpdateDisplayName_Administrator_Self() throws Exception { + testUpdateResources_UpdateDisplayName(TestAuthenticationFactory.createAdministrator("admin"), "admin"); } @Test - public void testUpdateResources_SetPassword_Administrator_Other() throws Exception { - updateResources_SetPassword(TestAuthenticationFactory.createAdministrator("admin"), "User100"); + public void testUpdateResources_UpdateDisplayName_Administrator_Other() throws Exception { + testUpdateResources_UpdateDisplayName(TestAuthenticationFactory.createAdministrator("admin"), "User100"); } @Test - public void testUpdateResources_SetPassword_NonAdministrator_Self() throws Exception { - updateResources_SetPassword(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User1"); + public void testUpdateResources_UpdateDisplayName_NonAdministrator_Self() throws Exception { + testUpdateResources_UpdateDisplayName(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User1"); } @Test(expected = AuthorizationException.class) - public void testUpdateResources_SetPassword_NonAdministrator_Other() throws Exception { - updateResources_SetPassword(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User100"); + public void testUpdateResources_UpdateDisplayName_NonAdministrator_Other() throws Exception { + testUpdateResources_UpdateDisplayName(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User100"); + } + + @Test + public void testUpdateResources_UpdateLocalUserName_Administrator_Self() throws Exception { + testUpdateResources_UpdateLocalUserName(TestAuthenticationFactory.createAdministrator("admin"), "admin"); + } + + @Test + public void testUpdateResources_UpdateLocalUserName_Administrator_Other() throws Exception { + testUpdateResources_UpdateLocalUserName(TestAuthenticationFactory.createAdministrator("admin"), "User100"); + } + + @Test(expected = AuthorizationException.class) + public void testUpdateResources_UpdateLocalUserName_NonAdministrator_Self() throws Exception { + testUpdateResources_UpdateLocalUserName(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User1"); + } + + @Test(expected = AuthorizationException.class) + public void testUpdateResources_UpdateLocalUserName_NonAdministrator_Other() throws Exception { + testUpdateResources_UpdateLocalUserName(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User100"); + } + + @Test + public void testUpdateResources_UpdatePassword_Administrator_Self() throws Exception { + testUpdateResources_UpdatePassword(TestAuthenticationFactory.createAdministrator("admin"), "admin"); + } + + @Test + public void testUpdateResources_UpdatePassword_Administrator_Other() throws Exception { + testUpdateResources_UpdatePassword(TestAuthenticationFactory.createAdministrator("admin"), "User100"); + } + + @Test + public void testUpdateResources_UpdatePassword_NonAdministrator_Self() throws Exception { + testUpdateResources_UpdatePassword(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User1"); + } + + @Test(expected = AuthorizationException.class) + public void testUpdateResources_UpdatePassword_NonAdministrator_Other() throws Exception { + testUpdateResources_UpdatePassword(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User100"); + } + + @Test + public void testUpdateResources_CreatePassword_Administrator_Self() throws Exception { + testUpdateResources_CreatePassword(TestAuthenticationFactory.createAdministrator("admin"), "admin"); + } + + @Test + public void testUpdateResources_CreatePassword_Administrator_Other() throws Exception { + testUpdateResources_CreatePassword(TestAuthenticationFactory.createAdministrator("admin"), "User100"); + } + + @Test(expected = AuthorizationException.class) + public void testUpdateResources_CreatePassword_NonAdministrator_Self() throws Exception { + testUpdateResources_CreatePassword(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User1"); + } + + @Test(expected = AuthorizationException.class) + public void testUpdateResources_CreatePassword_NonAdministrator_Other() throws Exception { + testUpdateResources_CreatePassword(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User100"); } @Test public void testDeleteResource_Administrator_Self() throws Exception { - deleteResourcesTest(TestAuthenticationFactory.createAdministrator("admin"), "User100"); + deleteResourcesTest(TestAuthenticationFactory.createAdministrator("admin"), "admin"); } @Test @@ -227,60 +380,142 @@ public class UserResourceProviderTest extends EasyMockSupport { private Injector createInjector() throws Exception { return Guice.createInjector(new AbstractModule() { @Override + protected <T> Provider<T> getProvider(Class<T> type) { + return super.getProvider(type); + } + + @Override protected void configure() { install(new FactoryModuleBuilder().build(UpgradeContextFactory.class)); install(new FactoryModuleBuilder().build(RoleGraphFactory.class)); - bind(EntityManager.class).toInstance(createNiceMock(EntityManager.class)); - bind(DBAccessor.class).toInstance(createNiceMock(DBAccessor.class)); - bind(ActionDBAccessor.class).toInstance(createNiceMock(ActionDBAccessor.class)); - bind(ExecutionScheduler.class).toInstance(createNiceMock(ExecutionScheduler.class)); - bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class)); + bind(EntityManager.class).toInstance(createMock(EntityManager.class)); + bind(DBAccessor.class).toInstance(createMock(DBAccessor.class)); + bind(ActionDBAccessor.class).toInstance(createMock(ActionDBAccessor.class)); + bind(ExecutionScheduler.class).toInstance(createMock(ExecutionScheduler.class)); + bind(OsFamily.class).toInstance(createMock(OsFamily.class)); bind(AmbariMetaInfo.class).toInstance(createMock(AmbariMetaInfo.class)); - bind(ActionManager.class).toInstance(createNiceMock(ActionManager.class)); - bind(RequestFactory.class).toInstance(createNiceMock(RequestFactory.class)); - bind(RequestExecutionFactory.class).toInstance(createNiceMock(RequestExecutionFactory.class)); - bind(StageFactory.class).toInstance(createNiceMock(StageFactory.class)); - bind(Clusters.class).toInstance(createNiceMock(Clusters.class)); - bind(AbstractRootServiceResponseFactory.class).toInstance(createNiceMock(AbstractRootServiceResponseFactory.class)); - bind(StackManagerFactory.class).toInstance(createNiceMock(StackManagerFactory.class)); - bind(ConfigFactory.class).toInstance(createNiceMock(ConfigFactory.class)); - bind(ConfigGroupFactory.class).toInstance(createNiceMock(ConfigGroupFactory.class)); - bind(ServiceFactory.class).toInstance(createNiceMock(ServiceFactory.class)); - bind(ServiceComponentFactory.class).toInstance(createNiceMock(ServiceComponentFactory.class)); - bind(ServiceComponentHostFactory.class).toInstance(createNiceMock(ServiceComponentHostFactory.class)); - bind(PasswordEncoder.class).toInstance(createNiceMock(PasswordEncoder.class)); - bind(KerberosHelper.class).toInstance(createNiceMock(KerberosHelper.class)); - bind(Users.class).toInstance(createMock(Users.class)); - bind(AmbariManagementController.class).to(AmbariManagementControllerImpl.class); + bind(ActionManager.class).toInstance(createMock(ActionManager.class)); + bind(RequestFactory.class).toInstance(createMock(RequestFactory.class)); + bind(RequestExecutionFactory.class).toInstance(createMock(RequestExecutionFactory.class)); + bind(StageFactory.class).toInstance(createMock(StageFactory.class)); + bind(Clusters.class).toInstance(createMock(Clusters.class)); + bind(AbstractRootServiceResponseFactory.class).toInstance(createMock(AbstractRootServiceResponseFactory.class)); + bind(StackManagerFactory.class).toInstance(createMock(StackManagerFactory.class)); + bind(ConfigFactory.class).toInstance(createMock(ConfigFactory.class)); + bind(ConfigGroupFactory.class).toInstance(createMock(ConfigGroupFactory.class)); + bind(ServiceFactory.class).toInstance(createMock(ServiceFactory.class)); + bind(ServiceComponentFactory.class).toInstance(createMock(ServiceComponentFactory.class)); + bind(ServiceComponentHostFactory.class).toInstance(createMock(ServiceComponentHostFactory.class)); + bind(PasswordEncoder.class).toInstance(createMock(PasswordEncoder.class)); + bind(KerberosHelper.class).toInstance(createMock(KerberosHelper.class)); + bind(AmbariManagementController.class).toInstance(createMock(AmbariManagementController.class)); bind(RoleCommandOrderProvider.class).to(CachedRoleCommandOrderProvider.class); bind(CredentialStoreService.class).to(CredentialStoreServiceImpl.class); bind(HostRoleCommandDAO.class).toInstance(createMock(HostRoleCommandDAO.class)); bind(HookService.class).toInstance(createMock(HookService.class)); bind(HookContextFactory.class).toInstance(createMock(HookContextFactory.class)); bind(HostRoleCommandFactory.class).to(HostRoleCommandFactoryImpl.class); + bind(UserDAO.class).toInstance(createMock(UserDAO.class)); + + bind(UserAuthenticationDAO.class).toInstance(createMock(UserAuthenticationDAO.class)); + bind(GroupDAO.class).toInstance(createMock(GroupDAO.class)); + bind(MemberDAO.class).toInstance(createMock(MemberDAO.class)); + bind(PrincipalDAO.class).toInstance(createMock(PrincipalDAO.class)); + bind(PermissionDAO.class).toInstance(createMock(PermissionDAO.class)); + bind(PrivilegeDAO.class).toInstance(createMock(PrivilegeDAO.class)); + bind(ResourceDAO.class).toInstance(createMock(ResourceDAO.class)); + bind(PrincipalTypeDAO.class).toInstance(createMock(PrincipalTypeDAO.class)); } }); } - private void createResourcesTest(Authentication authentication) throws Exception { + private void createResourcesTest(Authentication authentication, Set<Map<String, Object>> resourceProperties) throws Exception { Injector injector = createInjector(); + UserDAO userDAO = injector.getInstance(UserDAO.class); + Capture<? extends UserEntity> userEntityCapture = newCapture(CaptureType.ALL); + + Map<String, Map<String, Object>> expectedUsers = new HashMap<>(); + + for (Map<String, Object> properties : resourceProperties) { + String username = (String) properties.get(UserResourceProvider.USER_USERNAME_PROPERTY_ID); + + if (!StringUtils.isEmpty(username)) { + Assert.assertFalse("User names must be unique for this test case", expectedUsers.containsKey(username.toLowerCase())); + + expect(userDAO.findUserByName(username)).andReturn(null).times(2); + userDAO.create(capture(userEntityCapture)); + expectLastCall().once(); + + PrincipalTypeEntity principalTypeEntity = createMock(PrincipalTypeEntity.class); + + PrincipalTypeDAO principalTypeDAO = injector.getInstance(PrincipalTypeDAO.class); + expect(principalTypeDAO.findById(PrincipalTypeEntity.USER_PRINCIPAL_TYPE)).andReturn(principalTypeEntity).once(); + + PrincipalDAO principalDAO = injector.getInstance(PrincipalDAO.class); + principalDAO.create(anyObject(PrincipalEntity.class)); + expectLastCall().andAnswer(new IAnswer<Object>() { + @Override + public Object answer() throws Throwable { + Object[] args = getCurrentArguments(); + + ((PrincipalEntity) args[0]).setId(1L); + return null; + } + }).once(); + + + HookContextFactory hookContextFactory = injector.getInstance(HookContextFactory.class); + expect(hookContextFactory.createUserHookContext(username)).andReturn(null).once(); - UserEntity userEntity100 = createNiceMock(UserEntity.class); - UserEntity userEntity200 = createNiceMock(UserEntity.class); + HookService hookService = injector.getInstance(HookService.class); + expect(hookService.execute(anyObject(HookContext.class))).andReturn(true).once(); - Users users = injector.getInstance(Users.class); - expect(users.createUser("User100", "User100", "User100", null)) - .andReturn(userEntity100) - .once(); - expect(users.createUser("user200", "user200", "user200", null)) - .andReturn(userEntity200) - .once(); - users.addLocalAuthentication(userEntity100, "password100"); - users.addLocalAuthentication(userEntity200, "password200"); - expectLastCall().once(); + if (properties.get(UserResourceProvider.USER_PASSWORD_PROPERTY_ID) != null) { + ResourceProviderFactory factory = createMock(ResourceProviderFactory.class); + ResourceProvider resourceProvider = createMock(ResourceProvider.class); + RequestStatus status = createMock(RequestStatus.class); + expect(resourceProvider.createResources(anyObject(Request.class))).andReturn(status).once(); + expect(factory.getUserAuthenticationSourceResourceProvider()).andReturn(resourceProvider).once(); + + AbstractControllerResourceProvider.init(factory); + } + + if (properties.get(UserResourceProvider.USER_ADMIN_PROPERTY_ID) != null) { + Boolean isAdmin = Boolean.TRUE.equals(properties.get(UserResourceProvider.USER_ADMIN_PROPERTY_ID)); + + if (isAdmin) { + PermissionEntity permissionEntity = createMock(PermissionEntity.class); + PermissionDAO permissionDAO = injector.getInstance(PermissionDAO.class); + expect(permissionDAO.findAmbariAdminPermission()).andReturn(permissionEntity).once(); + + ResourceEntity resourceEntity = createMock(ResourceEntity.class); + ResourceDAO resourceDAO = injector.getInstance(ResourceDAO.class); + expect(resourceDAO.findAmbariResource()).andReturn(resourceEntity).once(); + + PrivilegeDAO privilegeDAO = injector.getInstance(PrivilegeDAO.class); + privilegeDAO.create(anyObject(PrivilegeEntity.class)); + expectLastCall().andAnswer(new IAnswer<Object>() { + @Override + public Object answer() throws Throwable { + Object[] args = getCurrentArguments(); + + ((PrivilegeEntity) args[0]).setId(1); + return null; + } + }).once(); + + expect(principalDAO.merge(anyObject(PrincipalEntity.class))).andReturn(null).once(); + + expect(userDAO.merge(anyObject(UserEntity.class))).andReturn(null).once(); + } + } + + expectedUsers.put(username.toLowerCase(), properties); + } + } // replay replayAll(); @@ -292,53 +527,73 @@ public class UserResourceProviderTest extends EasyMockSupport { ResourceProvider provider = getResourceProvider(injector); - // add the property map to a set for the request. add more maps for multiple creates - Set<Map<String, Object>> propertySet = new LinkedHashSet<>(); - - Map<String, Object> properties; - - properties = new LinkedHashMap<>(); - properties.put(UserResourceProvider.USER_USERNAME_PROPERTY_ID, "User100"); - properties.put(UserResourceProvider.USER_PASSWORD_PROPERTY_ID, "password100"); - propertySet.add(properties); - - properties = new LinkedHashMap<>(); - properties.put(UserResourceProvider.USER_USERNAME_PROPERTY_ID, "user200"); - properties.put(UserResourceProvider.USER_PASSWORD_PROPERTY_ID, "password200"); - propertySet.add(properties); - // create the request - Request request = PropertyHelper.getCreateRequest(propertySet, null); + Request request = PropertyHelper.getCreateRequest(resourceProperties, null); provider.createResources(request); // verify verifyAll(); + + List<? extends UserEntity> capturedUserEntities = userEntityCapture.getValues(); + Assert.assertEquals(expectedUsers.size(), capturedUserEntities.size()); + + for (UserEntity userEntity : capturedUserEntities) { + String userName = userEntity.getUserName(); + Map<String, Object> userProperties = expectedUsers.get(userName); + + Assert.assertNotNull(userProperties); + + String username = (String) userProperties.get(UserResourceProvider.USER_USERNAME_PROPERTY_ID); + String displayName = (String) userProperties.get(UserResourceProvider.USER_DISPLAY_NAME_PROPERTY_ID); + String localUsername = (String) userProperties.get(UserResourceProvider.USER_LOCAL_USERNAME_PROPERTY_ID); + Boolean isActive = (userProperties.containsKey(UserResourceProvider.USER_ACTIVE_PROPERTY_ID)) + ? !Boolean.FALSE.equals(userProperties.get(UserResourceProvider.USER_ACTIVE_PROPERTY_ID)) + : Boolean.TRUE; + + Assert.assertEquals(username.toLowerCase(), userEntity.getUserName()); + Assert.assertEquals(StringUtils.defaultIfEmpty(localUsername, username), userEntity.getLocalUsername()); + Assert.assertEquals(StringUtils.defaultIfEmpty(displayName, username), userEntity.getDisplayName()); + Assert.assertEquals(isActive, userEntity.getActive()); + } } - private void getResourcesTest(Authentication authentication) throws Exception { + private void getResourcesTest(Authentication authentication, String requestedUsername) throws Exception { Injector injector = createInjector(); - Users users = injector.getInstance(Users.class); + String username = requestedUsername; + if (username == null) { + if (!"admin".equals(authentication.getName())) { + username = authentication.getName(); + } + } - if ("admin".equals(authentication.getName())) { + UserDAO userDAO = injector.getInstance(UserDAO.class); + + PrincipalEntity userPrincipalEntity = createMock(PrincipalEntity.class); + expect(userPrincipalEntity.getPrivileges()).andReturn(null).anyTimes(); + + if (username == null) { UserEntity userEntity1 = createMockUserEntity("User1"); + expect(userEntity1.getPrincipal()).andReturn(userPrincipalEntity).once(); + UserEntity userEntity10 = createMockUserEntity("User10"); + expect(userEntity10.getPrincipal()).andReturn(userPrincipalEntity).once(); + UserEntity userEntity100 = createMockUserEntity("User100"); + expect(userEntity100.getPrincipal()).andReturn(userPrincipalEntity).once(); + UserEntity userEntityAdmin = createMockUserEntity("admin"); + expect(userEntityAdmin.getPrincipal()).andReturn(userPrincipalEntity).once(); List<UserEntity> allUsers = Arrays.asList(userEntity1, userEntity10, userEntity100, userEntityAdmin); - expect(users.getAllUserEntities()).andReturn(allUsers).once(); - expect(users.hasAdminPrivilege(userEntity1)).andReturn(false).once(); - expect(users.hasAdminPrivilege(userEntity10)).andReturn(false).once(); - expect(users.hasAdminPrivilege(userEntity100)).andReturn(false).once(); - expect(users.hasAdminPrivilege(userEntityAdmin)).andReturn(true).once(); + expect(userDAO.findAll()).andReturn(allUsers).once(); } else { + UserEntity userEntity = createMockUserEntity(username); + expect(userEntity.getPrincipal()).andReturn(userPrincipalEntity).once(); - UserEntity userEntity = createMockUserEntity("User1"); - expect(users.getUserEntity("User1")).andReturn(userEntity).once(); - expect(users.hasAdminPrivilege(userEntity)).andReturn(false).once(); + expect(userDAO.findUserByName(username)).andReturn(userEntity).once(); } replayAll(); @@ -356,9 +611,9 @@ public class UserResourceProviderTest extends EasyMockSupport { Request request = PropertyHelper.getReadRequest(propertyIds); - Set<Resource> resources = provider.getResources(request, null); + Set<Resource> resources = provider.getResources(request, (requestedUsername == null) ? null : createPredicate(requestedUsername)); - if ("admin".equals(authentication.getName())) { + if (username == null) { List<String> expectedList = Arrays.asList("User1", "User10", "User100", "admin"); Assert.assertEquals(4, resources.size()); for (Resource resource : resources) { @@ -368,145 +623,204 @@ public class UserResourceProviderTest extends EasyMockSupport { } else { Assert.assertEquals(1, resources.size()); for (Resource resource : resources) { - Assert.assertEquals("User1", resource.getPropertyValue(UserResourceProvider.USER_USERNAME_PROPERTY_ID)); + Assert.assertEquals(username, resource.getPropertyValue(UserResourceProvider.USER_USERNAME_PROPERTY_ID)); } } verifyAll(); } - private void getResourceTest(Authentication authentication, String requestedUsername) throws Exception { - Injector injector = createInjector(); - - UserEntity userEntity = createMockUserEntity(requestedUsername); - - Users users = injector.getInstance(Users.class); - expect(users.getUserEntity(requestedUsername)).andReturn(userEntity).once(); - expect(users.hasAdminPrivilege(userEntity)).andReturn(false).once(); - - replayAll(); - - AmbariMetaInfo ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class); - ambariMetaInfo.init(); + private void testUpdateResources_UpdateAdmin(Authentication authentication, String requestedUsername) throws Exception { + updateResourcesTest(authentication, requestedUsername, Collections.<String, Object>singletonMap(UserResourceProvider.USER_ADMIN_PROPERTY_ID, true), false); + } - SecurityContextHolder.getContext().setAuthentication(authentication); + private void testUpdateResources_UpdateActive(Authentication authentication, String requestedUsername) throws Exception { + updateResourcesTest(authentication, requestedUsername, Collections.<String, Object>singletonMap(UserResourceProvider.USER_ACTIVE_PROPERTY_ID, false), false); + } - ResourceProvider provider = getResourceProvider(injector); + private void testUpdateResources_UpdateDisplayName(Authentication authentication, String requestedUsername) throws Exception { + updateResourcesTest(authentication, requestedUsername, Collections.<String, Object>singletonMap(UserResourceProvider.USER_DISPLAY_NAME_PROPERTY_ID, "Updated Display Name"), false); + } - Set<String> propertyIds = new HashSet<>(); - propertyIds.add(UserResourceProvider.USER_USERNAME_PROPERTY_ID); - propertyIds.add(UserResourceProvider.USER_PASSWORD_PROPERTY_ID); + private void testUpdateResources_UpdateLocalUserName(Authentication authentication, String requestedUsername) throws Exception { + updateResourcesTest(authentication, requestedUsername, Collections.<String, Object>singletonMap(UserResourceProvider.USER_LOCAL_USERNAME_PROPERTY_ID, "updated_username"), false); + } - Request request = PropertyHelper.getReadRequest(propertyIds); + private void testUpdateResources_UpdatePassword(Authentication authentication, String requestedUsername) throws Exception { + Map<String, Object> properties = new LinkedHashMap<>(); + properties.put(UserResourceProvider.USER_OLD_PASSWORD_PROPERTY_ID, "old_password"); + properties.put(UserResourceProvider.USER_PASSWORD_PROPERTY_ID, "new_password"); - Set<Resource> resources = provider.getResources(request, createPredicate(requestedUsername)); + updateResourcesTest(authentication, requestedUsername, properties, true); + } - Assert.assertEquals(1, resources.size()); - for (Resource resource : resources) { - String userName = (String) resource.getPropertyValue(UserResourceProvider.USER_USERNAME_PROPERTY_ID); - Assert.assertEquals(requestedUsername, userName); - } + private void testUpdateResources_CreatePassword(Authentication authentication, String requestedUsername) throws Exception { + Map<String, Object> properties = new LinkedHashMap<>(); + properties.put(UserResourceProvider.USER_OLD_PASSWORD_PROPERTY_ID, "old_password"); + properties.put(UserResourceProvider.USER_PASSWORD_PROPERTY_ID, "new_password"); - verifyAll(); + updateResourcesTest(authentication, requestedUsername, properties, false); } - private void updateResources_SetAdmin(Authentication authentication, String requestedUsername) throws Exception { + private void updateResourcesTest(Authentication authentication, String requestedUsername, Map<String, Object> updates, boolean passwordAlreadyExists) throws Exception { Injector injector = createInjector(); - UserEntity userEntity = createMockUserEntity(requestedUsername); + Capture<Request> requestCapture = newCapture(CaptureType.FIRST); + Capture<Predicate> predicateCapture = newCapture(CaptureType.FIRST); + boolean hasUpdates = false; - Users users = injector.getInstance(Users.class); - expect(users.getUserEntity(requestedUsername)).andReturn(userEntity).once(); + ResourceProviderFactory factory = createMock(ResourceProviderFactory.class); - if ("admin".equals(authentication.getName())) { - users.grantAdminPrivilege(userEntity); + UserEntity userEntity = createMock(UserEntity.class); + expect(userEntity.getUserName()).andReturn(requestedUsername).anyTimes(); + expect(userEntity.getActive()).andReturn(true).anyTimes(); + expect(userEntity.getDisplayName()).andReturn(requestedUsername).anyTimes(); + expect(userEntity.getLocalUsername()).andReturn(requestedUsername).anyTimes(); + + if (updates.containsKey(UserResourceProvider.USER_DISPLAY_NAME_PROPERTY_ID)) { + userEntity.setDisplayName((String) updates.get(UserResourceProvider.USER_DISPLAY_NAME_PROPERTY_ID)); expectLastCall().once(); + hasUpdates = true; } - replayAll(); - - AmbariMetaInfo ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class); - ambariMetaInfo.init(); - - SecurityContextHolder.getContext().setAuthentication(authentication); - - ResourceProvider provider = getResourceProvider(injector); + if (updates.containsKey(UserResourceProvider.USER_LOCAL_USERNAME_PROPERTY_ID)) { + userEntity.setLocalUsername((String) updates.get(UserResourceProvider.USER_LOCAL_USERNAME_PROPERTY_ID)); + expectLastCall().once(); + hasUpdates = true; + } - // add the property map to a set for the request. - Map<String, Object> properties = new LinkedHashMap<>(); - properties.put(UserResourceProvider.USER_ADMIN_PROPERTY_ID, "true"); + if (updates.containsKey(UserResourceProvider.USER_ACTIVE_PROPERTY_ID)) { + userEntity.setActive((Boolean) updates.get(UserResourceProvider.USER_ACTIVE_PROPERTY_ID)); + expectLastCall().once(); + hasUpdates = true; + } - // create the request - Request request = PropertyHelper.getUpdateRequest(properties, null); + UserDAO userDAO = injector.getInstance(UserDAO.class); + expect(userDAO.findUserByName(requestedUsername)).andReturn(userEntity).once(); - provider.updateResources(request, createPredicate(requestedUsername)); + if (hasUpdates) { + expect(userDAO.merge(userEntity)).andReturn(userEntity).once(); + } - verifyAll(); - } + if (updates.get(UserResourceProvider.USER_ADMIN_PROPERTY_ID) != null) { + Boolean isAdmin = Boolean.TRUE.equals(updates.get(UserResourceProvider.USER_ADMIN_PROPERTY_ID)); - private void updateResources_SetActive(Authentication authentication, String requestedUsername) throws Exception { - Injector injector = createInjector(); + if (isAdmin) { + PermissionEntity permissionEntity = createMock(PermissionEntity.class); + PermissionDAO permissionDAO = injector.getInstance(PermissionDAO.class); + expect(permissionDAO.findAmbariAdminPermission()).andReturn(permissionEntity).once(); - UserEntity userEntity = createMockUserEntity(requestedUsername); + ResourceEntity resourceEntity = createMock(ResourceEntity.class); + ResourceDAO resourceDAO = injector.getInstance(ResourceDAO.class); + expect(resourceDAO.findAmbariResource()).andReturn(resourceEntity).once(); - Users users = injector.getInstance(Users.class); - expect(users.getUserEntity(requestedUsername)).andReturn(userEntity).once(); + PrivilegeDAO privilegeDAO = injector.getInstance(PrivilegeDAO.class); + privilegeDAO.create(anyObject(PrivilegeEntity.class)); + expectLastCall().andAnswer(new IAnswer<Object>() { + @Override + public Object answer() throws Throwable { + Object[] args = getCurrentArguments(); - if ("admin".equals(authentication.getName())) { - users.setUserActive(userEntity, true); - expectLastCall().once(); - } + ((PrivilegeEntity) args[0]).setId(1); + return null; + } + }).once(); - replayAll(); + PrincipalDAO principalDAO = injector.getInstance(PrincipalDAO.class); + expect(principalDAO.merge(anyObject(PrincipalEntity.class))).andReturn(null).once(); - AmbariMetaInfo ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class); - ambariMetaInfo.init(); + PrincipalEntity principalEntity = createMock(PrincipalEntity.class); + expect(principalEntity.getPrivileges()).andReturn(new HashSet<PrivilegeEntity>()).anyTimes(); - SecurityContextHolder.getContext().setAuthentication(authentication); + expect(userEntity.getPrincipal()).andReturn(principalEntity).anyTimes(); - ResourceProvider provider = getResourceProvider(injector); + expect(userDAO.merge(anyObject(UserEntity.class))).andReturn(null).once(); + } + } - // add the property map to a set for the request. - Map<String, Object> properties = new LinkedHashMap<>(); - properties.put(UserResourceProvider.USER_ACTIVE_PROPERTY_ID, "true"); + if (updates.containsKey(UserResourceProvider.USER_PASSWORD_PROPERTY_ID)) { + if(passwordAlreadyExists) { + UserAuthenticationEntity authenticationEntity = createMock(UserAuthenticationEntity.class); + expect(authenticationEntity.getUserAuthenticationId()).andReturn(100L).anyTimes(); + expect(authenticationEntity.getAuthenticationType()).andReturn(UserAuthenticationType.LOCAL).anyTimes(); - Request request = PropertyHelper.getUpdateRequest(properties, null); + expect(userEntity.getAuthenticationEntities()).andReturn(Collections.singletonList(authenticationEntity)).once(); + } + else { + expect(userEntity.getAuthenticationEntities()).andReturn(Collections.<UserAuthenticationEntity>emptyList()).once(); + } - provider.updateResources(request, createPredicate(requestedUsername)); + RequestStatus status = createMock(RequestStatus.class); - verifyAll(); - } + ResourceProvider resourceProvider = createMock(ResourceProvider.class); - private void updateResources_SetPassword(Authentication authentication, String requestedUsername) throws Exception { - Injector injector = createInjector(); + if(passwordAlreadyExists) { + expect(resourceProvider.updateResources(capture(requestCapture), capture(predicateCapture))).andReturn(status).once(); + } + else { + expect(resourceProvider.createResources(capture(requestCapture))).andReturn(status).once(); + } - UserEntity userEntity = createMockUserEntity(requestedUsername); + expect(factory.getUserAuthenticationSourceResourceProvider()).andReturn(resourceProvider).once(); + } - Users users = injector.getInstance(Users.class); - expect(users.getUserEntity(requestedUsername)).andReturn(userEntity).once(); - users.modifyPassword(userEntity, "old_password", "new_password"); - expectLastCall().once(); + AmbariEventPublisher publisher = createNiceMock(AmbariEventPublisher.class); replayAll(); AmbariMetaInfo ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class); ambariMetaInfo.init(); + ViewRegistry.initInstance(new ViewRegistry(publisher)); + AbstractControllerResourceProvider.init(factory); SecurityContextHolder.getContext().setAuthentication(authentication); ResourceProvider provider = getResourceProvider(injector); - // add the property map to a set for the request. - Map<String, Object> properties = new LinkedHashMap<>(); - properties.put(UserResourceProvider.USER_OLD_PASSWORD_PROPERTY_ID, "old_password"); - properties.put(UserResourceProvider.USER_PASSWORD_PROPERTY_ID, "new_password"); - // create the request - Request request = PropertyHelper.getUpdateRequest(properties, null); + Request request = PropertyHelper.getUpdateRequest(updates, null); provider.updateResources(request, createPredicate(requestedUsername)); verifyAll(); + + if (updates.containsKey(UserResourceProvider.USER_PASSWORD_PROPERTY_ID)) { + // Verify that the correct request was issued to update update the user's password... + Request capturedRequest = requestCapture.getValue(); + Set<Map<String, Object>> capturedProperties = capturedRequest.getProperties(); + Map<String, Object> properties = capturedProperties.iterator().next(); + Assert.assertNotNull(capturedProperties); + if(passwordAlreadyExists) { + Assert.assertEquals(updates.get(UserResourceProvider.USER_PASSWORD_PROPERTY_ID), properties.get(UserAuthenticationSourceResourceProvider.AUTHENTICATION_KEY_PROPERTY_ID)); + Assert.assertEquals(updates.get(UserResourceProvider.USER_OLD_PASSWORD_PROPERTY_ID), properties.get(UserAuthenticationSourceResourceProvider.AUTHENTICATION_OLD_KEY_PROPERTY_ID)); + } + else { + Assert.assertEquals(updates.get(UserResourceProvider.USER_PASSWORD_PROPERTY_ID), properties.get(UserAuthenticationSourceResourceProvider.AUTHENTICATION_KEY_PROPERTY_ID)); + Assert.assertEquals(UserAuthenticationType.LOCAL.name(), properties.get(UserAuthenticationSourceResourceProvider.AUTHENTICATION_AUTHENTICATION_TYPE_PROPERTY_ID)); + Assert.assertEquals(requestedUsername, properties.get(UserAuthenticationSourceResourceProvider.AUTHENTICATION_USER_NAME_PROPERTY_ID)); + } + + if(passwordAlreadyExists) { + Predicate capturedPredicate = predicateCapture.getValue(); + Assert.assertEquals(AndPredicate.class, capturedPredicate.getClass()); + AndPredicate andPredicate = (AndPredicate) capturedPredicate; + Predicate[] predicates = andPredicate.getPredicates(); + Assert.assertEquals(2, predicates.length); + for (Predicate p : predicates) { + Assert.assertEquals(EqualsPredicate.class, p.getClass()); + EqualsPredicate equalsPredicate = (EqualsPredicate) p; + + if (UserAuthenticationSourceResourceProvider.AUTHENTICATION_USER_NAME_PROPERTY_ID.equals(equalsPredicate.getPropertyId())) { + Assert.assertEquals(requestedUsername, equalsPredicate.getValue()); + } else if (UserAuthenticationSourceResourceProvider.AUTHENTICATION_AUTHENTICATION_SOURCE_ID_PROPERTY_ID.equals(equalsPredicate.getPropertyId())) { + Assert.assertEquals(100L, equalsPredicate.getValue()); + } + } + } + else { + Assert.assertFalse(predicateCapture.hasCaptured()); + } + } } private void deleteResourcesTest(Authentication authentication, String requestedUsername) throws Exception { @@ -514,11 +828,23 @@ public class UserResourceProviderTest extends EasyMockSupport { UserEntity userEntity = createMockUserEntity(requestedUsername); - Users users = injector.getInstance(Users.class); - expect(users.getUserEntity(requestedUsername)).andReturn(userEntity).once(); - users.removeUser(userEntity); + List<PrincipalEntity> adminPrincipals = Collections.singletonList(createMock(PrincipalEntity.class)); + + List<UserEntity> adminUserEntities = new ArrayList<>(); + adminUserEntities.add(createMockUserEntity("some admin")); + if ("admin".equals(requestedUsername)) { + adminUserEntities.add(userEntity); + } + + UserDAO userDAO = injector.getInstance(UserDAO.class); + expect(userDAO.findUserByName(requestedUsername)).andReturn(userEntity).once(); + (expect(userDAO.findUsersByPrincipal(adminPrincipals))).andReturn(adminUserEntities).once(); + userDAO.remove(userEntity); expectLastCall().atLeastOnce(); + PrincipalDAO principalDAO = injector.getInstance(PrincipalDAO.class); + expect(principalDAO.findByPermissionId(PermissionEntity.AMBARI_ADMINISTRATOR_PERMISSION)).andReturn(adminPrincipals).once(); + // replay replayAll(); @@ -547,17 +873,18 @@ public class UserResourceProviderTest extends EasyMockSupport { UserEntity userEntity = createMock(UserEntity.class); expect(userEntity.getUserId()).andReturn(username.hashCode()).anyTimes(); expect(userEntity.getUserName()).andReturn(username).anyTimes(); + expect(userEntity.getLocalUsername()).andReturn(username).anyTimes(); + expect(userEntity.getDisplayName()).andReturn(username).anyTimes(); expect(userEntity.getActive()).andReturn(true).anyTimes(); + expect(userEntity.getCreateTime()).andReturn(CREATE_TIME).anyTimes(); + expect(userEntity.getConsecutiveFailures()).andReturn(0).anyTimes(); expect(userEntity.getAuthenticationEntities()).andReturn(Collections.<UserAuthenticationEntity>emptyList()).anyTimes(); expect(userEntity.getMemberEntities()).andReturn(Collections.<MemberEntity>emptySet()).anyTimes(); return userEntity; } private ResourceProvider getResourceProvider(Injector injector) { - UserResourceProvider resourceProvider = new UserResourceProvider( - PropertyHelper.getPropertyIds(Resource.Type.User), - PropertyHelper.getKeyPropertyIds(Resource.Type.User), - injector.getInstance(AmbariManagementController.class)); + UserResourceProvider resourceProvider = new UserResourceProvider(injector.getInstance(AmbariManagementController.class)); injector.injectMembers(resourceProvider); return resourceProvider; http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/test/java/org/apache/ambari/server/security/TestAuthenticationFactory.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/TestAuthenticationFactory.java b/ambari-server/src/test/java/org/apache/ambari/server/security/TestAuthenticationFactory.java index 43d56cd..65ea12b 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/security/TestAuthenticationFactory.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/security/TestAuthenticationFactory.java @@ -31,6 +31,7 @@ import org.apache.ambari.server.orm.entities.ResourceTypeEntity; import org.apache.ambari.server.security.authorization.AmbariGrantedAuthority; import org.apache.ambari.server.security.authorization.ResourceType; import org.apache.ambari.server.security.authorization.RoleAuthorization; +import org.apache.ambari.server.security.authorization.UserIdAuthentication; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; @@ -40,7 +41,7 @@ public class TestAuthenticationFactory { } public static Authentication createAdministrator(String name) { - return new TestAuthorization(name, Collections.singleton(createAdministratorGrantedAuthority())); + return new TestAuthorization(1, name, Collections.singleton(createAdministratorGrantedAuthority())); } public static Authentication createClusterAdministrator() { @@ -52,11 +53,11 @@ public class TestAuthenticationFactory { } public static Authentication createClusterAdministrator(String name, Long clusterResourceId) { - return new TestAuthorization(name, Collections.singleton(createClusterAdministratorGrantedAuthority(clusterResourceId))); + return new TestAuthorization(1, name, Collections.singleton(createClusterAdministratorGrantedAuthority(clusterResourceId))); } public static Authentication createClusterOperator(String name, Long clusterResourceId) { - return new TestAuthorization(name, Collections.singleton(createClusterOperatorGrantedAuthority(clusterResourceId))); + return new TestAuthorization(1, name, Collections.singleton(createClusterOperatorGrantedAuthority(clusterResourceId))); } public static Authentication createServiceAdministrator() { @@ -64,7 +65,7 @@ public class TestAuthenticationFactory { } public static Authentication createServiceAdministrator(String name, Long clusterResourceId) { - return new TestAuthorization(name, Collections.singleton(createServiceAdministratorGrantedAuthority(clusterResourceId))); + return new TestAuthorization(1, name, Collections.singleton(createServiceAdministratorGrantedAuthority(clusterResourceId))); } public static Authentication createServiceOperator() { @@ -72,7 +73,7 @@ public class TestAuthenticationFactory { } public static Authentication createServiceOperator(String name, Long clusterResourceId) { - return new TestAuthorization(name, Collections.singleton(createServiceOperatorGrantedAuthority(clusterResourceId))); + return new TestAuthorization(1, name, Collections.singleton(createServiceOperatorGrantedAuthority(clusterResourceId))); } public static Authentication createClusterUser() { @@ -80,7 +81,7 @@ public class TestAuthenticationFactory { } public static Authentication createClusterUser(String name, Long clusterResourceId) { - return new TestAuthorization(name, Collections.singleton(createClusterUserGrantedAuthority(clusterResourceId))); + return new TestAuthorization(1, name, Collections.singleton(createClusterUserGrantedAuthority(clusterResourceId))); } public static Authentication createViewUser(Long viewResourceId) { @@ -88,7 +89,7 @@ public class TestAuthenticationFactory { } public static Authentication createViewUser(String name, Long viewResourceId) { - return new TestAuthorization(name, Collections.singleton(createViewUserGrantedAuthority(viewResourceId))); + return new TestAuthorization(1, name, Collections.singleton(createViewUserGrantedAuthority(viewResourceId))); } private static GrantedAuthority createAdministratorGrantedAuthority() { @@ -402,11 +403,13 @@ public class TestAuthenticationFactory { } - private static class TestAuthorization implements Authentication { + private static class TestAuthorization implements Authentication, UserIdAuthentication { + private final Integer userId; private final String name; private final Collection<? extends GrantedAuthority> authorities; - private TestAuthorization(String name, Collection<? extends GrantedAuthority> authorities) { + private TestAuthorization(Integer userId, String name, Collection<? extends GrantedAuthority> authorities) { + this.userId = userId; this.name = name; this.authorities = authorities; } @@ -445,5 +448,10 @@ public class TestAuthenticationFactory { public String getName() { return name; } + + @Override + public Integer getUserId() { + return userId; + } } } http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/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 e049b4e..e99bdfd 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 @@ -22,6 +22,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.sql.SQLException; import java.util.Collection; @@ -47,12 +48,7 @@ import org.apache.ambari.server.orm.entities.UserAuthenticationEntity; import org.apache.ambari.server.orm.entities.UserEntity; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; -import org.mockito.Mockito; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.crypto.password.PasswordEncoder; import com.google.inject.Guice; @@ -89,8 +85,6 @@ public class TestUsers { injector = Guice.createInjector(module); injector.getInstance(GuiceJpaInitializer.class); injector.injectMembers(this); - Authentication auth = new UsernamePasswordAuthenticationToken("admin", null); - SecurityContextHolder.getContext().setAuthentication(auth); // create admin permission ResourceTypeEntity resourceTypeEntity = new ResourceTypeEntity(); @@ -166,23 +160,56 @@ public class TestUsers { assertNotNull(foundUserEntity); UserAuthenticationEntity foundLocalAuthenticationEntity; - foundLocalAuthenticationEntity = getLocalAuthenticationEntity(foundUserEntity); + foundLocalAuthenticationEntity = getAuthenticationEntity(foundUserEntity, UserAuthenticationType.LOCAL); assertNotNull(foundLocalAuthenticationEntity); assertNotSame("user", foundLocalAuthenticationEntity.getAuthenticationKey()); assertTrue(passwordEncoder.matches("user", foundLocalAuthenticationEntity.getAuthenticationKey())); foundUserEntity = userDAO.findUserByName("admin"); assertNotNull(foundUserEntity); - users.modifyPassword(foundUserEntity, "admin", "user_new_password"); + users.modifyAuthentication(foundLocalAuthenticationEntity, "user", "user_new_password", false); - foundUserEntity = userDAO.findUserByName("admin"); + foundUserEntity = userDAO.findUserByName("user"); assertNotNull(foundUserEntity); - foundLocalAuthenticationEntity = getLocalAuthenticationEntity(foundUserEntity); + foundLocalAuthenticationEntity = getAuthenticationEntity(foundUserEntity, UserAuthenticationType.LOCAL); assertNotNull(foundLocalAuthenticationEntity); assertTrue(passwordEncoder.matches("user_new_password", foundLocalAuthenticationEntity.getAuthenticationKey())); } @Test + public void testModifyPassword_EmptyPassword() throws Exception { + UserEntity userEntity; + + userEntity = users.createUser("user", "user", "user"); + users.addLocalAuthentication(userEntity, "user"); + + UserEntity foundUserEntity = userDAO.findUserByName("user"); + assertNotNull(foundUserEntity); + + UserAuthenticationEntity foundLocalAuthenticationEntity; + foundLocalAuthenticationEntity = getAuthenticationEntity(foundUserEntity, UserAuthenticationType.LOCAL); + assertNotNull(foundLocalAuthenticationEntity); + assertNotSame("user", foundLocalAuthenticationEntity.getAuthenticationKey()); + assertTrue(passwordEncoder.matches("user", foundLocalAuthenticationEntity.getAuthenticationKey())); + + try { + users.modifyAuthentication(foundLocalAuthenticationEntity, "user", null, false); + fail("Null password should not be allowed"); + } + catch (AmbariException e) { + assertEquals("The new password does not meet the Ambari password requirements", e.getLocalizedMessage()); + } + + try { + users.modifyAuthentication(foundLocalAuthenticationEntity, "user", "", false); + fail("Empty password should not be allowed"); + } + catch (AmbariException e) { + assertEquals("The new password does not meet the Ambari password requirements", e.getLocalizedMessage()); + } + } + + @Test public void testRevokeAdminPrivilege() throws Exception { final UserEntity userEntity = users.createUser("old_admin", "old_admin", "old_admin"); users.grantAdminPrivilege(userEntity); @@ -238,14 +265,14 @@ public class TestUsers { // create duplicate user try { users.createUser("user1", "user1", null); - Assert.fail("It shouldn't be possible to create duplicate user"); + fail("It shouldn't be possible to create duplicate user"); } catch (AmbariException e) { // This is expected } try { users.createUser("USER1", "user1", null); - Assert.fail("It shouldn't be possible to create duplicate user"); + fail("It shouldn't be possible to create duplicate user"); } catch (AmbariException e) { // This is expected } @@ -294,7 +321,7 @@ public class TestUsers { try { users.setUserActive("fake user", true); - Assert.fail("It shouldn't be possible to call setUserActive() on non-existing user"); + fail("It shouldn't be possible to call setUserActive() on non-existing user"); } catch (Exception ex) { // This is expected } @@ -315,7 +342,7 @@ public class TestUsers { try { users.addLdapAuthentication(users.getUserEntity("fake user"), "some other dn"); - Assert.fail("It shouldn't be possible to call setUserLdap() on non-existing user"); + fail("It shouldn't be possible to call setUserLdap() on non-existing user"); } catch (AmbariException ex) { // This is expected } @@ -331,7 +358,7 @@ public class TestUsers { try { users.setGroupLdap("fake group"); - Assert.fail("It shouldn't be possible to call setGroupLdap() on non-existing group"); + fail("It shouldn't be possible to call setGroupLdap() on non-existing group"); } catch (AmbariException ex) { // This is expected } @@ -379,7 +406,7 @@ public class TestUsers { try { users.getAllMembers("non existing"); - Assert.fail("It shouldn't be possible to call getAllMembers() on non-existing group"); + fail("It shouldn't be possible to call getAllMembers() on non-existing group"); } catch (Exception ex) { // This is expected } @@ -395,22 +422,19 @@ public class TestUsers { @Test public void testModifyPassword_UserByHimselfPasswordOk() throws Exception { - Authentication auth = new UsernamePasswordAuthenticationToken("user", null); - SecurityContextHolder.getContext().setAuthentication(auth); - UserEntity userEntity = users.createUser("user", "user", null); users.addLocalAuthentication(userEntity, "user"); userEntity = userDAO.findUserByName("user"); - UserAuthenticationEntity localAuthenticationEntity = getLocalAuthenticationEntity(userEntity); + UserAuthenticationEntity localAuthenticationEntity = getAuthenticationEntity(userEntity, UserAuthenticationType.LOCAL); assertNotNull(localAuthenticationEntity); assertNotSame("user", localAuthenticationEntity.getAuthenticationKey()); assertTrue(passwordEncoder.matches("user", localAuthenticationEntity.getAuthenticationKey())); - users.modifyPassword("user", "user", "user_new_password"); + users.modifyAuthentication(localAuthenticationEntity, "user", "user_new_password", true); userEntity = userDAO.findUserByName("user"); - localAuthenticationEntity = getLocalAuthenticationEntity(userEntity); + localAuthenticationEntity = getAuthenticationEntity(userEntity, UserAuthenticationType.LOCAL); assertNotNull(localAuthenticationEntity); assertTrue(passwordEncoder.matches("user_new_password", localAuthenticationEntity.getAuthenticationKey())); @@ -418,66 +442,101 @@ public class TestUsers { @Test public void testModifyPassword_UserByHimselfPasswordNotOk() throws Exception { - Authentication auth = new UsernamePasswordAuthenticationToken("user", null); - SecurityContextHolder.getContext().setAuthentication(auth); - UserEntity userEntity = users.createUser("user", "user", null); users.addLocalAuthentication(userEntity, "user"); userEntity = userDAO.findUserByName("user"); UserAuthenticationEntity foundLocalAuthenticationEntity; - foundLocalAuthenticationEntity = getLocalAuthenticationEntity(userEntity); + foundLocalAuthenticationEntity = getAuthenticationEntity(userEntity, UserAuthenticationType.LOCAL); assertNotNull(foundLocalAuthenticationEntity); assertNotSame("user", foundLocalAuthenticationEntity.getAuthenticationKey()); assertTrue(passwordEncoder.matches("user", foundLocalAuthenticationEntity.getAuthenticationKey())); try { - users.modifyPassword("user", "admin", "user_new_password"); - Assert.fail("Exception should be thrown here as password is incorrect"); + users.modifyAuthentication(foundLocalAuthenticationEntity, "admin", "user_new_password", true); + fail("Exception should be thrown here as password is incorrect"); } catch (AmbariException ex) { // This is expected } } @Test - public void testModifyPassword_UserByNonAdmin() throws Exception { - Authentication auth = new UsernamePasswordAuthenticationToken("user2", null); - SecurityContextHolder.getContext().setAuthentication(auth); + public void testAddAndRemoveAuthentication() throws Exception { + users.createUser("user", "user", "user"); - UserEntity userEntity; - userEntity = users.createUser("user", "user", null); - users.addLocalAuthentication(userEntity, "user"); + UserEntity userEntity = userDAO.findUserByName("user"); + assertNotNull(userEntity); + assertEquals("user", userEntity.getUserName()); - userEntity = users.createUser("user2", "user2", null); - users.addLocalAuthentication(userEntity, "user2"); + UserEntity userEntity2 = userDAO.findUserByName("user"); + assertNotNull(userEntity2); + assertEquals("user", userEntity2.getUserName()); - UserAuthenticationEntity foundLocalAuthenticationEntity = getLocalAuthenticationEntity(userDAO.findUserByName("user")); - assertNotNull(foundLocalAuthenticationEntity); - assertNotSame("user", foundLocalAuthenticationEntity.getAuthenticationKey()); - assertTrue(passwordEncoder.matches("user", foundLocalAuthenticationEntity.getAuthenticationKey())); + assertEquals(0, users.getUserAuthenticationEntities("user", null).size()); - try { - users.modifyPassword("user", "user2", "user_new_password"); - Assert.fail("Exception should be thrown here as user2 can't change password of user"); - } catch (AuthorizationException ex) { - // This is expected - } - } + users.addAuthentication(userEntity, UserAuthenticationType.LOCAL, "local_key"); + assertEquals(1, users.getUserAuthenticationEntities("user", null).size()); + assertEquals(1, users.getUserAuthenticationEntities("user", UserAuthenticationType.LOCAL).size()); + assertTrue(passwordEncoder.matches("local_key", users.getUserAuthenticationEntities("user", UserAuthenticationType.LOCAL).iterator().next().getAuthenticationKey())); + assertEquals(0, users.getUserAuthenticationEntities("user", UserAuthenticationType.KERBEROS).size()); - @Test - @Ignore // TODO @Transactional annotation breaks this test - public void testCreateUserDefaultParams() throws Exception { - final Users spy = Mockito.spy(users); - spy.createUser("user", "user", null); - Mockito.verify(spy).createUser("user", "user", null); + users.addAuthentication(userEntity, UserAuthenticationType.PAM, "pam_key"); + assertEquals(2, users.getUserAuthenticationEntities("user", null).size()); + assertEquals(1, users.getUserAuthenticationEntities("user", UserAuthenticationType.PAM).size()); + assertEquals("pam_key", users.getUserAuthenticationEntities("user", UserAuthenticationType.PAM).iterator().next().getAuthenticationKey()); + assertEquals(0, users.getUserAuthenticationEntities("user", UserAuthenticationType.KERBEROS).size()); + + users.addAuthentication(userEntity, UserAuthenticationType.JWT, "jwt_key"); + assertEquals(3, users.getUserAuthenticationEntities("user", null).size()); + assertEquals(1, users.getUserAuthenticationEntities("user", UserAuthenticationType.JWT).size()); + assertEquals("jwt_key", users.getUserAuthenticationEntities("user", UserAuthenticationType.JWT).iterator().next().getAuthenticationKey()); + assertEquals(0, users.getUserAuthenticationEntities("user", UserAuthenticationType.KERBEROS).size()); + + users.addAuthentication(userEntity, UserAuthenticationType.LDAP, "ldap_key"); + assertEquals(4, users.getUserAuthenticationEntities("user", null).size()); + assertEquals(1, users.getUserAuthenticationEntities("user", UserAuthenticationType.LDAP).size()); + assertEquals("ldap_key", users.getUserAuthenticationEntities("user", UserAuthenticationType.LDAP).iterator().next().getAuthenticationKey()); + assertEquals(0, users.getUserAuthenticationEntities("user", UserAuthenticationType.KERBEROS).size()); + + users.addAuthentication(userEntity, UserAuthenticationType.KERBEROS, "kerberos_key"); + assertEquals(5, users.getUserAuthenticationEntities("user", null).size()); + assertEquals("kerberos_key", users.getUserAuthenticationEntities("user", UserAuthenticationType.KERBEROS).iterator().next().getAuthenticationKey()); + assertEquals(1, users.getUserAuthenticationEntities("user", UserAuthenticationType.KERBEROS).size()); + + // UserEntity was updated by user.addAuthentication + assertEquals(5, userEntity.getAuthenticationEntities().size()); + + // UserEntity2 needs to be refreshed... + assertEquals(0, userEntity2.getAuthenticationEntities().size()); + userEntity2 = userDAO.findUserByName("user"); + assertEquals(5, userEntity2.getAuthenticationEntities().size()); + + + // Test Remove + Long kerberosAuthenticationId = users.getUserAuthenticationEntities("user", UserAuthenticationType.KERBEROS).iterator().next().getUserAuthenticationId(); + Long pamAuthenticationId = users.getUserAuthenticationEntities("user", UserAuthenticationType.PAM).iterator().next().getUserAuthenticationId(); + + users.removeAuthentication("user", kerberosAuthenticationId); + assertEquals(4, users.getUserAuthenticationEntities("user", null).size()); + + users.removeAuthentication(userEntity, kerberosAuthenticationId); + assertEquals(4, users.getUserAuthenticationEntities("user", null).size()); + + users.removeAuthentication(userEntity, pamAuthenticationId); + assertEquals(3, users.getUserAuthenticationEntities("user", null).size()); + + // UserEntity2 needs to be refreshed... + assertEquals(5, userEntity2.getAuthenticationEntities().size()); + userEntity2 = userDAO.findUserByName("user"); + assertEquals(3, userEntity2.getAuthenticationEntities().size()); } - private UserAuthenticationEntity getLocalAuthenticationEntity(UserEntity userEntity) { + private UserAuthenticationEntity getAuthenticationEntity(UserEntity userEntity, UserAuthenticationType type) { assertNotNull(userEntity); Collection<UserAuthenticationEntity> authenticationEntities = userEntity.getAuthenticationEntities(); assertNotNull(authenticationEntities); for (UserAuthenticationEntity authenticationEntity : authenticationEntities) { - if (authenticationEntity.getAuthenticationType() == UserAuthenticationType.LOCAL) { + if (authenticationEntity.getAuthenticationType() == type) { return authenticationEntity; } }
