소스 검색

AMBARI-6830. Admin View: add boolean is_admin to api for /users.

Siddharth Wagle 10 년 전
부모
커밋
0715d9bf35

+ 11 - 3
ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java

@@ -704,7 +704,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
         throw new AmbariException("User already exists.");
       }
 
-      users.createUser(request.getUsername(), request.getPassword());
+      users.createUser(request.getUsername(), request.getPassword(), request.isActive(), request.isAdmin());
 
       if (0 != request.getRoles().size()) {
         user = users.getAnyUser(request.getUsername());
@@ -2396,6 +2396,14 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
       if (null != request.isActive()) {
         users.setUserActive(u, request.isActive());
       }
+
+      if (null != request.isAdmin()) {
+        if (request.isAdmin()) {
+          users.grantAdminPrivilege(u.getUserId());
+        } else {
+          users.revokeAdminPrivilege(u.getUserId());
+        }
+      }
     }
   }
 
@@ -2738,7 +2746,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
       // get them all
       if (null == r.getUsername()) {
         for (User u : users.getAllUsers()) {
-          UserResponse resp = new UserResponse(u.getUserName(), u.isLdapUser(), u.isActive());
+          UserResponse resp = new UserResponse(u.getUserName(), u.isLdapUser(), u.isActive(), u.isAdmin());
           resp.setRoles(new HashSet<String>(u.getRoles()));
           resp.setGroups(new HashSet<String>(u.getGroups()));
           responses.add(resp);
@@ -2754,7 +2762,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
                 + r.getUsername() + "'");
           }
         } else {
-          UserResponse resp = new UserResponse(u.getUserName(), u.isLdapUser(), u.isActive());
+          UserResponse resp = new UserResponse(u.getUserName(), u.isLdapUser(), u.isActive(), u.isAdmin());
           resp.setRoles(new HashSet<String>(u.getRoles()));
           resp.setGroups(new HashSet<String>(u.getGroups()));
           responses.add(resp);

+ 2 - 6
ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java

@@ -464,12 +464,8 @@ public class AmbariServer {
       Users users = injector.getInstance(Users.class);
 
       users.createDefaultRoles();
-      users.createUser("admin", "admin");
-      users.createUser("user", "user");
-      try {
-        users.promoteToAdmin(users.getLocalUser("admin"));
-      } catch (AmbariException ignored) {
-      }
+      users.createUser("admin", "admin", true, true);
+      users.createUser("user", "user", true, false);
 
       MetainfoEntity schemaVersion = new MetainfoEntity();
       schemaVersion.setMetainfoName(Configuration.SERVER_VERSION_KEY);

+ 9 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/UserRequest.java

@@ -29,6 +29,7 @@ public class UserRequest {
   private String oldPassword;
   private Boolean active;
   private Set<String> roles = new HashSet<String>();
+  private Boolean admin;
 
   public UserRequest(String name) {
     this.userName = name;
@@ -70,6 +71,14 @@ public class UserRequest {
     this.active = active;
   }
 
+  public Boolean isAdmin() {
+    return admin;
+  }
+
+  public void setAdmin(Boolean admin) {
+    this.admin = admin;
+  }
+
   @Override
   public String toString() {
     StringBuilder sb = new StringBuilder();

+ 7 - 1
ambari-server/src/main/java/org/apache/ambari/server/controller/UserResponse.java

@@ -29,12 +29,14 @@ public class UserResponse {
   private final String userName;
   private final boolean isLdapUser;
   private final boolean isActive;
+  private final boolean isAdmin;
   private Set<String> groups = Collections.emptySet();
 
-  public UserResponse(String name, boolean isLdapUser, boolean isActive) {
+  public UserResponse(String name, boolean isLdapUser, boolean isActive, boolean isAdmin) {
     this.userName = name;
     this.isLdapUser = isLdapUser;
     this.isActive = isActive;
+    this.isAdmin = isAdmin;
   }
 
   public String getUsername() {
@@ -88,4 +90,8 @@ public class UserResponse {
   public boolean isActive() {
     return isActive;
   }
+
+  public boolean isAdmin() {
+    return isAdmin;
+  }
 }

+ 8 - 0
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/UserResourceProvider.java

@@ -45,6 +45,7 @@ class UserResourceProvider extends AbstractControllerResourceProvider {
   protected static final String USER_LDAP_USER_PROPERTY_ID    = PropertyHelper.getPropertyId("Users", "ldap_user");
   protected static final String USER_ACTIVE_PROPERTY_ID       = PropertyHelper.getPropertyId("Users", "active");
   protected static final String USER_GROUPS_PROPERTY_ID       = PropertyHelper.getPropertyId("Users", "groups");
+  protected static final String USER_ADMIN_PROPERTY_ID        = PropertyHelper.getPropertyId("Users", "admin");
 
   private static Set<String> pkPropertyIds =
       new HashSet<String>(Arrays.asList(new String[]{
@@ -129,6 +130,9 @@ class UserResourceProvider extends AbstractControllerResourceProvider {
       setResourceProperty(resource, USER_GROUPS_PROPERTY_ID,
           userResponse.getGroups(), requestedIds);
 
+      setResourceProperty(resource, USER_ADMIN_PROPERTY_ID,
+          userResponse.isAdmin(), requestedIds);
+
       resources.add(resource);
     }
 
@@ -207,6 +211,10 @@ class UserResourceProvider extends AbstractControllerResourceProvider {
       request.setActive(Boolean.valueOf(properties.get(USER_ACTIVE_PROPERTY_ID).toString()));
     }
 
+    if (null != properties.get(USER_ADMIN_PROPERTY_ID)) {
+      request.setAdmin(Boolean.valueOf(properties.get(USER_ADMIN_PROPERTY_ID).toString()));
+    }
+
     return request;
   }
 }

+ 11 - 12
ambari-server/src/main/java/org/apache/ambari/server/orm/dao/PermissionDAO.java

@@ -34,16 +34,6 @@ import java.util.List;
 @Singleton
 public class PermissionDAO {
 
-  /**
-   * Id of built-in VIEW.USE permission.
-   */
-  private static int VIEW_USE_PERMISSION_ID = 4;
-
-  /**
-   * Name of built-in VIEW.USE permission.
-   */
-  private static String VIEW_USE_PERMISSION_NAME = "VIEW.USE";
-
   /**
    * JPA entity manager
    */
@@ -83,7 +73,7 @@ public class PermissionDAO {
    * @return a matching permission entity or null
    */
   public PermissionEntity findPermissionByNameAndType(String name, ResourceTypeEntity resourceType) {
-    if (name.equals(VIEW_USE_PERMISSION_NAME)) {
+    if (name.equals(PermissionEntity.VIEW_USE_PERMISSION_NAME)) {
       // VIEW.USE permission should be available for any type of views
       return findViewUsePermission();
     }
@@ -93,12 +83,21 @@ public class PermissionDAO {
     return daoUtils.selectSingle(query);
   }
 
+  /**
+   * Find AMBARI.ADMIN permission.
+   *
+   * @return a matching permission entity or null
+   */
+  public PermissionEntity findAmbariAdminPermission() {
+    return findById(PermissionEntity.AMBARI_ADMIN_PERMISSION);
+  }
+
   /**
    * Find VIEW.USE permission.
    *
    * @return a matching permission entity or null
    */
   public PermissionEntity findViewUsePermission() {
-    return findById(VIEW_USE_PERMISSION_ID);
+    return findById(PermissionEntity.VIEW_USE_PERMISSION);
   }
 }

+ 9 - 0
ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ResourceDAO.java

@@ -80,4 +80,13 @@ public class ResourceDAO {
   public ResourceEntity merge(ResourceEntity entity) {
     return entityManagerProvider.get().merge(entity);
   }
+
+  /**
+   * Finds root level resource.
+   *
+   * @return the matching resource or null
+   */
+  public ResourceEntity findAmbariResource() {
+    return findById(ResourceEntity.AMBARI_RESOURCE_ID);
+  }
 }

+ 38 - 4
ambari-server/src/main/java/org/apache/ambari/server/orm/entities/PrincipalEntity.java

@@ -18,7 +18,20 @@
 
 package org.apache.ambari.server.orm.entities;
 
-import javax.persistence.*;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinColumns;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
 
 /**
  * Represents an admin principal.
@@ -47,6 +60,9 @@ public class PrincipalEntity {
   })
   private PrincipalTypeEntity principalType;
 
+  @OneToMany(mappedBy = "principal")
+  private Set<PrivilegeEntity> privileges = new HashSet<PrivilegeEntity>();
+
 
   // ----- PrincipalEntity ---------------------------------------------------
 
@@ -62,7 +78,7 @@ public class PrincipalEntity {
   /**
    * Set the principal id.
    *
-   * @param id  the type id.
+   * @param id the type id.
    */
   public void setId(Long id) {
     this.id = id;
@@ -71,7 +87,7 @@ public class PrincipalEntity {
   /**
    * Get the principal type entity.
    *
-   * @return  the principal type entity
+   * @return the principal type entity
    */
   public PrincipalTypeEntity getPrincipalType() {
     return principalType;
@@ -80,12 +96,30 @@ public class PrincipalEntity {
   /**
    * Set the principal type entity.
    *
-   * @param principalType  the principal type entity
+   * @param principalType the principal type entity
    */
   public void setPrincipalType(PrincipalTypeEntity principalType) {
     this.principalType = principalType;
   }
 
+  /**
+   * Get the principal privileges.
+   *
+   * @return the principal privileges
+   */
+  public Set<PrivilegeEntity> getPrivileges() {
+    return privileges;
+  }
+
+  /**
+   * Set the principal privileges.
+   *
+   * @param privileges the principal privileges
+   */
+  public void setPrivileges(Set<PrivilegeEntity> privileges) {
+    this.privileges = privileges;
+  }
+
 
   // ----- Object overrides --------------------------------------------------
 

+ 2 - 2
ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapDataPopulator.java

@@ -204,7 +204,7 @@ public class AmbariLdapDataPopulator {
           this.users.setUserLdap(userName);
         }
       } else {
-        this.users.createUser(userName, "");
+        this.users.createUser(userName, "", true, false);
         this.users.setUserLdap(userName);
       }
     }
@@ -230,7 +230,7 @@ public class AmbariLdapDataPopulator {
         internalUsers.remove(externalMember);
         internalMembers.remove(externalMember);
       } else {
-        users.createUser(externalMember, "");
+        users.createUser(externalMember, "", true, false);
         users.setUserLdap(externalMember);
       }
       users.addMemberToGroup(groupName, externalMember);

+ 13 - 0
ambari-server/src/main/java/org/apache/ambari/server/security/authorization/User.java

@@ -22,6 +22,8 @@ import java.util.Collection;
 import java.util.Date;
 
 import org.apache.ambari.server.orm.entities.MemberEntity;
+import org.apache.ambari.server.orm.entities.PermissionEntity;
+import org.apache.ambari.server.orm.entities.PrivilegeEntity;
 import org.apache.ambari.server.orm.entities.RoleEntity;
 import org.apache.ambari.server.orm.entities.UserEntity;
 
@@ -36,6 +38,7 @@ public class User {
   final boolean active;
   final Collection<String> roles = new ArrayList<String>();
   final Collection<String> groups = new ArrayList<String>();
+  boolean admin = false;
 
   User(UserEntity userEntity) {
     userId = userEntity.getUserId();
@@ -49,6 +52,12 @@ public class User {
     for (MemberEntity memberEntity : userEntity.getMemberEntities()) {
       groups.add(memberEntity.getGroup().getGroupName());
     }
+    for (PrivilegeEntity privilegeEntity: userEntity.getPrincipal().getPrivileges()) {
+      if (privilegeEntity.getPermission().getPermissionName().equals(PermissionEntity.AMBARI_ADMIN_PERMISSION_NAME)) {
+        admin = true;
+        break;
+      }
+    }
   }
 
   public int getUserId() {
@@ -71,6 +80,10 @@ public class User {
     return active;
   }
 
+  public boolean isAdmin() {
+    return admin;
+  }
+
   public Collection<String> getRoles() {
     return roles;
   }

+ 67 - 2
ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java

@@ -27,14 +27,19 @@ import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.orm.dao.GroupDAO;
 import org.apache.ambari.server.orm.dao.MemberDAO;
+import org.apache.ambari.server.orm.dao.PermissionDAO;
 import org.apache.ambari.server.orm.dao.PrincipalDAO;
 import org.apache.ambari.server.orm.dao.PrincipalTypeDAO;
+import org.apache.ambari.server.orm.dao.PrivilegeDAO;
+import org.apache.ambari.server.orm.dao.ResourceDAO;
 import org.apache.ambari.server.orm.dao.RoleDAO;
 import org.apache.ambari.server.orm.dao.UserDAO;
 import org.apache.ambari.server.orm.entities.GroupEntity;
 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.RoleEntity;
 import org.apache.ambari.server.orm.entities.UserEntity;
 import org.slf4j.Logger;
@@ -68,6 +73,12 @@ public class Users {
   @Inject
   protected PrincipalDAO principalDAO;
   @Inject
+  protected PermissionDAO permissionDAO;
+  @Inject
+  protected PrivilegeDAO privilegeDAO;
+  @Inject
+  protected ResourceDAO resourceDAO;
+  @Inject
   protected PrincipalTypeDAO principalTypeDAO;
   @Inject
   protected PasswordEncoder passwordEncoder;
@@ -217,10 +228,22 @@ public class Users {
   }
 
   /**
-   * Creates new local user with provided userName and password
+   * Creates new local user with provided userName and password.
+   */
+  public void createUser(String userName, String password) {
+    createUser(userName, password, true, false);
+  }
+
+  /**
+   * Creates new local user with provided userName and password.
+   *
+   * @param userName user name
+   * @param password password
+   * @param active is user active
+   * @param admin is user admin
    */
   @Transactional
-  public synchronized void createUser(String userName, String password) {
+  public synchronized void createUser(String userName, String password, Boolean active, Boolean admin) {
 
     // create an admin principal to represent this user
     PrincipalTypeEntity principalTypeEntity = principalTypeDAO.findById(PrincipalTypeEntity.USER_PRINCIPAL_TYPE);
@@ -239,6 +262,9 @@ public class Users {
     userEntity.setUserPassword(passwordEncoder.encode(password));
     userEntity.setRoleEntities(new HashSet<RoleEntity>());
     userEntity.setPrincipal(principalEntity);
+    if (active != null) {
+      userEntity.setActive(active);
+    }
 
     RoleEntity roleEntity = roleDAO.findByName(getUserRole());
     if (roleEntity == null) {
@@ -249,6 +275,10 @@ public class Users {
     userEntity.getRoleEntities().add(roleEntity);
     userDAO.create(userEntity);
 
+    if (admin != null && admin) {
+      grantAdminPrivilege(userEntity.getUserId());
+    }
+
     roleEntity.getUserEntities().add(userEntity);
     roleDAO.merge(roleEntity);
   }
@@ -365,6 +395,41 @@ public class Users {
     }
   }
 
+  /**
+   * Grants AMBARI.ADMIN privilege to provided user.
+   *
+   * @param user user
+   */
+  public synchronized void grantAdminPrivilege(Integer userId) {
+    final UserEntity user = userDAO.findByPK(userId);
+    final PrivilegeEntity adminPrivilege = new PrivilegeEntity();
+    adminPrivilege.setPermission(permissionDAO.findAmbariAdminPermission());
+    adminPrivilege.setPrincipal(user.getPrincipal());
+    adminPrivilege.setResource(resourceDAO.findAmbariResource());
+    if (!user.getPrincipal().getPrivileges().contains(adminPrivilege)) {
+      privilegeDAO.create(adminPrivilege);
+      user.getPrincipal().getPrivileges().add(adminPrivilege);
+      userDAO.merge(user);
+    }
+  }
+
+  /**
+   * Revokes AMBARI.ADMIN privilege from provided user.
+   *
+   * @param user user
+   */
+  public synchronized void revokeAdminPrivilege(Integer userId) {
+    final UserEntity user = userDAO.findByPK(userId);
+    for (PrivilegeEntity privilege: user.getPrincipal().getPrivileges()) {
+      if (privilege.getPermission().getPermissionName().equals(PermissionEntity.AMBARI_ADMIN_PERMISSION_NAME)) {
+        user.getPrincipal().getPrivileges().remove(privilege);
+        userDAO.merge(user);
+        privilegeDAO.remove(privilege);
+        break;
+      }
+    }
+  }
+
   /**
    * Grants ADMIN role to provided user
    * @throws AmbariException

+ 1 - 0
ambari-server/src/main/resources/properties.json

@@ -176,6 +176,7 @@
         "Users/ldap_user",
         "Users/active",
         "Users/groups",
+        "Users/admin",
         "_"
     ],
     "Group":[

+ 1 - 1
ambari-server/src/test/java/org/apache/ambari/server/controller/internal/UserResourceProviderTest.java

@@ -92,7 +92,7 @@ public class UserResourceProviderTest {
     AmbariManagementController managementController = createMock(AmbariManagementController.class);
 
     Set<UserResponse> allResponse = new HashSet<UserResponse>();
-    allResponse.add(new UserResponse("User100", false, true));
+    allResponse.add(new UserResponse("User100", false, true, false));
 
     // set expectations
     expect(managementController.getUsers(AbstractResourceProviderTest.Matcher.getUserRequestSet("User100"))).