You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by dm...@apache.org on 2014/02/14 19:27:04 UTC

git commit: AMBARI-4653. Prevent deleting all users (Dmytro Shkvyra via dlysnichenko)

Updated Branches:
  refs/heads/trunk bad3a8a28 -> 5d69aaaf2


AMBARI-4653. Prevent deleting all users (Dmytro Shkvyra via dlysnichenko)


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

Branch: refs/heads/trunk
Commit: 5d69aaaf2954a501abd4f2e1f7e2fe473c2d0a6f
Parents: bad3a8a
Author: Lisnichenko Dmitro <dl...@hortonworks.com>
Authored: Fri Feb 14 20:25:32 2014 +0200
Committer: Lisnichenko Dmitro <dl...@hortonworks.com>
Committed: Fri Feb 14 20:26:30 2014 +0200

----------------------------------------------------------------------
 .../apache/ambari/server/orm/dao/UserDAO.java   |  8 ++
 .../server/security/authorization/Users.java    | 20 ++++-
 .../ambari/server/orm/dao/UserDAOTest.java      | 86 ++++++++++++++++++++
 .../security/authorization/TestUsers.java       | 25 +++++-
 4 files changed, 136 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/5d69aaaf/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 89c9cd8..8ea1877 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
@@ -27,6 +27,7 @@ import javax.persistence.EntityManager;
 import javax.persistence.NoResultException;
 import javax.persistence.TypedQuery;
 import java.util.List;
+import org.apache.ambari.server.orm.entities.RoleEntity;
 
 @Singleton
 public class UserDAO {
@@ -48,6 +49,13 @@ public class UserDAO {
   }
 
   @Transactional
+  public List<UserEntity> findAllLocalUsersByRole(RoleEntity roleEntity) {
+    TypedQuery<UserEntity> query = entityManagerProvider.get().createQuery("SELECT role.userEntities FROM RoleEntity role WHERE role = :roleEntity", UserEntity.class);
+    query.setParameter("roleEntity", roleEntity);
+    return query.getResultList();
+  }
+  
+  @Transactional
   public UserEntity findLocalUserByName(String userName) {
     TypedQuery<UserEntity> query = entityManagerProvider.get().createNamedQuery("localUserByName", UserEntity.class);
     query.setParameter("username", userName.toLowerCase());

http://git-wip-us.apache.org/repos/asf/ambari/blob/5d69aaaf/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 90ee80c..b4cbdf9 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
@@ -38,6 +38,7 @@ import org.springframework.security.crypto.password.PasswordEncoder;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import com.google.inject.persist.Transactional;
+import java.util.Set;
 
 /**
  * Provides high-level access to Users and Roles in database
@@ -179,6 +180,10 @@ public class Users {
   public synchronized void removeUser(User user) throws AmbariException {
     UserEntity userEntity = userDAO.findByPK(user.getUserId());
     if (userEntity != null) {
+      if (!isUserCanBeRemoved(userEntity)){
+        throw new AmbariException("Could not remove user " + userEntity.getUserName() +
+              ". System should have at least one user with administrator role.");
+      }
       userDAO.remove(userEntity);
     } else {
       throw new AmbariException("User " + user + " doesn't exist");
@@ -258,7 +263,13 @@ public class Users {
     if (roleEntity == null) {
       throw new AmbariException("Role " + role + " doesn't exist");
     }
-
+    if (role.equals(getAdminRole())){
+      if (!isUserCanBeRemoved(userEntity)){
+        throw new AmbariException("Could not remove admin role from user " + userEntity.getUserName() +
+        ". System should have at least one user with administrator role.");
+      }
+    }
+    
     if (userEntity.getRoleEntities().contains(roleEntity)) {
       userEntity.getRoleEntities().remove(roleEntity);
       roleEntity.getUserEntities().remove(userEntity);
@@ -270,6 +281,13 @@ public class Users {
 
   }
 
+  public synchronized boolean isUserCanBeRemoved(UserEntity userEntity){
+    RoleEntity roleEntity = new RoleEntity();
+    roleEntity.setRoleName(getAdminRole());
+    Set<UserEntity> userEntitysSet = new HashSet<UserEntity>(userDAO.findAllLocalUsersByRole(roleEntity));
+    return (userEntitysSet.contains(userEntity) && userEntitysSet.size() < 2) ? false : true;
+  }  
+  
   public String getUserRole() {
     return configuration.getConfigsMap().get(Configuration.USER_ROLE_NAME_KEY);
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/5d69aaaf/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
new file mode 100644
index 0000000..a123507
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/UserDAOTest.java
@@ -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.
+ */
+
+package org.apache.ambari.server.orm.dao;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import org.junit.Before;
+import org.junit.Test;
+import static org.easymock.EasyMock.createStrictMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reset;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+import java.util.Collections;
+import java.util.List;
+import org.apache.ambari.server.orm.entities.RoleEntity;
+import org.apache.ambari.server.orm.entities.UserEntity;
+
+/**
+ * BlueprintDAO unit tests.
+ */
+public class UserDAOTest {
+
+  @Inject
+  DaoUtils daoUtils;
+
+  Provider<EntityManager> entityManagerProvider = createStrictMock(Provider.class);
+  EntityManager entityManager = createStrictMock(EntityManager.class);
+
+  @Before
+  public void init() {
+    reset(entityManagerProvider);
+    expect(entityManagerProvider.get()).andReturn(entityManager).atLeastOnce();
+    replay(entityManagerProvider);
+  }
+
+
+  @Test
+  public void testfindAllLocalUsersByRole() {
+    UserEntity entity = new UserEntity();
+    RoleEntity roleEntity = new RoleEntity();
+    TypedQuery<UserEntity> query = createStrictMock(TypedQuery.class);
+
+    // set expectations
+    expect(entityManager.createQuery(eq("SELECT role.userEntities FROM RoleEntity role WHERE role = :roleEntity"), eq(UserEntity.class))).andReturn(query);
+    roleEntity.setRoleName("admin");
+    expect(query.setParameter("roleEntity", roleEntity)).andReturn(query);
+    expect(query.getResultList()).andReturn(Collections.singletonList(entity));
+    
+    replay(entityManager, query);
+
+    UserDAO dao = new UserDAO();
+    dao.entityManagerProvider = entityManagerProvider;
+    roleEntity.setRoleName("admin");
+    
+    List<UserEntity> results = dao.findAllLocalUsersByRole(roleEntity);
+
+    assertEquals(1, results.size());
+    assertSame(entity, results.get(0));
+
+    verify(entityManagerProvider, entityManager, query);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5d69aaaf/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 1d660b5..d5fc62a 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
@@ -114,13 +114,15 @@ public class TestUsers {
     fail("Exception was not thrown");
   }
 
-  @Test
+  @Test(expected = AmbariException.class)
   public void testPromoteUser() throws Exception {
     users.createUser("admin", "admin");
+    users.createUser("admin2", "admin2");
     User user = users.getLocalUser("admin");
     assertTrue(user.getRoles().contains(users.getUserRole()));
     assertFalse(user.getRoles().contains(users.getAdminRole()));
-
+    users.promoteToAdmin(user);
+    user = users.getLocalUser("admin2");
     users.promoteToAdmin(user);
 
     user = users.getLocalUser("admin");
@@ -130,14 +132,33 @@ public class TestUsers {
 
     user = users.getLocalUser("admin");
     assertFalse(user.getRoles().contains(users.getAdminRole()));
+    
+    user = users.getLocalUser("admin2");
+    users.demoteAdmin(user);
 
   }
+  
+  @Test(expected = AmbariException.class)
+  public void testRemoveUser() throws Exception {
+    users.createUser("admin", "admin");
+    User user = users.getLocalUser("admin");
+    users.promoteToAdmin(user);
+
+    user = users.getLocalUser("admin");
+    assertTrue(user.getRoles().contains(users.getAdminRole()));
+
+    users.removeUser(user);
+  }
+
 
   @Test
   public void testPromoteLdapUser() throws Exception {
     createLdapUser();
 
     User ldapUser = users.getLdapUser("ldapUser");
+    users.createUser("localadmin", "admin");
+    User localUser = users.getLocalUser("localadmin");
+    users.promoteToAdmin(localUser);
 
     users.promoteToAdmin(ldapUser);