ambari-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stoa...@apache.org
Subject ambari git commit: AMBARI-20482. Accessing a user after sync with AD is failing with 500. (Balazs Bence Sari via stoader)
Date Fri, 17 Mar 2017 15:47:03 GMT
Repository: ambari
Updated Branches:
  refs/heads/branch-2.5 bb2697359 -> 50da75949


AMBARI-20482. Accessing a user after sync with AD is failing with 500. (Balazs Bence Sari
via stoader)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/50da7594
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/50da7594
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/50da7594

Branch: refs/heads/branch-2.5
Commit: 50da759491e9224a7a7511f864867503388801ea
Parents: bb26973
Author: Balazs Bence Sari <bsari@hortonworks.com>
Authored: Fri Mar 17 16:46:38 2017 +0100
Committer: Toader, Sebastian <stoader@hortonworks.com>
Committed: Fri Mar 17 16:46:38 2017 +0100

----------------------------------------------------------------------
 .../ActiveWidgetLayoutResourceProvider.java     |   2 +-
 .../apache/ambari/server/orm/dao/UserDAO.java   |  38 ++++++
 .../server/security/authorization/Users.java    |  23 ++--
 .../ActiveWidgetLayoutResourceProviderTest.java |   2 +-
 .../ambari/server/orm/dao/UserDAOTest.java      | 116 ++++++++++++++++---
 .../security/authorization/TestUsers.java       |   8 +-
 .../security/authorization/UsersTest.java       |  94 +++++++++++----
 7 files changed, 227 insertions(+), 56 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/50da7594/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ActiveWidgetLayoutResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ActiveWidgetLayoutResourceProvider.java
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ActiveWidgetLayoutResourceProvider.java
index d149a70..bd45816 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ActiveWidgetLayoutResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ActiveWidgetLayoutResourceProvider.java
@@ -158,7 +158,7 @@ public class ActiveWidgetLayoutResourceProvider extends AbstractControllerResour
       }
 
       java.lang.reflect.Type type = new TypeToken<Set<Map<String, String>>>(){}.getType();
-        Set<Map<String, String>> activeWidgetLayouts = gson.fromJson(userDAO.findUserByName(userName).getActiveWidgetLayouts(),
type);
+        Set<Map<String, String>> activeWidgetLayouts = gson.fromJson(userDAO.findSingleUserByName(userName).getActiveWidgetLayouts(),
type);
         if (activeWidgetLayouts != null) {
           for (Map<String, String> widgetLayoutId : activeWidgetLayouts) {
             layoutEntities.add(widgetLayoutDAO.findById(Long.parseLong(widgetLayoutId.get(ID))));

http://git-wip-us.apache.org/repos/asf/ambari/blob/50da7594/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UserDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UserDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UserDAO.java
index d3c2d89..3329dcc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UserDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/UserDAO.java
@@ -23,6 +23,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import javax.annotation.Nullable;
 import javax.persistence.EntityManager;
 import javax.persistence.NoResultException;
 import javax.persistence.TypedQuery;
@@ -31,6 +32,7 @@ import org.apache.ambari.server.orm.RequiresSession;
 import org.apache.ambari.server.orm.entities.PrincipalEntity;
 import org.apache.ambari.server.orm.entities.UserEntity;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
@@ -74,6 +76,42 @@ public class UserDAO {
     }
   }
 
+  /**
+   * <p>Finds user by name. If duplicate users exists (with different type), the returned
one will be chosen by this user
+   * type precedence: LOCAL -> LDAP -> JWT -> PAM</p>
+   * <p>In Ambari 3.0, user management will be rethought hence the deprecation</p>
+   * @param userName the user name
+   * @return The corresponding user or {@code null} if none is found. If multiple users exist
with different types, user
+   *   type precedence (see above) will decide.
+   */
+   @RequiresSession
+   @Deprecated
+   @Nullable
+   public UserEntity findSingleUserByName(String userName) {
+     TypedQuery<UserEntity> query = entityManagerProvider.get().createNamedQuery("userByName",
UserEntity.class);
+     query.setParameter("username", userName.toLowerCase());
+     List<UserEntity> resultList = query.getResultList();
+     switch (resultList.size()) {
+       case 0:
+         return null;
+       case 1:
+         return resultList.get(0);
+       default:
+         ImmutableMap.Builder<UserType, UserEntity> mapBuilder = ImmutableMap.<UserType,
UserEntity>builder();
+         for (UserEntity user: resultList) {
+           mapBuilder.put(user.getUserType(), user);
+         }
+         ImmutableMap<UserType, UserEntity> usersByType = mapBuilder.build();
+         UserEntity user =
+             usersByType.containsKey(UserType.LOCAL) ? usersByType.get(UserType.LOCAL) :
+                 usersByType.containsKey(UserType.LOCAL.LDAP) ? usersByType.get(UserType.LDAP)
:
+                     usersByType.containsKey(UserType.JWT) ? usersByType.get(UserType.JWT)
:
+                         usersByType.get(UserType.PAM);
+         return user;
+     }
+   }
+
+
   @RequiresSession
   public UserEntity findUserByNameAndType(String userName, UserType userType) {
     TypedQuery<UserEntity> query = entityManagerProvider.get().createQuery("SELECT
user FROM UserEntity user WHERE " +

http://git-wip-us.apache.org/repos/asf/ambari/blob/50da7594/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 4b3237b..78ab64a 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
@@ -120,22 +120,11 @@ public class Users {
   /**
    * This method works incorrectly, userName is not unique if users have different types
    *
-   * @return One user. Priority is LOCAL -> LDAP -> JWT
+   * @return One user. Priority is LOCAL -> LDAP -> JWT -> PAM
    */
   @Deprecated
   public User getAnyUser(String userName) {
-    UserEntity userEntity = userDAO.findUserByNameAndType(userName, UserType.LOCAL);
-    if (userEntity == null) {
-      userEntity = userDAO.findUserByNameAndType(userName, UserType.LDAP);
-    }
-    if (userEntity == null) {
-      userEntity = userDAO.findUserByNameAndType(userName, UserType.JWT);
-    }
-
-    if (userEntity == null) {
-        userEntity = userDAO.findUserByNameAndType(userName, UserType.PAM);
-    }
-
+    UserEntity userEntity = userDAO.findSingleUserByName(userName);
     return (null == userEntity) ? null : new User(userEntity);
   }
 
@@ -153,9 +142,12 @@ public class Users {
    * Retrieves User then userName is unique in users DB. Will return null if there no user
with provided userName or
    * there are some users with provided userName but with different types.
    *
+   * <p>User names in the future will likely be unique hence the deprecation.</p>
+   *
    * @param userName
    * @return User if userName is unique in DB, null otherwise
    */
+  @Deprecated
   public User getUserIfUnique(String userName) {
     List<UserEntity> userEntities = new ArrayList<>();
     UserEntity userEntity = userDAO.findUserByNameAndType(userName, UserType.LOCAL);
@@ -311,9 +303,10 @@ public class Users {
       throw new AmbariException("UserType not specified.");
     }
 
-    User existingUser = getUser(userName, userType);
+    User existingUser = getAnyUser(userName);
     if (existingUser != null) {
-      throw new AmbariException("User " + existingUser.getUserName() + " already exists");
+      throw new AmbariException("User " + existingUser.getUserName() + " already exists with
type "
+          + existingUser.getUserType());
     }
 
     PrincipalTypeEntity principalTypeEntity = principalTypeDAO.findById(PrincipalTypeEntity.USER_PRINCIPAL_TYPE);

http://git-wip-us.apache.org/repos/asf/ambari/blob/50da7594/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ActiveWidgetLayoutResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ActiveWidgetLayoutResourceProviderTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ActiveWidgetLayoutResourceProviderTest.java
index e18b3b1..601981a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ActiveWidgetLayoutResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ActiveWidgetLayoutResourceProviderTest.java
@@ -171,7 +171,7 @@ public class ActiveWidgetLayoutResourceProviderTest extends EasyMockSupport
{
     UserEntity userEntity = createMockUserEntity(requestedUsername);
 
     UserDAO userDAO = injector.getInstance(UserDAO.class);
-    expect(userDAO.findUserByName(requestedUsername)).andReturn(userEntity).atLeastOnce();
+    expect(userDAO.findSingleUserByName(requestedUsername)).andReturn(userEntity).atLeastOnce();
 
     WidgetLayoutDAO widgetLayoutDAO = injector.getInstance(WidgetLayoutDAO.class);
     expect(widgetLayoutDAO.findById(1L)).andReturn(createMockWidgetLayout(1L, requestedUsername)).atLeastOnce();

http://git-wip-us.apache.org/repos/asf/ambari/blob/50da7594/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/UserDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/UserDAOTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/UserDAOTest.java
index b46f816..0503b94 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/UserDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/UserDAOTest.java
@@ -18,31 +18,121 @@
 
 package org.apache.ambari.server.orm.dao;
 
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import org.junit.Before;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyString;
 import static org.easymock.EasyMock.createStrictMock;
+import static org.easymock.EasyMock.createNiceMock;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.reset;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.Arrays;
+
 import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+
+import org.apache.ambari.server.orm.DBAccessor;
+import org.apache.ambari.server.orm.entities.UserEntity;
+import org.apache.ambari.server.security.authorization.UserType;
+import org.junit.Test;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Provider;
+
+
 
 /**
  * UserDAO unit tests.
  */
 public class UserDAOTest {
 
-  @Inject
-  DaoUtils daoUtils;
+  private static String SERVICEOP_USER_NAME = "serviceopuser";
+  private UserDAO userDAO;
+
+  public void init(UserEntity... usersInDB) {
+    final EntityManager entityManager = createStrictMock(EntityManager.class);
+    final DaoUtils daoUtils = createNiceMock(DaoUtils.class);
+    final DBAccessor dbAccessor = createNiceMock(DBAccessor.class);
+    final Injector mockInjector = Guice.createInjector(new AbstractModule() {
+      @Override
+      protected void configure() {
+        bind(EntityManagerProvider.class);
+        bind(EntityManager.class).toInstance(entityManager);
+        bind(DBAccessor.class).toInstance(dbAccessor);
+        bind(DaoUtils.class).toInstance(daoUtils);
+      }
+    });
+    userDAO = mockInjector.getInstance(UserDAO.class);
+
+    TypedQuery<UserEntity> userQuery = createNiceMock(TypedQuery.class);
+    expect(userQuery.getResultList()).andReturn(Arrays.asList(usersInDB));
+    expect(entityManager.createNamedQuery(anyString(), anyObject(Class.class))).andReturn(userQuery);
+    replay(entityManager, daoUtils, dbAccessor, userQuery);
+  }
+
+  @Test
+  public void testFindSingleUserByName_NoUsers() {
+    init();
+    assertNull(userDAO.findSingleUserByName(SERVICEOP_USER_NAME));
+  }
+
+  @Test
+  public void testFindSingleUserByName_SingleUser() {
+    init(user(UserType.PAM));
+    assertEquals(UserType.PAM, userDAO.findSingleUserByName(SERVICEOP_USER_NAME).getUserType());
+  }
+
+  @Test
+  public void testFindSingleUserByName_LocalIsFirstPrecedence() {
+    init(user(UserType.LOCAL),
+        user(UserType.LDAP),
+        user(UserType.JWT),
+        user(UserType.PAM));
+    assertEquals(UserType.LOCAL, userDAO.findSingleUserByName(SERVICEOP_USER_NAME).getUserType());
+  }
+
+  @Test
+  public void testFindSingleUserByName_LdapIsSecondPrecedence() {
+    init(user(UserType.LDAP),
+        user(UserType.JWT),
+        user(UserType.PAM));
+    assertEquals(UserType.LDAP, userDAO.findSingleUserByName(SERVICEOP_USER_NAME).getUserType());
+  }
+
+  @Test
+  public void testFindSingleUserByName_JwtIsThirdPrecedence() {
+    init(user(UserType.JWT),
+        user(UserType.PAM));
+    assertEquals(UserType.JWT, userDAO.findSingleUserByName(SERVICEOP_USER_NAME).getUserType());
+  }
+
+  private static final UserEntity user(UserType type) {
+    return user(SERVICEOP_USER_NAME, type);
+  }
+
+  private static final UserEntity user(String name, UserType type) {
+    UserEntity userEntity = new UserEntity();
+    userEntity.setUserName(name);
+    userEntity.setUserType(type);
+    return userEntity;
+  }
+
+  static class EntityManagerProvider implements Provider<EntityManager> {
+    private final EntityManager entityManager;
 
-  Provider<EntityManager> entityManagerProvider = createStrictMock(Provider.class);
-  EntityManager entityManager = createStrictMock(EntityManager.class);
+    @Inject
+    public EntityManagerProvider(EntityManager entityManager) {
+      this.entityManager = entityManager;
+    }
 
-  @Before
-  public void init() {
-    reset(entityManagerProvider);
-    expect(entityManagerProvider.get()).andReturn(entityManager).atLeastOnce();
-    replay(entityManagerProvider);
+    @Override
+    public EntityManager get() {
+      return entityManager;
+    }
   }
 
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/50da7594/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 875fd46..364664d 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
@@ -240,17 +240,13 @@ public class TestUsers {
     // get user if unique
     Assert.assertNotNull(users.getUserIfUnique("user"));
 
-    users.createUser("user", "user", UserType.LDAP, true, false);
-
-    Assert.assertNull(users.getUserIfUnique("user"));
-
     //remove user
-    Assert.assertEquals(4, users.getAllUsers().size());
+    Assert.assertEquals(3, users.getAllUsers().size());
 
     users.removeUser(users.getAnyUser("user1"));
 
     Assert.assertNull(users.getAnyUser("user1"));
-    Assert.assertEquals(3, users.getAllUsers().size());
+    Assert.assertEquals(2, users.getAllUsers().size());
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/ambari/blob/50da7594/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/UsersTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/UsersTest.java
b/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/UsersTest.java
index 6ba384c..7b79e00 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/UsersTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/UsersTest.java
@@ -18,17 +18,28 @@
 
 package org.apache.ambari.server.security.authorization;
 
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyString;
+import static org.easymock.EasyMock.capture;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.newCapture;
 
-import junit.framework.Assert;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import javax.annotation.Nullable;
+import javax.persistence.EntityManager;
 
+import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.hooks.HookContextFactory;
 import org.apache.ambari.server.hooks.HookService;
-import org.apache.ambari.server.hooks.users.UserHookService;
 import org.apache.ambari.server.orm.DBAccessor;
 import org.apache.ambari.server.orm.dao.MemberDAO;
+import org.apache.ambari.server.orm.dao.PrincipalDAO;
 import org.apache.ambari.server.orm.dao.PrivilegeDAO;
 import org.apache.ambari.server.orm.dao.UserDAO;
 import org.apache.ambari.server.orm.entities.GroupEntity;
@@ -39,28 +50,25 @@ import org.apache.ambari.server.orm.entities.PrivilegeEntity;
 import org.apache.ambari.server.orm.entities.UserEntity;
 import org.apache.ambari.server.state.stack.OsFamily;
 import org.easymock.Capture;
-import org.easymock.CaptureType;
+import org.easymock.EasyMock;
 import org.easymock.EasyMockSupport;
+import org.junit.Assert;
 import org.junit.Test;
 import org.springframework.security.crypto.password.PasswordEncoder;
 
-import javax.persistence.EntityManager;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
 
-import static org.easymock.EasyMock.capture;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.newCapture;
 
 public class UsersTest extends EasyMockSupport {
 
+  public static final String SERVICEOP_USER_NAME = "serviceopuser";
+  private Injector injector;
 
   @Test
   public void testGetUserAuthorities() throws Exception {
-    Injector injector = getInjector();
+    createInjector();
 
     PrincipalEntity userPrincipalEntity = createMock(PrincipalEntity.class);
 
@@ -136,19 +144,65 @@ public class UsersTest extends EasyMockSupport {
     Assert.assertTrue(authorities.contains(new AmbariGrantedAuthority(clusterUserViewUserPrivilegeEntity)));
   }
 
-  private Injector getInjector() {
-    return Guice.createInjector(new AbstractModule() {
+  /**
+   * User creation should complete without exception in case of unique user name
+   */
+  @Test
+  public void testCreateUser_NoDuplicates() throws Exception {
+    initForCreateUser(null);
+    Users users = injector.getInstance(Users.class);
+    users.createUser(SERVICEOP_USER_NAME, "qwert");
+  }
+
+  /**
+   * User creation should throw {@link AmbariException} in case another user exists with
the same name but
+   * different user type.
+   */
+  @Test(expected = AmbariException.class)
+  public void testCreateUser_Duplicate() throws Exception {
+    UserEntity existing = new UserEntity();
+    existing.setUserName(SERVICEOP_USER_NAME);
+    existing.setUserType(UserType.LDAP);
+    existing.setUserId(1);
+    existing.setMemberEntities(Collections.<MemberEntity>emptySet());
+    PrincipalEntity principal = new PrincipalEntity();
+    principal.setPrivileges(Collections.<PrivilegeEntity>emptySet());
+    existing.setPrincipal(principal);
+    initForCreateUser(existing);
+
+    Users users = injector.getInstance(Users.class);
+    users.createUser(SERVICEOP_USER_NAME, "qwert");
+  }
+
+  private void initForCreateUser(@Nullable UserEntity existingUser) {
+    UserDAO userDao = createStrictMock(UserDAO.class);
+    expect(userDao.findSingleUserByName(anyString())).andReturn(existingUser);
+    userDao.create(anyObject(UserEntity.class));
+    expectLastCall();
+    EntityManager entityManager = createNiceMock(EntityManager.class);
+    expect(entityManager.find(eq(PrincipalEntity.class), EasyMock.anyObject())).andReturn(null);
+    replayAll();
+    createInjector(userDao, entityManager);
+  }
+
+  private void createInjector() {
+    createInjector(createMock(UserDAO.class), createMock(EntityManager.class));
+  }
+
+  private void createInjector(final UserDAO mockUserDao, final EntityManager mockEntityManager)
{
+    injector = Guice.createInjector(new AbstractModule() {
       @Override
       protected void configure() {
-        bind(EntityManager.class).toInstance(createMock(EntityManager.class));
+        bind(EntityManager.class).toInstance(mockEntityManager);
         bind(DBAccessor.class).toInstance(createMock(DBAccessor.class));
         bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
-        bind(UserDAO.class).toInstance(createMock(UserDAO.class));
+        bind(UserDAO.class).toInstance(mockUserDao);
         bind(MemberDAO.class).toInstance(createMock(MemberDAO.class));
         bind(PrivilegeDAO.class).toInstance(createMock(PrivilegeDAO.class));
         bind(PasswordEncoder.class).toInstance(createMock(PasswordEncoder.class));
         bind(HookService.class).toInstance(createMock(HookService.class));
         bind(HookContextFactory.class).toInstance(createMock(HookContextFactory.class));
+        bind(PrincipalDAO.class).toInstance(createMock(PrincipalDAO.class));
       }
     });
   }


Mime
View raw message