mirror of https://github.com/apache/cloudstack.git
Merge branch 'rbac' of https://git-wip-us.apache.org/repos/asf/cloudstack into rbac
This commit is contained in:
commit
4499a7bfa0
|
|
@ -12,4 +12,6 @@ public interface AclEntityPermission extends InternalIdentity {
|
|||
Long getEntityId();
|
||||
|
||||
AccessType getAccessType();
|
||||
|
||||
boolean isAllowed();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
// 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.cloudstack.acl;
|
||||
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
public interface AclRolePermission extends InternalIdentity {
|
||||
|
||||
Long getAclRoleId();
|
||||
|
||||
String getEntityType();
|
||||
|
||||
AccessType getAccessType();
|
||||
|
||||
boolean isAllowed();
|
||||
}
|
||||
|
|
@ -32,7 +32,7 @@ public class AclEntityPermissionVO implements AclEntityPermission {
|
|||
|
||||
@Column(name = "entity_id")
|
||||
private long entityId;
|
||||
|
||||
|
||||
@Column(name = "entity_uuid")
|
||||
private String entityUuid;
|
||||
|
||||
|
|
@ -40,6 +40,9 @@ public class AclEntityPermissionVO implements AclEntityPermission {
|
|||
@Enumerated(value = EnumType.STRING)
|
||||
AccessType accessType;
|
||||
|
||||
@Column(name = "permission")
|
||||
private boolean permission;
|
||||
|
||||
@Column(name = GenericDao.REMOVED_COLUMN)
|
||||
private Date removed;
|
||||
|
||||
|
|
@ -50,14 +53,16 @@ public class AclEntityPermissionVO implements AclEntityPermission {
|
|||
|
||||
}
|
||||
|
||||
public AclEntityPermissionVO(long groupId, String entityType, long entityId, String entityUuid, AccessType atype) {
|
||||
public AclEntityPermissionVO(long groupId, String entityType, long entityId, String entityUuid, AccessType atype,
|
||||
boolean permission) {
|
||||
aclGroupId = groupId;
|
||||
this.entityType = entityType;
|
||||
this.entityId = entityId;
|
||||
this.entityUuid = entityUuid;
|
||||
accessType = atype;
|
||||
this.permission = permission;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
|
|
@ -115,4 +120,10 @@ public class AclEntityPermissionVO implements AclEntityPermission {
|
|||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowed() {
|
||||
return permission;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,99 @@
|
|||
// 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.cloudstack.acl;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EnumType;
|
||||
import javax.persistence.Enumerated;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
|
||||
@Entity
|
||||
@Table(name = ("acl_role_permission"))
|
||||
public class AclRolePermissionVO implements AclRolePermission {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "role_id")
|
||||
private long aclRoleId;
|
||||
|
||||
@Column(name = "entity_type")
|
||||
private String entityType;
|
||||
|
||||
@Column(name = "access_type")
|
||||
@Enumerated(value = EnumType.STRING)
|
||||
AccessType accessType;
|
||||
|
||||
@Column(name = "permission")
|
||||
private boolean permission;
|
||||
|
||||
public AclRolePermissionVO() {
|
||||
|
||||
}
|
||||
|
||||
public AclRolePermissionVO(long roleId, String entityType, AccessType atype) {
|
||||
aclRoleId = roleId;
|
||||
this.entityType = entityType;
|
||||
accessType = atype;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getAclRoleId() {
|
||||
return aclRoleId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEntityType() {
|
||||
return entityType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessType getAccessType() {
|
||||
return accessType;
|
||||
}
|
||||
|
||||
|
||||
public void setAclRoleId(long aclRoleId) {
|
||||
this.aclRoleId = aclRoleId;
|
||||
}
|
||||
|
||||
public void setEntityType(String entityType) {
|
||||
this.entityType = entityType;
|
||||
}
|
||||
|
||||
public void setAccessType(AccessType accessType) {
|
||||
this.accessType = accessType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowed() {
|
||||
return permission;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// 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.cloudstack.acl.dao;
|
||||
|
||||
import org.apache.cloudstack.acl.AclRolePermissionVO;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface AclRolePermissionDao extends GenericDao<AclRolePermissionVO, Long> {
|
||||
|
||||
AclRolePermissionVO findByRoleAndEntity(long roleId, String entityType, AccessType accessType);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
// 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.cloudstack.acl.dao;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import org.apache.cloudstack.acl.AclRolePermissionVO;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
|
||||
@Component
|
||||
public class AclRolePermissionDaoImpl extends GenericDaoBase<AclRolePermissionVO, Long> implements AclRolePermissionDao {
|
||||
private SearchBuilder<AclRolePermissionVO> findByRoleEntity;
|
||||
|
||||
public AclRolePermissionDaoImpl()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
|
||||
findByRoleEntity = createSearchBuilder();
|
||||
findByRoleEntity.and("roleId", findByRoleEntity.entity().getAclRoleId(), SearchCriteria.Op.EQ);
|
||||
findByRoleEntity.and("entityType", findByRoleEntity.entity().getEntityType(), SearchCriteria.Op.EQ);
|
||||
findByRoleEntity.and("accessType", findByRoleEntity.entity().getAccessType(), SearchCriteria.Op.EQ);
|
||||
findByRoleEntity.done();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AclRolePermissionVO findByRoleAndEntity(long roleId, String entityType, AccessType accessType) {
|
||||
SearchCriteria<AclRolePermissionVO> sc = findByRoleEntity.create();
|
||||
sc.setParameters("roleId", roleId);
|
||||
sc.setParameters("entityType", entityType);
|
||||
sc.setParameters("accessType", accessType);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
}
|
||||
|
|
@ -16,15 +16,10 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.acl.api;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.acl.APIChecker;
|
||||
import org.apache.cloudstack.acl.AclRole;
|
||||
|
|
@ -35,12 +30,10 @@ import com.cloud.exception.PermissionDeniedException;
|
|||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.utils.PropertiesUtil;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.utils.component.PluggableService;
|
||||
|
||||
// This is the default API access checker that grab's the user's account
|
||||
// based on the account type, access is granted
|
||||
// This is the Role Based API access checker that grab's the account's roles
|
||||
// based on the set of roles, access is granted if any of the role has access to the api
|
||||
@Local(value=APIChecker.class)
|
||||
public class RoleBasedAPIAccessChecker extends AdapterBase implements APIChecker {
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
// 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.cloudstack.acl.entity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.AclGroupAccountMapVO;
|
||||
import org.apache.cloudstack.acl.AclRole;
|
||||
import org.apache.cloudstack.acl.AclService;
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.SecurityChecker;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.acl.dao.AclGroupAccountMapDao;
|
||||
import org.apache.cloudstack.acl.dao.AclGroupDao;
|
||||
|
||||
import com.cloud.acl.DomainChecker;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountService;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
public class RoleBasedEntityAccessChecker extends DomainChecker implements SecurityChecker {
|
||||
|
||||
@Inject
|
||||
AccountService _accountService;
|
||||
@Inject
|
||||
AclService _aclService;
|
||||
|
||||
@Inject
|
||||
AclGroupAccountMapDao _aclGroupAccountMapDao;
|
||||
|
||||
@Override
|
||||
public boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType)
|
||||
throws PermissionDeniedException {
|
||||
|
||||
// check if explicit allow/deny is present for this entity in
|
||||
// acl_entity_permission
|
||||
|
||||
List<AclGroupAccountMapVO> acctGroups = _aclGroupAccountMapDao.listByAccountId(caller.getId());
|
||||
|
||||
|
||||
// Is Caller RootAdmin? Yes, granted true
|
||||
if (_accountService.isRootAdmin(caller.getId())) {
|
||||
return true;
|
||||
}
|
||||
// Is Caller Owner of the entity? Yes, granted true
|
||||
if (caller.getId() == entity.getAccountId()) {
|
||||
return true;
|
||||
}
|
||||
// Get the Roles of the Caller
|
||||
List<AclRole> roles = _aclService.getAclRoles(caller.getId());
|
||||
|
||||
// Do you have DomainAdmin Role? If yes can access the entity in the
|
||||
// domaintree
|
||||
|
||||
// check the entity grant table
|
||||
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.acl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -49,6 +50,11 @@ import com.cloud.utils.component.Manager;
|
|||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.EntityManager;
|
||||
import com.cloud.utils.db.GenericSearchBuilder;
|
||||
import com.cloud.utils.db.JoinBuilder.JoinType;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
|
||||
@Local(value = {AclService.class})
|
||||
|
|
@ -253,7 +259,7 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager {
|
|||
if (entity instanceof Identity) {
|
||||
entityUuid = ((Identity)entity).getUuid();
|
||||
}
|
||||
perm = new AclEntityPermissionVO(aclGroupId, entityType, entityId, entityUuid, accessType);
|
||||
perm = new AclEntityPermissionVO(aclGroupId, entityType, entityId, entityUuid, accessType, true);
|
||||
_entityPermissionDao.persist(perm);
|
||||
}
|
||||
return group;
|
||||
|
|
@ -507,14 +513,53 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager {
|
|||
|
||||
@Override
|
||||
public List<AclRole> getAclRoles(long accountId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
|
||||
SearchBuilder<AclGroupAccountMapVO> groupSB = _aclGroupAccountMapDao.createSearchBuilder();
|
||||
groupSB.and("account", groupSB.entity().getAccountId(), Op.EQ);
|
||||
|
||||
GenericSearchBuilder<AclGroupRoleMapVO, Long> roleSB = _aclGroupRoleMapDao.createSearchBuilder(Long.class);
|
||||
roleSB.selectField(roleSB.entity().getAclRoleId());
|
||||
roleSB.join("accountgroupjoin", groupSB, groupSB.entity().getAclGroupId(), roleSB.entity().getAclGroupId(),
|
||||
JoinType.INNER);
|
||||
roleSB.done();
|
||||
SearchCriteria<Long> roleSc = roleSB.create();
|
||||
roleSc.setJoinParameters("accountgroupjoin", "account", accountId);
|
||||
|
||||
List<Long> roleIds = _aclGroupRoleMapDao.customSearch(roleSc, null);
|
||||
|
||||
SearchBuilder<AclRoleVO> sb = _aclRoleDao.createSearchBuilder();
|
||||
sb.and("ids", sb.entity().getId(), Op.IN);
|
||||
SearchCriteria<AclRoleVO> sc = sb.create();
|
||||
sc.setParameters("ids", roleIds.toArray(new Object[roleIds.size()]));
|
||||
List<AclRoleVO> roles = _aclRoleDao.customSearch(sc, null);
|
||||
|
||||
return new ArrayList<AclRole>(roles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAPIAccessibleForRoles(String apiName, List<AclRole> roles) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
|
||||
boolean accessible = false;
|
||||
|
||||
List<Long> roleIds = new ArrayList<Long>();
|
||||
for (AclRole role : roles) {
|
||||
roleIds.add(role.getId());
|
||||
}
|
||||
|
||||
SearchBuilder<AclApiPermissionVO> sb = _apiPermissionDao.createSearchBuilder();
|
||||
sb.and("apiName", sb.entity().getApiName(), Op.EQ);
|
||||
sb.and("roleId", sb.entity().getAclRoleId(), Op.IN);
|
||||
|
||||
SearchCriteria<AclApiPermissionVO> sc = sb.create();
|
||||
sc.setParameters("roleId", roleIds.toArray(new Object[roleIds.size()]));
|
||||
|
||||
List<AclApiPermissionVO> permissions = _apiPermissionDao.customSearch(sc, null);
|
||||
|
||||
if (permissions != null && !permissions.isEmpty()) {
|
||||
accessible = true;
|
||||
}
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -362,13 +362,23 @@ CREATE TABLE `cloud`.`acl_entity_permission` (
|
|||
`entity_type` varchar(100) NOT NULL,
|
||||
`entity_id` bigint unsigned NOT NULL,
|
||||
`entity_uuid` varchar(40),
|
||||
`access_type` varchar(40) NOT NULL,
|
||||
`access_type` varchar(40) NOT NULL,
|
||||
`permission` int(1) unsigned NOT NULL COMMENT '1 allowed, 0 for denied',
|
||||
`removed` datetime COMMENT 'date the permission was revoked',
|
||||
`created` datetime COMMENT 'date the permission was granted',
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `fk_acl_entity_permission__group_id` FOREIGN KEY(`group_id`) REFERENCES `acl_group` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `cloud`.`acl_role_permission` (
|
||||
`id` bigint unsigned NOT NULL UNIQUE auto_increment,
|
||||
`role_id` bigint unsigned NOT NULL,
|
||||
`entity_type` varchar(100) NOT NULL,
|
||||
`access_type` varchar(40) NOT NULL,
|
||||
`permission` int(1) unsigned NOT NULL COMMENT '1 allowed, 0 for denied',
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `fk_acl_role_permission___role_id` FOREIGN KEY(`role_id`) REFERENCES `acl_role` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
DROP VIEW IF EXISTS `cloud`.`acl_role_view`;
|
||||
CREATE VIEW `cloud`.`acl_role_view` AS
|
||||
|
|
|
|||
Loading…
Reference in New Issue