You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rl...@apache.org on 2017/07/19 12:41:51 UTC
[1/6] ambari git commit: AMBARI-20861. BE: Extend Ambari REST API to
Support User Account Management Improvements (rlevas)
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;
}
}
[6/6] ambari git commit: AMBARI-20861. BE: Extend Ambari REST API to
Support User Account Management Improvements (rlevas)
Posted by rl...@apache.org.
AMBARI-20861. BE: Extend Ambari REST API to Support User Account Management Improvements (rlevas)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/317905e4
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/317905e4
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/317905e4
Branch: refs/heads/branch-feature-AMBARI-20859
Commit: 317905e40e0b4b384809ad7d900a09d97827f599
Parents: 903cd1a
Author: Robert Levas <rl...@hortonworks.com>
Authored: Wed Jul 19 08:41:36 2017 -0400
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Wed Jul 19 08:41:36 2017 -0400
----------------------------------------------------------------------
ambari-server/docs/api/generated/index.html | 6354 +++++++++++++-----
ambari-server/docs/api/generated/swagger.json | 959 ++-
.../docs/api/v1/authentication-source-create.md | 86 +
.../docs/api/v1/authentication-source-delete.md | 49 +
.../docs/api/v1/authentication-source-get.md | 93 +
.../docs/api/v1/authentication-source-list.md | 116 +
.../api/v1/authentication-source-resources.md | 117 +
.../docs/api/v1/authentication-source-update.md | 104 +
ambari-server/docs/api/v1/index.md | 12 +
ambari-server/docs/api/v1/user-create.md | 107 +
ambari-server/docs/api/v1/user-delete.md | 48 +
ambari-server/docs/api/v1/user-get.md | 97 +
ambari-server/docs/api/v1/user-list.md | 98 +
ambari-server/docs/api/v1/user-resources.md | 175 +
ambari-server/docs/api/v1/user-update.md | 115 +
.../resources/ResourceInstanceFactoryImpl.java | 4 +
.../api/resources/UserResourceDefinition.java | 1 +
.../ambari/server/api/services/BaseService.java | 70 +-
.../users/UserAuthenticationSourceService.java | 223 +
.../server/api/services/users/UserService.java | 132 +-
.../server/controller/ControllerModule.java | 2 +
.../controller/ResourceProviderFactory.java | 7 +-
.../UserAuthenticationSourceRequest.java | 82 +
...uthenticationSourceRequestCreateSwagger.java | 40 +
...uthenticationSourceRequestUpdateSwagger.java | 40 +
.../UserAuthenticationSourceResponse.java | 127 +
.../ambari/server/controller/UserRequest.java | 17 +-
.../UserRequestCreateUserSwagger.java | 49 +
.../UserRequestCreateUsersSwagger.java | 52 +
.../UserRequestUpdateUserSwagger.java | 52 +
.../ambari/server/controller/UserResponse.java | 76 +-
.../AbstractControllerResourceProvider.java | 4 +-
...serAuthenticationSourceResourceProvider.java | 417 ++
.../internal/UserResourceProvider.java | 297 +-
.../ambari/server/controller/spi/Resource.java | 2 +
.../server/orm/dao/UserAuthenticationDAO.java | 8 +
.../orm/entities/UserAuthenticationEntity.java | 24 +-
.../server/security/authorization/Users.java | 288 +-
.../src/main/resources/properties.json | 11 -
.../resources/UserResourceDefinitionTest.java | 13 +-
.../controller/internal/RequestImplTest.java | 7 -
...uthenticationSourceResourceProviderTest.java | 448 ++
.../internal/UserResourceProviderDBTest.java | 22 +-
.../internal/UserResourceProviderTest.java | 705 +-
.../security/TestAuthenticationFactory.java | 26 +-
.../security/authorization/TestUsers.java | 171 +-
46 files changed, 9413 insertions(+), 2534 deletions(-)
----------------------------------------------------------------------
[5/6] ambari git commit: AMBARI-20861. BE: Extend Ambari REST API to
Support User Account Management Improvements (rlevas)
Posted by rl...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/docs/api/generated/index.html
----------------------------------------------------------------------
diff --git a/ambari-server/docs/api/generated/index.html b/ambari-server/docs/api/generated/index.html
index 21e043b..5ade7a8 100644
--- a/ambari-server/docs/api/generated/index.html
+++ b/ambari-server/docs/api/generated/index.html
@@ -907,10 +907,10 @@ margin-bottom: 20px;
"stack_version" : {
"type" : "string"
},
- "stack_name" : {
+ "artifact_name" : {
"type" : "string"
},
- "artifact_name" : {
+ "stack_name" : {
"type" : "string"
}
}
@@ -918,15 +918,15 @@ margin-bottom: 20px;
defs.BlueprintInfo = {
"type" : "object",
"properties" : {
+ "blueprint_name" : {
+ "type" : "string"
+ },
"security" : {
"$ref" : "#/definitions/SecurityInfo"
},
"stack_version" : {
"type" : "string"
},
- "blueprint_name" : {
- "type" : "string"
- },
"stack_name" : {
"type" : "string"
}
@@ -1004,25 +1004,25 @@ margin-bottom: 20px;
defs.ClusterArtifactResponse = {
"type" : "object",
"properties" : {
- "Artifacts" : {
- "$ref" : "#/definitions/ClusterArtifactResponseInfo"
- },
"artifact_data" : {
"type" : "object",
"additionalProperties" : {
"type" : "object",
"properties" : { }
}
+ },
+ "Artifacts" : {
+ "$ref" : "#/definitions/ClusterArtifactResponseInfo"
}
}
};
defs.ClusterArtifactResponseInfo = {
"type" : "object",
"properties" : {
- "cluster_name" : {
+ "artifact_name" : {
"type" : "string"
},
- "artifact_name" : {
+ "cluster_name" : {
"type" : "string"
}
}
@@ -1214,14 +1214,14 @@ margin-bottom: 20px;
defs.ClusterServiceArtifactResponseInfo = {
"type" : "object",
"properties" : {
- "cluster_name" : {
- "type" : "string"
- },
"service_name" : {
"type" : "string"
},
"artifact_name" : {
"type" : "string"
+ },
+ "cluster_name" : {
+ "type" : "string"
}
}
};
@@ -1239,15 +1239,6 @@ margin-bottom: 20px;
"scope" : {
"type" : "string"
},
- "service_name" : {
- "type" : "string"
- },
- "component_name" : {
- "type" : "string"
- },
- "stack_version" : {
- "type" : "string"
- },
"conditions" : {
"type" : "array",
"items" : {
@@ -1260,6 +1251,15 @@ margin-bottom: 20px;
"dependent_service_name" : {
"type" : "string"
},
+ "service_name" : {
+ "type" : "string"
+ },
+ "stack_version" : {
+ "type" : "string"
+ },
+ "component_name" : {
+ "type" : "string"
+ },
"stack_name" : {
"type" : "string"
}
@@ -1268,10 +1268,10 @@ margin-bottom: 20px;
defs.ComponentInfo = {
"type" : "object",
"properties" : {
- "name" : {
+ "provision_action" : {
"type" : "string"
},
- "provision_action" : {
+ "name" : {
"type" : "string"
}
}
@@ -1443,6 +1443,66 @@ margin-bottom: 20px;
}
}
};
+ defs.CreateUserAuthenticationSourceInfo = {
+ "type" : "object",
+ "required" : [ "authentication_type", "key" ],
+ "properties" : {
+ "key" : {
+ "type" : "string"
+ },
+ "authentication_type" : {
+ "type" : "string",
+ "enum" : [ "LOCAL", "LDAP", "JWT", "PAM", "KERBEROS" ]
+ }
+ }
+};
+ defs.CreateUserInfo = {
+ "type" : "object",
+ "properties" : {
+ "display_name" : {
+ "type" : "string"
+ },
+ "active" : {
+ "type" : "boolean",
+ "default" : false
+ },
+ "password" : {
+ "type" : "string"
+ },
+ "admin" : {
+ "type" : "boolean",
+ "default" : false
+ },
+ "local_user_name" : {
+ "type" : "string"
+ }
+ }
+};
+ defs.CreateUsersInfo = {
+ "type" : "object",
+ "properties" : {
+ "display_name" : {
+ "type" : "string"
+ },
+ "active" : {
+ "type" : "boolean",
+ "default" : false
+ },
+ "user_name" : {
+ "type" : "string"
+ },
+ "password" : {
+ "type" : "string"
+ },
+ "admin" : {
+ "type" : "boolean",
+ "default" : false
+ },
+ "local_user_name" : {
+ "type" : "string"
+ }
+ }
+};
defs.DependencyConditionInfo = {
"type" : "object"
};
@@ -1709,10 +1769,10 @@ margin-bottom: 20px;
"maintenance_state" : {
"type" : "string"
},
- "host_group" : {
+ "blueprint" : {
"type" : "string"
},
- "blueprint" : {
+ "host_group" : {
"type" : "string"
},
"public_host_name" : {
@@ -1796,10 +1856,10 @@ margin-bottom: 20px;
"type" : "string",
"enum" : [ "OFF", "ON", "IMPLIED_FROM_SERVICE", "IMPLIED_FROM_HOST", "IMPLIED_FROM_SERVICE_AND_HOST" ]
},
- "public_host_name" : {
+ "host_health_report" : {
"type" : "string"
},
- "host_health_report" : {
+ "public_host_name" : {
"type" : "string"
}
}
@@ -2229,20 +2289,17 @@ margin-bottom: 20px;
"type" : "boolean",
"default" : false
},
- "baseUrl" : {
+ "repoId" : {
"type" : "string"
},
- "mirrorsList" : {
+ "baseUrl" : {
"type" : "string"
},
- "latestUri" : {
+ "mirrorsList" : {
"type" : "string"
},
"repoName" : {
"type" : "string"
- },
- "repoId" : {
- "type" : "string"
}
}
};
@@ -2288,9 +2345,6 @@ margin-bottom: 20px;
"defaultBaseUrl" : {
"type" : "string"
},
- "latestBaseUrl" : {
- "type" : "string"
- },
"repoSaved" : {
"type" : "boolean",
"default" : false
@@ -2346,6 +2400,15 @@ margin-bottom: 20px;
"$ref" : "#/definitions/RepositoryVersionEntity"
}
},
+ "repositoryXml" : {
+ "$ref" : "#/definitions/VersionDefinitionXml"
+ },
+ "stackId" : {
+ "$ref" : "#/definitions/StackId"
+ },
+ "stackVersion" : {
+ "type" : "string"
+ },
"operatingSystemsJson" : {
"type" : "string"
},
@@ -2353,17 +2416,8 @@ margin-bottom: 20px;
"type" : "integer",
"format" : "int64"
},
- "stackVersion" : {
- "type" : "string"
- },
- "stackId" : {
- "$ref" : "#/definitions/StackId"
- },
"stackName" : {
"type" : "string"
- },
- "repositoryXml" : {
- "$ref" : "#/definitions/VersionDefinitionXml"
}
}
};
@@ -2389,14 +2443,14 @@ margin-bottom: 20px;
"$ref" : "#/definitions/RepositoryInfo"
}
},
- "latestURI" : {
- "type" : "string"
- },
"errors" : {
"type" : "array",
"items" : {
"type" : "string"
}
+ },
+ "latestURI" : {
+ "type" : "string"
}
},
"xml" : {
@@ -2406,9 +2460,6 @@ margin-bottom: 20px;
defs.Request = {
"type" : "object",
"properties" : {
- "cluster_name" : {
- "type" : "string"
- },
"exclusive" : {
"type" : "boolean",
"default" : false
@@ -2418,6 +2469,9 @@ margin-bottom: 20px;
"items" : {
"$ref" : "#/definitions/RequestResourceFilter"
}
+ },
+ "cluster_name" : {
+ "type" : "string"
}
}
};
@@ -2431,14 +2485,14 @@ margin-bottom: 20px;
"properties" : { }
}
},
- "action" : {
- "type" : "string"
+ "operation_level" : {
+ "$ref" : "#/definitions/OperationLevel"
},
"command" : {
"type" : "string"
},
- "operation_level" : {
- "$ref" : "#/definitions/OperationLevel"
+ "action" : {
+ "type" : "string"
}
}
};
@@ -2495,16 +2549,16 @@ margin-bottom: 20px;
defs.RequestResourceFilter = {
"type" : "object",
"properties" : {
- "service_name" : {
+ "hosts_predicate" : {
"type" : "string"
},
- "component_name" : {
+ "hosts" : {
"type" : "string"
},
- "hosts_predicate" : {
+ "service_name" : {
"type" : "string"
},
- "hosts" : {
+ "component_name" : {
"type" : "string"
}
}
@@ -2526,29 +2580,23 @@ margin-bottom: 20px;
"start_time" : {
"type" : "string"
},
- "request_context" : {
- "type" : "string"
- },
"request_status" : {
"type" : "string"
},
- "cluster_name" : {
+ "request_context" : {
"type" : "string"
},
- "request_schedule" : {
- "type" : "string"
+ "task_count" : {
+ "type" : "integer",
+ "format" : "int32"
},
- "id" : {
+ "completed_task_count" : {
"type" : "string"
},
"aborted_task_count" : {
"type" : "integer",
"format" : "int32"
},
- "create_time" : {
- "type" : "integer",
- "format" : "int64"
- },
"end_time" : {
"type" : "string"
},
@@ -2560,9 +2608,6 @@ margin-bottom: 20px;
"type" : "integer",
"format" : "int32"
},
- "inputs" : {
- "type" : "string"
- },
"operation_level" : {
"type" : "string"
},
@@ -2570,6 +2615,9 @@ margin-bottom: 20px;
"type" : "number",
"format" : "double"
},
+ "id" : {
+ "type" : "string"
+ },
"queued_task_count" : {
"type" : "integer",
"format" : "int32"
@@ -2584,11 +2632,17 @@ margin-bottom: 20px;
"$ref" : "#/definitions/RequestResourceFilter"
}
},
- "task_count" : {
+ "create_time" : {
"type" : "integer",
- "format" : "int32"
+ "format" : "int64"
},
- "completed_task_count" : {
+ "inputs" : {
+ "type" : "string"
+ },
+ "cluster_name" : {
+ "type" : "string"
+ },
+ "request_schedule" : {
"type" : "string"
}
}
@@ -2745,19 +2799,19 @@ margin-bottom: 20px;
defs.SecurityInfo = {
"type" : "object",
"properties" : {
+ "kerberos_descriptor_reference" : {
+ "type" : "string"
+ },
+ "security_type" : {
+ "type" : "string",
+ "enum" : [ "NONE", "KERBEROS" ]
+ },
"kerberos_descriptor" : {
"type" : "object",
"additionalProperties" : {
"type" : "object",
"properties" : { }
}
- },
- "security_type" : {
- "type" : "string",
- "enum" : [ "NONE", "KERBEROS" ]
- },
- "kerberos_descriptor_reference" : {
- "type" : "string"
}
}
};
@@ -3518,11 +3572,11 @@ margin-bottom: 20px;
"stack_version" : {
"type" : "string"
},
- "stack_name" : {
- "type" : "string"
- },
"theme_data" : {
"$ref" : "#/definitions/Theme"
+ },
+ "stack_name" : {
+ "type" : "string"
}
}
};
@@ -3542,6 +3596,95 @@ margin-bottom: 20px;
}
}
};
+ defs.UpdateUserInfo = {
+ "type" : "object",
+ "properties" : {
+ "display_name" : {
+ "type" : "string"
+ },
+ "active" : {
+ "type" : "boolean",
+ "default" : false
+ },
+ "password" : {
+ "type" : "string"
+ },
+ "admin" : {
+ "type" : "boolean",
+ "default" : false
+ },
+ "local_user_name" : {
+ "type" : "string"
+ },
+ "old_password" : {
+ "type" : "string"
+ }
+ }
+};
+ defs.UserAuthenticationSourceRequestCreateSwagger = {
+ "type" : "object",
+ "properties" : {
+ "AuthenticationSourceInfo" : {
+ "$ref" : "#/definitions/CreateUserAuthenticationSourceInfo"
+ }
+ }
+};
+ defs.UserAuthenticationSourceRequestUpdateInfo = {
+ "type" : "object",
+ "required" : [ "key" ],
+ "properties" : {
+ "key" : {
+ "type" : "string"
+ },
+ "old_key" : {
+ "type" : "string"
+ }
+ }
+};
+ defs.UserAuthenticationSourceRequestUpdateSwagger = {
+ "type" : "object",
+ "properties" : {
+ "AuthenticationSourceInfo" : {
+ "$ref" : "#/definitions/UserAuthenticationSourceRequestUpdateInfo"
+ }
+ }
+};
+ defs.UserAuthenticationSourceResponse = {
+ "type" : "object",
+ "required" : [ "authentication_type", "source_id", "user_name" ],
+ "properties" : {
+ "user_name" : {
+ "type" : "string"
+ },
+ "source_id" : {
+ "type" : "integer",
+ "format" : "int64"
+ },
+ "authentication_type" : {
+ "type" : "string",
+ "enum" : [ "LOCAL", "LDAP", "JWT", "PAM", "KERBEROS" ]
+ },
+ "key" : {
+ "type" : "string"
+ },
+ "created" : {
+ "type" : "string",
+ "format" : "date-time"
+ },
+ "updated" : {
+ "type" : "string",
+ "format" : "date-time"
+ }
+ }
+};
+ defs.UserAuthenticationSourceResponseSwagger = {
+ "type" : "object",
+ "properties" : {
+ "AuthenticationSourceInfo" : {
+ "$ref" : "#/definitions/UserAuthenticationSourceResponse"
+ }
+ }
+};
defs.UserAuthorizationResponse = {
"type" : "object",
"required" : [ "AuthorizationInfo/user_name" ],
@@ -3625,72 +3768,92 @@ margin-bottom: 20px;
}
}
};
- defs.UserRequest = {
+ defs.UserRequestCreateUserSwagger = {
"type" : "object",
"properties" : {
- "Users/password" : {
- "type" : "string"
- },
- "Users/old_password" : {
- "type" : "string"
- },
- "Users/active" : {
- "type" : "boolean",
- "default" : false
- },
- "Users/admin" : {
- "type" : "boolean",
- "default" : false
- },
- "Users/display_name" : {
- "type" : "string"
- },
- "Users/local_user_name" : {
- "type" : "string"
+ "Users" : {
+ "$ref" : "#/definitions/CreateUserInfo"
+ }
+ }
+};
+ defs.UserRequestCreateUsersSwagger = {
+ "type" : "object",
+ "properties" : {
+ "Users" : {
+ "$ref" : "#/definitions/CreateUsersInfo"
+ }
+ }
+};
+ defs.UserRequestUpdateUserSwagger = {
+ "type" : "object",
+ "properties" : {
+ "Users" : {
+ "$ref" : "#/definitions/UpdateUserInfo"
}
}
};
defs.UserResponse = {
"type" : "object",
- "required" : [ "Users/user_name" ],
"properties" : {
- "Users/authentication_type" : {
+ "display_name" : {
+ "type" : "string"
+ },
+ "user_type" : {
"type" : "string",
"enum" : [ "LOCAL", "LDAP", "JWT", "PAM", "KERBEROS" ]
},
- "Users/groups" : {
+ "groups" : {
"type" : "array",
"uniqueItems" : true,
"items" : {
"type" : "string"
}
},
- "Users/active" : {
+ "created" : {
+ "type" : "string",
+ "format" : "date-time"
+ },
+ "consecutive_failures" : {
+ "type" : "integer",
+ "format" : "int32"
+ },
+ "active" : {
"type" : "boolean",
"default" : false
},
- "Users/user_name" : {
+ "user_name" : {
"type" : "string"
},
- "Users/admin" : {
+ "admin" : {
"type" : "boolean",
"default" : false
},
- "Users/ldap_user" : {
+ "ldap_user" : {
"type" : "boolean",
"default" : false
+ },
+ "local_user_name" : {
+ "type" : "string"
+ }
+ }
+};
+ defs.UserResponseSwagger = {
+ "type" : "object",
+ "properties" : {
+ "Users" : {
+ "$ref" : "#/definitions/UserResponse"
}
}
};
defs.ValidationResult = {
"type" : "object",
"properties" : {
- "detail" : {
- "type" : "string"
- },
"valid" : {
"type" : "boolean",
"default" : false
+ },
+ "detail" : {
+ "type" : "string"
}
}
};
@@ -4537,6 +4700,22 @@ margin-bottom: 20px;
<li data-group="Stacks" data-name="stacksServiceGetStacks" class="">
<a href="#api-Stacks-stacksServiceGetStacks">stacksServiceGetStacks</a>
</li>
+ <li class="nav-header" data-group="UserAuthenticationSources"><a href="#api-UserAuthenticationSources">API Methods - UserAuthenticationSources</a></li>
+ <li data-group="UserAuthenticationSources" data-name="createAuthenticationSources" class="">
+ <a href="#api-UserAuthenticationSources-createAuthenticationSources">createAuthenticationSources</a>
+ </li>
+ <li data-group="UserAuthenticationSources" data-name="deleteAuthenticationSource" class="">
+ <a href="#api-UserAuthenticationSources-deleteAuthenticationSource">deleteAuthenticationSource</a>
+ </li>
+ <li data-group="UserAuthenticationSources" data-name="getAuthenticationSource" class="">
+ <a href="#api-UserAuthenticationSources-getAuthenticationSource">getAuthenticationSource</a>
+ </li>
+ <li data-group="UserAuthenticationSources" data-name="getAuthenticationSources" class="">
+ <a href="#api-UserAuthenticationSources-getAuthenticationSources">getAuthenticationSources</a>
+ </li>
+ <li data-group="UserAuthenticationSources" data-name="updateAuthenticationSource" class="">
+ <a href="#api-UserAuthenticationSources-updateAuthenticationSource">updateAuthenticationSource</a>
+ </li>
<li class="nav-header" data-group="Users"><a href="#api-Users">API Methods - Users</a></li>
<li data-group="Users" data-name="activeWidgetLayoutServiceGetServices" class="">
<a href="#api-Users-activeWidgetLayoutServiceGetServices">activeWidgetLayoutServiceGetServices</a>
@@ -4544,6 +4723,24 @@ margin-bottom: 20px;
<li data-group="Users" data-name="activeWidgetLayoutServiceUpdateServices" class="">
<a href="#api-Users-activeWidgetLayoutServiceUpdateServices">activeWidgetLayoutServiceUpdateServices</a>
</li>
+ <li data-group="Users" data-name="createUser" class="">
+ <a href="#api-Users-createUser">createUser</a>
+ </li>
+ <li data-group="Users" data-name="createUsers" class="">
+ <a href="#api-Users-createUsers">createUsers</a>
+ </li>
+ <li data-group="Users" data-name="deleteUser" class="">
+ <a href="#api-Users-deleteUser">deleteUser</a>
+ </li>
+ <li data-group="Users" data-name="getUser" class="">
+ <a href="#api-Users-getUser">getUser</a>
+ </li>
+ <li data-group="Users" data-name="getUsers" class="">
+ <a href="#api-Users-getUsers">getUsers</a>
+ </li>
+ <li data-group="Users" data-name="updateUser" class="">
+ <a href="#api-Users-updateUser">updateUser</a>
+ </li>
<li data-group="Users" data-name="userAuthorizationServiceGetAuthorization" class="">
<a href="#api-Users-userAuthorizationServiceGetAuthorization">userAuthorizationServiceGetAuthorization</a>
</li>
@@ -4556,21 +4753,6 @@ margin-bottom: 20px;
<li data-group="Users" data-name="userPrivilegeServiceGetPrivileges" class="">
<a href="#api-Users-userPrivilegeServiceGetPrivileges">userPrivilegeServiceGetPrivileges</a>
</li>
- <li data-group="Users" data-name="userServiceCreateUser" class="">
- <a href="#api-Users-userServiceCreateUser">userServiceCreateUser</a>
- </li>
- <li data-group="Users" data-name="userServiceDeleteUser" class="">
- <a href="#api-Users-userServiceDeleteUser">userServiceDeleteUser</a>
- </li>
- <li data-group="Users" data-name="userServiceGetUser" class="">
- <a href="#api-Users-userServiceGetUser">userServiceGetUser</a>
- </li>
- <li data-group="Users" data-name="userServiceGetUsers" class="">
- <a href="#api-Users-userServiceGetUsers">userServiceGetUsers</a>
- </li>
- <li data-group="Users" data-name="userServiceUpdateUser" class="">
- <a href="#api-Users-userServiceUpdateUser">userServiceUpdateUser</a>
- </li>
<li class="nav-header" data-group="Views"><a href="#api-Views">API Methods - Views</a></li>
<li data-group="Views" data-name="viewDataMigrationServiceMigrateData" class="">
<a href="#api-Views-viewDataMigrationServiceMigrateData">viewDataMigrationServiceMigrateData</a>
@@ -45153,121 +45335,100 @@ except ApiException as e:
</div>
<hr>
</section>
- <section id="api-Users">
- <h1>Users</h1>
- <div id="api-Users-activeWidgetLayoutServiceGetServices">
- <article id="api-Users-activeWidgetLayoutServiceGetServices-0" data-group="User" data-name="activeWidgetLayoutServiceGetServices" data-version="0">
+ <section id="api-UserAuthenticationSources">
+ <h1>UserAuthenticationSources</h1>
+ <div id="api-UserAuthenticationSources-createAuthenticationSources">
+ <article id="api-UserAuthenticationSources-createAuthenticationSources-0" data-group="User" data-name="createAuthenticationSources" data-version="0">
<div class="pull-left">
- <h1>activeWidgetLayoutServiceGetServices</h1>
- <p>Get user widget layouts</p>
+ <h1>createAuthenticationSources</h1>
+ <p>Create one or more new authentication sources for a user</p>
</div>
<div class="pull-right"></div>
<div class="clearfix"></div>
<p></p>
- <p class="marked">Returns all active widget layouts for user.</p>
+ <p class="marked"></p>
<p></p>
<br />
- <pre class="prettyprint language-html prettyprinted" data-type="get"><code><span class="pln">/users/{userName}/activeWidgetLayouts</span></code></pre>
+ <pre class="prettyprint language-html prettyprinted" data-type="post"><code><span class="pln">/users/{userName}/sources</span></code></pre>
<p>
<h3>Usage and SDK Samples</h3>
</p>
<ul class="nav nav-tabs nav-tabs-examples">
- <li class="active"><a href="#examples-Users-activeWidgetLayoutServiceGetServices-0-curl">Curl</a></li>
- <li class=""><a href="#examples-Users-activeWidgetLayoutServiceGetServices-0-java">Java</a></li>
- <li class=""><a href="#examples-Users-activeWidgetLayoutServiceGetServices-0-android">Android</a></li>
- <!--<li class=""><a href="#examples-Users-activeWidgetLayoutServiceGetServices-0-groovy">Groovy</a></li>-->
- <li class=""><a href="#examples-Users-activeWidgetLayoutServiceGetServices-0-objc">Obj-C</a></li>
- <li class=""><a href="#examples-Users-activeWidgetLayoutServiceGetServices-0-javascript">JavaScript</a></li>
- <!--<li class=""><a href="#examples-Users-activeWidgetLayoutServiceGetServices-0-angular">Angular</a></li>-->
- <li class=""><a href="#examples-Users-activeWidgetLayoutServiceGetServices-0-csharp">C#</a></li>
- <li class=""><a href="#examples-Users-activeWidgetLayoutServiceGetServices-0-php">PHP</a></li>
- <li class=""><a href="#examples-Users-activeWidgetLayoutServiceGetServices-0-perl">Perl</a></li>
- <li class=""><a href="#examples-Users-activeWidgetLayoutServiceGetServices-0-python">Python</a></li>
+ <li class="active"><a href="#examples-UserAuthenticationSources-createAuthenticationSources-0-curl">Curl</a></li>
+ <li class=""><a href="#examples-UserAuthenticationSources-createAuthenticationSources-0-java">Java</a></li>
+ <li class=""><a href="#examples-UserAuthenticationSources-createAuthenticationSources-0-android">Android</a></li>
+ <!--<li class=""><a href="#examples-UserAuthenticationSources-createAuthenticationSources-0-groovy">Groovy</a></li>-->
+ <li class=""><a href="#examples-UserAuthenticationSources-createAuthenticationSources-0-objc">Obj-C</a></li>
+ <li class=""><a href="#examples-UserAuthenticationSources-createAuthenticationSources-0-javascript">JavaScript</a></li>
+ <!--<li class=""><a href="#examples-UserAuthenticationSources-createAuthenticationSources-0-angular">Angular</a></li>-->
+ <li class=""><a href="#examples-UserAuthenticationSources-createAuthenticationSources-0-csharp">C#</a></li>
+ <li class=""><a href="#examples-UserAuthenticationSources-createAuthenticationSources-0-php">PHP</a></li>
+ <li class=""><a href="#examples-UserAuthenticationSources-createAuthenticationSources-0-perl">Perl</a></li>
+ <li class=""><a href="#examples-UserAuthenticationSources-createAuthenticationSources-0-python">Python</a></li>
</ul>
<div class="tab-content">
- <div class="tab-pane active" id="examples-Users-activeWidgetLayoutServiceGetServices-0-curl">
- <pre class="prettyprint"><code class="language-bsh">curl -X <span style="text-transform: uppercase;">get</span> "http://localhost/api/v1/users/{userName}/activeWidgetLayouts?fields=&sortBy=&pageSize=&from=&to="</code></pre>
+ <div class="tab-pane active" id="examples-UserAuthenticationSources-createAuthenticationSources-0-curl">
+ <pre class="prettyprint"><code class="language-bsh">curl -X <span style="text-transform: uppercase;">post</span> "http://localhost/api/v1/users/{userName}/sources"</code></pre>
</div>
- <div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceGetServices-0-java">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-createAuthenticationSources-0-java">
<pre class="prettyprint"><code class="language-java">import io.swagger.client.*;
import io.swagger.client.auth.*;
import io.swagger.client.model.*;
-import io.swagger.client.api.UsersApi;
+import io.swagger.client.api.UserAuthenticationSourcesApi;
import java.io.File;
import java.util.*;
-public class UsersApiExample {
+public class UserAuthenticationSourcesApiExample {
public static void main(String[] args) {
- UsersApi apiInstance = new UsersApi();
+ UserAuthenticationSourcesApi apiInstance = new UserAuthenticationSourcesApi();
String userName = userName_example; // String | user name
- String fields = fields_example; // String | Filter user layout details
- String sortBy = sortBy_example; // String | Sort layouts (asc | desc)
- Integer pageSize = 56; // Integer | The number of resources to be returned for the paged response.
- String from = from_example; // String | The starting page resource (inclusive). Valid values are :offset | "start"
- String to = to_example; // String | The ending page resource (inclusive). Valid values are :offset | "end"
+ UserAuthenticationSourceRequestCreateSwagger body = ; // UserAuthenticationSourceRequestCreateSwagger |
try {
- array[ActiveWidgetLayoutResponse] result = apiInstance.activeWidgetLayoutServiceGetServices(userName, fields, sortBy, pageSize, from, to);
- System.out.println(result);
+ apiInstance.createAuthenticationSources(userName, body);
} catch (ApiException e) {
- System.err.println("Exception when calling UsersApi#activeWidgetLayoutServiceGetServices");
+ System.err.println("Exception when calling UserAuthenticationSourcesApi#createAuthenticationSources");
e.printStackTrace();
}
}
}</code></pre>
</div>
- <div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceGetServices-0-android">
- <pre class="prettyprint"><code class="language-java">import io.swagger.client.api.UsersApi;
+ <div class="tab-pane" id="examples-UserAuthenticationSources-createAuthenticationSources-0-android">
+ <pre class="prettyprint"><code class="language-java">import io.swagger.client.api.UserAuthenticationSourcesApi;
-public class UsersApiExample {
+public class UserAuthenticationSourcesApiExample {
public static void main(String[] args) {
- UsersApi apiInstance = new UsersApi();
+ UserAuthenticationSourcesApi apiInstance = new UserAuthenticationSourcesApi();
String userName = userName_example; // String | user name
- String fields = fields_example; // String | Filter user layout details
- String sortBy = sortBy_example; // String | Sort layouts (asc | desc)
- Integer pageSize = 56; // Integer | The number of resources to be returned for the paged response.
- String from = from_example; // String | The starting page resource (inclusive). Valid values are :offset | "start"
- String to = to_example; // String | The ending page resource (inclusive). Valid values are :offset | "end"
+ UserAuthenticationSourceRequestCreateSwagger body = ; // UserAuthenticationSourceRequestCreateSwagger |
try {
- array[ActiveWidgetLayoutResponse] result = apiInstance.activeWidgetLayoutServiceGetServices(userName, fields, sortBy, pageSize, from, to);
- System.out.println(result);
+ apiInstance.createAuthenticationSources(userName, body);
} catch (ApiException e) {
- System.err.println("Exception when calling UsersApi#activeWidgetLayoutServiceGetServices");
+ System.err.println("Exception when calling UserAuthenticationSourcesApi#createAuthenticationSources");
e.printStackTrace();
}
}
}</code></pre>
</div>
<!--
- <div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceGetServices-0-groovy">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-createAuthenticationSources-0-groovy">
<pre class="prettyprint language-json prettyprinted" data-type="json"><code>Coming Soon!</code></pre>
</div> -->
- <div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceGetServices-0-objc">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-createAuthenticationSources-0-objc">
<pre class="prettyprint"><code class="language-cpp">String *userName = userName_example; // user name
-String *fields = fields_example; // Filter user layout details (optional) (default to WidgetLayoutInfo/*)
-String *sortBy = sortBy_example; // Sort layouts (asc | desc) (optional) (default to WidgetLayoutInfo/user_name.asc)
-Integer *pageSize = 56; // The number of resources to be returned for the paged response. (optional) (default to 10)
-String *from = from_example; // The starting page resource (inclusive). Valid values are :offset | "start" (optional) (default to 0)
-String *to = to_example; // The ending page resource (inclusive). Valid values are :offset | "end" (optional)
+UserAuthenticationSourceRequestCreateSwagger *body = ; // (optional)
-UsersApi *apiInstance = [[UsersApi alloc] init];
+UserAuthenticationSourcesApi *apiInstance = [[UserAuthenticationSourcesApi alloc] init];
-// Get user widget layouts
-[apiInstance activeWidgetLayoutServiceGetServicesWith:userName
- fields:fields
- sortBy:sortBy
- pageSize:pageSize
- from:from
- to:to
- completionHandler: ^(array[ActiveWidgetLayoutResponse] output, NSError* error) {
- if (output) {
- NSLog(@"%@", output);
- }
+// Create one or more new authentication sources for a user
+[apiInstance createAuthenticationSourcesWith:userName
+ body:body
+ completionHandler: ^(NSError* error) {
if (error) {
NSLog(@"Error: %@", error);
}
@@ -45275,36 +45436,32 @@ UsersApi *apiInstance = [[UsersApi alloc] init];
</code></pre>
</div>
- <div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceGetServices-0-javascript">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-createAuthenticationSources-0-javascript">
<pre class="prettyprint"><code class="language-js">var SwaggerSpecForAmbariRestApi = require('swagger_spec_for_ambari_rest_api');
-var api = new SwaggerSpecForAmbariRestApi.UsersApi()
+var api = new SwaggerSpecForAmbariRestApi.UserAuthenticationSourcesApi()
var userName = userName_example; // {String} user name
var opts = {
- 'fields': fields_example, // {String} Filter user layout details
- 'sortBy': sortBy_example, // {String} Sort layouts (asc | desc)
- 'pageSize': 56, // {Integer} The number of resources to be returned for the paged response.
- 'from': from_example, // {String} The starting page resource (inclusive). Valid values are :offset | "start"
- 'to': to_example // {String} The ending page resource (inclusive). Valid values are :offset | "end"
+ 'body': // {UserAuthenticationSourceRequestCreateSwagger}
};
var callback = function(error, data, response) {
if (error) {
console.error(error);
} else {
- console.log('API called successfully. Returned data: ' + data);
+ console.log('API called successfully.');
}
};
-api.activeWidgetLayoutServiceGetServices(userName, opts, callback);
+api.createAuthenticationSources(userName, opts, callback);
</code></pre>
</div>
- <!--<div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceGetServices-0-angular">
+ <!--<div class="tab-pane" id="examples-UserAuthenticationSources-createAuthenticationSources-0-angular">
<pre class="prettyprint language-json prettyprinted" data-type="json"><code>Coming Soon!</code></pre>
</div>-->
- <div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceGetServices-0-csharp">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-createAuthenticationSources-0-csharp">
<pre class="prettyprint"><code class="language-cs">using System;
using System.Diagnostics;
using IO.Swagger.Api;
@@ -45313,78 +45470,63 @@ using IO.Swagger.Model;
namespace Example
{
- public class activeWidgetLayoutServiceGetServicesExample
+ public class createAuthenticationSourcesExample
{
public void main()
{
- var apiInstance = new UsersApi();
+ var apiInstance = new UserAuthenticationSourcesApi();
var userName = userName_example; // String | user name
- var fields = fields_example; // String | Filter user layout details (optional) (default to WidgetLayoutInfo/*)
- var sortBy = sortBy_example; // String | Sort layouts (asc | desc) (optional) (default to WidgetLayoutInfo/user_name.asc)
- var pageSize = 56; // Integer | The number of resources to be returned for the paged response. (optional) (default to 10)
- var from = from_example; // String | The starting page resource (inclusive). Valid values are :offset | "start" (optional) (default to 0)
- var to = to_example; // String | The ending page resource (inclusive). Valid values are :offset | "end" (optional)
+ var body = new UserAuthenticationSourceRequestCreateSwagger(); // UserAuthenticationSourceRequestCreateSwagger | (optional)
try
{
- // Get user widget layouts
- array[ActiveWidgetLayoutResponse] result = apiInstance.activeWidgetLayoutServiceGetServices(userName, fields, sortBy, pageSize, from, to);
- Debug.WriteLine(result);
+ // Create one or more new authentication sources for a user
+ apiInstance.createAuthenticationSources(userName, body);
}
catch (Exception e)
{
- Debug.Print("Exception when calling UsersApi.activeWidgetLayoutServiceGetServices: " + e.Message );
+ Debug.Print("Exception when calling UserAuthenticationSourcesApi.createAuthenticationSources: " + e.Message );
}
}
}
}</code></pre>
</div>
- <div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceGetServices-0-php">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-createAuthenticationSources-0-php">
<pre class="prettyprint"><code class="language-php"><?php
require_once(__DIR__ . '/vendor/autoload.php');
-$api_instance = new Swagger\Client\Api\UsersApi();
+$api_instance = new Swagger\Client\Api\UserAuthenticationSourcesApi();
$userName = userName_example; // String | user name
-$fields = fields_example; // String | Filter user layout details
-$sortBy = sortBy_example; // String | Sort layouts (asc | desc)
-$pageSize = 56; // Integer | The number of resources to be returned for the paged response.
-$from = from_example; // String | The starting page resource (inclusive). Valid values are :offset | "start"
-$to = to_example; // String | The ending page resource (inclusive). Valid values are :offset | "end"
+$body = ; // UserAuthenticationSourceRequestCreateSwagger |
try {
- $result = $api_instance->activeWidgetLayoutServiceGetServices($userName, $fields, $sortBy, $pageSize, $from, $to);
- print_r($result);
+ $api_instance->createAuthenticationSources($userName, $body);
} catch (Exception $e) {
- echo 'Exception when calling UsersApi->activeWidgetLayoutServiceGetServices: ', $e->getMessage(), PHP_EOL;
+ echo 'Exception when calling UserAuthenticationSourcesApi->createAuthenticationSources: ', $e->getMessage(), PHP_EOL;
}
?></code></pre>
</div>
- <div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceGetServices-0-perl">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-createAuthenticationSources-0-perl">
<pre class="prettyprint"><code class="language-perl">use Data::Dumper;
use WWW::SwaggerClient::Configuration;
-use WWW::SwaggerClient::UsersApi;
+use WWW::SwaggerClient::UserAuthenticationSourcesApi;
-my $api_instance = WWW::SwaggerClient::UsersApi->new();
+my $api_instance = WWW::SwaggerClient::UserAuthenticationSourcesApi->new();
my $userName = userName_example; # String | user name
-my $fields = fields_example; # String | Filter user layout details
-my $sortBy = sortBy_example; # String | Sort layouts (asc | desc)
-my $pageSize = 56; # Integer | The number of resources to be returned for the paged response.
-my $from = from_example; # String | The starting page resource (inclusive). Valid values are :offset | "start"
-my $to = to_example; # String | The ending page resource (inclusive). Valid values are :offset | "end"
+my $body = WWW::SwaggerClient::Object::UserAuthenticationSourceRequestCreateSwagger->new(); # UserAuthenticationSourceRequestCreateSwagger |
eval {
- my $result = $api_instance->activeWidgetLayoutServiceGetServices(userName => $userName, fields => $fields, sortBy => $sortBy, pageSize => $pageSize, from => $from, to => $to);
- print Dumper($result);
+ $api_instance->createAuthenticationSources(userName => $userName, body => $body);
};
if ($@) {
- warn "Exception when calling UsersApi->activeWidgetLayoutServiceGetServices: $@\n";
+ warn "Exception when calling UserAuthenticationSourcesApi->createAuthenticationSources: $@\n";
}</code></pre>
</div>
- <div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceGetServices-0-python">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-createAuthenticationSources-0-python">
<pre class="prettyprint"><code class="language-python">from __future__ import print_statement
import time
import swagger_client
@@ -45392,20 +45534,15 @@ from swagger_client.rest import ApiException
from pprint import pprint
# create an instance of the API class
-api_instance = swagger_client.UsersApi()
+api_instance = swagger_client.UserAuthenticationSourcesApi()
userName = userName_example # String | user name
-fields = fields_example # String | Filter user layout details (optional) (default to WidgetLayoutInfo/*)
-sortBy = sortBy_example # String | Sort layouts (asc | desc) (optional) (default to WidgetLayoutInfo/user_name.asc)
-pageSize = 56 # Integer | The number of resources to be returned for the paged response. (optional) (default to 10)
-from = from_example # String | The starting page resource (inclusive). Valid values are :offset | "start" (optional) (default to 0)
-to = to_example # String | The ending page resource (inclusive). Valid values are :offset | "end" (optional)
+body = # UserAuthenticationSourceRequestCreateSwagger | (optional)
try:
- # Get user widget layouts
- api_response = api_instance.activeWidgetLayoutServiceGetServices(userName, fields=fields, sortBy=sortBy, pageSize=pageSize, from=from, to=to)
- pprint(api_response)
+ # Create one or more new authentication sources for a user
+ api_instance.createAuthenticationSources(userName, body=body)
except ApiException as e:
- print("Exception when calling UsersApi->activeWidgetLayoutServiceGetServices: %s\n" % e)</code></pre>
+ print("Exception when calling UserAuthenticationSourcesApi->createAuthenticationSources: %s\n" % e)</code></pre>
</div>
</div>
@@ -45436,7 +45573,7 @@ except ApiException as e:
var view = new JSONSchemaView(schema,1);
- var result = $('#d2e199_activeWidgetLayoutServiceGetServices_userName');
+ var result = $('#d2e199_createAuthenticationSources_userName');
result.empty();
result.append(view.render());
@@ -45446,332 +45583,225 @@ except ApiException as e:
});
</script>
- <div id="d2e199_activeWidgetLayoutServiceGetServices_userName"></div>
+ <div id="d2e199_createAuthenticationSources_userName"></div>
</td>
</tr>
</table>
-
-
- <div class="methodsubtabletitle">Query parameters</div>
+ <div class="methodsubtabletitle">Body parameters</div>
<table id="methodsubtable">
<tr>
<th width="150px">Name</th>
<th>Description</th>
</tr>
- <tr><td style="width:150px;">fields</td>
-<td>
-
-
-<script>
- $(document).ready(function() {
- var schemaWrapper = {
- "name" : "fields",
- "in" : "query",
- "description" : "Filter user layout details",
- "required" : false,
- "type" : "string",
- "default" : "WidgetLayoutInfo/*"
-};
- var schema = schemaWrapper;
-
-
-
-
- var view = new JSONSchemaView(schema,1);
- var result = $('#d2e199_activeWidgetLayoutServiceGetServices_fields');
- result.empty();
- result.append(view.render());
-
-
-
-
-
- });
- </script>
- <div id="d2e199_activeWidgetLayoutServiceGetServices_fields"></div>
-</td>
-</tr>
-
- <tr><td style="width:150px;">sortBy</td>
+ <tr><td style="width:150px;">body </td>
<td>
<script>
$(document).ready(function() {
var schemaWrapper = {
- "name" : "sortBy",
- "in" : "query",
- "description" : "Sort layouts (asc | desc)",
+ "in" : "body",
+ "name" : "body",
"required" : false,
- "type" : "string",
- "default" : "WidgetLayoutInfo/user_name.asc"
+ "schema" : {
+ "$ref" : "#/definitions/UserAuthenticationSourceRequestCreateSwagger"
+ }
};
- var schema = schemaWrapper;
-
-
-
+
+ var schema = schemaWrapper.schema;
+ schemaWrapper.definitions = defs;
+ JsonRefs.resolveRefs(schemaWrapper, {"depth":3, "resolveRemoteRefs":false,"resolveFileRefs":false },function (err, resolved, metadata) {
+
- var view = new JSONSchemaView(schema,1);
- var result = $('#d2e199_activeWidgetLayoutServiceGetServices_sortBy');
+
+ var view = new JSONSchemaView(resolved.schema,2,{isBodyParam: true});
+
+ var result = $('#d2e199_createAuthenticationSources_body');
result.empty();
result.append(view.render());
+
-
-
+
+
+
});
- </script>
- <div id="d2e199_activeWidgetLayoutServiceGetServices_sortBy"></div>
-</td>
-</tr>
-
- <tr><td style="width:150px;">page_size</td>
-<td>
-
-
-<script>
- $(document).ready(function() {
- var schemaWrapper = {
- "name" : "page_size",
- "in" : "query",
- "description" : "The number of resources to be returned for the paged response.",
- "required" : false,
- "type" : "integer",
- "default" : 10
-};
- var schema = schemaWrapper;
-
-
-
-
- var view = new JSONSchemaView(schema,1);
- var result = $('#d2e199_activeWidgetLayoutServiceGetServices_pageSize');
- result.empty();
- result.append(view.render());
-
-
});
</script>
- <div id="d2e199_activeWidgetLayoutServiceGetServices_pageSize"></div>
+ <div id="d2e199_createAuthenticationSources_body"></div>
</td>
</tr>
- <tr><td style="width:150px;">from</td>
-<td>
-
+ </table>
-<script>
- $(document).ready(function() {
- var schemaWrapper = {
- "name" : "from",
- "in" : "query",
- "description" : "The starting page resource (inclusive). Valid values are :offset | \"start\"",
- "required" : false,
- "type" : "string",
- "default" : "0"
-};
- var schema = schemaWrapper;
+ <h2>Responses</h2>
+ <h3> Status: 201 - Successful operation </h3>
+ <ul class="nav nav-tabs nav-tabs-examples" >
+ </ul>
- var view = new JSONSchemaView(schema,1);
- var result = $('#d2e199_activeWidgetLayoutServiceGetServices_from');
- result.empty();
- result.append(view.render());
+ <div class="tab-content" style='margin-bottom: 10px;'>
+ </div>
+ <h3> Status: 202 - Request is accepted, but not completely processed yet </h3>
+ <ul class="nav nav-tabs nav-tabs-examples" >
+ </ul>
+ <div class="tab-content" style='margin-bottom: 10px;'>
+ </div>
+ <h3> Status: 400 - Invalid arguments </h3>
- });
- </script>
- <div id="d2e199_activeWidgetLayoutServiceGetServices_from"></div>
-</td>
-</tr>
+ <ul class="nav nav-tabs nav-tabs-examples" >
+ </ul>
- <tr><td style="width:150px;">to</td>
-<td>
+ <div class="tab-content" style='margin-bottom: 10px;'>
+ </div>
+ <h3> Status: 401 - Not authenticated </h3>
-<script>
- $(document).ready(function() {
- var schemaWrapper = {
- "name" : "to",
- "in" : "query",
- "description" : "The ending page resource (inclusive). Valid values are :offset | \"end\"",
- "required" : false,
- "type" : "string"
-};
- var schema = schemaWrapper;
+ <ul class="nav nav-tabs nav-tabs-examples" >
+ </ul>
+ <div class="tab-content" style='margin-bottom: 10px;'>
+ </div>
+ <h3> Status: 403 - Not permitted to perform the operation </h3>
+ <ul class="nav nav-tabs nav-tabs-examples" >
+ </ul>
- var view = new JSONSchemaView(schema,1);
- var result = $('#d2e199_activeWidgetLayoutServiceGetServices_to');
- result.empty();
- result.append(view.render());
+ <div class="tab-content" style='margin-bottom: 10px;'>
+ </div>
+ <h3> Status: 404 - The requested resource doesn't exist. </h3>
+ <ul class="nav nav-tabs nav-tabs-examples" >
+ </ul>
+ <div class="tab-content" style='margin-bottom: 10px;'>
+ </div>
+ <h3> Status: 409 - The requested resource already exists. </h3>
- });
- </script>
- <div id="d2e199_activeWidgetLayoutServiceGetServices_to"></div>
-</td>
-</tr>
+ <ul class="nav nav-tabs nav-tabs-examples" >
+ </ul>
- </table>
+ <div class="tab-content" style='margin-bottom: 10px;'>
+ </div>
- <h2>Responses</h2>
- <h3> Status: 200 - successful operation </h3>
+ <h3> Status: 500 - Internal server error </h3>
<ul class="nav nav-tabs nav-tabs-examples" >
- <li class="active">
- <a data-toggle="tab" href="#responses-activeWidgetLayoutServiceGetServices-200-schema">Schema</a>
- </li>
-
</ul>
<div class="tab-content" style='margin-bottom: 10px;'>
- <div class="tab-pane active" id="responses-activeWidgetLayoutServiceGetServices-200-schema">
- <div id='responses-activeWidgetLayoutServiceGetServices-200-schema-200' style="padding: 30px; border-left: 1px solid #eee; border-right: 1px solid #eee; border-bottom: 1px solid #eee;">
- <script>
- $(document).ready(function() {
- var schemaWrapper = {
- "description" : "successful operation",
- "schema" : {
- "type" : "array",
- "items" : {
- "$ref" : "#/definitions/ActiveWidgetLayoutResponse"
- }
- }
-};
- var schema = schemaWrapper.schema;
- schemaWrapper.definitions = defs;
- //console.log(JSON.stringify(schema))
- JsonRefs.resolveRefs(schemaWrapper, {
- "depth": 3,
- "resolveRemoteRefs": false,
- "resolveFileRefs": false
- }, function(err, resolved, metadata) {
- //console.log(JSON.stringify(resolved));
- var view = new JSONSchemaView(resolved.schema, 3);
- $('#responses-activeWidgetLayoutServiceGetServices-200-schema-data').val(JSON.stringify(resolved.schema));
- var result = $('#responses-activeWidgetLayoutServiceGetServices-200-schema-200');
- result.empty();
- result.append(view.render());
- });
- });
- </script>
- </div>
- <input id='responses-activeWidgetLayoutServiceGetServices-200-schema-data' type='hidden' value=''></input>
- </div>
</div>
</article>
</div>
<hr>
- <div id="api-Users-activeWidgetLayoutServiceUpdateServices">
- <article id="api-Users-activeWidgetLayoutServiceUpdateServices-0" data-group="User" data-name="activeWidgetLayoutServiceUpdateServices" data-version="0">
+ <div id="api-UserAuthenticationSources-deleteAuthenticationSource">
+ <article id="api-UserAuthenticationSources-deleteAuthenticationSource-0" data-group="User" data-name="deleteAuthenticationSource" data-version="0">
<div class="pull-left">
- <h1>activeWidgetLayoutServiceUpdateServices</h1>
- <p>Update user widget layouts</p>
+ <h1>deleteAuthenticationSource</h1>
+ <p>Deletes an existing authentication source</p>
</div>
<div class="pull-right"></div>
<div class="clearfix"></div>
<p></p>
- <p class="marked">Updates user widget layout.</p>
+ <p class="marked"></p>
<p></p>
<br />
- <pre class="prettyprint language-html prettyprinted" data-type="put"><code><span class="pln">/users/{userName}/activeWidgetLayouts</span></code></pre>
+ <pre class="prettyprint language-html prettyprinted" data-type="delete"><code><span class="pln">/users/{userName}/sources/{sourceId}</span></code></pre>
<p>
<h3>Usage and SDK Samples</h3>
</p>
<ul class="nav nav-tabs nav-tabs-examples">
- <li class="active"><a href="#examples-Users-activeWidgetLayoutServiceUpdateServices-0-curl">Curl</a></li>
- <li class=""><a href="#examples-Users-activeWidgetLayoutServiceUpdateServices-0-java">Java</a></li>
- <li class=""><a href="#examples-Users-activeWidgetLayoutServiceUpdateServices-0-android">Android</a></li>
- <!--<li class=""><a href="#examples-Users-activeWidgetLayoutServiceUpdateServices-0-groovy">Groovy</a></li>-->
- <li class=""><a href="#examples-Users-activeWidgetLayoutServiceUpdateServices-0-objc">Obj-C</a></li>
- <li class=""><a href="#examples-Users-activeWidgetLayoutServiceUpdateServices-0-javascript">JavaScript</a></li>
- <!--<li class=""><a href="#examples-Users-activeWidgetLayoutServiceUpdateServices-0-angular">Angular</a></li>-->
- <li class=""><a href="#examples-Users-activeWidgetLayoutServiceUpdateServices-0-csharp">C#</a></li>
- <li class=""><a href="#examples-Users-activeWidgetLayoutServiceUpdateServices-0-php">PHP</a></li>
- <li class=""><a href="#examples-Users-activeWidgetLayoutServiceUpdateServices-0-perl">Perl</a></li>
- <li class=""><a href="#examples-Users-activeWidgetLayoutServiceUpdateServices-0-python">Python</a></li>
+ <li class="active"><a href="#examples-UserAuthenticationSources-deleteAuthenticationSource-0-curl">Curl</a></li>
+ <li class=""><a href="#examples-UserAuthenticationSources-deleteAuthenticationSource-0-java">Java</a></li>
+ <li class=""><a href="#examples-UserAuthenticationSources-deleteAuthenticationSource-0-android">Android</a></li>
+ <!--<li class=""><a href="#examples-UserAuthenticationSources-deleteAuthenticationSource-0-groovy">Groovy</a></li>-->
+ <li class=""><a href="#examples-UserAuthenticationSources-deleteAuthenticationSource-0-objc">Obj-C</a></li>
+ <li class=""><a href="#examples-UserAuthenticationSources-deleteAuthenticationSource-0-javascript">JavaScript</a></li>
+ <!--<li class=""><a href="#examples-UserAuthenticationSources-deleteAuthenticationSource-0-angular">Angular</a></li>-->
+ <li class=""><a href="#examples-UserAuthenticationSources-deleteAuthenticationSource-0-csharp">C#</a></li>
+ <li class=""><a href="#examples-UserAuthenticationSources-deleteAuthenticationSource-0-php">PHP</a></li>
+ <li class=""><a href="#examples-UserAuthenticationSources-deleteAuthenticationSource-0-perl">Perl</a></li>
+ <li class=""><a href="#examples-UserAuthenticationSources-deleteAuthenticationSource-0-python">Python</a></li>
</ul>
<div class="tab-content">
- <div class="tab-pane active" id="examples-Users-activeWidgetLayoutServiceUpdateServices-0-curl">
- <pre class="prettyprint"><code class="language-bsh">curl -X <span style="text-transform: uppercase;">put</span> "http://localhost/api/v1/users/{userName}/activeWidgetLayouts"</code></pre>
+ <div class="tab-pane active" id="examples-UserAuthenticationSources-deleteAuthenticationSource-0-curl">
+ <pre class="prettyprint"><code class="language-bsh">curl -X <span style="text-transform: uppercase;">delete</span> "http://localhost/api/v1/users/{userName}/sources/{sourceId}"</code></pre>
</div>
- <div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceUpdateServices-0-java">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-deleteAuthenticationSource-0-java">
<pre class="prettyprint"><code class="language-java">import io.swagger.client.*;
import io.swagger.client.auth.*;
import io.swagger.client.model.*;
-import io.swagger.client.api.UsersApi;
+import io.swagger.client.api.UserAuthenticationSourcesApi;
import java.io.File;
import java.util.*;
-public class UsersApiExample {
+public class UserAuthenticationSourcesApiExample {
public static void main(String[] args) {
- UsersApi apiInstance = new UsersApi();
+ UserAuthenticationSourcesApi apiInstance = new UserAuthenticationSourcesApi();
String userName = userName_example; // String | user name
- ActiveWidgetLayoutRequest body = ; // ActiveWidgetLayoutRequest | input parameters in json form
+ String sourceId = sourceId_example; // String | source id
try {
- apiInstance.activeWidgetLayoutServiceUpdateServices(userName, body);
+ apiInstance.deleteAuthenticationSource(userName, sourceId);
} catch (ApiException e) {
- System.err.println("Exception when calling UsersApi#activeWidgetLayoutServiceUpdateServices");
+ System.err.println("Exception when calling UserAuthenticationSourcesApi#deleteAuthenticationSource");
e.printStackTrace();
}
}
}</code></pre>
</div>
- <div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceUpdateServices-0-android">
- <pre class="prettyprint"><code class="language-java">import io.swagger.client.api.UsersApi;
+ <div class="tab-pane" id="examples-UserAuthenticationSources-deleteAuthenticationSource-0-android">
+ <pre class="prettyprint"><code class="language-java">import io.swagger.client.api.UserAuthenticationSourcesApi;
-public class UsersApiExample {
+public class UserAuthenticationSourcesApiExample {
public static void main(String[] args) {
- UsersApi apiInstance = new UsersApi();
+ UserAuthenticationSourcesApi apiInstance = new UserAuthenticationSourcesApi();
String userName = userName_example; // String | user name
- ActiveWidgetLayoutRequest body = ; // ActiveWidgetLayoutRequest | input parameters in json form
+ String sourceId = sourceId_example; // String | source id
try {
- apiInstance.activeWidgetLayoutServiceUpdateServices(userName, body);
+ apiInstance.deleteAuthenticationSource(userName, sourceId);
} catch (ApiException e) {
- System.err.println("Exception when calling UsersApi#activeWidgetLayoutServiceUpdateServices");
+ System.err.println("Exception when calling UserAuthenticationSourcesApi#deleteAuthenticationSource");
e.printStackTrace();
}
}
}</code></pre>
</div>
<!--
- <div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceUpdateServices-0-groovy">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-deleteAuthenticationSource-0-groovy">
<pre class="prettyprint language-json prettyprinted" data-type="json"><code>Coming Soon!</code></pre>
</div> -->
- <div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceUpdateServices-0-objc">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-deleteAuthenticationSource-0-objc">
<pre class="prettyprint"><code class="language-cpp">String *userName = userName_example; // user name
-ActiveWidgetLayoutRequest *body = ; // input parameters in json form
+String *sourceId = sourceId_example; // source id
-UsersApi *apiInstance = [[UsersApi alloc] init];
+UserAuthenticationSourcesApi *apiInstance = [[UserAuthenticationSourcesApi alloc] init];
-// Update user widget layouts
-[apiInstance activeWidgetLayoutServiceUpdateServicesWith:userName
- body:body
+// Deletes an existing authentication source
+[apiInstance deleteAuthenticationSourceWith:userName
+ sourceId:sourceId
completionHandler: ^(NSError* error) {
if (error) {
NSLog(@"Error: %@", error);
@@ -45780,14 +45810,14 @@ UsersApi *apiInstance = [[UsersApi alloc] init];
</code></pre>
</div>
- <div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceUpdateServices-0-javascript">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-deleteAuthenticationSource-0-javascript">
<pre class="prettyprint"><code class="language-js">var SwaggerSpecForAmbariRestApi = require('swagger_spec_for_ambari_rest_api');
-var api = new SwaggerSpecForAmbariRestApi.UsersApi()
+var api = new SwaggerSpecForAmbariRestApi.UserAuthenticationSourcesApi()
var userName = userName_example; // {String} user name
-var body = ; // {ActiveWidgetLayoutRequest} input parameters in json form
+var sourceId = sourceId_example; // {String} source id
var callback = function(error, data, response) {
@@ -45797,14 +45827,14 @@ var callback = function(error, data, response) {
console.log('API called successfully.');
}
};
-api.activeWidgetLayoutServiceUpdateServices(userName, body, callback);
+api.deleteAuthenticationSource(userName, sourceId, callback);
</code></pre>
</div>
- <!--<div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceUpdateServices-0-angular">
+ <!--<div class="tab-pane" id="examples-UserAuthenticationSources-deleteAuthenticationSource-0-angular">
<pre class="prettyprint language-json prettyprinted" data-type="json"><code>Coming Soon!</code></pre>
</div>-->
- <div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceUpdateServices-0-csharp">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-deleteAuthenticationSource-0-csharp">
<pre class="prettyprint"><code class="language-cs">using System;
using System.Diagnostics;
using IO.Swagger.Api;
@@ -45813,63 +45843,63 @@ using IO.Swagger.Model;
namespace Example
{
- public class activeWidgetLayoutServiceUpdateServicesExample
+ public class deleteAuthenticationSourceExample
{
public void main()
{
- var apiInstance = new UsersApi();
+ var apiInstance = new UserAuthenticationSourcesApi();
var userName = userName_example; // String | user name
- var body = new ActiveWidgetLayoutRequest(); // ActiveWidgetLayoutRequest | input parameters in json form
+ var sourceId = sourceId_example; // String | source id
try
{
- // Update user widget layouts
- apiInstance.activeWidgetLayoutServiceUpdateServices(userName, body);
+ // Deletes an existing authentication source
+ apiInstance.deleteAuthenticationSource(userName, sourceId);
}
catch (Exception e)
{
- Debug.Print("Exception when calling UsersApi.activeWidgetLayoutServiceUpdateServices: " + e.Message );
+ Debug.Print("Exception when calling UserAuthenticationSourcesApi.deleteAuthenticationSource: " + e.Message );
}
}
}
}</code></pre>
</div>
- <div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceUpdateServices-0-php">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-deleteAuthenticationSource-0-php">
<pre class="prettyprint"><code class="language-php"><?php
require_once(__DIR__ . '/vendor/autoload.php');
-$api_instance = new Swagger\Client\Api\UsersApi();
+$api_instance = new Swagger\Client\Api\UserAuthenticationSourcesApi();
$userName = userName_example; // String | user name
-$body = ; // ActiveWidgetLayoutRequest | input parameters in json form
+$sourceId = sourceId_example; // String | source id
try {
- $api_instance->activeWidgetLayoutServiceUpdateServices($userName, $body);
+ $api_instance->deleteAuthenticationSource($userName, $sourceId);
} catch (Exception $e) {
- echo 'Exception when calling UsersApi->activeWidgetLayoutServiceUpdateServices: ', $e->getMessage(), PHP_EOL;
+ echo 'Exception when calling UserAuthenticationSourcesApi->deleteAuthenticationSource: ', $e->getMessage(), PHP_EOL;
}
?></code></pre>
</div>
- <div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceUpdateServices-0-perl">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-deleteAuthenticationSource-0-perl">
<pre class="prettyprint"><code class="language-perl">use Data::Dumper;
use WWW::SwaggerClient::Configuration;
-use WWW::SwaggerClient::UsersApi;
+use WWW::SwaggerClient::UserAuthenticationSourcesApi;
-my $api_instance = WWW::SwaggerClient::UsersApi->new();
+my $api_instance = WWW::SwaggerClient::UserAuthenticationSourcesApi->new();
my $userName = userName_example; # String | user name
-my $body = WWW::SwaggerClient::Object::ActiveWidgetLayoutRequest->new(); # ActiveWidgetLayoutRequest | input parameters in json form
+my $sourceId = sourceId_example; # String | source id
eval {
- $api_instance->activeWidgetLayoutServiceUpdateServices(userName => $userName, body => $body);
+ $api_instance->deleteAuthenticationSource(userName => $userName, sourceId => $sourceId);
};
if ($@) {
- warn "Exception when calling UsersApi->activeWidgetLayoutServiceUpdateServices: $@\n";
+ warn "Exception when calling UserAuthenticationSourcesApi->deleteAuthenticationSource: $@\n";
}</code></pre>
</div>
- <div class="tab-pane" id="examples-Users-activeWidgetLayoutServiceUpdateServices-0-python">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-deleteAuthenticationSource-0-python">
<pre class="prettyprint"><code class="language-python">from __future__ import print_statement
import time
import swagger_client
@@ -45877,15 +45907,15 @@ from swagger_client.rest import ApiException
from pprint import pprint
# create an instance of the API class
-api_instance = swagger_client.UsersApi()
+api_instance = swagger_client.UserAuthenticationSourcesApi()
userName = userName_example # String | user name
-body = # ActiveWidgetLayoutRequest | input parameters in json form
+sourceId = sourceId_example # String | source id
try:
- # Update user widget layouts
- api_instance.activeWidgetLayoutServiceUpdateServices(userName, body)
+ # Deletes an existing authentication source
+ api_instance.deleteAuthenticationSource(userName, sourceId)
except ApiException as e:
- print("Exception when calling UsersApi->activeWidgetLayoutServiceUpdateServices: %s\n" % e)</code></pre>
+ print("Exception when calling UserAuthenticationSourcesApi->deleteAuthenticationSource: %s\n" % e)</code></pre>
</div>
</div>
@@ -45916,7 +45946,7 @@ except ApiException as e:
var view = new JSONSchemaView(schema,1);
- var result = $('#d2e199_activeWidgetLayoutServiceUpdateServices_userName');
+ var result = $('#d2e199_deleteAuthenticationSource_userName');
result.empty();
result.append(view.render());
@@ -45926,60 +45956,40 @@ except ApiException as e:
});
</script>
- <div id="d2e199_activeWidgetLayoutServiceUpdateServices_userName"></div>
+ <div id="d2e199_deleteAuthenticationSource_userName"></div>
</td>
</tr>
- </table>
-
-
- <div class="methodsubtabletitle">Body parameters</div>
- <table id="methodsubtable">
- <tr>
- <th width="150px">Name</th>
- <th>Description</th>
- </tr>
- <tr><td style="width:150px;">body <span style="color:red;">*</span></td>
+ <tr><td style="width:150px;">sourceId*</td>
<td>
<script>
$(document).ready(function() {
var schemaWrapper = {
- "in" : "body",
- "name" : "body",
- "description" : "input parameters in json form",
+ "name" : "sourceId",
+ "in" : "path",
+ "description" : "source id",
"required" : true,
- "schema" : {
- "$ref" : "#/definitions/ActiveWidgetLayoutRequest"
- }
+ "type" : "string"
};
-
- var schema = schemaWrapper.schema;
- schemaWrapper.definitions = defs;
- JsonRefs.resolveRefs(schemaWrapper, {"depth":3, "resolveRemoteRefs":false,"resolveFileRefs":false },function (err, resolved, metadata) {
-
+ var schema = schemaWrapper;
-
- var view = new JSONSchemaView(resolved.schema,2,{isBodyParam: true});
-
- var result = $('#d2e199_activeWidgetLayoutServiceUpdateServices_body');
+
+
+
+ var view = new JSONSchemaView(schema,1);
+ var result = $('#d2e199_deleteAuthenticationSource_sourceId');
result.empty();
result.append(view.render());
-
-
-
-
-
- });
});
</script>
- <div id="d2e199_activeWidgetLayoutServiceUpdateServices_body"></div>
+ <div id="d2e199_deleteAuthenticationSource_sourceId"></div>
</td>
</tr>
@@ -45987,6 +45997,8 @@ except ApiException as e:
+
+
<h2>Responses</h2>
<h3> Status: 200 - Successful operation </h3>
@@ -45996,7 +46008,31 @@ except ApiException as e:
<div class="tab-content" style='margin-bottom: 10px;'>
</div>
- <h3> Status: 500 - Server Error </h3>
+ <h3> Status: 401 - Not authenticated </h3>
+
+ <ul class="nav nav-tabs nav-tabs-examples" >
+ </ul>
+
+ <div class="tab-content" style='margin-bottom: 10px;'>
+ </div>
+
+ <h3> Status: 403 - Not permitted to perform the operation </h3>
+
+ <ul class="nav nav-tabs nav-tabs-examples" >
+ </ul>
+
+ <div class="tab-content" style='margin-bottom: 10px;'>
+ </div>
+
+ <h3> Status: 404 - The requested resource doesn't exist. </h3>
+
+ <ul class="nav nav-tabs nav-tabs-examples" >
+ </ul>
+
+ <div class="tab-content" style='margin-bottom: 10px;'>
+ </div>
+
+ <h3> Status: 500 - Internal server error </h3>
<ul class="nav nav-tabs nav-tabs-examples" >
</ul>
@@ -46007,104 +46043,104 @@ except ApiException as e:
</article>
</div>
<hr>
- <div id="api-Users-userAuthorizationServiceGetAuthorization">
- <article id="api-Users-userAuthorizationServiceGetAuthorization-0" data-group="User" data-name="userAuthorizationServiceGetAuthorization" data-version="0">
+ <div id="api-UserAuthenticationSources-getAuthenticationSource">
+ <article id="api-UserAuthenticationSources-getAuthenticationSource-0" data-group="User" data-name="getAuthenticationSource" data-version="0">
<div class="pull-left">
- <h1>userAuthorizationServiceGetAuthorization</h1>
- <p>Get user authorization</p>
+ <h1>getAuthenticationSource</h1>
+ <p>Get user authentication source</p>
</div>
<div class="pull-right"></div>
<div class="clearfix"></div>
<p></p>
- <p class="marked">Returns user authorization details.</p>
+ <p class="marked"></p>
<p></p>
<br />
- <pre class="prettyprint language-html prettyprinted" data-type="get"><code><span class="pln">/users/{userName}/authorizations/{authorization_id}</span></code></pre>
+ <pre class="prettyprint language-html prettyprinted" data-type="get"><code><span class="pln">/users/{userName}/sources/{sourceId}</span></code></pre>
<p>
<h3>Usage and SDK Samples</h3>
</p>
<ul class="nav nav-tabs nav-tabs-examples">
- <li class="active"><a href="#examples-Users-userAuthorizationServiceGetAuthorization-0-curl">Curl</a></li>
- <li class=""><a href="#examples-Users-userAuthorizationServiceGetAuthorization-0-java">Java</a></li>
- <li class=""><a href="#examples-Users-userAuthorizationServiceGetAuthorization-0-android">Android</a></li>
- <!--<li class=""><a href="#examples-Users-userAuthorizationServiceGetAuthorization-0-groovy">Groovy</a></li>-->
- <li class=""><a href="#examples-Users-userAuthorizationServiceGetAuthorization-0-objc">Obj-C</a></li>
- <li class=""><a href="#examples-Users-userAuthorizationServiceGetAuthorization-0-javascript">JavaScript</a></li>
- <!--<li class=""><a href="#examples-Users-userAuthorizationServiceGetAuthorization-0-angular">Angular</a></li>-->
- <li class=""><a href="#examples-Users-userAuthorizationServiceGetAuthorization-0-csharp">C#</a></li>
- <li class=""><a href="#examples-Users-userAuthorizationServiceGetAuthorization-0-php">PHP</a></li>
- <li class=""><a href="#examples-Users-userAuthorizationServiceGetAuthorization-0-perl">Perl</a></li>
- <li class=""><a href="#examples-Users-userAuthorizationServiceGetAuthorization-0-python">Python</a></li>
+ <li class="active"><a href="#examples-UserAuthenticationSources-getAuthenticationSource-0-curl">Curl</a></li>
+ <li class=""><a href="#examples-UserAuthenticationSources-getAuthenticationSource-0-java">Java</a></li>
+ <li class=""><a href="#examples-UserAuthenticationSources-getAuthenticationSource-0-android">Android</a></li>
+ <!--<li class=""><a href="#examples-UserAuthenticationSources-getAuthenticationSource-0-groovy">Groovy</a></li>-->
+ <li class=""><a href="#examples-UserAuthenticationSources-getAuthenticationSource-0-objc">Obj-C</a></li>
+ <li class=""><a href="#examples-UserAuthenticationSources-getAuthenticationSource-0-javascript">JavaScript</a></li>
+ <!--<li class=""><a href="#examples-UserAuthenticationSources-getAuthenticationSource-0-angular">Angular</a></li>-->
+ <li class=""><a href="#examples-UserAuthenticationSources-getAuthenticationSource-0-csharp">C#</a></li>
+ <li class=""><a href="#examples-UserAuthenticationSources-getAuthenticationSource-0-php">PHP</a></li>
+ <li class=""><a href="#examples-UserAuthenticationSources-getAuthenticationSource-0-perl">Perl</a></li>
+ <li class=""><a href="#examples-UserAuthenticationSources-getAuthenticationSource-0-python">Python</a></li>
</ul>
<div class="tab-content">
- <div class="tab-pane active" id="examples-Users-userAuthorizationServiceGetAuthorization-0-curl">
- <pre class="prettyprint"><code class="language-bsh">curl -X <span style="text-transform: uppercase;">get</span> "http://localhost/api/v1/users/{userName}/authorizations/{authorization_id}?fields="</code></pre>
+ <div class="tab-pane active" id="examples-UserAuthenticationSources-getAuthenticationSource-0-curl">
+ <pre class="prettyprint"><code class="language-bsh">curl -X <span style="text-transform: uppercase;">get</span> "http://localhost/api/v1/users/{userName}/sources/{sourceId}?fields="</code></pre>
</div>
- <div class="tab-pane" id="examples-Users-userAuthorizationServiceGetAuthorization-0-java">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-getAuthenticationSource-0-java">
<pre class="prettyprint"><code class="language-java">import io.swagger.client.*;
import io.swagger.client.auth.*;
import io.swagger.client.model.*;
-import io.swagger.client.api.UsersApi;
+import io.swagger.client.api.UserAuthenticationSourcesApi;
import java.io.File;
import java.util.*;
-public class UsersApiExample {
+public class UserAuthenticationSourcesApiExample {
public static void main(String[] args) {
- UsersApi apiInstance = new UsersApi();
+ UserAuthenticationSourcesApi apiInstance = new UserAuthenticationSourcesApi();
String userName = userName_example; // String | user name
- String authorizationId = authorizationId_example; // String | Authorization Id
- String fields = fields_example; // String | Filter user authorization details
+ String sourceId = sourceId_example; // String | source id
+ String fields = fields_example; // String | Filter fields in the response (identifier fields are mandatory)
try {
- UserAuthorizationResponse result = apiInstance.userAuthorizationServiceGetAuthorization(userName, authorizationId, fields);
+ UserAuthenticationSourceResponseSwagger result = apiInstance.getAuthenticationSource(userName, sourceId, fields);
System.out.println(result);
} catch (ApiException e) {
- System.err.println("Exception when calling UsersApi#userAuthorizationServiceGetAuthorization");
+ System.err.println("Exception when calling UserAuthenticationSourcesApi#getAuthenticationSource");
e.printStackTrace();
}
}
}</code></pre>
</div>
- <div class="tab-pane" id="examples-Users-userAuthorizationServiceGetAuthorization-0-android">
- <pre class="prettyprint"><code class="language-java">import io.swagger.client.api.UsersApi;
+ <div class="tab-pane" id="examples-UserAuthenticationSources-getAuthenticationSource-0-android">
+ <pre class="prettyprint"><code class="language-java">import io.swagger.client.api.UserAuthenticationSourcesApi;
-public class UsersApiExample {
+public class UserAuthenticationSourcesApiExample {
public static void main(String[] args) {
- UsersApi apiInstance = new UsersApi();
+ UserAuthenticationSourcesApi apiInstance = new UserAuthenticationSourcesApi();
String userName = userName_example; // String | user name
- String authorizationId = authorizationId_example; // String | Authorization Id
- String fields = fields_example; // String | Filter user authorization details
+ String sourceId = sourceId_example; // String | source id
+ String fields = fields_example; // String | Filter fields in the response (identifier fields are mandatory)
try {
- UserAuthorizationResponse result = apiInstance.userAuthorizationServiceGetAuthorization(userName, authorizationId, fields);
+ UserAuthenticationSourceResponseSwagger result = apiInstance.getAuthenticationSource(userName, sourceId, fields);
System.out.println(result);
} catch (ApiException e) {
- System.err.println("Exception when calling UsersApi#userAuthorizationServiceGetAuthorization");
+ System.err.println("Exception when calling UserAuthenticationSourcesApi#getAuthenticationSource");
e.printStackTrace();
}
}
}</code></pre>
</div>
<!--
- <div class="tab-pane" id="examples-Users-userAuthorizationServiceGetAuthorization-0-groovy">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-getAuthenticationSource-0-groovy">
<pre class="prettyprint language-json prettyprinted" data-type="json"><code>Coming Soon!</code></pre>
</div> -->
- <div class="tab-pane" id="examples-Users-userAuthorizationServiceGetAuthorization-0-objc">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-getAuthenticationSource-0-objc">
<pre class="prettyprint"><code class="language-cpp">String *userName = userName_example; // user name
-String *authorizationId = authorizationId_example; // Authorization Id
-String *fields = fields_example; // Filter user authorization details (optional) (default to AuthorizationInfo/*)
+String *sourceId = sourceId_example; // source id
+String *fields = fields_example; // Filter fields in the response (identifier fields are mandatory) (optional) (default to AuthenticationSourceInfo/*)
-UsersApi *apiInstance = [[UsersApi alloc] init];
+UserAuthenticationSourcesApi *apiInstance = [[UserAuthenticationSourcesApi alloc] init];
-// Get user authorization
-[apiInstance userAuthorizationServiceGetAuthorizationWith:userName
- authorizationId:authorizationId
+// Get user authentication source
+[apiInstance getAuthenticationSourceWith:userName
+ sourceId:sourceId
fields:fields
- completionHandler: ^(UserAuthorizationResponse output, NSError* error) {
+ completionHandler: ^(UserAuthenticationSourceResponseSwagger output, NSError* error) {
if (output) {
NSLog(@"%@", output);
}
@@ -46115,17 +46151,17 @@ UsersApi *apiInstance = [[UsersApi alloc] init];
</code></pre>
</div>
- <div class="tab-pane" id="examples-Users-userAuthorizationServiceGetAuthorization-0-javascript">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-getAuthenticationSource-0-javascript">
<pre class="prettyprint"><code class="language-js">var SwaggerSpecForAmbariRestApi = require('swagger_spec_for_ambari_rest_api');
-var api = new SwaggerSpecForAmbariRestApi.UsersApi()
+var api = new SwaggerSpecForAmbariRestApi.UserAuthenticationSourcesApi()
var userName = userName_example; // {String} user name
-var authorizationId = authorizationId_example; // {String} Authorization Id
+var sourceId = sourceId_example; // {String} source id
var opts = {
- 'fields': fields_example // {String} Filter user authorization details
+ 'fields': fields_example // {String} Filter fields in the response (identifier fields are mandatory)
};
var callback = function(error, data, response) {
@@ -46135,14 +46171,14 @@ var callback = function(error, data, response) {
console.log('API called successfully. Returned data: ' + data);
}
};
-api.userAuthorizationServiceGetAuthorization(userName, authorizationId, opts, callback);
+api.getAuthenticationSource(userName, sourceId, opts, callback);
</code></pre>
</div>
- <!--<div class="tab-pane" id="examples-Users-userAuthorizationServiceGetAuthorization-0-angular">
+ <!--<div class="tab-pane" id="examples-UserAuthenticationSources-getAuthenticationSource-0-angular">
<pre class="prettyprint language-json prettyprinted" data-type="json"><code>Coming Soon!</code></pre>
</div>-->
- <div class="tab-pane" id="examples-Users-userAuthorizationServiceGetAuthorization-0-csharp">
+ <div class="tab-pane" id="examples-UserAuthenticationSources-getAuthenticationSource-0-csharp">
<pre class="prettyprint"><code class="language-cs">using System;
using System.Diagnostics;
using IO.Swagger.Api;
@@ -46151,69 +46187,69 @@ using IO.Swagger.Model;
namespace Example
{
- public class userAuthorizationServiceGetAuthorizationExample
+ public class getAuthenticationSourceExample
{
public void main()
{
-
<TRUNCATED>
[2/6] ambari git commit: AMBARI-20861. BE: Extend Ambari REST API to
Support User Account Management Improvements (rlevas)
Posted by rl...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UserResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UserResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UserResourceProvider.java
index 45b733b..a2d9917 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UserResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UserResourceProvider.java
@@ -17,9 +17,9 @@
*/
package org.apache.ambari.server.controller.internal;
-import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -29,6 +29,7 @@ import org.apache.ambari.server.ObjectNotFoundException;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.UserRequest;
import org.apache.ambari.server.controller.UserResponse;
+import org.apache.ambari.server.controller.predicate.AndPredicate;
import org.apache.ambari.server.controller.predicate.EqualsPredicate;
import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
import org.apache.ambari.server.controller.spi.NoSuchResourceException;
@@ -38,8 +39,10 @@ import org.apache.ambari.server.controller.spi.RequestStatus;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
import org.apache.ambari.server.controller.spi.ResourcePredicateEvaluator;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
import org.apache.ambari.server.controller.spi.SystemException;
import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
import org.apache.ambari.server.orm.entities.MemberEntity;
import org.apache.ambari.server.orm.entities.UserAuthenticationEntity;
@@ -52,6 +55,8 @@ import org.apache.ambari.server.security.authorization.UserAuthenticationType;
import org.apache.ambari.server.security.authorization.Users;
import org.apache.commons.lang.StringUtils;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
@@ -63,21 +68,70 @@ public class UserResourceProvider extends AbstractControllerResourceProvider imp
// ----- Property ID constants ---------------------------------------------
+ public static final String USER_RESOURCE_CATEGORY = "Users";
+
// Users
- public static final String USER_USERNAME_PROPERTY_ID = PropertyHelper.getPropertyId("Users", "user_name");
- public static final String USER_PASSWORD_PROPERTY_ID = PropertyHelper.getPropertyId("Users", "password");
- public static final String USER_OLD_PASSWORD_PROPERTY_ID = PropertyHelper.getPropertyId("Users", "old_password");
+ public static final String USERNAME_PROPERTY_ID = "user_name";
+ public static final String DISPLAY_NAME_PROPERTY_ID = "display_name";
+ public static final String LOCAL_USERNAME_PROPERTY_ID = "local_user_name";
+ public static final String ACTIVE_PROPERTY_ID = "active";
+ public static final String CREATE_TIME_PROPERTY_ID = "created";
+ public static final String CONSECUTIVE_FAILURES_PROPERTY_ID = "consecutive_failures";
+ public static final String ADMIN_PROPERTY_ID = "admin";
+ public static final String GROUPS_PROPERTY_ID = "groups";
+
+ public static final String USER_USERNAME_PROPERTY_ID = USER_RESOURCE_CATEGORY + "/" + USERNAME_PROPERTY_ID;
+ public static final String USER_DISPLAY_NAME_PROPERTY_ID = USER_RESOURCE_CATEGORY + "/" + DISPLAY_NAME_PROPERTY_ID;
+ public static final String USER_LOCAL_USERNAME_PROPERTY_ID = USER_RESOURCE_CATEGORY + "/" + LOCAL_USERNAME_PROPERTY_ID;
+ public static final String USER_ACTIVE_PROPERTY_ID = USER_RESOURCE_CATEGORY + "/" + ACTIVE_PROPERTY_ID;
+ public static final String USER_CREATE_TIME_PROPERTY_ID = USER_RESOURCE_CATEGORY + "/" + CREATE_TIME_PROPERTY_ID;
+ public static final String USER_CONSECUTIVE_FAILURES_PROPERTY_ID = USER_RESOURCE_CATEGORY + "/" + CONSECUTIVE_FAILURES_PROPERTY_ID;
+ public static final String USER_ADMIN_PROPERTY_ID = USER_RESOURCE_CATEGORY + "/" + ADMIN_PROPERTY_ID;
+ public static final String USER_GROUPS_PROPERTY_ID = USER_RESOURCE_CATEGORY + "/" + GROUPS_PROPERTY_ID;
+
+ /* *******************************************************
+ * Deprecated properties, kept for backwards compatibility and to maintain API V1 contract.
+ * These properties are related to a user's authentication resource.
+ * ******************************************************* */
+ @Deprecated
+ public static final String PASSWORD_PROPERTY_ID = "password";
@Deprecated
- public static final String USER_LDAP_USER_PROPERTY_ID = PropertyHelper.getPropertyId("Users", "ldap_user");
+ public static final String OLD_PASSWORD_PROPERTY_ID = "old_password";
@Deprecated
- public static final String USER_TYPE_PROPERTY_ID = PropertyHelper.getPropertyId("Users", "user_type");
- public static final String USER_ACTIVE_PROPERTY_ID = PropertyHelper.getPropertyId("Users", "active");
- public static final String USER_GROUPS_PROPERTY_ID = PropertyHelper.getPropertyId("Users", "groups");
- public static final String USER_ADMIN_PROPERTY_ID = PropertyHelper.getPropertyId("Users", "admin");
+ public static final String LDAP_USER_PROPERTY_ID = "ldap_user";
+ @Deprecated
+ public static final String USER_TYPE_PROPERTY_ID = "user_type";
- private static Set<String> pkPropertyIds =
- new HashSet<>(Arrays.asList(new String[]{
- USER_USERNAME_PROPERTY_ID}));
+ @Deprecated
+ public static final String USER_PASSWORD_PROPERTY_ID = USER_RESOURCE_CATEGORY + "/" + PASSWORD_PROPERTY_ID;
+ @Deprecated
+ public static final String USER_OLD_PASSWORD_PROPERTY_ID = USER_RESOURCE_CATEGORY + "/" + OLD_PASSWORD_PROPERTY_ID;
+ @Deprecated
+ public static final String USER_LDAP_USER_PROPERTY_ID = USER_RESOURCE_CATEGORY + "/" + LDAP_USER_PROPERTY_ID;
+ @Deprecated
+ public static final String USER_USER_TYPE_PROPERTY_ID = USER_RESOURCE_CATEGORY + "/" + USER_TYPE_PROPERTY_ID;
+ /* ******************************************************* */
+
+ private static final Set<String> PK_PROPERTY_IDS = ImmutableSet.of(
+ USER_USERNAME_PROPERTY_ID
+ );
+ private static final Set<String> PROPERTY_IDS = ImmutableSet.of(
+ USER_USERNAME_PROPERTY_ID,
+ USER_DISPLAY_NAME_PROPERTY_ID,
+ USER_LOCAL_USERNAME_PROPERTY_ID,
+ USER_ACTIVE_PROPERTY_ID,
+ USER_CREATE_TIME_PROPERTY_ID,
+ USER_CONSECUTIVE_FAILURES_PROPERTY_ID,
+ USER_GROUPS_PROPERTY_ID,
+ USER_PASSWORD_PROPERTY_ID,
+ USER_OLD_PASSWORD_PROPERTY_ID,
+ USER_LDAP_USER_PROPERTY_ID,
+ USER_USER_TYPE_PROPERTY_ID,
+ USER_ADMIN_PROPERTY_ID
+ );
+ private static final Map<Resource.Type, String> KEY_PROPERTY_IDS = ImmutableMap.of(
+ Resource.Type.User, USER_USERNAME_PROPERTY_ID
+ );
@Inject
private Users users;
@@ -86,10 +140,8 @@ public class UserResourceProvider extends AbstractControllerResourceProvider imp
* Create a new resource provider for the given management controller.
*/
@AssistedInject
- UserResourceProvider(@Assisted Set<String> propertyIds,
- @Assisted Map<Resource.Type, String> keyPropertyIds,
- @Assisted AmbariManagementController managementController) {
- super(propertyIds, keyPropertyIds, managementController);
+ UserResourceProvider(@Assisted AmbariManagementController managementController) {
+ super(Resource.Type.User, PROPERTY_IDS, KEY_PROPERTY_IDS, managementController);
setRequiredCreateAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_USERS));
setRequiredDeleteAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_USERS));
@@ -109,7 +161,11 @@ public class UserResourceProvider extends AbstractControllerResourceProvider imp
createResources(new Command<Void>() {
@Override
public Void invoke() throws AmbariException {
- createUsers(requests);
+ try {
+ createUsers(requests);
+ } catch (ResourceAlreadyExistsException | AuthorizationException e) {
+ throw new AmbariException(e.getMessage(), e);
+ }
return null;
}
});
@@ -151,12 +207,18 @@ public class UserResourceProvider extends AbstractControllerResourceProvider imp
setResourceProperty(resource, USER_USERNAME_PROPERTY_ID,
userResponse.getUsername(), requestedIds);
+ setResourceProperty(resource, USER_DISPLAY_NAME_PROPERTY_ID,
+ userResponse.getDisplayName(), requestedIds);
+
+ setResourceProperty(resource, USER_LOCAL_USERNAME_PROPERTY_ID,
+ userResponse.getLocalUsername(), requestedIds);
+
// This is deprecated but here for backwards compatibility
setResourceProperty(resource, USER_LDAP_USER_PROPERTY_ID,
userResponse.isLdapUser(), requestedIds);
// This is deprecated but here for backwards compatibility
- setResourceProperty(resource, USER_TYPE_PROPERTY_ID,
+ setResourceProperty(resource, USER_USER_TYPE_PROPERTY_ID,
userResponse.getAuthenticationType(), requestedIds);
setResourceProperty(resource, USER_ACTIVE_PROPERTY_ID,
@@ -168,6 +230,12 @@ public class UserResourceProvider extends AbstractControllerResourceProvider imp
setResourceProperty(resource, USER_ADMIN_PROPERTY_ID,
userResponse.isAdmin(), requestedIds);
+ setResourceProperty(resource, USER_CONSECUTIVE_FAILURES_PROPERTY_ID,
+ userResponse.getConsecutiveFailures(), requestedIds);
+
+ setResourceProperty(resource, USER_CREATE_TIME_PROPERTY_ID,
+ userResponse.getCreateTime(), requestedIds);
+
resources.add(resource);
}
@@ -241,7 +309,7 @@ public class UserResourceProvider extends AbstractControllerResourceProvider imp
@Override
protected Set<String> getPKPropertyIds() {
- return pkPropertyIds;
+ return PK_PROPERTY_IDS;
}
private UserRequest getRequest(Map<String, Object> properties) {
@@ -251,6 +319,9 @@ public class UserResourceProvider extends AbstractControllerResourceProvider imp
UserRequest request = new UserRequest((String) properties.get(USER_USERNAME_PROPERTY_ID));
+ request.setDisplayName((String) properties.get(USER_DISPLAY_NAME_PROPERTY_ID));
+ request.setLocalUserName((String) properties.get(USER_LOCAL_USERNAME_PROPERTY_ID));
+
request.setPassword((String) properties.get(USER_PASSWORD_PROPERTY_ID));
request.setOldPassword((String) properties.get(USER_OLD_PASSWORD_PROPERTY_ID));
@@ -272,25 +343,45 @@ public class UserResourceProvider extends AbstractControllerResourceProvider imp
* @param requests the request objects which define the user.
* @throws AmbariException when the user cannot be created.
*/
- private void createUsers(Set<UserRequest> requests) throws AmbariException {
+ private void createUsers(Set<UserRequest> requests) throws AmbariException, ResourceAlreadyExistsException, AuthorizationException {
+ // First check for obvious issues... then try to create the accounts. This will help to avoid
+ // some accounts being created and some not due to an issue with one or more of the users.
for (UserRequest request : requests) {
String username = request.getUsername();
- String password = request.getPassword();
- if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
- throw new AmbariException("Username and password must be supplied.");
+ if (StringUtils.isEmpty(username)) {
+ throw new AmbariException("Username must be supplied.");
}
+ if (users.getUser(username) != null) {
+ String message;
+ if (requests.size() == 1) {
+ message = "The requested username already exists.";
+ } else {
+ message = "One or more of the requested usernames already exists.";
+ }
+ throw new ResourceAlreadyExistsException(message);
+ }
+ }
+
+ for (UserRequest request : requests) {
+ String username = request.getUsername();
String displayName = StringUtils.defaultIfEmpty(request.getDisplayName(), username);
String localUserName = StringUtils.defaultIfEmpty(request.getLocalUserName(), username);
UserEntity userEntity = users.createUser(username, localUserName, displayName, request.isActive());
if (userEntity != null) {
- users.addLocalAuthentication(userEntity, password);
-
if (Boolean.TRUE.equals(request.isAdmin())) {
users.grantAdminPrivilege(userEntity);
}
+
+ // Setting a user's the password here is to allow for backward compatibility with pre-Ambari-3.0
+ // versions so that the contract for REST API V1 is maintained.
+ if (!StringUtils.isEmpty(request.getPassword())) {
+ // This is performed as a user administrator since the authorization check was done prior
+ // to executing #createResourcesAuthorized.
+ addOrUpdateLocalAuthenticationSource(true, userEntity, request.getPassword(), null);
+ }
}
}
}
@@ -304,37 +395,73 @@ public class UserResourceProvider extends AbstractControllerResourceProvider imp
* the requested properties
*/
private void updateUsers(Set<UserRequest> requests) throws AmbariException, AuthorizationException {
- boolean isUserAdministrator = AuthorizationHelper.isAuthorized(ResourceType.AMBARI, null,
+ boolean asUserAdministrator = AuthorizationHelper.isAuthorized(ResourceType.AMBARI, null,
RoleAuthorization.AMBARI_MANAGE_USERS);
String authenticatedUsername = AuthorizationHelper.getAuthenticatedName();
- for (UserRequest request : requests) {
+ for (final UserRequest request : requests) {
String requestedUsername = request.getUsername();
// An administrator can modify any user, else a user can only modify themself.
- if (!isUserAdministrator && (!authenticatedUsername.equalsIgnoreCase(requestedUsername))) {
+ if (!asUserAdministrator && (!authenticatedUsername.equalsIgnoreCase(requestedUsername))) {
throw new AuthorizationException();
}
UserEntity userEntity = users.getUserEntity(requestedUsername);
- if (null == userEntity) {
+ if (null == userEntity) {// Only an user with the privs to manage users can update a user's active status
continue;
}
- if (null != request.isActive()) {
+ boolean hasUpdates = false;
+ if (isValueChanged(request.isActive(), userEntity.getActive())) {
// If this value is being set, make sure the authenticated user is an administrator before
// allowing to change it. Only administrators should be able to change a user's active state
- if (!isUserAdministrator) {
- throw new AuthorizationException("The authenticated user is not authorized to update the requested resource property");
+ if (!asUserAdministrator) {
+ throw new AuthorizationException("The authenticated user is not authorized to update the requested user's active property");
+ }
+
+ hasUpdates = true;
+ }
+
+ // Only an user with the privs to manage users can update a user's local username
+ if (isValueChanged(request.getLocalUserName(), userEntity.getLocalUsername())) {
+ // If this value is being set, make sure the authenticated user is an administrator before
+ // allowing to change it. Only administrators should be able to change a user's active state
+ if (!asUserAdministrator) {
+ throw new AuthorizationException("The authenticated user is not authorized to update the requested user's local username property");
}
- users.setUserActive(userEntity, request.isActive());
+
+ hasUpdates = true;
+ }
+
+ hasUpdates = hasUpdates || isValueChanged(request.getDisplayName(), userEntity.getDisplayName());
+
+ if (hasUpdates) {
+ users.safelyUpdateUserEntity(userEntity,
+ new Users.Command() {
+ @Override
+ public void perform(UserEntity userEntity) {
+ if (isValueChanged(request.isActive(), userEntity.getActive())) {
+ userEntity.setActive(request.isActive());
+ }
+
+ if (isValueChanged(request.getLocalUserName(), userEntity.getLocalUsername())) {
+ userEntity.setLocalUsername(request.getLocalUserName());
+ }
+
+ if (isValueChanged(request.getDisplayName(), userEntity.getDisplayName())) {
+ userEntity.setDisplayName(request.getDisplayName());
+ }
+ }
+ });
}
+ // Only an user with the privs to manage users can update a user's roles
if (null != request.isAdmin()) {
// If this value is being set, make sure the authenticated user is an administrator before
// allowing to change it. Only administrators should be able to change a user's administrative
// privileges
- if (!isUserAdministrator) {
+ if (!asUserAdministrator) {
throw new AuthorizationException("The authenticated user is not authorized to update the requested resource property");
}
@@ -345,13 +472,87 @@ public class UserResourceProvider extends AbstractControllerResourceProvider imp
}
}
- if (null != request.getOldPassword() && null != request.getPassword()) {
- users.modifyPassword(userEntity, request.getOldPassword(), request.getPassword());
+ // Setting/Changing a user's password here is for backward compatibility to maintain API V1 contract
+ if (request.getPassword() != null) {
+ addOrUpdateLocalAuthenticationSource(asUserAdministrator, userEntity, request.getPassword(), request.getOldPassword());
}
}
}
/**
+ * Adds to updates a user's local authentication source by issuing a call to the {@link UserAuthenticationSourceResourceProvider}.
+ * <p>
+ * This is for backward compatibility to maintain the contract for Ambari's REST API version V1.
+ *
+ * @param asUserAdministrator true if the authenticated user have privs to manage user; false otherwise
+ * @param subjectUserEntity the user to update
+ * @param password the password to set, it is expected that this value is not <code>null</code>
+ * @param oldPassword the old/current password to use for verification is needed, this value may be <code>null</code>
+ */
+ private void addOrUpdateLocalAuthenticationSource(boolean asUserAdministrator, UserEntity subjectUserEntity, String password, String oldPassword)
+ throws AuthorizationException, AmbariException {
+ ResourceProvider provider = AbstractControllerResourceProvider.getResourceProvider(Resource.Type.UserAuthenticationSource,
+ PropertyHelper.getPropertyIds(Resource.Type.UserAuthenticationSource),
+ PropertyHelper.getKeyPropertyIds(Resource.Type.UserAuthenticationSource),
+ getManagementController());
+
+ if (provider != null) {
+ // Determine if the user already has an LOCAL authentication source setup...
+ UserAuthenticationEntity userAuthenticationEntity = null;
+ List<UserAuthenticationEntity> authenticationEntities = subjectUserEntity.getAuthenticationEntities();
+ for (UserAuthenticationEntity authenticationEntity : authenticationEntities) {
+ if (authenticationEntity.getAuthenticationType() == UserAuthenticationType.LOCAL) {
+ userAuthenticationEntity = authenticationEntity;
+ break;
+ }
+ }
+ if (userAuthenticationEntity == null) {
+ // a new authentication source needs to be create... only a privileged user can do this...
+ if (!asUserAdministrator) {
+ throw new AuthorizationException("The authenticated user is not authorized to create a local authentication source.");
+ } else {
+ Set<Map<String, Object>> propertiesSet = new HashSet<>();
+ Map<String, Object> properties;
+ properties = new LinkedHashMap<>();
+ properties.put(UserAuthenticationSourceResourceProvider.AUTHENTICATION_USER_NAME_PROPERTY_ID, subjectUserEntity.getUserName());
+ properties.put(UserAuthenticationSourceResourceProvider.AUTHENTICATION_AUTHENTICATION_TYPE_PROPERTY_ID, UserAuthenticationType.LOCAL.name());
+ properties.put(UserAuthenticationSourceResourceProvider.AUTHENTICATION_KEY_PROPERTY_ID, password);
+ propertiesSet.add(properties);
+
+ try {
+ provider.createResources(PropertyHelper.getCreateRequest(propertiesSet, null));
+ } catch (Exception e) {
+ throw new AmbariException(e.getMessage(), e);
+ }
+ }
+ } else {
+ Map<String, Object> properties = new LinkedHashMap<>();
+ properties.put(UserAuthenticationSourceResourceProvider.AUTHENTICATION_OLD_KEY_PROPERTY_ID, oldPassword);
+ properties.put(UserAuthenticationSourceResourceProvider.AUTHENTICATION_KEY_PROPERTY_ID, password);
+
+ Predicate predicate1 = new PredicateBuilder()
+ .property(UserAuthenticationSourceResourceProvider.AUTHENTICATION_USER_NAME_PROPERTY_ID)
+ .equals(subjectUserEntity.getUserName())
+ .toPredicate();
+ Predicate predicate2 = new PredicateBuilder()
+ .property(UserAuthenticationSourceResourceProvider.AUTHENTICATION_AUTHENTICATION_SOURCE_ID_PROPERTY_ID)
+ .equals(userAuthenticationEntity.getUserAuthenticationId())
+ .toPredicate();
+
+ try {
+ provider.updateResources(PropertyHelper.getUpdateRequest(properties, null), new AndPredicate(predicate1, predicate2));
+ } catch (Exception e) {
+ throw new AmbariException(e.getMessage(), e);
+ }
+ }
+ }
+ }
+
+ private boolean isValueChanged(Object newValue, Object currentValue) {
+ return (newValue != null) && !newValue.equals(currentValue);
+ }
+
+ /**
* Deletes the users specified.
*
* @param requests the users to delete
@@ -436,13 +637,13 @@ public class UserResourceProvider extends AbstractControllerResourceProvider imp
boolean isLdapUser = false;
UserAuthenticationType userType = UserAuthenticationType.LOCAL;
- for (UserAuthenticationEntity authenticationEntity : authenticationEntities) {
- if (authenticationEntity.getAuthenticationType() == UserAuthenticationType.LDAP) {
- isLdapUser = true;
- userType = UserAuthenticationType.LDAP;
- } else if (authenticationEntity.getAuthenticationType() == UserAuthenticationType.PAM) {
- userType = UserAuthenticationType.PAM;
- }
+ for (UserAuthenticationEntity authenticationEntity : authenticationEntities) {
+ if (authenticationEntity.getAuthenticationType() == UserAuthenticationType.LDAP) {
+ isLdapUser = true;
+ userType = UserAuthenticationType.LDAP;
+ } else if (authenticationEntity.getAuthenticationType() == UserAuthenticationType.PAM) {
+ userType = UserAuthenticationType.PAM;
+ }
}
Set<String> groups = new HashSet<>();
@@ -452,7 +653,15 @@ public class UserResourceProvider extends AbstractControllerResourceProvider imp
boolean isAdmin = users.hasAdminPrivilege(userEntity);
- UserResponse userResponse = new UserResponse(userEntity.getUserName(), userType, isLdapUser, userEntity.getActive(), isAdmin);
+ UserResponse userResponse = new UserResponse(userEntity.getUserName(),
+ userEntity.getDisplayName(),
+ userEntity.getLocalUsername(),
+ userType,
+ isLdapUser,
+ userEntity.getActive(),
+ isAdmin,
+ userEntity.getConsecutiveFailures(),
+ userEntity.getCreateTime());
userResponse.setGroups(groups);
return userResponse;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
index 362b4e6..d1be8a4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
@@ -134,6 +134,7 @@ public interface Resource {
StackLevelConfiguration,
LdapSyncEvent,
UserPrivilege,
+ UserAuthenticationSource,
GroupPrivilege,
RepositoryVersion,
CompatibleRepositoryVersion,
@@ -255,6 +256,7 @@ public interface Resource {
public static final Type StackLevelConfiguration = InternalType.StackLevelConfiguration.getType();
public static final Type LdapSyncEvent = InternalType.LdapSyncEvent.getType();
public static final Type UserPrivilege = InternalType.UserPrivilege.getType();
+ public static final Type UserAuthenticationSource = InternalType.UserAuthenticationSource.getType();
public static final Type GroupPrivilege = InternalType.GroupPrivilege.getType();
public static final Type RepositoryVersion = InternalType.RepositoryVersion.getType();
public static final Type CompatibleRepositoryVersion = InternalType.CompatibleRepositoryVersion.getType();
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UserAuthenticationDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UserAuthenticationDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UserAuthenticationDAO.java
index 5ecff52..c4e5cce 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UserAuthenticationDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UserAuthenticationDAO.java
@@ -25,6 +25,7 @@ import javax.persistence.TypedQuery;
import org.apache.ambari.server.orm.RequiresSession;
import org.apache.ambari.server.orm.entities.UserAuthenticationEntity;
+import org.apache.ambari.server.security.authorization.UserAuthenticationType;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -50,6 +51,13 @@ public class UserAuthenticationDAO {
return daoUtils.selectList(query);
}
+ @RequiresSession
+ public List<UserAuthenticationEntity> findByType(UserAuthenticationType authenticationType) {
+ TypedQuery<UserAuthenticationEntity> query = entityManagerProvider.get().createNamedQuery("UserAuthenticationEntity.findByType", UserAuthenticationEntity.class);
+ query.setParameter("authenticationType", authenticationType.name());
+ return daoUtils.selectList(query);
+ }
+
@Transactional
public void create(UserAuthenticationEntity entity) {
entityManagerProvider.get().persist(entity);
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UserAuthenticationEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UserAuthenticationEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UserAuthenticationEntity.java
index ffb8e6d..fb78629 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UserAuthenticationEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UserAuthenticationEntity.java
@@ -33,6 +33,8 @@ import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
import javax.persistence.Table;
import javax.persistence.TableGenerator;
import javax.persistence.Temporal;
@@ -45,13 +47,15 @@ import org.apache.commons.lang.builder.HashCodeBuilder;
@Table(name = "user_authentication")
@Entity
@NamedQueries({
- @NamedQuery(name = "UserAuthenticationEntity.findAll", query = "SELECT entity FROM UserAuthenticationEntity entity")
+ @NamedQuery(name = "UserAuthenticationEntity.findAll",
+ query = "SELECT entity FROM UserAuthenticationEntity entity"),
+ @NamedQuery(name = "UserAuthenticationEntity.findByType",
+ query = "SELECT entity FROM UserAuthenticationEntity entity where lower(entity.authenticationType)=lower(:authenticationType)")
})
@TableGenerator(name = "user_authentication_id_generator",
table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value"
, pkColumnValue = "user_authentication_id_seq"
, initialValue = 2
- , allocationSize = 500
)
public class UserAuthenticationEntity {
@@ -134,6 +138,22 @@ public class UserAuthenticationEntity {
this.user = user;
}
+ /**
+ * Ensure the create time and update time are set properly when the record is created.
+ */
+ @PrePersist
+ protected void onCreate() {
+ createTime = new Date();
+ updateTime = new Date();
+ }
+
+ /**
+ * Ensure the update time is set properly when the record is updated.
+ */
+ @PreUpdate
+ protected void onUpdate() {
+ updateTime = new Date();
+ }
@Override
public boolean equals(Object o) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/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 de12a16..d4eae9d 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
@@ -152,76 +152,6 @@ public class Users {
}
/**
- * Modifies password of local user
- *
- * @throws AmbariException
- */
- public synchronized void modifyPassword(String userName, String currentUserPassword, String newPassword) throws AmbariException, AuthorizationException {
- UserEntity userEntity = userDAO.findUserByName(userName);
- modifyPassword(userEntity, currentUserPassword, newPassword);
- }
-
- /**
- * Modifies password of local user
- *
- * @throws AmbariException
- */
- public synchronized void modifyPassword(UserEntity userEntity, String currentUserPassword, String newPassword) throws AmbariException, AuthorizationException {
-
- String authenticatedUserName = AuthorizationHelper.getAuthenticatedName();
- if (authenticatedUserName == null) {
- throw new AmbariException("Authentication required. Please sign in.");
- }
-
- if (userEntity != null) {
- /* **************************************************
- * Ensure that the authenticated user can change the password for the subject user. at least one
- * of the following must be true
- * * The authenticate user is requesting to change his/her own password
- * * The authenticated user has permissions to manage users
- * ************************************************** */
- boolean isSelf = userEntity.getUserName().equalsIgnoreCase(authenticatedUserName);
- if (!isSelf && !AuthorizationHelper.isAuthorized(ResourceType.AMBARI, null, RoleAuthorization.AMBARI_MANAGE_USERS)) {
- throw new AuthorizationException("You are not authorized perform this operation");
- }
-
- List<UserAuthenticationEntity> authenticationEntities = userEntity.getAuthenticationEntities();
- UserAuthenticationEntity localAuthenticationEntity = null;
-
- // Find the authentication entity for the local authentication type - only one should exist, if one exists at all.
- for (UserAuthenticationEntity authenticationEntity : authenticationEntities) {
- if (authenticationEntity.getAuthenticationType() == UserAuthenticationType.LOCAL) {
- localAuthenticationEntity = authenticationEntity;
- break;
- }
- }
-
- if (localAuthenticationEntity == null) {
- // The user account does not have a local authentication record. Therefore there is no local
- // password to change...
- throw new AmbariException("An Ambari-specific password is not set for this user. The user's password cannot be changed at this time.");
- } else if (isSelf &&
- (StringUtils.isEmpty(currentUserPassword) || !passwordEncoder.matches(currentUserPassword, localAuthenticationEntity.getAuthenticationKey()))) {
- // The authenticated user is the same user as subject user and the correct current password
- // was not supplied.
- throw new AmbariException("Wrong current password provided");
- }
-
- // TODO: validate the new password...
- if (StringUtils.isEmpty(newPassword)) {
- throw new AmbariException("The new password does not meet the Ambari password requirements");
- }
-
- // If we get here the authenticated user is authorized to change the password for the subject
- // user and the correct current password was supplied (if required).
- localAuthenticationEntity.setAuthenticationKey(passwordEncoder.encode(newPassword));
- userAuthenticationDAO.merge(localAuthenticationEntity);
- } else {
- throw new AmbariException("User not found");
- }
- }
-
- /**
* Enables/disables user.
*
* @param userName user name
@@ -245,7 +175,7 @@ public class Users {
* @throws AmbariException if user does not exist
*/
public synchronized void setUserActive(UserEntity userEntity, final boolean active) throws AmbariException {
- if(userEntity != null) {
+ if (userEntity != null) {
Command command = new Command() {
@Override
public void perform(UserEntity userEntity) {
@@ -347,7 +277,7 @@ public class Users {
/**
* Removes a user from the Ambari database.
* <p>
- * It is expected that the assoicated user authencation records are removed by this operation
+ * It is expected that the associated user authentication records are removed by this operation
* as well.
*
* @param user the user to remove
@@ -366,7 +296,7 @@ public class Users {
/**
* Removes a user from the Ambari database.
* <p>
- * It is expected that the assoicated user authencation records are removed by this operation
+ * It is expected that the associated user authentication records are removed by this operation
* as well.
*
* @param userEntity the user to remove
@@ -792,14 +722,14 @@ public class Users {
List<UserAuthenticationEntity> authenticationEntities = userEntity.getAuthenticationEntities();
boolean createNew = true;
- for (UserAuthenticationEntity authenticationEntity : authenticationEntities) {
- if (authenticationEntity.getAuthenticationType() == UserAuthenticationType.LDAP) {
- // TODO: check for the relevant LDAP entry... for now there will be only one.
- LOG.debug("Found existing LDAP authentication record for the user account with the username {}.", userName);
- createNew = false;
- break;
- }
+ for (UserAuthenticationEntity authenticationEntity : authenticationEntities) {
+ if (authenticationEntity.getAuthenticationType() == UserAuthenticationType.LDAP) {
+ // TODO: check for the relevant LDAP entry... for now there will be only one.
+ LOG.debug("Found existing LDAP authentication record for the user account with the username {}.", userName);
+ createNew = false;
+ break;
}
+ }
if (createNew) {
LOG.debug("Creating new LDAP authentication record for the user account with the username {}.", userName);
@@ -1110,6 +1040,154 @@ public class Users {
return implicitPrivileges;
}
+
+ /**
+ * Gets the collection of {@link UserAuthenticationEntity}s for a given user.
+ *
+ * @param username the username of a user; if null assumes all users
+ * @param authenticationType the authentication type, if null assumes all
+ * @return a collection of the requested {@link UserAuthenticationEntity}s
+ */
+ public Collection<UserAuthenticationEntity> getUserAuthenticationEntities(String username, UserAuthenticationType authenticationType) {
+ if (StringUtils.isEmpty(username)) {
+ if (authenticationType == null) {
+ // Get all
+ return userAuthenticationDAO.findAll();
+ } else {
+ // Get for the specified type
+ return userAuthenticationDAO.findByType(authenticationType);
+ }
+ } else {
+ UserEntity entity = userDAO.findUserByName(username);
+
+ if (entity == null) {
+ return null;
+ } else {
+ List<UserAuthenticationEntity> authenticationEntities = entity.getAuthenticationEntities();
+
+ if (authenticationType == null) {
+ // Get for the specified user
+ return authenticationEntities;
+ } else {
+ // Get for the specified user and type
+ List<UserAuthenticationEntity> pruned = new ArrayList<>();
+ for (UserAuthenticationEntity authenticationEntity : authenticationEntities) {
+ if (authenticationEntity.getAuthenticationType() == authenticationType) {
+ pruned.add(authenticationEntity);
+ }
+ }
+
+ return pruned;
+ }
+ }
+ }
+ }
+
+ /**
+ * Modifies authentication key of an authentication source for a user
+ *
+ * @throws AmbariException
+ */
+ @Transactional
+ public synchronized void modifyAuthentication(UserAuthenticationEntity userAuthenticationEntity, String currentKey, String newKey, boolean isSelf) throws AmbariException {
+
+ if (userAuthenticationEntity != null) {
+ if (userAuthenticationEntity.getAuthenticationType() == UserAuthenticationType.LOCAL) {
+ // If the authentication record represents a local password and the authenticated user is
+ // changing the password for himself, ensure the old key value matches the current key value
+ // If the authenticated user is can manager users and is not changing his own password, there
+ // is no need to check that the authenticated user knows the current password - just update it.
+ if (isSelf &&
+ (StringUtils.isEmpty(currentKey) || !passwordEncoder.matches(currentKey, userAuthenticationEntity.getAuthenticationKey()))) {
+ // The authenticated user is the same user as subject user and the correct current password
+ // was not supplied.
+ throw new AmbariException("Wrong current password provided");
+ }
+
+ validatePassword(newKey);
+
+ // If we get here the authenticated user is authorized to change the password for the subject
+ // user and the correct current password was supplied (if required).
+ userAuthenticationEntity.setAuthenticationKey(passwordEncoder.encode(newKey));
+ } else {
+ // If we get here the authenticated user is authorized to change the key for the subject.
+ userAuthenticationEntity.setAuthenticationKey(newKey);
+ }
+
+ userAuthenticationDAO.merge(userAuthenticationEntity);
+ }
+ }
+
+ public void removeAuthentication(String username, Long authenticationId) {
+ removeAuthentication(getUserEntity(username), authenticationId);
+ }
+
+ @Transactional
+ public void removeAuthentication(UserEntity userEntity, Long authenticationId) {
+ if ((userEntity != null) && (authenticationId != null)) {
+ boolean changed = false;
+
+ // Ensure we have a latest version of an attached UserEntity...
+ userEntity = userDAO.findByPK(userEntity.getUserId());
+
+ // Find the remove the specified UserAuthenticationEntity from the user's collection of
+ // UserAuthenticationEntities
+ List<UserAuthenticationEntity> authenticationEntities = userEntity.getAuthenticationEntities();
+ Iterator<UserAuthenticationEntity> iterator = authenticationEntities.iterator();
+ while (iterator.hasNext()) {
+ UserAuthenticationEntity authenticationEntity = iterator.next();
+ if (authenticationId.equals(authenticationEntity.getUserAuthenticationId())) {
+ userAuthenticationDAO.remove(authenticationEntity);
+ iterator.remove();
+ changed = true;
+ break;
+ }
+ }
+
+ if (changed) {
+ // Update the UserEntity to realize the changed set of authentication sources...
+ userDAO.merge(userEntity);
+ }
+ }
+ }
+
+
+ /**
+ * Adds a new authentication type for the given user.
+ *
+ * @param userEntity the user
+ * @param authenticationType the authentication type
+ * @param key the relevant key
+ * @throws AmbariException
+ * @see #addLocalAuthentication(UserEntity, String)
+ * @see #addLdapAuthentication(UserEntity, String)
+ * @see #addJWTAuthentication(UserEntity, String)
+ * @see #addKerberosAuthentication(UserEntity, String)
+ * @see #addPamAuthentication(UserEntity, String)
+ */
+ public void addAuthentication(UserEntity userEntity, UserAuthenticationType authenticationType, String key) throws AmbariException {
+ switch (authenticationType) {
+ case LOCAL:
+ addLocalAuthentication(userEntity, key);
+ break;
+ case LDAP:
+ addLdapAuthentication(userEntity, key);
+ break;
+ case JWT:
+ addJWTAuthentication(userEntity, key);
+ break;
+ case PAM:
+ addPamAuthentication(userEntity, key);
+ break;
+ case KERBEROS:
+ addKerberosAuthentication(userEntity, key);
+ break;
+ default:
+ throw new AmbariException("Unexpected user authentication type");
+ }
+ }
+
+
/**
* TODO: This is to be revisited for AMBARI-21217 (Update JWT Authentication process to work with improved user management facility)
* Adds the ability for a user to authenticate using a JWT token.
@@ -1172,6 +1250,8 @@ public class Users {
*/
public void addLocalAuthentication(UserEntity userEntity, String password) throws AmbariException {
+ validatePassword(password);
+
// Encode the password..
String encodedPassword = passwordEncoder.encode(password);
@@ -1341,6 +1421,22 @@ public class Users {
* Attempts to update the specified {@link UserEntity} while handling {@link OptimisticLockException}s
* by obtaining the latest version of the {@link UserEntity} and retrying the operation.
*
+ * If the maximum number of retries is exceeded (see {@link #MAX_RETRIES}), then the operation
+ * will fail by rethrowing the last exception encountered.
+ *
+ *
+ * @param userEntity the user entity
+ * @param command a command to perform on the user entity object that changes it state thus needing
+ * to be persisted
+ */
+ public UserEntity safelyUpdateUserEntity(UserEntity userEntity, Command command) {
+ return safelyUpdateUserEntity(userEntity, command, MAX_RETRIES);
+ }
+
+ /***
+ * Attempts to update the specified {@link UserEntity} while handling {@link OptimisticLockException}s
+ * by obtaining the latest version of the {@link UserEntity} and retrying the operation.
+ *
* If the maximum number of retries is exceeded, then the operation will fail by rethrowing the last
* exception encountered.
*
@@ -1348,8 +1444,9 @@ public class Users {
* @param userEntity the user entity
* @param command a command to perform on the user entity object that changes it state thus needing
* to be persisted
+ * @param maxRetries the maximum number of reties to peform before failing
*/
- private UserEntity safelyUpdateUserEntity(UserEntity userEntity, Command command, int maxRetries) {
+ public UserEntity safelyUpdateUserEntity(UserEntity userEntity, Command command, int maxRetries) {
int retriesLeft = maxRetries;
do {
@@ -1361,6 +1458,7 @@ public class Users {
return userEntity;
} catch (Throwable t) {
Throwable cause = t;
+ int failSafe = 50; // counter to ensure the following do/while loop does not loop indefinitely
do {
if (cause instanceof OptimisticLockException) {
@@ -1393,7 +1491,14 @@ public class Users {
// Get the cause to see if it is an OptimisticLockException
cause = cause.getCause();
}
- } while ((cause != null) && (cause != t)); // We are out of causes
+
+ // decrement the failsafe counter to ensure we do not get stuck in an infinite loop.
+ failSafe--;
+ } while ((cause != null) && (cause != t) && (failSafe > 0)); // We are out of causes
+
+ if ((cause == null) || (cause == t) || failSafe == 0) {
+ throw t;
+ }
}
} while (retriesLeft > 0); // We are out of retries
@@ -1401,6 +1506,23 @@ public class Users {
}
/**
+ * Validates the password meets configured requirements.
+ * <p>
+ * In the future this may be configurable. For now just make sure the password is not empty.
+ *
+ * @param password the password
+ * @return true if the password is valid; false otherwise
+ */
+ public boolean validatePassword(String password) throws AmbariException {
+ // TODO: validate the new password...
+ if (StringUtils.isEmpty(password)) {
+ throw new AmbariException("The new password does not meet the Ambari password requirements");
+ }
+
+ return true;
+ }
+
+ /**
* Validator is an interface to be implemented by authentication type specific validators to ensure
* new user authentication records meet the specific requirements for the relative authentication
* type.
@@ -1423,7 +1545,7 @@ public class Users {
*
* @see #safelyUpdateUserEntity(UserEntity, Command, int)
*/
- private interface Command {
+ public interface Command {
void perform(UserEntity userEntity);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/resources/properties.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/properties.json b/ambari-server/src/main/resources/properties.json
index 11ca7f6..d0a7c88 100644
--- a/ambari-server/src/main/resources/properties.json
+++ b/ambari-server/src/main/resources/properties.json
@@ -139,17 +139,6 @@
"Tasks/ops_display_name",
"_"
],
- "User":[
- "Users/user_name",
- "Users/password",
- "Users/old_password",
- "Users/ldap_user",
- "Users/user_type",
- "Users/active",
- "Users/groups",
- "Users/admin",
- "_"
- ],
"Group":[
"Groups/group_name",
"Groups/ldap_group",
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/test/java/org/apache/ambari/server/api/resources/UserResourceDefinitionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/resources/UserResourceDefinitionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/resources/UserResourceDefinitionTest.java
index 024b118..36e5cbf 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/resources/UserResourceDefinitionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/resources/UserResourceDefinitionTest.java
@@ -18,8 +18,10 @@
package org.apache.ambari.server.api.resources;
+import java.util.HashSet;
import java.util.Set;
+import org.apache.ambari.server.controller.spi.Resource;
import org.junit.Assert;
import org.junit.Test;
@@ -41,8 +43,17 @@ public class UserResourceDefinitionTest {
@Test
public void testGetSubResourceDefinitions() throws Exception {
+ Set<Resource.Type> expectedSubResourceDefinitionTypes = new HashSet<>();
+ expectedSubResourceDefinitionTypes.add(Resource.Type.UserAuthenticationSource);
+ expectedSubResourceDefinitionTypes.add(Resource.Type.UserPrivilege);
+ expectedSubResourceDefinitionTypes.add(Resource.Type.ActiveWidgetLayout);
+
final UserResourceDefinition userResourceDefinition = new UserResourceDefinition();
Set<SubResourceDefinition> subResourceDefinitions = userResourceDefinition.getSubResourceDefinitions();
- Assert.assertEquals(2, subResourceDefinitions.size());
+ Assert.assertEquals(expectedSubResourceDefinitionTypes.size(), subResourceDefinitions.size());
+
+ for(SubResourceDefinition subResourceDefinition : subResourceDefinitions) {
+ Assert.assertTrue(expectedSubResourceDefinitionTypes.contains(subResourceDefinition.getType()));
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestImplTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestImplTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestImplTest.java
index 3becc02..d70fed1 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestImplTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RequestImplTest.java
@@ -199,13 +199,6 @@ public class RequestImplTest {
request = PropertyHelper.getReadRequest(PropertyHelper.getPropertyIds(Resource.Type.User));
validPropertyIds = request.getPropertyIds();
- //User resource properties
- Assert.assertFalse(validPropertyIds.contains("Users/unsupported_property_id"));
- Assert.assertTrue(validPropertyIds.contains("Users/user_name"));
- Assert.assertTrue(validPropertyIds.contains("Users/password"));
- Assert.assertTrue(validPropertyIds.contains("Users/old_password"));
- Assert.assertTrue(validPropertyIds.contains("Users/ldap_user"));
-
request = PropertyHelper.getReadRequest(PropertyHelper.getPropertyIds(Resource.Type.Stack));
validPropertyIds = request.getPropertyIds();
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserAuthenticationSourceResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserAuthenticationSourceResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserAuthenticationSourceResourceProviderTest.java
new file mode 100644
index 0000000..f109c68
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserAuthenticationSourceResourceProviderTest.java
@@ -0,0 +1,448 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.internal;
+
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+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;
+
+import javax.persistence.EntityManager;
+
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.controller.predicate.AndPredicate;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+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.hooks.HookContextFactory;
+import org.apache.ambari.server.hooks.HookService;
+import org.apache.ambari.server.orm.DBAccessor;
+import org.apache.ambari.server.orm.entities.UserAuthenticationEntity;
+import org.apache.ambari.server.orm.entities.UserEntity;
+import org.apache.ambari.server.security.TestAuthenticationFactory;
+import org.apache.ambari.server.security.authorization.AuthorizationException;
+import org.apache.ambari.server.security.authorization.AuthorizationHelper;
+import org.apache.ambari.server.security.authorization.UserAuthenticationType;
+import org.apache.ambari.server.security.authorization.UserIdAuthentication;
+import org.apache.ambari.server.security.authorization.Users;
+import org.apache.ambari.server.stack.StackManagerFactory;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.stack.OsFamily;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.easymock.EasyMockSupport;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+/**
+ * UserAuthenticationSourceResourceProviderTest tests.
+ */
+public class UserAuthenticationSourceResourceProviderTest extends EasyMockSupport {
+
+ private static final Date CREATE_TIME = Calendar.getInstance().getTime();
+ private static final Date UPDATE_TIME = Calendar.getInstance().getTime();
+
+ @Before
+ public void resetMocks() {
+ resetAll();
+ }
+
+ @After
+ public void clearAuthentication() {
+ SecurityContextHolder.getContext().setAuthentication(null);
+ }
+
+ @Test
+ public void testCreateResources_Administrator() throws Exception {
+ createResourcesTest(TestAuthenticationFactory.createAdministrator("admin"));
+ }
+
+ @Test(expected = AuthorizationException.class)
+ public void testCreateResources_NonAdministrator() throws Exception {
+ createResourcesTest(TestAuthenticationFactory.createClusterAdministrator("User1", 2L));
+ }
+
+ @Test
+ public void testGetResources_Administrator() throws Exception {
+ getResourcesTest(TestAuthenticationFactory.createAdministrator("admin"));
+ }
+
+ @Test
+ public void testGetResources_NonAdministrator() throws Exception {
+ getResourcesTest(TestAuthenticationFactory.createClusterAdministrator("User1", 2L));
+ }
+
+ @Test
+ public void testGetResource_Administrator_Self() throws Exception {
+ getResourceTest(TestAuthenticationFactory.createAdministrator("admin"), "admin");
+ }
+
+ @Test
+ public void testGetResource_Administrator_Other() throws Exception {
+ getResourceTest(TestAuthenticationFactory.createAdministrator("admin"), "User1");
+ }
+
+ @Test
+ public void testGetResource_NonAdministrator_Self() throws Exception {
+ getResourceTest(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User1");
+ }
+
+ @Test(expected = AuthorizationException.class)
+ public void testGetResource_NonAdministrator_Other() throws Exception {
+ getResourceTest(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User100");
+ }
+
+ @Test
+ public void testUpdateResources_SetPassword_Administrator_Self() throws Exception {
+ updateResources_SetAuthenticationKey(TestAuthenticationFactory.createAdministrator("admin"), "User100", null);
+ }
+
+ @Test
+ public void testUpdateResources_SetPassword_Administrator_Other() throws Exception {
+ updateResources_SetAuthenticationKey(TestAuthenticationFactory.createAdministrator("admin"), "User100", null);
+ }
+
+ @Test
+ public void testUpdateResources_SetPassword_NonAdministrator_Self() throws Exception {
+ updateResources_SetAuthenticationKey(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User1", null);
+ }
+
+ @Test(expected = AuthorizationException.class)
+ public void testUpdateResources_SetPassword_NonAdministrator_Other() throws Exception {
+ updateResources_SetAuthenticationKey(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User100", null);
+ }
+
+ @Test
+ public void testUpdateResources_SetPassword_VerifyLocal_Success() throws Exception {
+ updateResources_SetAuthenticationKey(TestAuthenticationFactory.createAdministrator(), "User100", "local");
+ }
+
+ @Test(expected = ResourceNotFoundException.class)
+ public void testUpdateResources_SetPassword_VerifyLocal_Fail() throws Exception {
+ updateResources_SetAuthenticationKey(TestAuthenticationFactory.createAdministrator(), "User100", "KERBEROS");
+ }
+
+ @Test
+ public void testDeleteResource_Administrator_Self() throws Exception {
+ deleteResourcesTest(TestAuthenticationFactory.createAdministrator("admin"), "admin");
+ }
+
+ @Test
+ public void testDeleteResource_Administrator_Other() throws Exception {
+ deleteResourcesTest(TestAuthenticationFactory.createAdministrator("admin"), "User100");
+ }
+
+ @Test(expected = AuthorizationException.class)
+ public void testDeleteResource_NonAdministrator_Self() throws Exception {
+ deleteResourcesTest(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User1");
+ }
+
+ @Test(expected = AuthorizationException.class)
+ public void testDeleteResource_NonAdministrator_Other() throws Exception {
+ deleteResourcesTest(TestAuthenticationFactory.createClusterAdministrator("User1", 2L), "User100");
+ }
+
+ private Injector createInjector() throws Exception {
+ return Guice.createInjector(new AbstractModule() {
+ @Override
+ protected void configure() {
+ bind(EntityManager.class).toInstance(createNiceMock(EntityManager.class));
+ bind(DBAccessor.class).toInstance(createNiceMock(DBAccessor.class));
+ bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
+ bind(AmbariMetaInfo.class).toInstance(createMock(AmbariMetaInfo.class));
+ bind(Clusters.class).toInstance(createNiceMock(Clusters.class));
+ bind(StackManagerFactory.class).toInstance(createNiceMock(StackManagerFactory.class));
+ bind(PasswordEncoder.class).toInstance(createNiceMock(PasswordEncoder.class));
+ bind(Users.class).toInstance(createMock(Users.class));
+ bind(HookService.class).toInstance(createMock(HookService.class));
+ bind(HookContextFactory.class).toInstance(createMock(HookContextFactory.class));
+ }
+ });
+ }
+
+
+ private void createResourcesTest(Authentication authentication) throws Exception {
+ Injector injector = createInjector();
+
+ UserEntity userEntity100 = createNiceMock(UserEntity.class);
+ UserEntity userEntity200 = createNiceMock(UserEntity.class);
+
+ Users users = injector.getInstance(Users.class);
+ expect(users.getUserEntity("User100")).andReturn(userEntity100).once();
+ expect(users.getUserEntity("User200")).andReturn(userEntity200).once();
+ users.addAuthentication(userEntity100, UserAuthenticationType.LOCAL, "my_password_100_1234");
+ expectLastCall().once();
+ users.addAuthentication(userEntity200, UserAuthenticationType.LOCAL, "my_password_200_1234");
+ expectLastCall().once();
+
+ // replay
+ replayAll();
+
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+
+ AmbariMetaInfo ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class);
+ ambariMetaInfo.init();
+
+ 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(UserAuthenticationSourceResourceProvider.AUTHENTICATION_USER_NAME_PROPERTY_ID, "User100");
+ properties.put(UserAuthenticationSourceResourceProvider.AUTHENTICATION_AUTHENTICATION_TYPE_PROPERTY_ID, "local");
+ properties.put(UserAuthenticationSourceResourceProvider.AUTHENTICATION_KEY_PROPERTY_ID, "my_password_100_1234");
+ propertySet.add(properties);
+
+ properties = new LinkedHashMap<>();
+ properties.put(UserAuthenticationSourceResourceProvider.AUTHENTICATION_USER_NAME_PROPERTY_ID, "User200");
+ properties.put(UserAuthenticationSourceResourceProvider.AUTHENTICATION_AUTHENTICATION_TYPE_PROPERTY_ID, "local");
+ properties.put(UserAuthenticationSourceResourceProvider.AUTHENTICATION_KEY_PROPERTY_ID, "my_password_200_1234");
+ propertySet.add(properties);
+
+ // create the request
+ Request request = PropertyHelper.getCreateRequest(propertySet, null);
+
+ provider.createResources(request);
+
+ // verify
+ verifyAll();
+ }
+
+ private void getResourcesTest(Authentication authentication) throws Exception {
+ Injector injector = createInjector();
+
+ Users users = injector.getInstance(Users.class);
+ Map<String, UserAuthenticationEntity> entities = new HashMap<>();
+
+ entities.put("User1", createMockUserAuthenticationEntity("User1"));
+
+ if ("admin".equals(authentication.getName())) {
+ entities.put("User10", createMockUserAuthenticationEntity("User10"));
+ entities.put("User100", createMockUserAuthenticationEntity("User100"));
+ entities.put("admin", createMockUserAuthenticationEntity("admin"));
+
+ expect(users.getUserAuthenticationEntities(null, null)).andReturn(entities.values()).once();
+ } else {
+ expect(users.getUserAuthenticationEntities("User1", null)).andReturn(entities.values()).once();
+ }
+
+ replayAll();
+
+ AmbariMetaInfo ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class);
+ ambariMetaInfo.init();
+
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+
+ ResourceProvider provider = getResourceProvider(injector);
+
+ Set<String> propertyIds = new HashSet<>();
+ propertyIds.add(UserAuthenticationSourceResourceProvider.AUTHENTICATION_USER_NAME_PROPERTY_ID);
+ propertyIds.add(UserAuthenticationSourceResourceProvider.AUTHENTICATION_AUTHENTICATION_TYPE_PROPERTY_ID);
+ propertyIds.add(UserAuthenticationSourceResourceProvider.AUTHENTICATION_KEY_PROPERTY_ID);
+ propertyIds.add(UserAuthenticationSourceResourceProvider.AUTHENTICATION_CREATED_PROPERTY_ID);
+ propertyIds.add(UserAuthenticationSourceResourceProvider.AUTHENTICATION_UPDATED_PROPERTY_ID);
+
+ Request request = PropertyHelper.getReadRequest(propertyIds);
+
+ Set<Resource> resources = provider.getResources(request, null);
+
+ Assert.assertEquals(entities.size(), resources.size());
+ for (Resource resource : resources) {
+ String userName = (String) resource.getPropertyValue(UserAuthenticationSourceResourceProvider.AUTHENTICATION_USER_NAME_PROPERTY_ID);
+ Assert.assertTrue(entities.containsKey(userName));
+
+ // This value should never come back...
+ Assert.assertNull(resource.getPropertyValue(UserAuthenticationSourceResourceProvider.AUTHENTICATION_KEY_PROPERTY_ID));
+ }
+
+ verifyAll();
+ }
+
+ private void getResourceTest(Authentication authentication, String requestedUsername) throws Exception {
+ Injector injector = createInjector();
+
+ List<UserAuthenticationEntity> entities = new ArrayList<>();
+ entities.add(createMockUserAuthenticationEntity(requestedUsername));
+
+ Users users = injector.getInstance(Users.class);
+ expect(users.getUserAuthenticationEntities(requestedUsername, null)).andReturn(entities).once();
+
+ replayAll();
+
+ AmbariMetaInfo ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class);
+ ambariMetaInfo.init();
+
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+
+ ResourceProvider provider = getResourceProvider(injector);
+
+ Set<String> propertyIds = new HashSet<>();
+ propertyIds.add(UserAuthenticationSourceResourceProvider.AUTHENTICATION_USER_NAME_PROPERTY_ID);
+ propertyIds.add(UserAuthenticationSourceResourceProvider.AUTHENTICATION_KEY_PROPERTY_ID);
+
+ Request request = PropertyHelper.getReadRequest(propertyIds);
+
+ Set<Resource> resources = provider.getResources(request, createPredicate(requestedUsername, null));
+
+ Assert.assertEquals(1, resources.size());
+ for (Resource resource : resources) {
+ String userName = (String) resource.getPropertyValue(UserAuthenticationSourceResourceProvider.AUTHENTICATION_USER_NAME_PROPERTY_ID);
+ Assert.assertEquals(requestedUsername, userName);
+
+ // This value should never come back...
+ Assert.assertNull(resource.getPropertyValue(UserAuthenticationSourceResourceProvider.AUTHENTICATION_KEY_PROPERTY_ID));
+ }
+
+ verifyAll();
+ }
+
+ private void updateResources_SetAuthenticationKey(Authentication authentication, String requestedUsername, String authenticationType) throws Exception {
+ Injector injector = createInjector();
+
+ UserAuthenticationEntity userAuthenticationEntity = createMockUserAuthenticationEntity(requestedUsername);
+
+ boolean isSelf = authentication.getName().equalsIgnoreCase(requestedUsername);
+
+ List<UserAuthenticationEntity> userAuthenticationEntities = new ArrayList<>();
+ userAuthenticationEntities.add(userAuthenticationEntity);
+
+ UserEntity userEntity = createMock(UserEntity.class);
+ expect(userEntity.getAuthenticationEntities()).andReturn(userAuthenticationEntities).once();
+ if (isSelf) {
+ expect(userEntity.getUserId()).andReturn(((UserIdAuthentication) authentication).getUserId()).once();
+ } else {
+ expect(userEntity.getUserId()).andReturn(AuthorizationHelper.getAuthenticatedId() + 100).once();
+ }
+
+ Users users = injector.getInstance(Users.class);
+ expect(users.getUserEntity(requestedUsername)).andReturn(userEntity).once();
+ users.modifyAuthentication(userAuthenticationEntity, "old_password", "new_password", isSelf);
+ expectLastCall().once();
+
+ replayAll();
+
+ AmbariMetaInfo ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class);
+ ambariMetaInfo.init();
+
+ 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(UserAuthenticationSourceResourceProvider.AUTHENTICATION_OLD_KEY_PROPERTY_ID, "old_password");
+ properties.put(UserAuthenticationSourceResourceProvider.AUTHENTICATION_KEY_PROPERTY_ID, "new_password");
+
+ if(authenticationType != null) {
+ properties.put(UserAuthenticationSourceResourceProvider.AUTHENTICATION_AUTHENTICATION_TYPE_PROPERTY_ID, authenticationType);
+ }
+
+ // create the request
+ Request request = PropertyHelper.getUpdateRequest(properties, null);
+
+ provider.updateResources(request, createPredicate(requestedUsername, userAuthenticationEntity.getUserAuthenticationId()));
+
+ verifyAll();
+ }
+
+ private void deleteResourcesTest(Authentication authentication, String requestedUsername) throws Exception {
+ Injector injector = createInjector();
+
+ Users users = injector.getInstance(Users.class);
+ users.removeAuthentication(requestedUsername, 1L);
+ expectLastCall().atLeastOnce();
+
+ // replay
+ replayAll();
+
+ AmbariMetaInfo ambariMetaInfo = injector.getInstance(AmbariMetaInfo.class);
+ ambariMetaInfo.init();
+
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+
+ ResourceProvider provider = getResourceProvider(injector);
+
+ provider.deleteResources(new RequestImpl(null, null, null, null), createPredicate(requestedUsername, 1L));
+
+ // verify
+ verifyAll();
+ }
+
+
+ private Predicate createPredicate(String requestedUsername, Long sourceId) {
+ Predicate predicate1 = new PredicateBuilder()
+ .property(UserAuthenticationSourceResourceProvider.AUTHENTICATION_USER_NAME_PROPERTY_ID)
+ .equals(requestedUsername)
+ .toPredicate();
+
+ if (sourceId == null) {
+ return predicate1;
+ } else {
+ Predicate predicate2 = new PredicateBuilder()
+ .property(UserAuthenticationSourceResourceProvider.AUTHENTICATION_AUTHENTICATION_SOURCE_ID_PROPERTY_ID)
+ .equals(sourceId.toString())
+ .toPredicate();
+ return new AndPredicate(predicate1, predicate2);
+ }
+ }
+
+ private UserAuthenticationEntity createMockUserAuthenticationEntity(String username) {
+ UserAuthenticationEntity entity = createMock(UserAuthenticationEntity.class);
+ UserEntity userEntity = createMock(UserEntity.class);
+ expect(entity.getAuthenticationType()).andReturn(UserAuthenticationType.LOCAL).anyTimes();
+ expect(entity.getAuthenticationKey()).andReturn("this is a secret").anyTimes();
+ expect(entity.getCreateTime()).andReturn(CREATE_TIME).anyTimes();
+ expect(entity.getUpdateTime()).andReturn(UPDATE_TIME).anyTimes();
+ expect(entity.getUserAuthenticationId()).andReturn(100L).anyTimes();
+ expect(entity.getUser()).andReturn(userEntity).anyTimes();
+
+ expect(userEntity.getUserName()).andReturn(username).anyTimes();
+ return entity;
+ }
+
+ private ResourceProvider getResourceProvider(Injector injector) {
+ UserAuthenticationSourceResourceProvider resourceProvider = new UserAuthenticationSourceResourceProvider();
+
+ injector.injectMembers(resourceProvider);
+ return resourceProvider;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserResourceProviderDBTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserResourceProviderDBTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserResourceProviderDBTest.java
index db7548f..6c20eb0 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserResourceProviderDBTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserResourceProviderDBTest.java
@@ -18,9 +18,12 @@
package org.apache.ambari.server.controller.internal;
+import static org.easymock.EasyMock.expect;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.powermock.api.easymock.PowerMock.createMock;
+import static org.powermock.api.easymock.PowerMock.replay;
import java.sql.SQLException;
import java.util.ArrayList;
@@ -37,6 +40,7 @@ import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.H2DatabaseCleaner;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.ResourceProviderFactory;
import org.apache.ambari.server.controller.spi.Predicate;
import org.apache.ambari.server.controller.spi.Request;
import org.apache.ambari.server.controller.spi.RequestStatus;
@@ -68,6 +72,7 @@ public class UserResourceProviderDBTest {
private static AmbariManagementController amc;
private static Resource.Type userType = Resource.Type.User;
private static UserResourceProvider userResourceProvider;
+ private static UserAuthenticationSourceResourceProvider userAuthenticationSourceResourceProvider;
private static String JDBC_IN_MEMORY_URL_CREATE =
String.format("jdbc:derby:memory:myDB/%s;create=true", Configuration.DEFAULT_DERBY_SCHEMA);
private static String JDBC_IN_MEMORY_URL_DROP =
@@ -89,11 +94,18 @@ public class UserResourceProviderDBTest {
amc = injector.getInstance(AmbariManagementController.class);
- Set<String> propertyIds = PropertyHelper.getPropertyIds(userType);
- Map<Resource.Type, String> keyPropertyIds = PropertyHelper.getKeyPropertyIds(userType);
-
- userResourceProvider = new UserResourceProvider(propertyIds, keyPropertyIds, amc);
+ userResourceProvider = new UserResourceProvider(amc);
injector.injectMembers(userResourceProvider);
+
+ userAuthenticationSourceResourceProvider = new UserAuthenticationSourceResourceProvider();
+ injector.injectMembers(userAuthenticationSourceResourceProvider);
+
+
+ ResourceProviderFactory factory = createMock(ResourceProviderFactory.class);
+ expect(factory.getUserAuthenticationSourceResourceProvider()).andReturn(userAuthenticationSourceResourceProvider).anyTimes();
+ replay(factory);
+ AbstractControllerResourceProvider.init(factory);
+
}
/**
@@ -177,7 +189,7 @@ public class UserResourceProviderDBTest {
requestStatus = userResourceProvider.createResources(request);
assertTrue("Should fail with user exists", false);
} catch (Exception ex) {
- assertTrue(ex.getMessage().contains("User already exists"));
+ assertTrue(ex.getMessage().contains("already exists"));
}
// delete the created username
[3/6] ambari git commit: AMBARI-20861. BE: Extend Ambari REST API to
Support User Account Management Improvements (rlevas)
Posted by rl...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java
index d24780b..d9b8577 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java
@@ -49,46 +49,46 @@ import org.slf4j.LoggerFactory;
public abstract class BaseService {
public final static MediaType MEDIA_TYPE_TEXT_CSV_TYPE = new MediaType("text", "csv");
- static final String MSG_SUCCESSFUL_OPERATION = "Successful operation";
- static final String MSG_REQUEST_ACCEPTED = "Request is accepted, but not completely processed yet";
- static final String MSG_INVALID_ARGUMENTS = "Invalid arguments";
- static final String MSG_INVALID_REQUEST = "Invalid request";
- static final String MSG_CLUSTER_NOT_FOUND = "Cluster not found";
- static final String MSG_CLUSTER_OR_HOST_NOT_FOUND = "Cluster or host not found";
- static final String MSG_NOT_AUTHENTICATED = "Not authenticated";
- static final String MSG_PERMISSION_DENIED = "Not permitted to perform the operation";
- static final String MSG_SERVER_ERROR = "Internal server error";
- static final String MSG_RESOURCE_ALREADY_EXISTS = "The requested resource already exists.";
- static final String MSG_RESOURCE_NOT_FOUND = "The requested resource doesn't exist.";
-
- static final String QUERY_FIELDS = "fields";
- static final String QUERY_FILTER_DESCRIPTION = "Filter fields in the response (identifier fields are mandatory)";
- static final String QUERY_SORT = "sortBy";
- static final String QUERY_SORT_DESCRIPTION = "Sort resources in result by (asc | desc)";
- static final String QUERY_PAGE_SIZE = "page_size";
- static final String QUERY_PAGE_SIZE_DESCRIPTION = "The number of resources to be returned for the paged response.";
- static final String DEFAULT_PAGE_SIZE = "10";
- static final String QUERY_FROM = "from";
- static final String QUERY_FROM_DESCRIPTION = "The starting page resource (inclusive). \"start\" is also accepted.";
- static final String QUERY_FROM_VALUES = "range[0, infinity]";
- static final String DEFAULT_FROM = "0";
- static final String QUERY_TO = "to";
- static final String QUERY_TO_DESCRIPTION = "The ending page resource (inclusive). \"end\" is also accepted.";
- static final String QUERY_TO_TYPE = "integer";
- static final String QUERY_TO_VALUES = "range[1, infinity]";
- static final String QUERY_PREDICATE = "{predicate}";
- static final String QUERY_PREDICATE_DESCRIPTION = "The predicate to filter resources by. Omitting the predicate will " +
+ public static final String MSG_SUCCESSFUL_OPERATION = "Successful operation";
+ public static final String MSG_REQUEST_ACCEPTED = "Request is accepted, but not completely processed yet";
+ public static final String MSG_INVALID_ARGUMENTS = "Invalid arguments";
+ public static final String MSG_INVALID_REQUEST = "Invalid request";
+ public static final String MSG_CLUSTER_NOT_FOUND = "Cluster not found";
+ public static final String MSG_CLUSTER_OR_HOST_NOT_FOUND = "Cluster or host not found";
+ public static final String MSG_NOT_AUTHENTICATED = "Not authenticated";
+ public static final String MSG_PERMISSION_DENIED = "Not permitted to perform the operation";
+ public static final String MSG_SERVER_ERROR = "Internal server error";
+ public static final String MSG_RESOURCE_ALREADY_EXISTS = "The requested resource already exists.";
+ public static final String MSG_RESOURCE_NOT_FOUND = "The requested resource doesn't exist.";
+
+ public static final String QUERY_FIELDS = "fields";
+ public static final String QUERY_FILTER_DESCRIPTION = "Filter fields in the response (identifier fields are mandatory)";
+ public static final String QUERY_SORT = "sortBy";
+ public static final String QUERY_SORT_DESCRIPTION = "Sort resources in result by (asc | desc)";
+ public static final String QUERY_PAGE_SIZE = "page_size";
+ public static final String QUERY_PAGE_SIZE_DESCRIPTION = "The number of resources to be returned for the paged response.";
+ public static final String DEFAULT_PAGE_SIZE = "10";
+ public static final String QUERY_FROM = "from";
+ public static final String QUERY_FROM_DESCRIPTION = "The starting page resource (inclusive). \"start\" is also accepted.";
+ public static final String QUERY_FROM_VALUES = "range[0, infinity]";
+ public static final String DEFAULT_FROM = "0";
+ public static final String QUERY_TO = "to";
+ public static final String QUERY_TO_DESCRIPTION = "The ending page resource (inclusive). \"end\" is also accepted.";
+ public static final String QUERY_TO_TYPE = "integer";
+ public static final String QUERY_TO_VALUES = "range[1, infinity]";
+ public static final String QUERY_PREDICATE = "{predicate}";
+ public static final String QUERY_PREDICATE_DESCRIPTION = "The predicate to filter resources by. Omitting the predicate will " +
"match all resources.";
- static final String RESPONSE_CONTAINER_LIST = "List";
+ public static final String RESPONSE_CONTAINER_LIST = "List";
- static final String DATA_TYPE_INT = "integer";
- static final String DATA_TYPE_STRING = "string";
+ public static final String DATA_TYPE_INT = "integer";
+ public static final String DATA_TYPE_STRING = "string";
- static final String PARAM_TYPE_QUERY = "query";
- static final String PARAM_TYPE_BODY = "body";
+ public static final String PARAM_TYPE_QUERY = "query";
+ public static final String PARAM_TYPE_BODY = "body";
- static final String FIELDS_SEPARATOR = ", ";
+ public static final String FIELDS_SEPARATOR = ", ";
/**
* Logger instance.
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/api/services/users/UserAuthenticationSourceService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/users/UserAuthenticationSourceService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/users/UserAuthenticationSourceService.java
new file mode 100644
index 0000000..8600bbf
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/users/UserAuthenticationSourceService.java
@@ -0,0 +1,223 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.api.services.users;
+
+import static org.apache.ambari.server.controller.internal.UserAuthenticationSourceResourceProvider.AUTHENTICATION_AUTHENTICATION_SOURCE_ID_PROPERTY_ID;
+import static org.apache.ambari.server.controller.internal.UserAuthenticationSourceResourceProvider.AUTHENTICATION_SOURCE_RESOURCE_CATEGORY;
+import static org.apache.ambari.server.controller.internal.UserAuthenticationSourceResourceProvider.AUTHENTICATION_USER_NAME_PROPERTY_ID;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.api.services.BaseService;
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.controller.UserAuthenticationSourceResponse;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.HttpStatus;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+/**
+ * Service responsible for user authentication source resource requests.
+ */
+@Path("/users/{userName}/sources")
+@Api(value = "User Authentication Sources", description = "Endpoint for user specific authentication source operations")
+public class UserAuthenticationSourceService extends BaseService {
+
+ private static final String CREATE_REQUEST_TYPE = "org.apache.ambari.server.controller.UserAuthenticationSourceRequestCreateSwagger";
+ private static final String UPDATE_REQUEST_TYPE = "org.apache.ambari.server.controller.UserAuthenticationSourceRequestUpdateSwagger";
+ private static final String AUTHENTICATION_SOURCE_DEFAULT_SORT = AUTHENTICATION_AUTHENTICATION_SOURCE_ID_PROPERTY_ID + ".asc";
+
+ /**
+ * Handles: GET /users/{userName}/sources
+ * Get all authentication sources for the user.
+ *
+ * @param headers http headers
+ * @param ui uri info
+ * @param userName user name
+ * @return user resource instance representation
+ */
+ @GET
+ @Produces("text/plain")
+ @ApiOperation(value = "Get all authentication sources", response = UserAuthenticationSourceResponse.UserAuthenticationSourceResponseSwagger.class, responseContainer = "List")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY, defaultValue = AUTHENTICATION_AUTHENTICATION_SOURCE_ID_PROPERTY_ID + "," + AUTHENTICATION_USER_NAME_PROPERTY_ID),
+ @ApiImplicitParam(name = QUERY_SORT, value = QUERY_SORT_DESCRIPTION, dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY, defaultValue = AUTHENTICATION_SOURCE_DEFAULT_SORT),
+ @ApiImplicitParam(name = QUERY_PAGE_SIZE, value = QUERY_PAGE_SIZE_DESCRIPTION, defaultValue = DEFAULT_PAGE_SIZE, dataType = DATA_TYPE_INT, paramType = PARAM_TYPE_QUERY),
+ @ApiImplicitParam(name = QUERY_FROM, value = QUERY_FROM_DESCRIPTION, allowableValues = QUERY_FROM_VALUES, defaultValue = DEFAULT_FROM, dataType = DATA_TYPE_INT, paramType = PARAM_TYPE_QUERY),
+ @ApiImplicitParam(name = QUERY_TO, value = QUERY_TO_DESCRIPTION, allowableValues = QUERY_TO_VALUES, dataType = DATA_TYPE_INT, paramType = PARAM_TYPE_QUERY),
+ })
+ @ApiResponses({
+ @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION),
+ @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND),
+ @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED),
+ @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED),
+ @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
+ })
+ public Response getAuthenticationSources(@Context HttpHeaders headers, @Context UriInfo ui,
+ @ApiParam(value = "user name", required = true) @PathParam("userName") String userName) {
+ return handleRequest(headers, null, ui, Request.Type.GET, createResource(userName, null));
+ }
+
+ /**
+ * Handles: GET /users/{userName}/sources/{sourceID}
+ * Get a specific authentication source.
+ *
+ * @param headers http headers
+ * @param ui uri info
+ * @param userName user name
+ * @param sourceId authentication source id
+ * @return authentication source instance representation
+ */
+ @GET
+ @Path("{sourceId}")
+ @Produces("text/plain")
+ @ApiOperation(value = "Get user authentication source", response = UserAuthenticationSourceResponse.UserAuthenticationSourceResponseSwagger.class)
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY, defaultValue = AUTHENTICATION_SOURCE_RESOURCE_CATEGORY + "/*"),
+ })
+ @ApiResponses({
+ @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION),
+ @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND),
+ @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED),
+ @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED),
+ @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
+ })
+ public Response getAuthenticationSource(@Context HttpHeaders headers, @Context UriInfo ui,
+ @ApiParam(value = "user name", required = true) @PathParam("userName") String userName,
+ @ApiParam(value = "source id", required = true) @PathParam("sourceId") String sourceId) {
+ return handleRequest(headers, null, ui, Request.Type.GET, createResource(userName, sourceId));
+ }
+
+ /**
+ * Creates an authentication source.
+ * Handles: POST /users/{userName}/sources
+ *
+ * @param headers http headers
+ * @param ui uri info
+ * @param userName user name
+ * @return information regarding the created user
+ */
+ @POST
+ @Produces("text/plain")
+ @ApiOperation(value = "Create one or more new authentication sources for a user")
+ @ApiImplicitParams({
+ @ApiImplicitParam(dataType = CREATE_REQUEST_TYPE, paramType = PARAM_TYPE_BODY, allowMultiple = true)
+ })
+ @ApiResponses({
+ @ApiResponse(code = HttpStatus.SC_CREATED, message = MSG_SUCCESSFUL_OPERATION),
+ @ApiResponse(code = HttpStatus.SC_ACCEPTED, message = MSG_REQUEST_ACCEPTED),
+ @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = MSG_INVALID_ARGUMENTS),
+ @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND),
+ @ApiResponse(code = HttpStatus.SC_CONFLICT, message = MSG_RESOURCE_ALREADY_EXISTS),
+ @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED),
+ @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED),
+ @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
+ })
+ public Response createAuthenticationSources(String body, @Context HttpHeaders headers, @Context UriInfo ui,
+ @ApiParam(value = "user name", required = true) @PathParam("userName") String userName) {
+ return handleRequest(headers, body, ui, Request.Type.POST, createResource(userName, null));
+ }
+
+ /**
+ * Creates an authentication source.
+ * Handles: PUT /users/{userName}/sources/{sourceId}
+ *
+ * @param headers http headers
+ * @param ui uri info
+ * @param userName user name
+ * @param sourceId authentication source id
+ * @return information regarding the created user
+ */
+ @PUT
+ @Path("{sourceId}")
+ @Produces("text/plain")
+ @ApiOperation(value = "Updates an existing authentication source")
+ @ApiImplicitParams({
+ @ApiImplicitParam(dataType = UPDATE_REQUEST_TYPE, paramType = PARAM_TYPE_BODY)
+ })
+ @ApiResponses({
+ @ApiResponse(code = HttpStatus.SC_ACCEPTED, message = MSG_REQUEST_ACCEPTED),
+ @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = MSG_INVALID_ARGUMENTS),
+ @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND),
+ @ApiResponse(code = HttpStatus.SC_CONFLICT, message = MSG_RESOURCE_ALREADY_EXISTS),
+ @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED),
+ @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED),
+ @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
+ })
+ public Response updateAuthenticationSource(String body, @Context HttpHeaders headers, @Context UriInfo ui,
+ @ApiParam(value = "user name", required = true) @PathParam("userName") String userName,
+ @ApiParam(value = "source id", required = true) @PathParam("sourceId") String sourceId) {
+ return handleRequest(headers, body, ui, Request.Type.PUT, createResource(userName, sourceId));
+ }
+
+ /**
+ * Delete an authentication source.
+ * Handles: DELETE /users/{userName}/sources/{sourceId}
+ *
+ * @param headers http headers
+ * @param ui uri info
+ * @param userName user name
+ * @param sourceId authentication source id
+ * @return information regarding the created user
+ */
+ @DELETE
+ @Path("{sourceId}")
+ @Produces("text/plain")
+ @ApiOperation(value = "Deletes an existing authentication source")
+ @ApiResponses({
+ @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION),
+ @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND),
+ @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED),
+ @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED),
+ @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
+ })
+ public Response deleteAuthenticationSource(String body, @Context HttpHeaders headers, @Context UriInfo ui,
+ @ApiParam(value = "user name", required = true) @PathParam("userName") String userName,
+ @ApiParam(value = "source id", required = true) @PathParam("sourceId") String sourceId) {
+ return handleRequest(headers, body, ui, Request.Type.DELETE, createResource(userName, sourceId));
+ }
+
+ protected ResourceInstance createResource(String userName, String sourceId) {
+ final Map<Resource.Type, String> mapIds = new HashMap<>();
+ mapIds.put(Resource.Type.User, StringUtils.lowerCase(userName));
+ mapIds.put(Resource.Type.UserAuthenticationSource, sourceId);
+ return createResource(Resource.Type.UserAuthenticationSource, mapIds);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/api/services/users/UserService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/users/UserService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/users/UserService.java
index a69ed4e..4eb8587 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/users/UserService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/users/UserService.java
@@ -17,6 +17,9 @@
*/
package org.apache.ambari.server.api.services.users;
+import static org.apache.ambari.server.controller.internal.UserResourceProvider.USER_RESOURCE_CATEGORY;
+import static org.apache.ambari.server.controller.internal.UserResourceProvider.USER_USERNAME_PROPERTY_ID;
+
import java.util.Collections;
import javax.ws.rs.DELETE;
@@ -31,12 +34,12 @@ import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
-import org.apache.ambari.annotations.ApiIgnore;
import org.apache.ambari.server.api.resources.ResourceInstance;
import org.apache.ambari.server.api.services.BaseService;
import org.apache.ambari.server.api.services.Request;
import org.apache.ambari.server.controller.UserResponse;
import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.http.HttpStatus;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
@@ -53,23 +56,32 @@ import io.swagger.annotations.ApiResponses;
@Api(value = "Users", description = "Endpoint for user specific operations")
public class UserService extends BaseService {
+ private static final String UPDATE_USER_REQUEST_TYPE = "org.apache.ambari.server.controller.UserRequestUpdateUserSwagger";
+ private static final String CREATE_USER_REQUEST_TYPE = "org.apache.ambari.server.controller.UserRequestCreateUserSwagger";
+ private static final String CREATE_USERS_REQUEST_TYPE = "org.apache.ambari.server.controller.UserRequestCreateUsersSwagger";;
+ private static final String USER_DEFAULT_SORT = USER_USERNAME_PROPERTY_ID + ".asc";
+
/**
* Gets all users.
* Handles: GET /users requests.
*/
@GET
@Produces("text/plain")
- @ApiOperation(value = "Get all users", nickname = "UserService#getUsers", notes = "Returns details of all users.", response = UserResponse.class, responseContainer = "List")
+ @ApiOperation(value = "Get all users", response = UserResponse.UserResponseSwagger.class, responseContainer = "List")
@ApiImplicitParams({
- @ApiImplicitParam(name = "fields", value = "Filter user details", defaultValue = "Users/*", dataType = "string", paramType = "query"),
- @ApiImplicitParam(name = "sortBy", value = "Sort users (asc | desc)", defaultValue = "Users/user_name.asc", dataType = "string", paramType = "query"),
- @ApiImplicitParam(name = "page_size", value = "The number of resources to be returned for the paged response.", defaultValue = "10", dataType = "integer", paramType = "query"),
- @ApiImplicitParam(name = "from", value = "The starting page resource (inclusive). Valid values are :offset | \"start\"", defaultValue = "0", dataType = "string", paramType = "query"),
- @ApiImplicitParam(name = "to", value = "The ending page resource (inclusive). Valid values are :offset | \"end\"", dataType = "string", paramType = "query")
+ @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY, defaultValue = USER_USERNAME_PROPERTY_ID),
+ @ApiImplicitParam(name = QUERY_SORT, value = QUERY_SORT_DESCRIPTION, dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY, defaultValue = USER_DEFAULT_SORT),
+ @ApiImplicitParam(name = QUERY_PAGE_SIZE, value = QUERY_PAGE_SIZE_DESCRIPTION, defaultValue = DEFAULT_PAGE_SIZE, dataType = DATA_TYPE_INT, paramType = PARAM_TYPE_QUERY),
+ @ApiImplicitParam(name = QUERY_FROM, value = QUERY_FROM_DESCRIPTION, allowableValues = QUERY_FROM_VALUES, defaultValue = DEFAULT_FROM, dataType = DATA_TYPE_INT, paramType = PARAM_TYPE_QUERY),
+ @ApiImplicitParam(name = QUERY_TO, value = QUERY_TO_DESCRIPTION, allowableValues = QUERY_TO_VALUES, dataType = DATA_TYPE_INT, paramType = PARAM_TYPE_QUERY),
+ })
+ @ApiResponses({
+ @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION),
+ @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND),
+ @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED),
+ @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED),
+ @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
})
- @ApiResponses(value = {
- @ApiResponse(code = 200, message = "Successful operation", response = UserResponse.class, responseContainer = "List")}
- )
public Response getUsers(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
return handleRequest(headers, body, ui, Request.Type.GET, createUserResource(null));
}
@@ -78,23 +90,27 @@ public class UserService extends BaseService {
* Gets a single user.
* Handles: GET /users/{username} requests
*
- * @param headers http headers
- * @param ui uri info
- * @param userName the username
+ * @param headers http headers
+ * @param ui uri info
+ * @param userName the username
* @return information regarding the created user
*/
@GET
@Path("{userName}")
@Produces("text/plain")
- @ApiOperation(value = "Get single user", nickname = "UserService#getUser", notes = "Returns user details.", response = UserResponse.class)
+ @ApiOperation(value = "Get single user", response = UserResponse.UserResponseSwagger.class)
@ApiImplicitParams({
- @ApiImplicitParam(name = "fields", value = "Filter user details", defaultValue = "Users", dataType = "string", paramType = "query")
+ @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY, defaultValue = USER_RESOURCE_CATEGORY + "/*"),
+ })
+ @ApiResponses({
+ @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION),
+ @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND),
+ @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED),
+ @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED),
+ @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
})
- @ApiResponses(value = {
- @ApiResponse(code = 200, message = "Successful operation", response = UserResponse.class)}
- )
public Response getUser(String body, @Context HttpHeaders headers, @Context UriInfo ui,
- @ApiParam(value = "user name", required = true, defaultValue = "admin") @PathParam("userName") String userName) {
+ @ApiParam(value = "user name", required = true) @PathParam("userName") String userName) {
return handleRequest(headers, body, ui, Request.Type.GET, createUserResource(userName));
}
@@ -102,13 +118,27 @@ public class UserService extends BaseService {
* Creates a user.
* Handles: POST /users
*
- * @param headers http headers
- * @param ui uri info
+ * @param headers http headers
+ * @param ui uri info
* @return information regarding the created user
*/
- @POST @ApiIgnore // until documented
+ @POST
@Produces("text/plain")
- public Response createUser(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
+ @ApiOperation(value = "Creates one or more users in a single request")
+ @ApiImplicitParams({
+ @ApiImplicitParam(dataType = CREATE_USERS_REQUEST_TYPE, paramType = PARAM_TYPE_BODY, allowMultiple = true)
+ })
+ @ApiResponses({
+ @ApiResponse(code = HttpStatus.SC_CREATED, message = MSG_SUCCESSFUL_OPERATION),
+ @ApiResponse(code = HttpStatus.SC_ACCEPTED, message = MSG_REQUEST_ACCEPTED),
+ @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = MSG_INVALID_ARGUMENTS),
+ @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND),
+ @ApiResponse(code = HttpStatus.SC_CONFLICT, message = MSG_RESOURCE_ALREADY_EXISTS),
+ @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED),
+ @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED),
+ @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
+ })
+ public Response createUsers(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
return handleRequest(headers, body, ui, Request.Type.POST, createUserResource(null));
}
@@ -116,22 +146,28 @@ public class UserService extends BaseService {
* Creates a user.
* Handles: POST /users/{username}
*
- * @param headers http headers
- * @param ui uri info
- * @param userName the username
+ * @param headers http headers
+ * @param ui uri info
+ * @param userName the username
* @return information regarding the created user
*/
@POST
@Path("{userName}")
@Produces("text/plain")
- @ApiOperation(value = "Create new user", nickname = "UserService#createUser", notes = "Creates user resource.")
+ @ApiOperation(value = "Create new user")
@ApiImplicitParams({
- @ApiImplicitParam(name = "body", value = "input parameters in json form", required = true, dataType = "org.apache.ambari.server.controller.UserRequest", paramType = "body")
+ @ApiImplicitParam(dataType = CREATE_USER_REQUEST_TYPE, paramType = PARAM_TYPE_BODY)
+ })
+ @ApiResponses({
+ @ApiResponse(code = HttpStatus.SC_CREATED, message = MSG_SUCCESSFUL_OPERATION),
+ @ApiResponse(code = HttpStatus.SC_ACCEPTED, message = MSG_REQUEST_ACCEPTED),
+ @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = MSG_INVALID_ARGUMENTS),
+ @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND),
+ @ApiResponse(code = HttpStatus.SC_CONFLICT, message = MSG_RESOURCE_ALREADY_EXISTS),
+ @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED),
+ @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED),
+ @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
})
- @ApiResponses(value = {
- @ApiResponse(code = 200, message = "Successful operation"),
- @ApiResponse(code = 500, message = "Server Error")}
- )
public Response createUser(String body, @Context HttpHeaders headers, @Context UriInfo ui,
@ApiParam(value = "user name", required = true) @PathParam("userName") String userName) {
return handleRequest(headers, body, ui, Request.Type.POST, createUserResource(userName));
@@ -141,22 +177,27 @@ public class UserService extends BaseService {
* Updates a specific user.
* Handles: PUT /users/{userName}
*
- * @param headers http headers
- * @param ui uri info
- * @param userName the username
+ * @param headers http headers
+ * @param ui uri info
+ * @param userName the username
* @return information regarding the updated user
*/
@PUT
@Path("{userName}")
@Produces("text/plain")
- @ApiOperation(value = "Update user detail", nickname = "UserService#updateUser", notes = "Updates user resource.")
+ @ApiOperation(value = "Update user details")
@ApiImplicitParams({
- @ApiImplicitParam(name = "body", value = "input parameters in json form", required = true, dataType = "org.apache.ambari.server.controller.UserRequest", paramType = "body")
+ @ApiImplicitParam(dataType = UPDATE_USER_REQUEST_TYPE, paramType = PARAM_TYPE_BODY)
+ })
+ @ApiResponses({
+ @ApiResponse(code = HttpStatus.SC_ACCEPTED, message = MSG_REQUEST_ACCEPTED),
+ @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = MSG_INVALID_ARGUMENTS),
+ @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND),
+ @ApiResponse(code = HttpStatus.SC_CONFLICT, message = MSG_RESOURCE_ALREADY_EXISTS),
+ @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED),
+ @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED),
+ @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
})
- @ApiResponses(value = {
- @ApiResponse(code = 200, message = "Successful operation"),
- @ApiResponse(code = 500, message = "Server Error")}
- )
public Response updateUser(String body, @Context HttpHeaders headers, @Context UriInfo ui,
@ApiParam(value = "user name", required = true) @PathParam("userName") String userName) {
@@ -170,10 +211,10 @@ public class UserService extends BaseService {
@DELETE
@Path("{userName}")
@Produces("text/plain")
- @ApiOperation(value = "Delete single user", nickname = "UserService#deleteUser", notes = "Delete user resource.")
+ @ApiOperation(value = "Delete single user")
@ApiResponses(value = {
- @ApiResponse(code = 200, message = "Successful operation"),
- @ApiResponse(code = 500, message = "Server Error")}
+ @ApiResponse(code = 200, message = "Successful operation"),
+ @ApiResponse(code = 500, message = "Server Error")}
)
public Response deleteUser(@Context HttpHeaders headers, @Context UriInfo ui,
@ApiParam(value = "user name", required = true) @PathParam("userName") String userName) {
@@ -183,8 +224,7 @@ public class UserService extends BaseService {
/**
* Create a user resource instance.
*
- * @param userName user name
- *
+ * @param userName user name
* @return a user resource instance
*/
private ResourceInstance createUserResource(String userName) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index 25d12c7..f2fba6c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -72,6 +72,7 @@ import org.apache.ambari.server.controller.internal.MemberResourceProvider;
import org.apache.ambari.server.controller.internal.RepositoryVersionResourceProvider;
import org.apache.ambari.server.controller.internal.ServiceResourceProvider;
import org.apache.ambari.server.controller.internal.UpgradeResourceProvider;
+import org.apache.ambari.server.controller.internal.UserAuthenticationSourceResourceProvider;
import org.apache.ambari.server.controller.internal.UserResourceProvider;
import org.apache.ambari.server.controller.logging.LoggingRequestHelperFactory;
import org.apache.ambari.server.controller.logging.LoggingRequestHelperFactoryImpl;
@@ -466,6 +467,7 @@ public class ControllerModule extends AbstractModule {
.implement(ResourceProvider.class, Names.named("repositoryVersion"), RepositoryVersionResourceProvider.class)
.implement(ResourceProvider.class, Names.named("hostKerberosIdentity"), HostKerberosIdentityResourceProvider.class)
.implement(ResourceProvider.class, Names.named("user"), UserResourceProvider.class)
+ .implement(ResourceProvider.class, Names.named("userAuthenticationSource"), UserAuthenticationSourceResourceProvider.class)
.implement(ResourceProvider.class, Names.named("credential"), CredentialResourceProvider.class)
.implement(ResourceProvider.class, Names.named("kerberosDescriptor"), KerberosDescriptorResourceProvider.class)
.implement(ResourceProvider.class, Names.named("upgrade"), UpgradeResourceProvider.class)
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/controller/ResourceProviderFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ResourceProviderFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ResourceProviderFactory.java
index 2454bf7..d5bebf0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ResourceProviderFactory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ResourceProviderFactory.java
@@ -52,9 +52,10 @@ public interface ResourceProviderFactory {
AmbariManagementController managementController);
@Named("user")
- ResourceProvider getUserResourceProvider(Set<String> propertyIds,
- Map<Type, String> keyPropertyIds,
- AmbariManagementController managementController);
+ ResourceProvider getUserResourceProvider(AmbariManagementController managementController);
+
+ @Named("userAuthenticationSource")
+ ResourceProvider getUserAuthenticationSourceResourceProvider();
@Named("hostKerberosIdentity")
ResourceProvider getHostKerberosIdentityResourceProvider(AmbariManagementController managementController);
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/controller/UserAuthenticationSourceRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/UserAuthenticationSourceRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/UserAuthenticationSourceRequest.java
new file mode 100644
index 0000000..17297be
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/UserAuthenticationSourceRequest.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.controller;
+
+import org.apache.ambari.server.controller.internal.UserAuthenticationSourceResourceProvider;
+import org.apache.ambari.server.security.authorization.UserAuthenticationType;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * Represents a user authentication source request.
+ */
+@ApiModel
+public class UserAuthenticationSourceRequest {
+ private final String username;
+ private final Long sourceId;
+ private final UserAuthenticationType authenticationType;
+ private final String key;
+ private final String oldKey;
+
+ public UserAuthenticationSourceRequest(String username, Long sourceId) {
+ this(username, sourceId, null, null);
+
+ }
+
+ public UserAuthenticationSourceRequest(String username, Long sourceId, UserAuthenticationType authenticationType) {
+ this(username, sourceId, authenticationType, null);
+ }
+
+ public UserAuthenticationSourceRequest(String username, Long sourceId, UserAuthenticationType authenticationType, String key) {
+ this(username, sourceId, authenticationType, key, null);
+ }
+
+ public UserAuthenticationSourceRequest(String username, Long sourceId, UserAuthenticationType authenticationType, String key, String oldKey) {
+ this.username = username;
+ this.sourceId = sourceId;
+ this.authenticationType = authenticationType;
+ this.key = key;
+ this.oldKey = oldKey;
+ }
+
+ @ApiModelProperty(name = UserAuthenticationSourceResourceProvider.USER_NAME_PROPERTY_ID, hidden = true)
+ public String getUsername() {
+ return username;
+ }
+
+ @ApiModelProperty(name = UserAuthenticationSourceResourceProvider.AUTHENTICATION_SOURCE_ID_PROPERTY_ID)
+ public Long getSourceId() {
+ return sourceId;
+ }
+
+ @ApiModelProperty(name = UserAuthenticationSourceResourceProvider.AUTHENTICATION_TYPE_PROPERTY_ID)
+ public UserAuthenticationType getAuthenticationType() {
+ return authenticationType;
+ }
+
+ @ApiModelProperty(name = UserAuthenticationSourceResourceProvider.KEY_PROPERTY_ID)
+ public String getKey() {
+ return key;
+ }
+
+ @ApiModelProperty(name = UserAuthenticationSourceResourceProvider.OLD_KEY_PROPERTY_ID)
+ public String getOldKey() {
+ return oldKey;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/controller/UserAuthenticationSourceRequestCreateSwagger.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/UserAuthenticationSourceRequestCreateSwagger.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/UserAuthenticationSourceRequestCreateSwagger.java
new file mode 100644
index 0000000..72f010a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/UserAuthenticationSourceRequestCreateSwagger.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller;
+
+import org.apache.ambari.server.controller.internal.UserAuthenticationSourceResourceProvider;
+import org.apache.ambari.server.security.authorization.UserAuthenticationType;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * Interface to help correct Swagger documentation generation
+ */
+public interface UserAuthenticationSourceRequestCreateSwagger extends ApiModel {
+ @ApiModelProperty(name = UserAuthenticationSourceResourceProvider.AUTHENTICATION_SOURCE_RESOURCE_CATEGORY)
+ CreateUserAuthenticationSourceInfo getCreateUserAuthenticationSourceRequest();
+
+ interface CreateUserAuthenticationSourceInfo {
+ @ApiModelProperty(name = UserAuthenticationSourceResourceProvider.AUTHENTICATION_TYPE_PROPERTY_ID, required = true)
+ public UserAuthenticationType getAuthenticationType();
+
+ @ApiModelProperty(name = UserAuthenticationSourceResourceProvider.KEY_PROPERTY_ID, required = true)
+ public String getKey();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/controller/UserAuthenticationSourceRequestUpdateSwagger.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/UserAuthenticationSourceRequestUpdateSwagger.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/UserAuthenticationSourceRequestUpdateSwagger.java
new file mode 100644
index 0000000..3e1aa8c
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/UserAuthenticationSourceRequestUpdateSwagger.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller;
+
+import org.apache.ambari.server.controller.internal.UserAuthenticationSourceResourceProvider;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * Interface to help correct Swagger documentation generation
+ */
+public interface UserAuthenticationSourceRequestUpdateSwagger extends ApiModel {
+ @ApiModelProperty(name = UserAuthenticationSourceResourceProvider.AUTHENTICATION_SOURCE_RESOURCE_CATEGORY)
+ UserAuthenticationSourceRequestUpdateInfo getUpdateUserAuthenticationSourceRequest();
+
+ interface UserAuthenticationSourceRequestUpdateInfo {
+
+ @ApiModelProperty(name = UserAuthenticationSourceResourceProvider.KEY_PROPERTY_ID, required = true)
+ public String getKey();
+
+ @ApiModelProperty(name = UserAuthenticationSourceResourceProvider.OLD_KEY_PROPERTY_ID, required = false)
+ public String getOldKey();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/controller/UserAuthenticationSourceResponse.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/UserAuthenticationSourceResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/UserAuthenticationSourceResponse.java
new file mode 100644
index 0000000..6717ad6
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/UserAuthenticationSourceResponse.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.controller;
+
+import java.util.Date;
+
+import org.apache.ambari.server.controller.internal.UserAuthenticationSourceResourceProvider;
+import org.apache.ambari.server.security.authorization.UserAuthenticationType;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * Represents a user authentication source.
+ */
+public class UserAuthenticationSourceResponse implements ApiModel {
+
+ private final String userName;
+ private final Long sourceId;
+ private final UserAuthenticationType authenticationType;
+ private final String key;
+
+ private final Date createTime;
+ private final Date updateTime;
+
+ public UserAuthenticationSourceResponse(String userName, Long sourceId, UserAuthenticationType authenticationType, String key, Date createTime, Date updateTime) {
+ this.userName = userName;
+ this.sourceId = sourceId;
+ this.authenticationType = authenticationType;
+ this.key = key;
+ this.createTime = createTime;
+ this.updateTime = updateTime;
+ }
+
+ /**
+ * Returns user name
+ *
+ * @return user name
+ */
+ @ApiModelProperty(name = UserAuthenticationSourceResourceProvider.USER_NAME_PROPERTY_ID, required = true)
+ public String getUserName() {
+ return userName;
+ }
+
+
+ @ApiModelProperty(name = UserAuthenticationSourceResourceProvider.AUTHENTICATION_SOURCE_ID_PROPERTY_ID, required = true)
+ public Long getSourceId() {
+ return sourceId;
+ }
+
+ @ApiModelProperty(name = UserAuthenticationSourceResourceProvider.AUTHENTICATION_TYPE_PROPERTY_ID, required = true)
+ public UserAuthenticationType getAuthenticationType() {
+ return authenticationType;
+ }
+
+ @ApiModelProperty(name = UserAuthenticationSourceResourceProvider.KEY_PROPERTY_ID)
+ public String getKey() {
+ return key;
+ }
+
+ @ApiModelProperty(name = UserAuthenticationSourceResourceProvider.CREATED_PROPERTY_ID)
+ public Date getCreateTime() {
+ return createTime;
+ }
+
+ @ApiModelProperty(name = UserAuthenticationSourceResourceProvider.UPDATED_PROPERTY_ID)
+ public Date getUpdateTime() {
+ return updateTime;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ } else if (o == null || getClass() != o.getClass()) {
+ return false;
+ } else {
+ UserAuthenticationSourceResponse that = (UserAuthenticationSourceResponse) o;
+
+ EqualsBuilder equalsBuilder = new EqualsBuilder();
+ equalsBuilder.append(userName, that.userName);
+ equalsBuilder.append(sourceId, that.sourceId);
+ equalsBuilder.append(authenticationType, that.authenticationType);
+ equalsBuilder.append(key, that.key);
+ equalsBuilder.append(createTime, that.createTime);
+ equalsBuilder.append(updateTime, that.updateTime);
+ return equalsBuilder.isEquals();
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ HashCodeBuilder hashCodeBuilder = new HashCodeBuilder();
+ hashCodeBuilder.append(userName);
+ hashCodeBuilder.append(sourceId);
+ hashCodeBuilder.append(authenticationType);
+ hashCodeBuilder.append(key);
+ hashCodeBuilder.append(createTime);
+ hashCodeBuilder.append(updateTime);
+ return hashCodeBuilder.toHashCode();
+ }
+
+ /**
+ * Interface to help correct Swagger documentation generation
+ */
+ public interface UserAuthenticationSourceResponseSwagger {
+ @ApiModelProperty(name = UserAuthenticationSourceResourceProvider.AUTHENTICATION_SOURCE_RESOURCE_CATEGORY)
+ @SuppressWarnings("unused")
+ UserAuthenticationSourceResponse getUserAuthenticationSourceResponse();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/controller/UserRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/UserRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/UserRequest.java
index 3011d01..d0836a9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/UserRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/UserRequest.java
@@ -17,6 +17,8 @@
*/
package org.apache.ambari.server.controller;
+import org.apache.ambari.server.controller.internal.UserResourceProvider;
+
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -38,12 +40,12 @@ public class UserRequest {
this.userName = name;
}
- @ApiModelProperty(name = "Users/user_name",hidden = true)
+ @ApiModelProperty(name = UserResourceProvider.USERNAME_PROPERTY_ID)
public String getUsername() {
return userName;
}
- @ApiModelProperty(name = "Users/password")
+ @ApiModelProperty(name = UserResourceProvider.PASSWORD_PROPERTY_ID)
public String getPassword() {
return password;
}
@@ -52,7 +54,7 @@ public class UserRequest {
password = userPass;
}
- @ApiModelProperty(name = "Users/old_password")
+ @ApiModelProperty(name = UserResourceProvider.OLD_PASSWORD_PROPERTY_ID)
public String getOldPassword() {
return oldPassword;
}
@@ -61,7 +63,7 @@ public class UserRequest {
oldPassword = oldUserPass;
}
- @ApiModelProperty(name = "Users/active")
+ @ApiModelProperty(name = UserResourceProvider.ACTIVE_PROPERTY_ID)
public Boolean isActive() {
return active;
}
@@ -70,7 +72,7 @@ public class UserRequest {
this.active = active;
}
- @ApiModelProperty(name = "Users/admin")
+ @ApiModelProperty(name = UserResourceProvider.ADMIN_PROPERTY_ID)
public Boolean isAdmin() {
return admin;
}
@@ -79,7 +81,7 @@ public class UserRequest {
this.admin = admin;
}
- @ApiModelProperty(name = "Users/display_name")
+ @ApiModelProperty(name = UserResourceProvider.DISPLAY_NAME_PROPERTY_ID)
public String getDisplayName() {
return displayName;
}
@@ -88,7 +90,7 @@ public class UserRequest {
this.displayName = displayName;
}
- @ApiModelProperty(name = "Users/local_user_name")
+ @ApiModelProperty(name = UserResourceProvider.LOCAL_USERNAME_PROPERTY_ID)
public String getLocalUserName() {
return localUserName;
}
@@ -103,5 +105,4 @@ public class UserRequest {
sb.append("User, username=").append(userName);
return sb.toString();
}
-
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/controller/UserRequestCreateUserSwagger.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/UserRequestCreateUserSwagger.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/UserRequestCreateUserSwagger.java
new file mode 100644
index 0000000..44b6410
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/UserRequestCreateUserSwagger.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller;
+
+import org.apache.ambari.server.controller.internal.UserResourceProvider;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * Interface to help correct Swagger documentation generation
+ */
+public interface UserRequestCreateUserSwagger extends ApiModel {
+
+ @ApiModelProperty(name = UserResourceProvider.USER_RESOURCE_CATEGORY)
+ CreateUserInfo getCreateUserRequest();
+
+ interface CreateUserInfo {
+ @ApiModelProperty(name = UserResourceProvider.PASSWORD_PROPERTY_ID)
+ String getPassword();
+
+ @ApiModelProperty(name = UserResourceProvider.ACTIVE_PROPERTY_ID)
+ Boolean isActive();
+
+ @ApiModelProperty(name = UserResourceProvider.ADMIN_PROPERTY_ID)
+ Boolean isAdmin();
+
+ @ApiModelProperty(name = UserResourceProvider.DISPLAY_NAME_PROPERTY_ID)
+ String getDisplayName();
+
+ @ApiModelProperty(name = UserResourceProvider.LOCAL_USERNAME_PROPERTY_ID)
+ String getLocalUserName();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/controller/UserRequestCreateUsersSwagger.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/UserRequestCreateUsersSwagger.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/UserRequestCreateUsersSwagger.java
new file mode 100644
index 0000000..f26ae14
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/UserRequestCreateUsersSwagger.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller;
+
+import org.apache.ambari.server.controller.internal.UserResourceProvider;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * Interface to help correct Swagger documentation generation
+ */
+public interface UserRequestCreateUsersSwagger extends ApiModel {
+
+ @ApiModelProperty(name = UserResourceProvider.USER_RESOURCE_CATEGORY)
+ CreateUsersInfo getCreateUsersRequest();
+
+ interface CreateUsersInfo {
+ @ApiModelProperty(name = UserResourceProvider.USERNAME_PROPERTY_ID )
+ String getUsername();
+
+ @ApiModelProperty(name = UserResourceProvider.PASSWORD_PROPERTY_ID)
+ String getPassword();
+
+ @ApiModelProperty(name = UserResourceProvider.ACTIVE_PROPERTY_ID)
+ Boolean isActive();
+
+ @ApiModelProperty(name = UserResourceProvider.ADMIN_PROPERTY_ID)
+ Boolean isAdmin();
+
+ @ApiModelProperty(name = UserResourceProvider.DISPLAY_NAME_PROPERTY_ID)
+ String getDisplayName();
+
+ @ApiModelProperty(name = UserResourceProvider.LOCAL_USERNAME_PROPERTY_ID)
+ String getLocalUserName();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/controller/UserRequestUpdateUserSwagger.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/UserRequestUpdateUserSwagger.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/UserRequestUpdateUserSwagger.java
new file mode 100644
index 0000000..f2b2d84
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/UserRequestUpdateUserSwagger.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller;
+
+import org.apache.ambari.server.controller.internal.UserResourceProvider;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * Interface to help correct Swagger documentation generation
+ */
+public interface UserRequestUpdateUserSwagger extends ApiModel {
+
+ @ApiModelProperty(name = UserResourceProvider.USER_RESOURCE_CATEGORY)
+ UpdateUserInfo getUpdateUserRequest();
+
+ interface UpdateUserInfo {
+ @ApiModelProperty(name = UserResourceProvider.OLD_PASSWORD_PROPERTY_ID)
+ String getOldPassword();
+
+ @ApiModelProperty(name = UserResourceProvider.PASSWORD_PROPERTY_ID)
+ String getPassword();
+
+ @ApiModelProperty(name = UserResourceProvider.ACTIVE_PROPERTY_ID)
+ Boolean isActive();
+
+ @ApiModelProperty(name = UserResourceProvider.ADMIN_PROPERTY_ID)
+ Boolean isAdmin();
+
+ @ApiModelProperty(name = UserResourceProvider.DISPLAY_NAME_PROPERTY_ID)
+ String getDisplayName();
+
+ @ApiModelProperty(name = UserResourceProvider.LOCAL_USERNAME_PROPERTY_ID)
+ String getLocalUserName();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/controller/UserResponse.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/UserResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/UserResponse.java
index bcb3aaf..6204aac 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/UserResponse.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/UserResponse.java
@@ -18,8 +18,10 @@
package org.apache.ambari.server.controller;
import java.util.Collections;
+import java.util.Date;
import java.util.Set;
+import org.apache.ambari.server.controller.internal.UserResourceProvider;
import org.apache.ambari.server.security.authorization.UserAuthenticationType;
import io.swagger.annotations.ApiModelProperty;
@@ -27,38 +29,48 @@ import io.swagger.annotations.ApiModelProperty;
/**
* Represents a user maintenance request.
*/
-public class
-UserResponse implements ApiModel {
+public class UserResponse implements ApiModel {
private final String userName;
+ private final String displayName;
+ private final String localUserName;
private final UserAuthenticationType authenticationType;
private final boolean isLdapUser;
private final boolean isActive;
private final boolean isAdmin;
private Set<String> groups = Collections.emptySet();
- public UserResponse(String userName, UserAuthenticationType userType, boolean isLdapUser, boolean isActive, boolean isAdmin) {
+ private final Date createTime;
+ private final Integer consecutiveFailures;
+
+ public UserResponse(String userName, String displayName, String localUserName, UserAuthenticationType userType, boolean isLdapUser, boolean isActive, boolean isAdmin, Integer consecutiveFailures, Date createTime) {
this.userName = userName;
+ this.displayName = displayName;
+ this.localUserName = localUserName;
this.authenticationType = userType;
this.isLdapUser = isLdapUser;
this.isActive = isActive;
this.isAdmin = isAdmin;
+ this.consecutiveFailures = consecutiveFailures;
+ this.createTime = createTime;
}
- public UserResponse(String name, boolean isLdapUser, boolean isActive, boolean isAdmin) {
- this.userName = name;
- this.isLdapUser = isLdapUser;
- this.isActive = isActive;
- this.isAdmin = isAdmin;
- this.authenticationType = UserAuthenticationType.LOCAL;
- }
-
- @ApiModelProperty(name = "Users/user_name",required = true)
+ @ApiModelProperty(name = UserResourceProvider.USERNAME_PROPERTY_ID)
public String getUsername() {
return userName;
}
- @ApiModelProperty(name = "Users/groups")
+ @ApiModelProperty(name = UserResourceProvider.DISPLAY_NAME_PROPERTY_ID)
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ @ApiModelProperty(name = UserResourceProvider.LOCAL_USERNAME_PROPERTY_ID)
+ public String getLocalUsername() {
+ return localUserName;
+ }
+
+ @ApiModelProperty(name = UserResourceProvider.GROUPS_PROPERTY_ID)
public Set<String> getGroups() {
return groups;
}
@@ -70,34 +82,50 @@ UserResponse implements ApiModel {
/**
* @return the isLdapUser
*/
- @ApiModelProperty(name = "Users/ldap_user")
+ @ApiModelProperty(name = UserResourceProvider.LDAP_USER_PROPERTY_ID)
public boolean isLdapUser() {
return isLdapUser;
}
- @ApiModelProperty(name = "Users/active")
+ @ApiModelProperty(name = UserResourceProvider.ACTIVE_PROPERTY_ID)
public boolean isActive() {
return isActive;
}
- @ApiModelProperty(name = "Users/admin")
+ @ApiModelProperty(name = UserResourceProvider.ADMIN_PROPERTY_ID)
public boolean isAdmin() {
return isAdmin;
}
- @ApiModelProperty(name = "Users/authentication_type")
+ @ApiModelProperty(name = UserResourceProvider.USER_TYPE_PROPERTY_ID)
public UserAuthenticationType getAuthenticationType() {
return authenticationType;
}
+ @ApiModelProperty(name = UserResourceProvider.CONSECUTIVE_FAILURES_PROPERTY_ID)
+ public Integer getConsecutiveFailures() {
+ return consecutiveFailures;
+ }
+
+ @ApiModelProperty(name = UserResourceProvider.CREATE_TIME_PROPERTY_ID)
+ public Date getCreateTime() {
+ return createTime;
+ }
+
@Override
public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
UserResponse that = (UserResponse) o;
- if (userName != null ? !userName.equals(that.userName) : that.userName != null) return false;
+ if (userName != null ? !userName.equals(that.userName) : that.userName != null) {
+ return false;
+ }
return authenticationType == that.authenticationType;
}
@@ -108,4 +136,12 @@ UserResponse implements ApiModel {
result = 31 * result + (authenticationType != null ? authenticationType.hashCode() : 0);
return result;
}
+
+ /**
+ * Interface to help correct Swagger documentation generation
+ */
+ public interface UserResponseSwagger {
+ @ApiModelProperty(name = UserResourceProvider.USER_RESOURCE_CATEGORY)
+ UserResponse getUserResponse();
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
index 595b7f9..af2c0e8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
@@ -171,7 +171,9 @@ public abstract class AbstractControllerResourceProvider extends AbstractAuthori
case Task:
return new TaskResourceProvider(propertyIds, keyPropertyIds, managementController);
case User:
- return resourceProviderFactory.getUserResourceProvider(propertyIds, keyPropertyIds, managementController);
+ return resourceProviderFactory.getUserResourceProvider(managementController);
+ case UserAuthenticationSource:
+ return resourceProviderFactory.getUserAuthenticationSourceResourceProvider();
case Group:
return new GroupResourceProvider(propertyIds, keyPropertyIds, managementController);
case Member:
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UserAuthenticationSourceResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UserAuthenticationSourceResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UserAuthenticationSourceResourceProvider.java
new file mode 100644
index 0000000..6a5f528
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UserAuthenticationSourceResourceProvider.java
@@ -0,0 +1,417 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.controller.internal;
+
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.PrivilegeResponse;
+import org.apache.ambari.server.controller.UserAuthenticationSourceRequest;
+import org.apache.ambari.server.controller.UserAuthenticationSourceResponse;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+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.ResourceAlreadyExistsException;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.orm.entities.UserAuthenticationEntity;
+import org.apache.ambari.server.orm.entities.UserEntity;
+import org.apache.ambari.server.security.authorization.AuthorizationException;
+import org.apache.ambari.server.security.authorization.AuthorizationHelper;
+import org.apache.ambari.server.security.authorization.ResourceType;
+import org.apache.ambari.server.security.authorization.RoleAuthorization;
+import org.apache.ambari.server.security.authorization.UserAuthenticationType;
+import org.apache.ambari.server.security.authorization.Users;
+import org.apache.commons.lang.StringUtils;
+import org.apache.velocity.exception.ResourceNotFoundException;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Inject;
+
+/**
+ * Resource provider for user authentication source resources.
+ */
+public class UserAuthenticationSourceResourceProvider extends AbstractAuthorizedResourceProvider {
+
+ public static final String AUTHENTICATION_SOURCE_RESOURCE_CATEGORY = "AuthenticationSourceInfo";
+
+ public static final String AUTHENTICATION_SOURCE_ID_PROPERTY_ID = "source_id";
+ public static final String USER_NAME_PROPERTY_ID = "user_name";
+ public static final String AUTHENTICATION_TYPE_PROPERTY_ID = "authentication_type";
+ public static final String KEY_PROPERTY_ID = "key";
+ public static final String OLD_KEY_PROPERTY_ID = "old_key";
+ public static final String CREATED_PROPERTY_ID = "created";
+ public static final String UPDATED_PROPERTY_ID = "updated";
+
+ public static final String AUTHENTICATION_AUTHENTICATION_SOURCE_ID_PROPERTY_ID = AUTHENTICATION_SOURCE_RESOURCE_CATEGORY + "/" + AUTHENTICATION_SOURCE_ID_PROPERTY_ID;
+ public static final String AUTHENTICATION_USER_NAME_PROPERTY_ID = AUTHENTICATION_SOURCE_RESOURCE_CATEGORY + "/" + USER_NAME_PROPERTY_ID;
+ public static final String AUTHENTICATION_AUTHENTICATION_TYPE_PROPERTY_ID = AUTHENTICATION_SOURCE_RESOURCE_CATEGORY + "/" + AUTHENTICATION_TYPE_PROPERTY_ID;
+ public static final String AUTHENTICATION_KEY_PROPERTY_ID = AUTHENTICATION_SOURCE_RESOURCE_CATEGORY + "/" + KEY_PROPERTY_ID;
+ public static final String AUTHENTICATION_OLD_KEY_PROPERTY_ID = AUTHENTICATION_SOURCE_RESOURCE_CATEGORY + "/" + OLD_KEY_PROPERTY_ID;
+ public static final String AUTHENTICATION_CREATED_PROPERTY_ID = AUTHENTICATION_SOURCE_RESOURCE_CATEGORY + "/" + CREATED_PROPERTY_ID;
+ public static final String AUTHENTICATION_UPDATED_PROPERTY_ID = AUTHENTICATION_SOURCE_RESOURCE_CATEGORY + "/" + UPDATED_PROPERTY_ID;
+
+ private static final Set<String> PK_PROPERTY_IDS = ImmutableSet.of(
+ AUTHENTICATION_AUTHENTICATION_SOURCE_ID_PROPERTY_ID
+ );
+ private static final Set<String> PROPERTY_IDS = ImmutableSet.of(
+ AUTHENTICATION_AUTHENTICATION_SOURCE_ID_PROPERTY_ID,
+ AUTHENTICATION_USER_NAME_PROPERTY_ID,
+ AUTHENTICATION_AUTHENTICATION_TYPE_PROPERTY_ID,
+ AUTHENTICATION_KEY_PROPERTY_ID,
+ AUTHENTICATION_OLD_KEY_PROPERTY_ID,
+ AUTHENTICATION_CREATED_PROPERTY_ID,
+ AUTHENTICATION_UPDATED_PROPERTY_ID
+ );
+ private static final Map<Resource.Type, String> KEY_PROPERTY_IDS = ImmutableMap.of(
+ Resource.Type.User, AUTHENTICATION_USER_NAME_PROPERTY_ID,
+ Resource.Type.UserAuthenticationSource, AUTHENTICATION_AUTHENTICATION_SOURCE_ID_PROPERTY_ID
+ );
+
+ @Inject
+ private Users users;
+
+ /**
+ * Constructor.
+ */
+ public UserAuthenticationSourceResourceProvider() {
+ super(Resource.Type.UserAuthenticationSource, PROPERTY_IDS, KEY_PROPERTY_IDS);
+
+ EnumSet<RoleAuthorization> requiredAuthorizations = EnumSet.of(RoleAuthorization.AMBARI_MANAGE_USERS);
+ setRequiredCreateAuthorizations(requiredAuthorizations);
+ setRequiredDeleteAuthorizations(requiredAuthorizations);
+ setRequiredGetAuthorizations(requiredAuthorizations);
+ setRequiredUpdateAuthorizations(requiredAuthorizations);
+ }
+
+ // ----- PrivilegeResourceProvider -----------------------------------------
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return PK_PROPERTY_IDS;
+ }
+
+ @Override
+ public RequestStatus createResourcesAuthorized(Request request)
+ throws SystemException, UnsupportedPropertyException, ResourceAlreadyExistsException, NoSuchParentResourceException {
+ final Set<UserAuthenticationSourceRequest> requests = new HashSet<>();
+ for (Map<String, Object> propertyMap : request.getProperties()) {
+ requests.add(getRequest(propertyMap));
+ }
+
+ createResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException {
+ createUserAuthenticationSources(requests);
+ return null;
+ }
+ });
+
+ return getRequestStatus(null);
+ }
+
+ @Override
+ public Set<Resource> getResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+ final Set<UserAuthenticationSourceRequest> requests = new HashSet<>();
+ if (predicate == null) {
+ requests.add(getRequest(null));
+ } else {
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ requests.add(getRequest(propertyMap));
+ }
+ }
+
+ Set<UserAuthenticationSourceResponse> responses = getResources(new Command<Set<UserAuthenticationSourceResponse>>() {
+ @Override
+ public Set<UserAuthenticationSourceResponse> invoke() throws AmbariException, AuthorizationException {
+ return getUserAuthenticationSources(requests);
+ }
+ });
+
+ Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+ Set<Resource> resources = new HashSet<>();
+
+ for (UserAuthenticationSourceResponse response : responses) {
+ resources.add(toResource(response, requestedIds));
+ }
+
+ return resources;
+ }
+
+ @Override
+ public RequestStatus updateResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+ final Set<UserAuthenticationSourceRequest> requests = new HashSet<>();
+
+ for (Map<String, Object> propertyMap : getPropertyMaps(request.getProperties().iterator().next(), predicate)) {
+ requests.add(getRequest(propertyMap));
+ }
+
+ modifyResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException, AuthorizationException {
+ updateUserAuthenticationSources(requests);
+ return null;
+ }
+ });
+
+ return getRequestStatus(null);
+ }
+
+ @Override
+ public RequestStatus deleteResourcesAuthorized(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+ final Set<UserAuthenticationSourceRequest> requests = new HashSet<>();
+
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ requests.add(getRequest(propertyMap));
+ }
+
+ modifyResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException, AuthorizationException {
+ deleteUserAuthenticationSources(requests);
+ return null;
+ }
+ });
+
+ return getRequestStatus(null);
+ }
+
+ private UserAuthenticationSourceRequest getRequest(Map<String, Object> properties) {
+ String username;
+ Long sourceId;
+ UserAuthenticationType authenticationType;
+ String key;
+ String oldKey;
+
+ if (properties == null) {
+ username = null;
+ sourceId = null;
+ authenticationType = null;
+ key = null;
+ oldKey = null;
+ } else {
+ String tmp;
+
+ username = (String) properties.get(AUTHENTICATION_USER_NAME_PROPERTY_ID);
+ key = (String) properties.get(AUTHENTICATION_KEY_PROPERTY_ID);
+ oldKey = (String) properties.get(AUTHENTICATION_OLD_KEY_PROPERTY_ID);
+
+ tmp = (String) properties.get(AUTHENTICATION_AUTHENTICATION_SOURCE_ID_PROPERTY_ID);
+
+ if (StringUtils.isEmpty(tmp)) {
+ sourceId = null;
+ } else {
+ sourceId = Long.parseLong(tmp);
+ }
+
+ tmp = (String) properties.get(AUTHENTICATION_AUTHENTICATION_TYPE_PROPERTY_ID);
+ if (StringUtils.isEmpty(tmp)) {
+ authenticationType = null;
+ } else {
+ authenticationType = UserAuthenticationType.valueOf(tmp.trim().toUpperCase());
+ }
+ }
+
+ return new UserAuthenticationSourceRequest(username, sourceId, authenticationType, key, oldKey);
+ }
+
+ /**
+ * Creates user authentication sources.
+ *
+ * @param requests the request objects which define the user authentication source.
+ * @throws AmbariException when the user authentication source cannot be created.
+ */
+ private void createUserAuthenticationSources(Set<UserAuthenticationSourceRequest> requests) throws AmbariException {
+ for (UserAuthenticationSourceRequest request : requests) {
+ String username = request.getUsername();
+ if (StringUtils.isEmpty(username)) {
+ throw new AmbariException("Username must be supplied.");
+ }
+
+ UserAuthenticationType authenticationType = request.getAuthenticationType();
+ if (authenticationType == null) {
+ throw new AmbariException("A value authentication type must be supplied.");
+ }
+
+ UserEntity userEntity = users.getUserEntity(username);
+ if (userEntity == null) {
+ throw new AmbariException("There is no user with the supplied username");
+ }
+
+ users.addAuthentication(userEntity, authenticationType, request.getKey());
+ }
+ }
+
+ /**
+ * Gets the users authentication sources identified by the given request objects.
+ *
+ * @param requests the request objects
+ * @return a set of user responses
+ * @throws AmbariException if the user authentication sources could not be read
+ */
+ private Set<UserAuthenticationSourceResponse> getUserAuthenticationSources(Set<UserAuthenticationSourceRequest> requests)
+ throws AmbariException, AuthorizationException {
+
+ Set<UserAuthenticationSourceResponse> responses = new HashSet<>();
+
+ for (UserAuthenticationSourceRequest request : requests) {
+
+ String requestedUsername = request.getUsername();
+ String authenticatedUsername = AuthorizationHelper.getAuthenticatedName();
+
+ // A user authentication source resource may be retrieved by an administrator or the same user.
+ if (!AuthorizationHelper.isAuthorized(ResourceType.AMBARI, null, RoleAuthorization.AMBARI_MANAGE_USERS)) {
+ if (null == requestedUsername) {
+ // Since the authenticated user is not the administrator, force only that user's resource
+ // to be returned
+ requestedUsername = authenticatedUsername;
+ } else if (!requestedUsername.equalsIgnoreCase(authenticatedUsername)) {
+ // Since the authenticated user is not the administrator and is asking for a different user,
+ // throw an AuthorizationException
+ throw new AuthorizationException();
+ }
+ }
+
+ Collection<UserAuthenticationEntity> authenticationEntities = users.getUserAuthenticationEntities(requestedUsername, request.getAuthenticationType());
+ if (authenticationEntities != null) {
+ for (UserAuthenticationEntity authenticationEntity : authenticationEntities) {
+ responses.add(createUserAuthenticationSourceResponse(authenticationEntity));
+ }
+ }
+ }
+
+ return responses;
+ }
+
+ /**
+ * Delete the users authentication sources identified by the given request objects.
+ * <p>
+ * It ia assumed that the user has previously been authorized to perform this operation.
+ *
+ * @param requests the request objects
+ * @throws AmbariException if the user authentication sources could not be read
+ */
+ private void deleteUserAuthenticationSources(Set<UserAuthenticationSourceRequest> requests)
+ throws AmbariException, AuthorizationException {
+
+ for (UserAuthenticationSourceRequest r : requests) {
+ String username = r.getUsername();
+ Long sourceId = r.getSourceId();
+ if (!StringUtils.isEmpty(username) && (sourceId != null)) {
+ users.removeAuthentication(username, sourceId);
+ }
+ }
+ }
+
+ private void updateUserAuthenticationSources(Set<UserAuthenticationSourceRequest> requests) throws AuthorizationException, AmbariException {
+
+ Integer authenticatedUserId = AuthorizationHelper.getAuthenticatedId();
+
+
+ for (UserAuthenticationSourceRequest request : requests) {
+ String requestedUsername = request.getUsername();
+
+ UserEntity userEntity = users.getUserEntity(requestedUsername);
+ if (null == userEntity) {
+ continue;
+ }
+
+ boolean isSelf = authenticatedUserId.equals(userEntity.getUserId());
+ /* **************************************************
+ * Ensure that the authenticated user can change the password for the subject user. At least one
+ * of the following must be true
+ * * The authenticate user is requesting to change his/her own password for a local authentication source
+ * * The authenticated user has permissions to manage users
+ * ************************************************** */
+ if (!isSelf && !AuthorizationHelper.isAuthorized(ResourceType.AMBARI, null, RoleAuthorization.AMBARI_MANAGE_USERS)) {
+ throw new AuthorizationException("You are not authorized perform this operation");
+ }
+
+ UserAuthenticationEntity userAuthenticationEntity = null;
+ Long sourceId = request.getSourceId();
+
+ if (sourceId != null) {
+ List<UserAuthenticationEntity> authenticationEntities = userEntity.getAuthenticationEntities();
+ // Find the relevant authentication entity...
+ for (UserAuthenticationEntity authenticationEntity : authenticationEntities) {
+ if (sourceId.equals(authenticationEntity.getUserAuthenticationId())) {
+ userAuthenticationEntity = authenticationEntity;
+ break;
+ }
+ }
+ }
+
+ if (userAuthenticationEntity == null) {
+ // The requested authentication record was not found....
+ throw new ResourceNotFoundException("The requested authentication source was not found.");
+ }
+
+ // If the authentication_type is set, use it to verify that the found authentication source matches it...
+ if ((request.getAuthenticationType() != null) && (request.getAuthenticationType() != userAuthenticationEntity.getAuthenticationType())) {
+ throw new ResourceNotFoundException("The requested authentication source was not found - mismatch on authentication type");
+ }
+
+ users.modifyAuthentication(userAuthenticationEntity, request.getOldKey(), request.getKey(), isSelf);
+ }
+ }
+
+ private UserAuthenticationSourceResponse createUserAuthenticationSourceResponse(UserAuthenticationEntity entity) {
+ return new UserAuthenticationSourceResponse(entity.getUser().getUserName(),
+ entity.getUserAuthenticationId(),
+ entity.getAuthenticationType(),
+ entity.getAuthenticationKey(),
+ entity.getCreateTime(),
+ entity.getUpdateTime());
+ }
+
+
+ /**
+ * Translate the Response into a Resource
+ *
+ * @param response {@link PrivilegeResponse}
+ * @param requestedIds the relevant request ids
+ * @return a resource
+ */
+ private Resource toResource(UserAuthenticationSourceResponse response, Set<String> requestedIds) {
+ final ResourceImpl resource = new ResourceImpl(Resource.Type.UserAuthenticationSource);
+
+ setResourceProperty(resource, AUTHENTICATION_USER_NAME_PROPERTY_ID, response.getUserName(), requestedIds);
+ setResourceProperty(resource, AUTHENTICATION_AUTHENTICATION_SOURCE_ID_PROPERTY_ID, response.getSourceId(), requestedIds);
+ setResourceProperty(resource, AUTHENTICATION_AUTHENTICATION_TYPE_PROPERTY_ID, response.getAuthenticationType().name(), requestedIds);
+ setResourceProperty(resource, AUTHENTICATION_CREATED_PROPERTY_ID, response.getCreateTime(), requestedIds);
+ setResourceProperty(resource, AUTHENTICATION_UPDATED_PROPERTY_ID, response.getUpdateTime(), requestedIds);
+
+ // NOTE, AUTHENTICATION_KEY_PROPERTY_ID is not being returned here since we don't want to return
+ // any sensitive information. Once set that data should stay internal to Ambari.
+
+ return resource;
+ }
+}
\ No newline at end of file
[4/6] ambari git commit: AMBARI-20861. BE: Extend Ambari REST API to
Support User Account Management Improvements (rlevas)
Posted by rl...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/docs/api/generated/swagger.json
----------------------------------------------------------------------
diff --git a/ambari-server/docs/api/generated/swagger.json b/ambari-server/docs/api/generated/swagger.json
index 6347bfa..7baaa6a 100644
--- a/ambari-server/docs/api/generated/swagger.json
+++ b/ambari-server/docs/api/generated/swagger.json
@@ -29,8 +29,11 @@
"name" : "Stacks",
"description" : "Endpoint for stack specific operations"
}, {
+ "name" : "User Authentication Sources",
+ "description" : "Endpoint for user specific authentication source operations"
+ }, {
"name" : "Users",
- "description" : "Endpoint for user specific operations"
+ "description" : "Endpoint for User specific operations"
}, {
"name" : "Views"
}, {
@@ -4681,20 +4684,20 @@
"get" : {
"tags" : [ "Users" ],
"summary" : "Get all users",
- "description" : "Returns details of all users.",
- "operationId" : "UserService#getUsers",
+ "description" : "",
+ "operationId" : "getUsers",
"produces" : [ "text/plain" ],
"parameters" : [ {
"name" : "fields",
"in" : "query",
- "description" : "Filter user details",
+ "description" : "Filter fields in the response (identifier fields are mandatory)",
"required" : false,
"type" : "string",
- "default" : "Users/*"
+ "default" : "Users/user_name"
}, {
"name" : "sortBy",
"in" : "query",
- "description" : "Sort users (asc | desc)",
+ "description" : "Sort resources in result by (asc | desc)",
"required" : false,
"type" : "string",
"default" : "Users/user_name.asc"
@@ -4708,16 +4711,18 @@
}, {
"name" : "from",
"in" : "query",
- "description" : "The starting page resource (inclusive). Valid values are :offset | \"start\"",
+ "description" : "The starting page resource (inclusive). \"start\" is also accepted.",
"required" : false,
- "type" : "string",
- "default" : "0"
+ "type" : "integer",
+ "default" : 0,
+ "minimum" : 0.0
}, {
"name" : "to",
"in" : "query",
- "description" : "The ending page resource (inclusive). Valid values are :offset | \"end\"",
+ "description" : "The ending page resource (inclusive). \"end\" is also accepted.",
"required" : false,
- "type" : "string"
+ "type" : "integer",
+ "minimum" : 1.0
} ],
"responses" : {
"200" : {
@@ -4725,9 +4730,62 @@
"schema" : {
"type" : "array",
"items" : {
- "$ref" : "#/definitions/UserResponse"
+ "$ref" : "#/definitions/UserResponseSwagger"
}
}
+ },
+ "401" : {
+ "description" : "Not authenticated"
+ },
+ "403" : {
+ "description" : "Not permitted to perform the operation"
+ },
+ "404" : {
+ "description" : "The requested resource doesn't exist."
+ },
+ "500" : {
+ "description" : "Internal server error"
+ }
+ }
+ },
+ "post" : {
+ "tags" : [ "Users" ],
+ "summary" : "Creates one or more users in a single request",
+ "description" : "",
+ "operationId" : "createUsers",
+ "produces" : [ "text/plain" ],
+ "parameters" : [ {
+ "in" : "body",
+ "name" : "body",
+ "required" : false,
+ "schema" : {
+ "$ref" : "#/definitions/UserRequestCreateUsersSwagger"
+ }
+ } ],
+ "responses" : {
+ "201" : {
+ "description" : "Successful operation"
+ },
+ "202" : {
+ "description" : "Request is accepted, but not completely processed yet"
+ },
+ "400" : {
+ "description" : "Invalid arguments"
+ },
+ "401" : {
+ "description" : "Not authenticated"
+ },
+ "403" : {
+ "description" : "Not permitted to perform the operation"
+ },
+ "404" : {
+ "description" : "The requested resource doesn't exist."
+ },
+ "409" : {
+ "description" : "The requested resource already exists."
+ },
+ "500" : {
+ "description" : "Internal server error"
}
}
}
@@ -4736,38 +4794,49 @@
"get" : {
"tags" : [ "Users" ],
"summary" : "Get single user",
- "description" : "Returns user details.",
- "operationId" : "UserService#getUser",
+ "description" : "",
+ "operationId" : "getUser",
"produces" : [ "text/plain" ],
"parameters" : [ {
"name" : "userName",
"in" : "path",
"description" : "user name",
"required" : true,
- "type" : "string",
- "default" : "admin"
+ "type" : "string"
}, {
"name" : "fields",
"in" : "query",
- "description" : "Filter user details",
+ "description" : "Filter fields in the response (identifier fields are mandatory)",
"required" : false,
"type" : "string",
- "default" : "Users"
+ "default" : "Users/*"
} ],
"responses" : {
"200" : {
"description" : "Successful operation",
"schema" : {
- "$ref" : "#/definitions/UserResponse"
+ "$ref" : "#/definitions/UserResponseSwagger"
}
+ },
+ "401" : {
+ "description" : "Not authenticated"
+ },
+ "403" : {
+ "description" : "Not permitted to perform the operation"
+ },
+ "404" : {
+ "description" : "The requested resource doesn't exist."
+ },
+ "500" : {
+ "description" : "Internal server error"
}
}
},
"post" : {
"tags" : [ "Users" ],
"summary" : "Create new user",
- "description" : "Creates user resource.",
- "operationId" : "UserService#createUser",
+ "description" : "",
+ "operationId" : "createUser",
"produces" : [ "text/plain" ],
"parameters" : [ {
"name" : "userName",
@@ -4778,26 +4847,43 @@
}, {
"in" : "body",
"name" : "body",
- "description" : "input parameters in json form",
- "required" : true,
+ "required" : false,
"schema" : {
- "$ref" : "#/definitions/UserRequest"
+ "$ref" : "#/definitions/UserRequestCreateUserSwagger"
}
} ],
"responses" : {
- "200" : {
+ "201" : {
"description" : "Successful operation"
},
+ "202" : {
+ "description" : "Request is accepted, but not completely processed yet"
+ },
+ "400" : {
+ "description" : "Invalid arguments"
+ },
+ "401" : {
+ "description" : "Not authenticated"
+ },
+ "403" : {
+ "description" : "Not permitted to perform the operation"
+ },
+ "404" : {
+ "description" : "The requested resource doesn't exist."
+ },
+ "409" : {
+ "description" : "The requested resource already exists."
+ },
"500" : {
- "description" : "Server Error"
+ "description" : "Internal server error"
}
}
},
"put" : {
"tags" : [ "Users" ],
- "summary" : "Update user detail",
- "description" : "Updates user resource.",
- "operationId" : "UserService#updateUser",
+ "summary" : "Update user details",
+ "description" : "",
+ "operationId" : "updateUser",
"produces" : [ "text/plain" ],
"parameters" : [ {
"name" : "userName",
@@ -4808,26 +4894,40 @@
}, {
"in" : "body",
"name" : "body",
- "description" : "input parameters in json form",
- "required" : true,
+ "required" : false,
"schema" : {
- "$ref" : "#/definitions/UserRequest"
+ "$ref" : "#/definitions/UserRequestUpdateUserSwagger"
}
} ],
"responses" : {
- "200" : {
- "description" : "Successful operation"
+ "202" : {
+ "description" : "Request is accepted, but not completely processed yet"
+ },
+ "400" : {
+ "description" : "Invalid arguments"
+ },
+ "401" : {
+ "description" : "Not authenticated"
+ },
+ "403" : {
+ "description" : "Not permitted to perform the operation"
+ },
+ "404" : {
+ "description" : "The requested resource doesn't exist."
+ },
+ "409" : {
+ "description" : "The requested resource already exists."
},
"500" : {
- "description" : "Server Error"
+ "description" : "Internal server error"
}
}
},
"delete" : {
"tags" : [ "Users" ],
"summary" : "Delete single user",
- "description" : "Delete user resource.",
- "operationId" : "UserService#deleteUser",
+ "description" : "",
+ "operationId" : "deleteUser",
"produces" : [ "text/plain" ],
"parameters" : [ {
"name" : "userName",
@@ -5134,27 +5234,33 @@
}
}
},
- "/views" : {
+ "/users/{userName}/sources" : {
"get" : {
- "tags" : [ "Views" ],
- "summary" : "Get all views",
- "description" : "Returns details of all views.",
- "operationId" : "ViewService#getViews",
+ "tags" : [ "User Authentication Sources" ],
+ "summary" : "Get all authentication sources",
+ "description" : "",
+ "operationId" : "getAuthenticationSources",
"produces" : [ "text/plain" ],
"parameters" : [ {
+ "name" : "userName",
+ "in" : "path",
+ "description" : "user name",
+ "required" : true,
+ "type" : "string"
+ }, {
"name" : "fields",
"in" : "query",
- "description" : "Filter view details",
+ "description" : "Filter fields in the response (identifier fields are mandatory)",
"required" : false,
"type" : "string",
- "default" : "ViewInfo/*"
+ "default" : "AuthenticationSourceInfo/source_id,AuthenticationSourceInfo/user_name"
}, {
"name" : "sortBy",
"in" : "query",
- "description" : "Sort users (asc | desc)",
+ "description" : "Sort resources in result by (asc | desc)",
"required" : false,
"type" : "string",
- "default" : "ViewInfo/view_name.asc"
+ "default" : "AuthenticationSourceInfo/source_id.asc"
}, {
"name" : "page_size",
"in" : "query",
@@ -5165,16 +5271,18 @@
}, {
"name" : "from",
"in" : "query",
- "description" : "The starting page resource (inclusive). Valid values are :offset | \"start\"",
+ "description" : "The starting page resource (inclusive). \"start\" is also accepted.",
"required" : false,
- "type" : "string",
- "default" : "0"
+ "type" : "integer",
+ "default" : 0,
+ "minimum" : 0.0
}, {
"name" : "to",
"in" : "query",
- "description" : "The ending page resource (inclusive). Valid values are :offset | \"end\"",
+ "description" : "The ending page resource (inclusive). \"end\" is also accepted.",
"required" : false,
- "type" : "string"
+ "type" : "integer",
+ "minimum" : 1.0
} ],
"responses" : {
"200" : {
@@ -5182,68 +5290,318 @@
"schema" : {
"type" : "array",
"items" : {
- "$ref" : "#/definitions/ViewResponse"
+ "$ref" : "#/definitions/UserAuthenticationSourceResponseSwagger"
}
}
+ },
+ "401" : {
+ "description" : "Not authenticated"
+ },
+ "403" : {
+ "description" : "Not permitted to perform the operation"
+ },
+ "404" : {
+ "description" : "The requested resource doesn't exist."
+ },
+ "500" : {
+ "description" : "Internal server error"
}
}
- }
- },
- "/views/{viewName}" : {
- "get" : {
- "tags" : [ "Views" ],
- "summary" : "Get single view",
- "description" : "Returns view details.",
- "operationId" : "ViewService#getView",
+ },
+ "post" : {
+ "tags" : [ "User Authentication Sources" ],
+ "summary" : "Create one or more new authentication sources for a user",
+ "description" : "",
+ "operationId" : "createAuthenticationSources",
"produces" : [ "text/plain" ],
"parameters" : [ {
- "name" : "viewName",
+ "name" : "userName",
"in" : "path",
- "description" : "view name",
+ "description" : "user name",
"required" : true,
"type" : "string"
}, {
- "name" : "fields",
- "in" : "query",
- "description" : "Filter view details",
+ "in" : "body",
+ "name" : "body",
"required" : false,
- "type" : "string",
- "default" : "ViewInfo"
+ "schema" : {
+ "$ref" : "#/definitions/UserAuthenticationSourceRequestCreateSwagger"
+ }
} ],
"responses" : {
- "200" : {
- "description" : "Successful operation",
- "schema" : {
- "$ref" : "#/definitions/ViewResponse"
- }
+ "201" : {
+ "description" : "Successful operation"
+ },
+ "202" : {
+ "description" : "Request is accepted, but not completely processed yet"
+ },
+ "400" : {
+ "description" : "Invalid arguments"
+ },
+ "401" : {
+ "description" : "Not authenticated"
+ },
+ "403" : {
+ "description" : "Not permitted to perform the operation"
+ },
+ "404" : {
+ "description" : "The requested resource doesn't exist."
+ },
+ "409" : {
+ "description" : "The requested resource already exists."
+ },
+ "500" : {
+ "description" : "Internal server error"
}
}
}
},
- "/views/{viewName}/versions" : {
+ "/users/{userName}/sources/{sourceId}" : {
"get" : {
- "tags" : [ "Views" ],
- "summary" : "Get all versions for a view",
- "description" : "Returns details of all versions for a view.",
- "operationId" : "ViewVersionService#getVersions",
+ "tags" : [ "User Authentication Sources" ],
+ "summary" : "Get user authentication source",
+ "description" : "",
+ "operationId" : "getAuthenticationSource",
"produces" : [ "text/plain" ],
"parameters" : [ {
- "name" : "viewName",
+ "name" : "userName",
"in" : "path",
- "description" : "view name",
+ "description" : "user name",
"required" : true,
"type" : "string"
}, {
- "name" : "fields",
- "in" : "query",
- "description" : "Filter view version details",
- "required" : false,
- "type" : "string",
- "default" : "ViewVersionInfo/*"
+ "name" : "sourceId",
+ "in" : "path",
+ "description" : "source id",
+ "required" : true,
+ "type" : "string"
}, {
- "name" : "sortBy",
+ "name" : "fields",
"in" : "query",
- "description" : "Sort users (asc | desc)",
+ "description" : "Filter fields in the response (identifier fields are mandatory)",
+ "required" : false,
+ "type" : "string",
+ "default" : "AuthenticationSourceInfo/*"
+ } ],
+ "responses" : {
+ "200" : {
+ "description" : "Successful operation",
+ "schema" : {
+ "$ref" : "#/definitions/UserAuthenticationSourceResponseSwagger"
+ }
+ },
+ "401" : {
+ "description" : "Not authenticated"
+ },
+ "403" : {
+ "description" : "Not permitted to perform the operation"
+ },
+ "404" : {
+ "description" : "The requested resource doesn't exist."
+ },
+ "500" : {
+ "description" : "Internal server error"
+ }
+ }
+ },
+ "put" : {
+ "tags" : [ "User Authentication Sources" ],
+ "summary" : "Updates an existing authentication source",
+ "description" : "",
+ "operationId" : "updateAuthenticationSource",
+ "produces" : [ "text/plain" ],
+ "parameters" : [ {
+ "name" : "userName",
+ "in" : "path",
+ "description" : "user name",
+ "required" : true,
+ "type" : "string"
+ }, {
+ "name" : "sourceId",
+ "in" : "path",
+ "description" : "source id",
+ "required" : true,
+ "type" : "string"
+ }, {
+ "in" : "body",
+ "name" : "body",
+ "required" : false,
+ "schema" : {
+ "$ref" : "#/definitions/UserAuthenticationSourceRequestUpdateSwagger"
+ }
+ } ],
+ "responses" : {
+ "202" : {
+ "description" : "Request is accepted, but not completely processed yet"
+ },
+ "400" : {
+ "description" : "Invalid arguments"
+ },
+ "401" : {
+ "description" : "Not authenticated"
+ },
+ "403" : {
+ "description" : "Not permitted to perform the operation"
+ },
+ "404" : {
+ "description" : "The requested resource doesn't exist."
+ },
+ "409" : {
+ "description" : "The requested resource already exists."
+ },
+ "500" : {
+ "description" : "Internal server error"
+ }
+ }
+ },
+ "delete" : {
+ "tags" : [ "User Authentication Sources" ],
+ "summary" : "Deletes an existing authentication source",
+ "description" : "",
+ "operationId" : "deleteAuthenticationSource",
+ "produces" : [ "text/plain" ],
+ "parameters" : [ {
+ "name" : "userName",
+ "in" : "path",
+ "description" : "user name",
+ "required" : true,
+ "type" : "string"
+ }, {
+ "name" : "sourceId",
+ "in" : "path",
+ "description" : "source id",
+ "required" : true,
+ "type" : "string"
+ } ],
+ "responses" : {
+ "200" : {
+ "description" : "Successful operation"
+ },
+ "401" : {
+ "description" : "Not authenticated"
+ },
+ "403" : {
+ "description" : "Not permitted to perform the operation"
+ },
+ "404" : {
+ "description" : "The requested resource doesn't exist."
+ },
+ "500" : {
+ "description" : "Internal server error"
+ }
+ }
+ }
+ },
+ "/views" : {
+ "get" : {
+ "tags" : [ "Views" ],
+ "summary" : "Get all views",
+ "description" : "Returns details of all views.",
+ "operationId" : "ViewService#getViews",
+ "produces" : [ "text/plain" ],
+ "parameters" : [ {
+ "name" : "fields",
+ "in" : "query",
+ "description" : "Filter view details",
+ "required" : false,
+ "type" : "string",
+ "default" : "ViewInfo/*"
+ }, {
+ "name" : "sortBy",
+ "in" : "query",
+ "description" : "Sort users (asc | desc)",
+ "required" : false,
+ "type" : "string",
+ "default" : "ViewInfo/view_name.asc"
+ }, {
+ "name" : "page_size",
+ "in" : "query",
+ "description" : "The number of resources to be returned for the paged response.",
+ "required" : false,
+ "type" : "integer",
+ "default" : 10
+ }, {
+ "name" : "from",
+ "in" : "query",
+ "description" : "The starting page resource (inclusive). Valid values are :offset | \"start\"",
+ "required" : false,
+ "type" : "string",
+ "default" : "0"
+ }, {
+ "name" : "to",
+ "in" : "query",
+ "description" : "The ending page resource (inclusive). Valid values are :offset | \"end\"",
+ "required" : false,
+ "type" : "string"
+ } ],
+ "responses" : {
+ "200" : {
+ "description" : "Successful operation",
+ "schema" : {
+ "type" : "array",
+ "items" : {
+ "$ref" : "#/definitions/ViewResponse"
+ }
+ }
+ }
+ }
+ }
+ },
+ "/views/{viewName}" : {
+ "get" : {
+ "tags" : [ "Views" ],
+ "summary" : "Get single view",
+ "description" : "Returns view details.",
+ "operationId" : "ViewService#getView",
+ "produces" : [ "text/plain" ],
+ "parameters" : [ {
+ "name" : "viewName",
+ "in" : "path",
+ "description" : "view name",
+ "required" : true,
+ "type" : "string"
+ }, {
+ "name" : "fields",
+ "in" : "query",
+ "description" : "Filter view details",
+ "required" : false,
+ "type" : "string",
+ "default" : "ViewInfo"
+ } ],
+ "responses" : {
+ "200" : {
+ "description" : "Successful operation",
+ "schema" : {
+ "$ref" : "#/definitions/ViewResponse"
+ }
+ }
+ }
+ }
+ },
+ "/views/{viewName}/versions" : {
+ "get" : {
+ "tags" : [ "Views" ],
+ "summary" : "Get all versions for a view",
+ "description" : "Returns details of all versions for a view.",
+ "operationId" : "ViewVersionService#getVersions",
+ "produces" : [ "text/plain" ],
+ "parameters" : [ {
+ "name" : "viewName",
+ "in" : "path",
+ "description" : "view name",
+ "required" : true,
+ "type" : "string"
+ }, {
+ "name" : "fields",
+ "in" : "query",
+ "description" : "Filter view version details",
+ "required" : false,
+ "type" : "string",
+ "default" : "ViewVersionInfo/*"
+ }, {
+ "name" : "sortBy",
+ "in" : "query",
+ "description" : "Sort users (asc | desc)",
"required" : false,
"type" : "string",
"default" : "ViewVersionInfo/version.desc"
@@ -6086,13 +6444,13 @@
"Artifacts" : {
"type" : "object",
"properties" : {
- "service_name" : {
+ "stack_name" : {
"type" : "string"
},
- "stack_version" : {
+ "service_name" : {
"type" : "string"
},
- "stack_name" : {
+ "stack_version" : {
"type" : "string"
},
"artifact_name" : {
@@ -6103,6 +6461,9 @@
"BlueprintInfo" : {
"type" : "object",
"properties" : {
+ "stack_name" : {
+ "type" : "string"
+ },
"security" : {
"$ref" : "#/definitions/SecurityInfo"
},
@@ -6111,9 +6472,6 @@
},
"blueprint_name" : {
"type" : "string"
- },
- "stack_name" : {
- "type" : "string"
}
}
},
@@ -6187,14 +6545,14 @@
"ClusterArtifactResponse" : {
"type" : "object",
"properties" : {
- "Artifacts" : {
- "$ref" : "#/definitions/ClusterArtifactResponseInfo"
- },
"artifact_data" : {
"type" : "object",
"additionalProperties" : {
"type" : "object"
}
+ },
+ "Artifacts" : {
+ "$ref" : "#/definitions/ClusterArtifactResponseInfo"
}
}
},
@@ -6380,14 +6738,14 @@
"ClusterServiceArtifactResponse" : {
"type" : "object",
"properties" : {
+ "Artifacts" : {
+ "$ref" : "#/definitions/ClusterServiceArtifactResponseInfo"
+ },
"artifact_data" : {
"type" : "object",
"additionalProperties" : {
"type" : "object"
}
- },
- "Artifacts" : {
- "$ref" : "#/definitions/ClusterServiceArtifactResponseInfo"
}
}
},
@@ -6419,15 +6777,18 @@
"scope" : {
"type" : "string"
},
- "service_name" : {
+ "stack_name" : {
"type" : "string"
},
- "component_name" : {
+ "service_name" : {
"type" : "string"
},
"stack_version" : {
"type" : "string"
},
+ "component_name" : {
+ "type" : "string"
+ },
"conditions" : {
"type" : "array",
"items" : {
@@ -6439,9 +6800,6 @@
},
"dependent_service_name" : {
"type" : "string"
- },
- "stack_name" : {
- "type" : "string"
}
}
},
@@ -6596,30 +6954,90 @@
"format" : "int64"
}
},
- "configs" : {
- "type" : "object",
- "additionalProperties" : {
- "type" : "string"
- }
+ "configs" : {
+ "type" : "object",
+ "additionalProperties" : {
+ "type" : "string"
+ }
+ },
+ "configAttributes" : {
+ "type" : "object",
+ "additionalProperties" : {
+ "type" : "object",
+ "additionalProperties" : {
+ "type" : "string"
+ }
+ }
+ },
+ "propertiesTypes" : {
+ "type" : "object",
+ "additionalProperties" : {
+ "type" : "array",
+ "uniqueItems" : true,
+ "items" : {
+ "type" : "string"
+ }
+ }
+ }
+ }
+ },
+ "CreateUserAuthenticationSourceInfo" : {
+ "type" : "object",
+ "required" : [ "authentication_type", "key" ],
+ "properties" : {
+ "key" : {
+ "type" : "string"
+ },
+ "authentication_type" : {
+ "type" : "string",
+ "enum" : [ "LOCAL", "LDAP", "JWT", "PAM", "KERBEROS" ]
+ }
+ }
+ },
+ "CreateUserInfo" : {
+ "type" : "object",
+ "properties" : {
+ "display_name" : {
+ "type" : "string"
+ },
+ "active" : {
+ "type" : "boolean",
+ "default" : false
+ },
+ "password" : {
+ "type" : "string"
+ },
+ "admin" : {
+ "type" : "boolean",
+ "default" : false
+ },
+ "local_user_name" : {
+ "type" : "string"
+ }
+ }
+ },
+ "CreateUsersInfo" : {
+ "type" : "object",
+ "properties" : {
+ "display_name" : {
+ "type" : "string"
+ },
+ "active" : {
+ "type" : "boolean",
+ "default" : false
+ },
+ "user_name" : {
+ "type" : "string"
},
- "configAttributes" : {
- "type" : "object",
- "additionalProperties" : {
- "type" : "object",
- "additionalProperties" : {
- "type" : "string"
- }
- }
+ "password" : {
+ "type" : "string"
},
- "propertiesTypes" : {
- "type" : "object",
- "additionalProperties" : {
- "type" : "array",
- "uniqueItems" : true,
- "items" : {
- "type" : "string"
- }
- }
+ "admin" : {
+ "type" : "boolean",
+ "default" : false
+ },
+ "local_user_name" : {
+ "type" : "string"
}
}
},
@@ -6825,12 +7243,12 @@
"$ref" : "#/definitions/ComponentInfo"
}
},
- "name" : {
- "type" : "string"
- },
"cardinality" : {
"type" : "integer",
"format" : "int32"
+ },
+ "name" : {
+ "type" : "string"
}
}
},
@@ -6888,13 +7306,13 @@
"maintenance_state" : {
"type" : "string"
},
- "host_group" : {
+ "public_host_name" : {
"type" : "string"
},
"blueprint" : {
"type" : "string"
},
- "public_host_name" : {
+ "host_group" : {
"type" : "string"
}
}
@@ -6975,10 +7393,10 @@
"type" : "string",
"enum" : [ "OFF", "ON", "IMPLIED_FROM_SERVICE", "IMPLIED_FROM_HOST", "IMPLIED_FROM_SERVICE_AND_HOST" ]
},
- "public_host_name" : {
+ "host_health_report" : {
"type" : "string"
},
- "host_health_report" : {
+ "public_host_name" : {
"type" : "string"
}
}
@@ -7331,16 +7749,16 @@
"file_name" : {
"type" : "string"
},
- "service_name" : {
+ "stack_name" : {
"type" : "string"
},
"quicklink_data" : {
"$ref" : "#/definitions/QuickLinksConfiguration"
},
- "stack_version" : {
+ "service_name" : {
"type" : "string"
},
- "stack_name" : {
+ "stack_version" : {
"type" : "string"
}
}
@@ -7408,16 +7826,13 @@
"type" : "boolean",
"default" : false
},
- "baseUrl" : {
- "type" : "string"
- },
- "mirrorsList" : {
+ "repoName" : {
"type" : "string"
},
- "latestUri" : {
+ "baseUrl" : {
"type" : "string"
},
- "repoName" : {
+ "mirrorsList" : {
"type" : "string"
},
"repoId" : {
@@ -7467,9 +7882,6 @@
"defaultBaseUrl" : {
"type" : "string"
},
- "latestBaseUrl" : {
- "type" : "string"
- },
"repoSaved" : {
"type" : "boolean",
"default" : false
@@ -7525,6 +7937,15 @@
"$ref" : "#/definitions/RepositoryVersionEntity"
}
},
+ "stackId" : {
+ "$ref" : "#/definitions/StackId"
+ },
+ "repositoryXml" : {
+ "$ref" : "#/definitions/VersionDefinitionXml"
+ },
+ "stackName" : {
+ "type" : "string"
+ },
"operatingSystemsJson" : {
"type" : "string"
},
@@ -7534,15 +7955,6 @@
},
"stackVersion" : {
"type" : "string"
- },
- "stackId" : {
- "$ref" : "#/definitions/StackId"
- },
- "stackName" : {
- "type" : "string"
- },
- "repositoryXml" : {
- "$ref" : "#/definitions/VersionDefinitionXml"
}
}
},
@@ -7568,14 +7980,14 @@
"$ref" : "#/definitions/RepositoryInfo"
}
},
- "latestURI" : {
- "type" : "string"
- },
"errors" : {
"type" : "array",
"items" : {
"type" : "string"
}
+ },
+ "latestURI" : {
+ "type" : "string"
}
},
"xml" : {
@@ -7609,14 +8021,14 @@
"type" : "object"
}
},
- "action" : {
- "type" : "string"
+ "operation_level" : {
+ "$ref" : "#/definitions/OperationLevel"
},
"command" : {
"type" : "string"
},
- "operation_level" : {
- "$ref" : "#/definitions/OperationLevel"
+ "action" : {
+ "type" : "string"
}
}
},
@@ -7673,6 +8085,9 @@
"RequestResourceFilter" : {
"type" : "object",
"properties" : {
+ "hosts" : {
+ "type" : "string"
+ },
"service_name" : {
"type" : "string"
},
@@ -7681,9 +8096,6 @@
},
"hosts_predicate" : {
"type" : "string"
- },
- "hosts" : {
- "type" : "string"
}
}
},
@@ -7701,19 +8113,27 @@
"type" : {
"type" : "string"
},
- "start_time" : {
- "type" : "string"
+ "create_time" : {
+ "type" : "integer",
+ "format" : "int64"
},
"request_context" : {
"type" : "string"
},
- "request_status" : {
+ "task_count" : {
+ "type" : "integer",
+ "format" : "int32"
+ },
+ "completed_task_count" : {
"type" : "string"
},
- "cluster_name" : {
+ "start_time" : {
"type" : "string"
},
- "request_schedule" : {
+ "request_status" : {
+ "type" : "string"
+ },
+ "cluster_name" : {
"type" : "string"
},
"id" : {
@@ -7723,10 +8143,6 @@
"type" : "integer",
"format" : "int32"
},
- "create_time" : {
- "type" : "integer",
- "format" : "int64"
- },
"end_time" : {
"type" : "string"
},
@@ -7738,9 +8154,6 @@
"type" : "integer",
"format" : "int32"
},
- "inputs" : {
- "type" : "string"
- },
"operation_level" : {
"type" : "string"
},
@@ -7762,11 +8175,10 @@
"$ref" : "#/definitions/RequestResourceFilter"
}
},
- "task_count" : {
- "type" : "integer",
- "format" : "int32"
+ "request_schedule" : {
+ "type" : "string"
},
- "completed_task_count" : {
+ "inputs" : {
"type" : "string"
}
}
@@ -8172,14 +8584,14 @@
"StackArtifactResponse" : {
"type" : "object",
"properties" : {
- "Artifacts" : {
- "$ref" : "#/definitions/Artifacts"
- },
"artifact_data" : {
"type" : "object",
"additionalProperties" : {
"type" : "object"
}
+ },
+ "Artifacts" : {
+ "$ref" : "#/definitions/Artifacts"
}
}
},
@@ -8317,14 +8729,14 @@
"StackServiceArtifactResponse" : {
"type" : "object",
"properties" : {
- "Artifacts" : {
- "$ref" : "#/definitions/Artifacts"
- },
"artifact_data" : {
"type" : "object",
"additionalProperties" : {
"type" : "object"
}
+ },
+ "Artifacts" : {
+ "$ref" : "#/definitions/Artifacts"
}
}
},
@@ -8687,17 +9099,17 @@
"file_name" : {
"type" : "string"
},
- "service_name" : {
- "type" : "string"
+ "theme_data" : {
+ "$ref" : "#/definitions/Theme"
},
- "stack_version" : {
+ "stack_name" : {
"type" : "string"
},
- "stack_name" : {
+ "service_name" : {
"type" : "string"
},
- "theme_data" : {
- "$ref" : "#/definitions/Theme"
+ "stack_version" : {
+ "type" : "string"
}
}
},
@@ -8717,6 +9129,95 @@
}
}
},
+ "UpdateUserInfo" : {
+ "type" : "object",
+ "properties" : {
+ "display_name" : {
+ "type" : "string"
+ },
+ "active" : {
+ "type" : "boolean",
+ "default" : false
+ },
+ "password" : {
+ "type" : "string"
+ },
+ "admin" : {
+ "type" : "boolean",
+ "default" : false
+ },
+ "local_user_name" : {
+ "type" : "string"
+ },
+ "old_password" : {
+ "type" : "string"
+ }
+ }
+ },
+ "UserAuthenticationSourceRequestCreateSwagger" : {
+ "type" : "object",
+ "properties" : {
+ "AuthenticationSourceInfo" : {
+ "$ref" : "#/definitions/CreateUserAuthenticationSourceInfo"
+ }
+ }
+ },
+ "UserAuthenticationSourceRequestUpdateInfo" : {
+ "type" : "object",
+ "required" : [ "key" ],
+ "properties" : {
+ "key" : {
+ "type" : "string"
+ },
+ "old_key" : {
+ "type" : "string"
+ }
+ }
+ },
+ "UserAuthenticationSourceRequestUpdateSwagger" : {
+ "type" : "object",
+ "properties" : {
+ "AuthenticationSourceInfo" : {
+ "$ref" : "#/definitions/UserAuthenticationSourceRequestUpdateInfo"
+ }
+ }
+ },
+ "UserAuthenticationSourceResponse" : {
+ "type" : "object",
+ "required" : [ "authentication_type", "source_id", "user_name" ],
+ "properties" : {
+ "user_name" : {
+ "type" : "string"
+ },
+ "source_id" : {
+ "type" : "integer",
+ "format" : "int64"
+ },
+ "authentication_type" : {
+ "type" : "string",
+ "enum" : [ "LOCAL", "LDAP", "JWT", "PAM", "KERBEROS" ]
+ },
+ "key" : {
+ "type" : "string"
+ },
+ "created" : {
+ "type" : "string",
+ "format" : "date-time"
+ },
+ "updated" : {
+ "type" : "string",
+ "format" : "date-time"
+ }
+ }
+ },
+ "UserAuthenticationSourceResponseSwagger" : {
+ "type" : "object",
+ "properties" : {
+ "AuthenticationSourceInfo" : {
+ "$ref" : "#/definitions/UserAuthenticationSourceResponse"
+ }
+ }
+ },
"UserAuthorizationResponse" : {
"type" : "object",
"required" : [ "AuthorizationInfo/user_name" ],
@@ -8800,60 +9301,80 @@
}
}
},
- "UserRequest" : {
+ "UserRequestCreateUserSwagger" : {
"type" : "object",
"properties" : {
- "Users/password" : {
- "type" : "string"
- },
- "Users/old_password" : {
- "type" : "string"
- },
- "Users/active" : {
- "type" : "boolean",
- "default" : false
- },
- "Users/admin" : {
- "type" : "boolean",
- "default" : false
- },
- "Users/display_name" : {
- "type" : "string"
- },
- "Users/local_user_name" : {
- "type" : "string"
+ "Users" : {
+ "$ref" : "#/definitions/CreateUserInfo"
+ }
+ }
+ },
+ "UserRequestCreateUsersSwagger" : {
+ "type" : "object",
+ "properties" : {
+ "Users" : {
+ "$ref" : "#/definitions/CreateUsersInfo"
+ }
+ }
+ },
+ "UserRequestUpdateUserSwagger" : {
+ "type" : "object",
+ "properties" : {
+ "Users" : {
+ "$ref" : "#/definitions/UpdateUserInfo"
}
}
},
"UserResponse" : {
"type" : "object",
- "required" : [ "Users/user_name" ],
"properties" : {
- "Users/authentication_type" : {
+ "display_name" : {
+ "type" : "string"
+ },
+ "user_type" : {
"type" : "string",
"enum" : [ "LOCAL", "LDAP", "JWT", "PAM", "KERBEROS" ]
},
- "Users/groups" : {
+ "groups" : {
"type" : "array",
"uniqueItems" : true,
"items" : {
"type" : "string"
}
},
- "Users/active" : {
+ "created" : {
+ "type" : "string",
+ "format" : "date-time"
+ },
+ "consecutive_failures" : {
+ "type" : "integer",
+ "format" : "int32"
+ },
+ "active" : {
"type" : "boolean",
"default" : false
},
- "Users/user_name" : {
+ "user_name" : {
"type" : "string"
},
- "Users/admin" : {
+ "admin" : {
"type" : "boolean",
"default" : false
},
- "Users/ldap_user" : {
+ "ldap_user" : {
"type" : "boolean",
"default" : false
+ },
+ "local_user_name" : {
+ "type" : "string"
+ }
+ }
+ },
+ "UserResponseSwagger" : {
+ "type" : "object",
+ "properties" : {
+ "Users" : {
+ "$ref" : "#/definitions/UserResponse"
}
}
},
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/docs/api/v1/authentication-source-create.md
----------------------------------------------------------------------
diff --git a/ambari-server/docs/api/v1/authentication-source-create.md b/ambari-server/docs/api/v1/authentication-source-create.md
new file mode 100644
index 0000000..89f74c7
--- /dev/null
+++ b/ambari-server/docs/api/v1/authentication-source-create.md
@@ -0,0 +1,86 @@
+
+<!---
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+Create Authentication Source
+=====
+
+[Back to Authentication Source Resources](authentication-source-resources.md)
+
+**Summary**
+
+Create a new authentication source resource as a child to a user identified by <code>:user_name</code>.
+<p/><p/>
+Only users with the <code>AMBARI.MANAGE_USERS</code> privilege (currently, Ambari Administrators)
+may perform this operation.
+
+ POST /users/:user_name/sources
+
+**Response**
+
+<table>
+ <tr>
+ <th>HTTP CODE</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>500</td>
+ <td>Internal Server Error</td>
+ </tr>
+ <tr>
+ <td>403</td>
+ <td>Forbidden</td>
+ </tr>
+</table>
+
+
+**Examples*
+
+Create a LOCAL authentication source for the user with a username of "jdoe".
+
+ POST /users/jdoe/sources
+
+ {
+ "AuthenticationSourceInfo": {
+ "authentication_type": "LDAP",
+ "key": "some dn"
+ }
+ }
+
+ 201 Created
+
+
+Create multiple authentication sources for the user with a username of "jdoe".
+
+ POST /users/jdoe/sources
+
+ [
+ {
+ "AuthenticationSourceInfo": {
+ "authentication_type": "PAM",
+ "key": "pam_key"
+ }
+ },
+ {
+ "AuthenticationSourceInfo": {
+ "authentication_type": "LDAP",
+ "key": "ldap_key"
+ }
+ }
+ ]
+
+ 201 Created
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/docs/api/v1/authentication-source-delete.md
----------------------------------------------------------------------
diff --git a/ambari-server/docs/api/v1/authentication-source-delete.md b/ambari-server/docs/api/v1/authentication-source-delete.md
new file mode 100644
index 0000000..845b6f5
--- /dev/null
+++ b/ambari-server/docs/api/v1/authentication-source-delete.md
@@ -0,0 +1,49 @@
+
+<!---
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+Delete Authentication Source
+=====
+
+[Back to Authentication Source Resources](authentication-source-resources.md)
+
+**Summary**
+
+Removes an existing authentication source resource identified by <code>:source_id</code> for a user
+identified by <code>:user_name</code>.
+<p/><p/>
+Only users with the <code>AMBARI.MANAGE_USERS</code> privilege (currently, Ambari Administrators)
+may perform this operation.
+
+ DELETE /users/:user_name/source/:source_id
+
+**Response**
+
+<table>
+ <tr>
+ <th>HTTP CODE</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>500</td>
+ <td>Internal Server Error</td>
+ </tr>
+ <tr>
+ <td>403</td>
+ <td>Forbidden</td>
+ </tr>
+</table>
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/docs/api/v1/authentication-source-get.md
----------------------------------------------------------------------
diff --git a/ambari-server/docs/api/v1/authentication-source-get.md b/ambari-server/docs/api/v1/authentication-source-get.md
new file mode 100644
index 0000000..8ff5fd1
--- /dev/null
+++ b/ambari-server/docs/api/v1/authentication-source-get.md
@@ -0,0 +1,93 @@
+
+<!---
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+Get Authentication Source
+=====
+
+[Back to Authentication Source Resources](authentication-source-resources.md)
+
+**Summary**
+
+Gets the details about an existing authentication source identified by <code>:source_id</code> for
+a user identified by <code>:user_name</code>
+
+ GET /users/:user_name/sources/:source_id
+
+**Response**
+
+<table>
+ <tr>
+ <th>HTTP CODE</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>200</td>
+ <td>OK</td>
+ </tr>
+ <tr>
+ <td>400</td>
+ <td>Bad Request</td>
+ </tr>
+ <tr>
+ <td>401</td>
+ <td>Unauthorized</td>
+ </tr>
+ <tr>
+ <td>403</td>
+ <td>Forbidden</td>
+ </tr>
+ <tr>
+ <td>404</td>
+ <td>Not Found</td>
+ </tr>
+ <tr>
+ <td>500</td>
+ <td>Internal Server Error</td>
+ </tr>
+</table>
+
+**Example**
+
+Get a specific authentication source for user with the user_name of jdoe.
+
+ GET /users/jdoe/sources/1234
+
+ 200 OK
+ {
+ "href" : "http://your.ambari.server/api/v1/users/userc/sources/1234",
+ "AuthenticationSourceInfo" : {
+ "source_id" : 1234,
+ "user_name" : "jdoe"
+ }
+ }
+
+Get more details about specific authentication source for user with the user_name of jdoe.
+
+ GET /users/jdoe/sources/1234?fields=*
+
+ 200 OK
+ {
+ "href" : "http://your.ambari.server/api/v1/users/userc/sources/1234",
+ "AuthenticationSourceInfo" : {
+ "authentication_type" : "LOCAL",
+ "created" : 1498844132119,
+ "source_id" : 1234,
+ "updated" : 1498844157794,
+ "user_name" : "jdoe"
+ }
+ }
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/docs/api/v1/authentication-source-list.md
----------------------------------------------------------------------
diff --git a/ambari-server/docs/api/v1/authentication-source-list.md b/ambari-server/docs/api/v1/authentication-source-list.md
new file mode 100644
index 0000000..6a7c574
--- /dev/null
+++ b/ambari-server/docs/api/v1/authentication-source-list.md
@@ -0,0 +1,116 @@
+
+<!---
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+List Authentication Sources
+=====
+
+[Back to Authentication Source Resources](authentication-source-resources.md)
+
+**Summary**
+
+Returns a collection of the existing authentication sources for a given user, identified by
+<code>:user_name</code>.
+
+ GET /users/:user_name/sources
+
+**Response**
+
+<table>
+ <tr>
+ <th>HTTP CODE</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>200</td>
+ <td>OK</td>
+ </tr>
+ <tr>
+ <td>400</td>
+ <td>Bad Request</td>
+ </tr>
+ <tr>
+ <td>401</td>
+ <td>Unauthorized</td>
+ </tr>
+ <tr>
+ <td>403</td>
+ <td>Forbidden</td>
+ </tr>
+ <tr>
+ <td>404</td>
+ <td>Not Found</td>
+ </tr>
+ <tr>
+ <td>500</td>
+ <td>Internal Server Error</td>
+ </tr>
+</table>
+
+**Example**
+
+Get the collection of all authentication sources for user with username jdoe.
+
+ GET /users/jdoe/sources
+
+ 200 OK
+ {
+ "href" : "http://your.ambari.server/api/v1/users/jdoe/sources?fields=*",
+ "items" : [
+ {
+ "href" : "http://your.ambari.server/api/v1/users/jdoe/sources/1004",
+ "AuthenticationSourceInfo" : {
+ "authentication_type" : "LOCAL",
+ "created" : 1497472842579,
+ "source_id" : 1004,
+ "updated" : 1497472842579,
+ "user_name" : "jdoe"
+ }
+ },
+ {
+ "href" : "http://your.ambari.server/api/v1/users/jdoe/sources/3653",
+ "AuthenticationSourceInfo" : {
+ "authentication_type" : "LDAP",
+ "created" : 1499372841818,
+ "source_id" : 3653,
+ "updated" : 1499372841818,
+ "user_name" : "jdoe"
+ }
+ },
+ {
+ "href" : "http://your.ambari.server/api/v1/users/jdoe/sources/3654",
+ "AuthenticationSourceInfo" : {
+ "authentication_type" : "LDAP",
+ "created" : 1499373089670,
+ "source_id" : 3654,
+ "updated" : 1499373089670,
+ "user_name" : "jdoe"
+ }
+ },
+ {
+ "href" : "http://your.ambari.server/api/v1/users/jdoe/sources/3655",
+ "AuthenticationSourceInfo" : {
+ "authentication_type" : "PAM",
+ "created" : 1499373089677,
+ "source_id" : 3655,
+ "updated" : 1499373089677,
+ "user_name" : "jdoe"
+ }
+ }
+ ]
+ }
+
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/docs/api/v1/authentication-source-resources.md
----------------------------------------------------------------------
diff --git a/ambari-server/docs/api/v1/authentication-source-resources.md b/ambari-server/docs/api/v1/authentication-source-resources.md
new file mode 100644
index 0000000..417d2ca
--- /dev/null
+++ b/ambari-server/docs/api/v1/authentication-source-resources.md
@@ -0,0 +1,117 @@
+<!---
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# Authentication Source Resources
+Authentication Source resources represent authentication sources that a user may use to authenticate
+so they may login to Ambari. Each user account may have multiple authentication sources of various
+types (LOCAL, LDAP, JWT, KERBEROS, PAM, etc...). Each authentication source type has its own
+requirements. For example, a user may have only one LOCAL authentication source.
+<p/>
+Users with the <code>AMBARI.MANAGE_USERS</code> privilege (currently, Ambari Administrators) can
+view and update all authentication source resources. Any other user can only view and (partially)
+update their own authentication source resources. For example a user may change their own password
+by updating the relevant authentication source resource.
+
+###API Summary
+
+- [List authentication sources](authentication-source-list.md)
+- [Get authentication source](authentication-source-get.md)
+- [Create authentication source](authentication-source-create.md)
+- [Update authentication source](authentication-source-update.md)
+- [Delete authentication source](authenticationsource-delete.md)
+
+###Properties
+
+<table>
+ <tr>
+ <th>Property</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>AuthenticationSourceInfo/source_id</td>
+ <td>
+ The authentication source's unique id - this value may be used to uniquely identify an
+ authentication source.
+ <p/><p/>
+ The value is generated internally and is read-only.
+ </td>
+ </tr>
+ <tr>
+ <td>AuthenticationSourceInfo/user_name</td>
+ <td>
+ The parent resource's user name.
+ <p/><p/>
+ The value is read-only.
+ </td>
+ </tr>
+ <tr>
+ <td>AuthenticationSourceInfo/authentication_type</td>
+ <td>
+ The type of authentication source. Possible values include:
+ <ul>
+ <li>LOCAL - the user has an Ambari-local password</li>
+ <li>LDAP - the user authenticates using an LDAP server</li>
+ <li>KERBEROS - the user authenticates using a Kerberos token</li>
+ <li>PAM - the user authenticates using PAM</li>
+ <li>JWT - the user authenticates using a JWT token from Knox</li>
+ </ul>
+ <p/><p/>
+ The value must be set when creating the resource; otherwise it is read-only.
+ </td>
+ </tr>
+ <tr>
+ <td>AuthenticationSourceInfo/key</td>
+ <td>
+ The authencation type-specific key. For example, if the authentcation type is LOCAL, than
+ the authentication key is the password.
+ <p/><p/>
+ The value is settable by an Ambari administrator and potentially the parent user (depending
+ on authentication type); otherwise it not returned in queries to .
+ </td>
+ </tr>
+ <tr>
+ <td>AuthenticationSourceInfo/old_key</td>
+ <td>
+ This propery may be set when updating an authentication source resource if verification of the
+ current key is needed before being allowed to set a new one. For eample if setting a new
+ password for an authentication source of type LOCAL, this value is required when a user is
+ updating the value. It is not used when an Ambari user administrator is updating a user's
+ password. The need for this property is specific to the requirments of the authentication
+ source type.
+ <p/><p/>
+ The value is write-only.
+ </td>
+ </tr>
+ <tr>
+ <td>AuthenticationSourceInfo/created</td>
+ <td>
+ The timestamp indicating when the authentcation source resource was created.
+ <p/><p/>
+ The value is generated internally and is read-only.
+ </td>
+ </tr>
+ <tr>
+ <td>AuthenticationSourceInfo/updated</td>
+ <td>
+ The timestamp indicating when the authentcation source resource was updated.
+ <p/><p/>
+ The value is generated internally and is read-only.
+ </td>
+ </tr>
+ </tr>
+</table>
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/docs/api/v1/authentication-source-update.md
----------------------------------------------------------------------
diff --git a/ambari-server/docs/api/v1/authentication-source-update.md b/ambari-server/docs/api/v1/authentication-source-update.md
new file mode 100644
index 0000000..be2c2a9
--- /dev/null
+++ b/ambari-server/docs/api/v1/authentication-source-update.md
@@ -0,0 +1,104 @@
+
+<!---
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+Modify Authentication Source
+=====
+
+[Back to Authentication Source Resources](authentication-source-resources.md)
+
+**Summary**
+
+Update an existing authentication source identified by <code>:source_id</code> for a user identified
+by <code>:user_name</code>. If the <code>AuthenticationSourceInfo/authentication_type</code> is set
+the found authentication source resource is tested to ensure it matches the expected value.
+
+ PUT /user/:user_name/sources/:source_id
+
+**Response**
+
+<table>
+ <tr>
+ <th>HTTP CODE</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>200</td>
+ <td>OK</td>
+ </tr>
+ <tr>
+ <td>400</td>
+ <td>Bad Request</td>
+ </tr>
+ <tr>
+ <td>401</td>
+ <td>Unauthorized</td>
+ </tr>
+ <tr>
+ <td>403</td>
+ <td>Forbidden</td>
+ </tr>
+ <tr>
+ <td>404</td>
+ <td>Not Found</td>
+ </tr>
+ <tr>
+ <td>500</td>
+ <td>Internal Server Error</td>
+ </tr>
+</table>
+
+**Examples**
+
+Update an authentication source for user jdoe when authenticated as a user administrator.
+
+ PUT /users/jdoe/sources/1234
+
+ {
+ "AuthenticationSourceInfo": {
+ "key": "new_secret"
+ }
+ }
+
+ 200 OK
+
+Update an authentication source for user jdoe when authenticated as a user administrator, verifying
+that the authentication source resource is a LOCAL authentication source.
+
+ PUT /users/jdoe/sources/1234
+
+ {
+ "AuthenticationSourceInfo": {
+ "authentication_type": "LOCAL",
+ "key": "new_secret"
+ }
+ }
+
+ 200 OK
+
+Update an authentication source for user jdoe when authenticated as jdoe.
+
+ PUT /users/jdoe/sources/1234
+
+ {
+ "AuthenticationSourceInfo": {
+ "old_key": "secret",
+ "key": "new_secret"
+ }
+ }
+
+ 200 OK
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/docs/api/v1/index.md
----------------------------------------------------------------------
diff --git a/ambari-server/docs/api/v1/index.md b/ambari-server/docs/api/v1/index.md
index da05d75..d69b214 100644
--- a/ambari-server/docs/api/v1/index.md
+++ b/ambari-server/docs/api/v1/index.md
@@ -372,6 +372,18 @@ Permission resources are used to help determine authorization rights for a user.
[Permission Resources](permission-resources.md)
+#### users
+User resources represent users that may use Ambari. A user is given permissions to perform tasks within Ambari.
+
+[User Resources](user-resources.md)
+
+#### authentication sources
+Authentication source resources are child resources of [user resources](#users). Each source represent an authentication
+source that a user may use to login into Ambari. There are different types of authentication sources
+such as (but not limited to) local, LDAP, JWT, and Kerberos.
+
+[Authentication Source Resources](authentication-source-resources.md)
+
Partial Response
----
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/docs/api/v1/user-create.md
----------------------------------------------------------------------
diff --git a/ambari-server/docs/api/v1/user-create.md b/ambari-server/docs/api/v1/user-create.md
new file mode 100644
index 0000000..47524de
--- /dev/null
+++ b/ambari-server/docs/api/v1/user-create.md
@@ -0,0 +1,107 @@
+
+<!---
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+Create User
+=====
+
+[Back to User Resources](user-resources.md)
+
+**Summary**
+
+Create a new user resource identified by <code>:user_name</code>.
+<p/><p/>
+Only users with the <code>AMBARI.MANAGE_USERS</code> privilege (currently, Ambari Administrators)
+may perform this operation.
+
+ POST /users/:user_name
+
+**Response**
+
+<table>
+ <tr>
+ <th>HTTP CODE</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>500</td>
+ <td>Internal Server Error</td>
+ </tr>
+ <tr>
+ <td>403</td>
+ <td>The authenticated user does not have authorization to create/store user persisted data.</td>
+ </tr>
+</table>
+
+
+**Examples*
+
+Create a user with a username of "jdoe".
+
+ POST /users/jdoe
+
+ {
+ "Users": {
+ "local_user_name": "jdoe",
+ "display_name": "Jane Doe",
+ "admin" : false
+ }
+ }
+
+ 201 Created
+
+
+Create multiple users.
+
+ POST /users
+
+ [
+ {
+ "Users": {
+ "user_name": "UserA",
+ "admin": "true"
+ }
+ },
+ {
+ "Users": {
+ "user_name": "userb",
+ "active": "false"
+ }
+ },
+ {
+ "Users": {
+ "user_name": "userc",
+ "local_user_name": "UserC"
+ }
+ },
+ {
+ "Users": {
+ "user_name": "userd",
+ "local_user_name": "userD",
+ "display_name": "User D"
+ }
+ },
+ {
+ "Users": {
+ "user_name": "usere",
+ "password": "hadoop"
+ }
+ }
+ ]
+
+ 201 Created
+
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/docs/api/v1/user-delete.md
----------------------------------------------------------------------
diff --git a/ambari-server/docs/api/v1/user-delete.md b/ambari-server/docs/api/v1/user-delete.md
new file mode 100644
index 0000000..a8a5375
--- /dev/null
+++ b/ambari-server/docs/api/v1/user-delete.md
@@ -0,0 +1,48 @@
+
+<!---
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+Delete User
+=====
+
+[Back to User Resources](user-resources.md)
+
+**Summary**
+
+Removes an existing user resource identified by <code>:user_name</code>.
+<p/><p/>
+Only users with the <code>AMBARI.MANAGE_USERS</code> privilege (currently, Ambari Administrators)
+may perform this operation.
+
+ DELETE /users/:user_name
+
+**Response**
+
+<table>
+ <tr>
+ <th>HTTP CODE</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>500</td>
+ <td>Internal Server Error</td>
+ </tr>
+ <tr>
+ <td>403</td>
+ <td>The authenticated user does not have the appropriate authorizations to delete the requested resource(s)</td>
+ </tr>
+</table>
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/docs/api/v1/user-get.md
----------------------------------------------------------------------
diff --git a/ambari-server/docs/api/v1/user-get.md b/ambari-server/docs/api/v1/user-get.md
new file mode 100644
index 0000000..9e8db95
--- /dev/null
+++ b/ambari-server/docs/api/v1/user-get.md
@@ -0,0 +1,97 @@
+
+<!---
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+Get a User
+=====
+
+[Back to User Resources](user-resources.md)
+
+**Summary**
+
+Gets the details about an existing user identified by <code>:user_name</code>
+
+ GET /users/:user_name
+
+**Response**
+
+<table>
+ <tr>
+ <th>HTTP CODE</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>200</td>
+ <td>OK</td>
+ </tr>
+ <tr>
+ <td>400</td>
+ <td>Bad Request</td>
+ </tr>
+ <tr>
+ <td>401</td>
+ <td>Unauthorized</td>
+ </tr>
+ <tr>
+ <td>403</td>
+ <td>The authenticated user is not authorized to perform the requested operation</td>
+ </tr>
+ <tr>
+ <td>404</td>
+ <td>Not Found</td>
+ </tr>
+ <tr>
+ <td>500</td>
+ <td>Internal Server Error</td>
+ </tr>
+</table>
+
+**Example**
+
+Get the user with the user_name of jdoe.
+
+ GET /users/jdoe
+
+ 200 OK
+ {
+ "href" : "http://your.ambari.server/api/v1/users/jdoe",
+ "Users" : {
+ "user_id" : 100,
+ "user_name" : "jdoe",
+ "local_user_name" : "jdoe",
+ "display_name" : "Jane Doe",
+ "admin" : false,
+ "active" : true,
+ "consecutive_failures" : 0,
+ "created" : 1497472842569,
+ "groups" : [ ],
+ "ldap_user" : false,
+ "user_type" : "LOCAL"
+ }
+ "widget_layouts" : [ ],
+ "privileges" : [ ],
+ "sources" : [
+ {
+ "href" : "http://your.ambari.server/api/v1/users/jdoe/sources/1004",
+ "AuthenticationSourceInfo" : {
+ "source_id" : 1004,
+ "user_name" : "jdoe"
+ }
+ }
+ ]
+ }
+
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/docs/api/v1/user-list.md
----------------------------------------------------------------------
diff --git a/ambari-server/docs/api/v1/user-list.md b/ambari-server/docs/api/v1/user-list.md
new file mode 100644
index 0000000..ee1abbb
--- /dev/null
+++ b/ambari-server/docs/api/v1/user-list.md
@@ -0,0 +1,98 @@
+
+<!---
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+List Users
+=====
+
+[Back to User Resources](user-resources.md)
+
+**Summary**
+
+Returns a collection of the existing Users.
+
+ GET /users
+
+**Response**
+
+<table>
+ <tr>
+ <th>HTTP CODE</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>200</td>
+ <td>OK</td>
+ </tr>
+ <tr>
+ <td>400</td>
+ <td>Bad Request</td>
+ </tr>
+ <tr>
+ <td>401</td>
+ <td>Unauthorized</td>
+ </tr>
+ <tr>
+ <td>403</td>
+ <td>Forbidden</td>
+ </tr>
+ <tr>
+ <td>404</td>
+ <td>Not Found</td>
+ </tr>
+ <tr>
+ <td>500</td>
+ <td>Internal Server Error</td>
+ </tr>
+</table>
+
+**Example**
+
+Get the collection of all currently stored users.
+
+ GET /users
+
+ 200 OK
+ {
+ "href" : "http://your.ambari.server/api/v1/users",
+ "items" : [
+ {
+ "href" : "http://your.ambari.server/api/v1/users/admin",
+ "Users" : {
+ "user_name" : "admin"
+ }
+ },
+ {
+ "href" : "http://your.ambari.server/api/v1/users/jdoe",
+ "Users" : {
+ "user_name" : "jdoe"
+ }
+ },
+ {
+ "href" : "http://your.ambari.server/api/v1/users/jsmith",
+ "Users" : {
+ "user_name" : "jsmith"
+ }
+ },
+ {
+ "href" : "http://your.ambari.server/api/v1/users/jqpublic",
+ "Users" : {
+ "user_nane" : "jqpublic"
+ }
+ }
+ ]
+ }
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/docs/api/v1/user-resources.md
----------------------------------------------------------------------
diff --git a/ambari-server/docs/api/v1/user-resources.md b/ambari-server/docs/api/v1/user-resources.md
new file mode 100644
index 0000000..45a17d7
--- /dev/null
+++ b/ambari-server/docs/api/v1/user-resources.md
@@ -0,0 +1,175 @@
+<!---
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# User Resources
+User resources represent user accounts in Ambari. Each user account has a set of authentication
+sources and is is given permission to perform tasks within Ambari.
+<p/>
+Users with the <code>AMBARI.MANAGE_USERS</code> privilege (currently, Ambari Administrators) can
+view and update all user resources. Any other user can only view and (partially) update their own
+user resource.
+
+###API Summary
+
+- [List users](user-list.md)
+- [Get user](user-get.md)
+- [Create user](user-create.md)
+- [Update user](user-update.md)
+- [Delete user](user-delete.md)
+
+###Properties
+
+<table>
+ <tr>
+ <th>Property</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>Users/user_id</td>
+ <td>
+ The user's unique id - this value may be used to uniquely identify a user.
+ <p/><p/>
+ The value is generated internally and is read-only.
+ </td>
+ </tr>
+ <tr>
+ <td>Users/user_name</td>
+ <td>
+ The user's unique name - this value is case-insensitive and may be used to uniquely
+ identify a user.
+ <p/><p/>
+ The value must be set when creating the resource; otherwise it is read-only.
+ </td>
+ </tr>
+ <tr>
+ <td>Users/local_user_name</td>
+ <td>
+ The user's local user name - this value is case-sensitive and used as the username to use
+ when accessing service via Ambari Views. If not set, the username value will be used.
+ <p/><p/>
+ The value is settable by an Ambari administrator; otherwise it is read-only.
+ </td>
+ </tr>
+ <tr>
+ <td>Users/display_name</td>
+ <td>
+ The user's local user name - this value is used for display purposes in messages and user
+ intefaces. If not set, the username value will be used.
+ <p/><p/>
+ The value is settable by the user or an Ambari administrator.
+ </td>
+ </tr>
+ <tr>
+ <td>Users/active</td>
+ <td>
+ The user's active/inactive status - <code>true</code> if active; <code>false</code> if
+ inactive.
+ <p/><p/>
+ The value is settable by an Ambari administrator; otherwise it is read-only.
+ </td>
+ </tr>
+ <tr>
+ <td>Users/consecutive_failures</td>
+ <td>
+ The number of consecutive authentication failures since the last successful authentication
+ attempt.
+ <p/><p/>
+ The value is read-only.
+ </td>
+ </tr>
+ <tr>
+ <td>Users/created</td>
+ <td>
+ The timestamp indicating when the user resource was created.
+ <p/><p/>
+ The value is generated internally and is read-only.
+ </td>
+ </tr>
+ <tr>
+ <td>Users/groups</td>
+ <td>
+ The set of groups for which the user is a member.
+ <p/><p/>
+ The value is read-only.
+ </td>
+ </tr>
+ <tr>
+ <td>Users/admin</td>
+ <td>
+ Indicates wheather the user has administrative privilieges (<code>true</code>) or not
+ (<code>false</code>). This propery is deprecated and is provided to maintain the REST API V1
+ contract. This information may be found by querying for the user's permissions (or roles).
+ <p/><p/>
+ The value is settable by an Ambari administrator; otherwise it is read-only.
+ </td>
+ </tr>
+ <tr>
+ <td>Users/ldap_user</td>
+ <td>
+ Indicates wheather the user was imported from an LDAP server. This propery is deprecated
+ and is provided to maintain the REST API V1 contract. This information may be found by querying
+ for the user's authentication sources.
+ <p/><p/>
+ The value is read-only.
+ </td>
+ </tr>
+ <tr>
+ <td>Users/user_type</td>
+ <td>
+ The type of user account. Possible values include:
+ <ul>
+ <li>LOCAL - the user has an Ambari-local password</li>
+ <li>LDAP - the user authenticates using an LDAP server</li>
+ <li>KERBEROS - the user authenticates using a Kerberos token</li>
+ <li>PAM - the user authenticates using PAM</li>
+ <li>JWT - the user authenticates using a JWT token from Knox</li>
+ </ul>
+ This propery is deprecated and is provided to maintain the REST API V1 contract. This
+ information may be found by querying for the user's authentication sources.
+ <p/><p/>
+ Since this value contains a single entry, it does not properly indicate what authentication
+ sources a user may use. However, if the set of authentication sources contains an LDAP source,
+ this value will be set to LDAP.
+ <p/><p/>
+ The value is read-only.
+ </td>
+ </tr>
+ <tr>
+ <td>Users/password</td>
+ <td>
+ This propery is deprecated and is provided to maintain the REST API V1 contract.
+ This propery may be set when creating or updating a user resource to set it's (Ambari) local
+ password. However, it is expected that a LOCAL authentication source resource is created and
+ updated instead.
+ <p/><p/>
+ The value is write-only.
+ </td>
+ </tr>
+ <tr>
+ <td>Users/old_password</td>
+ <td>
+ This propery is deprecated and is provided to maintain the REST API V1 contract.
+ This propery may be set when updating a user resource to set a new password for a (Ambari) local
+ password. This value is required when a user is updating their own password. It is not used
+ when an Ambari administrator is updating a user's password. However, it is expected that a
+ LOCAL authentication source resource is updated instead.
+ <p/><p/>
+ The value is write-only.
+ </td>
+ </tr>
+</table>
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/docs/api/v1/user-update.md
----------------------------------------------------------------------
diff --git a/ambari-server/docs/api/v1/user-update.md b/ambari-server/docs/api/v1/user-update.md
new file mode 100644
index 0000000..e93388f
--- /dev/null
+++ b/ambari-server/docs/api/v1/user-update.md
@@ -0,0 +1,115 @@
+
+<!---
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+Update a User
+=====
+
+[Back to User Resources](user-resources.md)
+
+**Summary**
+
+Update an existing user resource identified by <code>:user_name</code>
+
+ PUT /user/:user_name
+
+**Response**
+
+<table>
+ <tr>
+ <th>HTTP CODE</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>200</td>
+ <td>OK</td>
+ </tr>
+ <tr>
+ <td>400</td>
+ <td>Bad Request</td>
+ </tr>
+ <tr>
+ <td>401</td>
+ <td>Unauthorized</td>
+ </tr>
+ <tr>
+ <td>403</td>
+ <td>The authenticated user does not have authorization to create/store user persisted data.</td>
+ </tr>
+ <tr>
+ <td>404</td>
+ <td>Not Found</td>
+ </tr>
+ <tr>
+ <td>500</td>
+ <td>Internal Server Error</td>
+ </tr>
+</table>
+
+**Examples**
+
+Update a user.
+
+ PUT /users/jdoe
+
+ {
+ "User" : {
+ "display_name" : "Jane Q. Doe"
+ }
+ }
+
+ 200 OK
+
+Set (create/update) a user's password as a user administrator. Deprecated, see
+[Source Resources](authentication-source-resources.md).
+
+ POST /users/jdoe
+
+ {
+ "User" : {
+ "password" : "secret"
+ }
+ }
+
+ 200 OK
+
+Change a user's existing password as the (non-administrative) user. Deprecated, see
+[Source Resources](authentication-source-resources.md).
+
+ POST /users/jdoe
+
+ {
+ "User" : {
+ "password" : "secret",
+ "old_password" : "old_secret"
+ }
+ }
+
+ 200 OK
+
+Set a user to be an Ambari Administrator, as a user administrator. Deprecated, see
+[Permission Resources](permission-resources.md).
+
+ POST /users/jdoe
+
+ {
+ "User" : {
+ "admin" : true
+ }
+ }
+
+ 200 OK
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
index 96e288f..ababe00 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
@@ -141,6 +141,10 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
resourceDefinition = new UserResourceDefinition();
break;
+ case UserAuthenticationSource:
+ resourceDefinition = new SimpleResourceDefinition(Resource.Type.UserAuthenticationSource, "source", "sources");
+ break;
+
case Group:
resourceDefinition = new GroupResourceDefinition();
break;
http://git-wip-us.apache.org/repos/asf/ambari/blob/317905e4/ambari-server/src/main/java/org/apache/ambari/server/api/resources/UserResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/UserResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/UserResourceDefinition.java
index b228c82..c62ca71 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/UserResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/UserResourceDefinition.java
@@ -44,6 +44,7 @@ public class UserResourceDefinition extends BaseResourceDefinition {
@Override
public Set<SubResourceDefinition> getSubResourceDefinitions() {
final Set<SubResourceDefinition> subResourceDefinitions = new HashSet<>();
+ subResourceDefinitions.add(new SubResourceDefinition(Resource.Type.UserAuthenticationSource));
subResourceDefinitions.add(new SubResourceDefinition(Resource.Type.UserPrivilege));
subResourceDefinitions.add(new SubResourceDefinition(Resource.Type.ActiveWidgetLayout));
return subResourceDefinitions;