diff --git a/api/src/org/apache/cloudstack/acl/AclRolePermission.java b/api/src/org/apache/cloudstack/acl/AclRolePermission.java new file mode 100644 index 00000000000..4ec16bc38a7 --- /dev/null +++ b/api/src/org/apache/cloudstack/acl/AclRolePermission.java @@ -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(); +} diff --git a/engine/schema/src/org/apache/cloudstack/acl/AclRolePermissionVO.java b/engine/schema/src/org/apache/cloudstack/acl/AclRolePermissionVO.java new file mode 100644 index 00000000000..d866d915843 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/acl/AclRolePermissionVO.java @@ -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; + } +} diff --git a/engine/schema/src/org/apache/cloudstack/acl/dao/AclRolePermissionDao.java b/engine/schema/src/org/apache/cloudstack/acl/dao/AclRolePermissionDao.java new file mode 100644 index 00000000000..74d491dc600 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/acl/dao/AclRolePermissionDao.java @@ -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 findByRoleAndEntity(long roleId, String entityType, AccessType accessType); + +} diff --git a/engine/schema/src/org/apache/cloudstack/acl/dao/AclRolePermissionDaoImpl.java b/engine/schema/src/org/apache/cloudstack/acl/dao/AclRolePermissionDaoImpl.java new file mode 100644 index 00000000000..c7141f8057f --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/acl/dao/AclRolePermissionDaoImpl.java @@ -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 implements AclRolePermissionDao { + private SearchBuilder findByRoleEntity; + + public AclRolePermissionDaoImpl() + { + + } + + @Override + public boolean configure(String name, Map 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 sc = findByRoleEntity.create(); + sc.setParameters("roleId", roleId); + sc.setParameters("entityType", entityType); + sc.setParameters("accessType", accessType); + return findOneBy(sc); + } +} diff --git a/plugins/acl/role-based-access-checkers/src/org/apache/cloudstack/acl/entity/RoleBasedEntityAccessChecker.java b/plugins/acl/role-based-access-checkers/src/org/apache/cloudstack/acl/entity/RoleBasedEntityAccessChecker.java new file mode 100644 index 00000000000..0f83b28b44d --- /dev/null +++ b/plugins/acl/role-based-access-checkers/src/org/apache/cloudstack/acl/entity/RoleBasedEntityAccessChecker.java @@ -0,0 +1,66 @@ +// 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.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 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; + + @Override + public boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType) + throws PermissionDeniedException { + + // 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 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; + } +} diff --git a/setup/db/db/schema-420to430.sql b/setup/db/db/schema-420to430.sql index c23c4980873..6d03a6d6958 100644 --- a/setup/db/db/schema-420to430.sql +++ b/setup/db/db/schema-420to430.sql @@ -369,6 +369,15 @@ CREATE TABLE `cloud`.`acl_entity_permission` ( 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