You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mc...@apache.org on 2013/10/01 02:04:53 UTC
git commit: updated refs/heads/rbac to 5583506
Updated Branches:
refs/heads/rbac de0904ba6 -> 5583506c0
Add entity permission grant and revoke API.
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/5583506c
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/5583506c
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/5583506c
Branch: refs/heads/rbac
Commit: 5583506c0ca5c2eb30073ab1e6d9e035b13ba98a
Parents: de0904b
Author: Min Chen <mi...@citrix.com>
Authored: Mon Sep 30 17:03:34 2013 -0700
Committer: Min Chen <mi...@citrix.com>
Committed: Mon Sep 30 17:03:34 2013 -0700
----------------------------------------------------------------------
api/src/com/cloud/event/EventTypes.java | 2 +
.../org/apache/cloudstack/acl/AclService.java | 6 +
.../apache/cloudstack/acl/SecurityChecker.java | 4 +-
.../org/apache/cloudstack/api/ApiConstants.java | 4 +
.../admin/acl/GrantPermissionToAclGroupCmd.java | 131 +++++++++++++++++++
.../acl/RevokePermissionFromAclGroupCmd.java | 131 +++++++++++++++++++
.../response/AclEntityPermissionResponse.java | 112 ++++++++++++++++
.../api/response/AclGroupResponse.java | 17 +++
client/tomcatconf/commands.properties.in | 2 +
.../cloudstack/acl/AclEntityPermissionVO.java | 42 +++++-
.../acl/dao/AclEntityPermissionDaoImpl.java | 5 +
server/src/com/cloud/api/ApiResponseHelper.java | 18 +--
.../api/query/dao/AclGroupJoinDaoImpl.java | 15 +++
.../com/cloud/api/query/vo/AclGroupJoinVO.java | 32 +++++
.../com/cloud/server/ManagementServerImpl.java | 4 +
.../apache/cloudstack/acl/AclServiceImpl.java | 98 +++++++++++++-
setup/db/db/schema-420to430.sql | 11 +-
17 files changed, 615 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5583506c/api/src/com/cloud/event/EventTypes.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java
index 5b7bf59..076a7c5 100755
--- a/api/src/com/cloud/event/EventTypes.java
+++ b/api/src/com/cloud/event/EventTypes.java
@@ -453,6 +453,8 @@ public class EventTypes {
public static final String EVENT_ACL_GROUP_UPDATE = "ACLGROUP.UPDATE";
public static final String EVENT_ACL_GROUP_CREATE = "ACLGROUP.CREATE";
public static final String EVENT_ACL_GROUP_DELETE = "ACLGROUP.DELETE";
+ public static final String EVENT_ACL_GROUP_GRANT = "ACLGROUP.GRANT";
+ public static final String EVENT_ACL_GROUP_REVOKE = "ACLGROUP.REVOKE";
static {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5583506c/api/src/org/apache/cloudstack/acl/AclService.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/acl/AclService.java b/api/src/org/apache/cloudstack/acl/AclService.java
index 1f4d620..e01c3b6 100644
--- a/api/src/org/apache/cloudstack/acl/AclService.java
+++ b/api/src/org/apache/cloudstack/acl/AclService.java
@@ -18,6 +18,8 @@ package org.apache.cloudstack.acl;
import java.util.List;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+
public interface AclService {
/**
@@ -50,6 +52,10 @@ public interface AclService {
AclGroup removeAccountsFromGroup(List<Long> acctIds, Long groupId);
+ AclGroup grantEntityPermissionToAclGroup(long aclGroupId, String entityType, long entityId, AccessType accessType);
+
+ AclGroup revokeEntityPermissionFromAclGroup(long aclGroupId, String entityType, long entityId, AccessType accessType);
+
/**
* Creates an acl group for the given domain.
*
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5583506c/api/src/org/apache/cloudstack/acl/SecurityChecker.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/acl/SecurityChecker.java b/api/src/org/apache/cloudstack/acl/SecurityChecker.java
index 3a721fe..9943f6b 100644
--- a/api/src/org/apache/cloudstack/acl/SecurityChecker.java
+++ b/api/src/org/apache/cloudstack/acl/SecurityChecker.java
@@ -34,7 +34,9 @@ public interface SecurityChecker extends Adapter {
ListEntry,
ModifyEntry,
ModifyProject,
- UseNetwork
+ UseNetwork,
+ DeleteEntry,
+ OperationOnEntry
}
/**
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5583506c/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index cd8479f..78200e5 100755
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -525,6 +525,10 @@ public class ApiConstants {
public static final String ACL_ROLE_IDS = "roleids";
public static final String ACL_APIS = "apis";
public static final String ACL_GROUPS = "groups";
+ public static final String ACL_PERMISSIONS = "permission";
+ public static final String ENTITY_TYPE = "entitytype";
+ public static final String ENTITY_ID = "entityid";
+ public static final String ACCESS_TYPE = "accesstype";
public enum HostDetails {
all, capacity, events, stats, min;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5583506c/api/src/org/apache/cloudstack/api/command/admin/acl/GrantPermissionToAclGroupCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/acl/GrantPermissionToAclGroupCmd.java b/api/src/org/apache/cloudstack/api/command/admin/acl/GrantPermissionToAclGroupCmd.java
new file mode 100644
index 0000000..9fefa75
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/admin/acl/GrantPermissionToAclGroupCmd.java
@@ -0,0 +1,131 @@
+// 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.api.command.admin.acl;
+
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.AclGroup;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.AclGroupResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+
+
+@APICommand(name = "grantPermissionToAclGroup", description = "grant entity permission to an acl group", responseObject = AclGroupResponse.class)
+public class GrantPermissionToAclGroupCmd extends BaseAsyncCmd {
+ public static final Logger s_logger = Logger.getLogger(GrantPermissionToAclGroupCmd.class.getName());
+ private static final String s_name = "grantpermissiontoaclgroupresponse";
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+
+ @ACL
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = AclGroupResponse.class,
+ required = true, description = "The ID of the acl group")
+ private Long id;
+
+ @Parameter(name = ApiConstants.ENTITY_TYPE, type = CommandType.STRING, required = true, description = "entity class simple name.")
+ private String entityType;
+
+ @Parameter(name = ApiConstants.ENTITY_ID, type = CommandType.UUID, required = true, description = "The ID of the entity")
+ private Long entityId;
+
+ @Parameter(name = ApiConstants.ACCESS_TYPE, type = CommandType.STRING, required = true, description = "access type for the entity")
+ private String accessType;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getEntityType() {
+ return entityType;
+ }
+
+ public Long getEntityId() {
+ return entityId;
+ }
+
+ public AccessType getAccessType() {
+ return AccessType.valueOf(accessType);
+ }
+
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+ }
+
+ @Override
+ public void execute() throws ResourceUnavailableException,
+ InsufficientCapacityException, ServerApiException {
+ CallContext.current().setEventDetails("Acl group Id: " + getId());
+ AclGroup result = _aclService.grantEntityPermissionToAclGroup(id, entityType, entityId, getAccessType());
+ if (result != null){
+ AclGroupResponse response = _responseGenerator.createAclGroupResponse(result);
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to grant permission to acl group");
+ }
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_ACL_GROUP_GRANT;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "granting permission to acl group";
+ }
+
+ @Override
+ public ApiCommandJobType getInstanceType() {
+ return ApiCommandJobType.AclGroup;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5583506c/api/src/org/apache/cloudstack/api/command/admin/acl/RevokePermissionFromAclGroupCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/acl/RevokePermissionFromAclGroupCmd.java b/api/src/org/apache/cloudstack/api/command/admin/acl/RevokePermissionFromAclGroupCmd.java
new file mode 100644
index 0000000..b9a75d7
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/admin/acl/RevokePermissionFromAclGroupCmd.java
@@ -0,0 +1,131 @@
+// 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.api.command.admin.acl;
+
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.acl.AclGroup;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.ACL;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.AclGroupResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.user.Account;
+
+
+@APICommand(name = "revokePermissionFromAclGroup", description = "revoke entity permission from an acl group", responseObject = AclGroupResponse.class)
+public class RevokePermissionFromAclGroupCmd extends BaseAsyncCmd {
+ public static final Logger s_logger = Logger.getLogger(RevokePermissionFromAclGroupCmd.class.getName());
+ private static final String s_name = "revokepermissiontoaclgroupresponse";
+
+ /////////////////////////////////////////////////////
+ //////////////// API parameters /////////////////////
+ /////////////////////////////////////////////////////
+
+
+ @ACL
+ @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = AclGroupResponse.class,
+ required = true, description = "The ID of the acl group")
+ private Long id;
+
+ @Parameter(name = ApiConstants.ENTITY_TYPE, type = CommandType.STRING, required = true, description = "entity class simple name.")
+ private String entityType;
+
+ @Parameter(name = ApiConstants.ENTITY_ID, type = CommandType.UUID, required = true, description = "The ID of the entity")
+ private Long entityId;
+
+ @Parameter(name = ApiConstants.ACCESS_TYPE, type = CommandType.STRING, required = true, description = "access type for the entity")
+ private String accessType;
+
+ /////////////////////////////////////////////////////
+ /////////////////// Accessors ///////////////////////
+ /////////////////////////////////////////////////////
+
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getEntityType() {
+ return entityType;
+ }
+
+ public Long getEntityId() {
+ return entityId;
+ }
+
+ public AccessType getAccessType() {
+ return AccessType.valueOf(accessType);
+ }
+
+
+ /////////////////////////////////////////////////////
+ /////////////// API Implementation///////////////////
+ /////////////////////////////////////////////////////
+
+ @Override
+ public String getCommandName() {
+ return s_name;
+ }
+
+
+ @Override
+ public long getEntityOwnerId() {
+ return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
+ }
+
+ @Override
+ public void execute() throws ResourceUnavailableException,
+ InsufficientCapacityException, ServerApiException {
+ CallContext.current().setEventDetails("Acl group Id: " + getId());
+ AclGroup result = _aclService.revokeEntityPermissionFromAclGroup(id, entityType, entityId, getAccessType());
+ if (result != null){
+ AclGroupResponse response = _responseGenerator.createAclGroupResponse(result);
+ response.setResponseName(getCommandName());
+ setResponseObject(response);
+ } else {
+ throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to grant permission to acl group");
+ }
+ }
+
+ @Override
+ public String getEventType() {
+ return EventTypes.EVENT_ACL_GROUP_GRANT;
+ }
+
+ @Override
+ public String getEventDescription() {
+ return "granting permission to acl group";
+ }
+
+ @Override
+ public ApiCommandJobType getInstanceType() {
+ return ApiCommandJobType.AclGroup;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5583506c/api/src/org/apache/cloudstack/api/response/AclEntityPermissionResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/AclEntityPermissionResponse.java b/api/src/org/apache/cloudstack/api/response/AclEntityPermissionResponse.java
new file mode 100644
index 0000000..da3b4b2
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/response/AclEntityPermissionResponse.java
@@ -0,0 +1,112 @@
+// 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.api.response;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+
+import com.cloud.serializer.Param;
+
+public class AclEntityPermissionResponse extends BaseResponse {
+
+ @SerializedName(ApiConstants.GROUP_ID)
+ @Param(description = "the ID of the acl group")
+ private String groupId;
+
+ @SerializedName(ApiConstants.ENTITY_TYPE)
+ @Param(description = "the entity type of this permission")
+ private String entityType;
+
+ @SerializedName(ApiConstants.ENTITY_ID)
+ @Param(description = "the uuid of the entity involved in this permission")
+ private String entityId;
+
+ @SerializedName(ApiConstants.ACCESS_TYPE)
+ @Param(description = "access type involved in this permission")
+ private String accessType;
+
+
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ public String getEntityType() {
+ return entityType;
+ }
+
+ public void setEntityType(String entityType) {
+ this.entityType = entityType;
+ }
+
+ public String getEntityId() {
+ return entityId;
+ }
+
+ public void setEntityId(String entityId) {
+ this.entityId = entityId;
+ }
+
+ public String getAccessType() {
+ return accessType;
+ }
+
+ public void setAccessType(String accessType) {
+ this.accessType = accessType;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((entityType == null) ? 0 : entityType.hashCode());
+ result = prime * result + ((entityId == null) ? 0 : entityId.hashCode());
+ result = prime * result + ((accessType == null) ? 0 : accessType.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ AclEntityPermissionResponse other = (AclEntityPermissionResponse) obj;
+ if (entityType == null) {
+ if (other.entityType != null)
+ return false;
+ } else if (!entityType.equals(other.entityType)) {
+ return false;
+ } else if ((entityId == null && other.entityId != null) || !entityId.equals(other.entityId)) {
+ return false;
+ } else if ((accessType == null && other.accessType != null) || !accessType.equals(other.accessType)) {
+ return false;
+ }
+ return true;
+ }
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5583506c/api/src/org/apache/cloudstack/api/response/AclGroupResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/AclGroupResponse.java b/api/src/org/apache/cloudstack/api/response/AclGroupResponse.java
index 94fe8b5..e531504 100644
--- a/api/src/org/apache/cloudstack/api/response/AclGroupResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/AclGroupResponse.java
@@ -60,9 +60,14 @@ public class AclGroupResponse extends BaseResponse {
@Param(description = "acl roles granted to this acl group ")
private Set<AclRoleResponse> roleList;
+ @SerializedName(ApiConstants.ACL_PERMISSIONS)
+ @Param(description = "permissions granted to this acl group ")
+ private Set<AclEntityPermissionResponse> permList;
+
public AclGroupResponse() {
accountIdList = new LinkedHashSet<String>();
roleList = new LinkedHashSet<AclRoleResponse>();
+ permList = new LinkedHashSet<AclEntityPermissionResponse>();
}
@Override
@@ -116,6 +121,18 @@ public class AclGroupResponse extends BaseResponse {
return roleList;
}
+ public Set<AclEntityPermissionResponse> getPermissionList() {
+ return permList;
+ }
+
+ public void setPermissionList(Set<AclEntityPermissionResponse> perms) {
+ permList = perms;
+ }
+
+ public void addPermission(AclEntityPermissionResponse perm) {
+ permList.add(perm);
+ }
+
@Override
public int hashCode() {
final int prime = 31;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5583506c/client/tomcatconf/commands.properties.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in
index 8aad3a7..9bb0ea2 100644
--- a/client/tomcatconf/commands.properties.in
+++ b/client/tomcatconf/commands.properties.in
@@ -692,4 +692,6 @@ addAclRoleToAclGroup=7
removeAclRoleFromAclGroup=7
addAccountToAclGroup=7
removeAccountFromAclGroup=7
+grantPermissionToAclGroup=7
+revokePermissionFromAclGroup=7
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5583506c/engine/schema/src/org/apache/cloudstack/acl/AclEntityPermissionVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/acl/AclEntityPermissionVO.java b/engine/schema/src/org/apache/cloudstack/acl/AclEntityPermissionVO.java
index b9e9174..a394516 100644
--- a/engine/schema/src/org/apache/cloudstack/acl/AclEntityPermissionVO.java
+++ b/engine/schema/src/org/apache/cloudstack/acl/AclEntityPermissionVO.java
@@ -31,7 +31,10 @@ public class AclEntityPermissionVO implements AclEntityPermission {
private String entityType;
@Column(name = "entity_id")
- private Long entityId;
+ private long entityId;
+
+ @Column(name = "entity_uuid")
+ private String entityUuid;
@Column(name = "access_type")
@Enumerated(value = EnumType.STRING)
@@ -43,6 +46,18 @@ public class AclEntityPermissionVO implements AclEntityPermission {
@Column(name = GenericDao.CREATED_COLUMN)
private Date created;
+ public AclEntityPermissionVO() {
+
+ }
+
+ public AclEntityPermissionVO(long groupId, String entityType, long entityId, String entityUuid, AccessType atype) {
+ aclGroupId = groupId;
+ this.entityType = entityType;
+ this.entityId = entityId;
+ this.entityUuid = entityUuid;
+ accessType = atype;
+ }
+
@Override
public long getId() {
return id;
@@ -63,11 +78,36 @@ public class AclEntityPermissionVO implements AclEntityPermission {
return entityId;
}
+ public String getEntityUuid() {
+ return entityUuid;
+ }
+
@Override
public AccessType getAccessType() {
return accessType;
}
+
+ public void setAclGroupId(long aclGroupId) {
+ this.aclGroupId = aclGroupId;
+ }
+
+ public void setEntityType(String entityType) {
+ this.entityType = entityType;
+ }
+
+ public void setEntityId(long entityId) {
+ this.entityId = entityId;
+ }
+
+ public void setEntityUuid(String entityUuid) {
+ this.entityUuid = entityUuid;
+ }
+
+ public void setAccessType(AccessType accessType) {
+ this.accessType = accessType;
+ }
+
public Date getRemoved() {
return removed;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5583506c/engine/schema/src/org/apache/cloudstack/acl/dao/AclEntityPermissionDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/acl/dao/AclEntityPermissionDaoImpl.java b/engine/schema/src/org/apache/cloudstack/acl/dao/AclEntityPermissionDaoImpl.java
index 71c6e64..482c9f3 100644
--- a/engine/schema/src/org/apache/cloudstack/acl/dao/AclEntityPermissionDaoImpl.java
+++ b/engine/schema/src/org/apache/cloudstack/acl/dao/AclEntityPermissionDaoImpl.java
@@ -33,6 +33,11 @@ import com.cloud.utils.db.SearchCriteria;
public class AclEntityPermissionDaoImpl extends GenericDaoBase<AclEntityPermissionVO, Long> implements AclEntityPermissionDao {
private SearchBuilder<AclEntityPermissionVO> findByGroupEntity;
+ public AclEntityPermissionDaoImpl()
+ {
+
+ }
+
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
super.configure(name, params);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5583506c/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index c4ab6b8..b19d6ef 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -151,6 +151,7 @@ import org.apache.cloudstack.usage.UsageTypes;
import com.cloud.api.query.ViewResponseHelper;
import com.cloud.api.query.vo.AccountJoinVO;
+import com.cloud.api.query.vo.AclGroupJoinVO;
import com.cloud.api.query.vo.AclRoleJoinVO;
import com.cloud.api.query.vo.AsyncJobJoinVO;
import com.cloud.api.query.vo.ControlledViewEntity;
@@ -3683,19 +3684,10 @@ public class ApiResponseHelper implements ResponseGenerator {
@Override
public AclGroupResponse createAclGroupResponse(AclGroup group) {
- AclGroupResponse response = new AclGroupResponse();
-
- response.setId(group.getUuid());
- response.setName(group.getName());
- response.setDescription(group.getDescription());
- Domain domain = _entityMgr.findById(Domain.class, group.getDomainId());
- if (domain != null) {
- response.setDomainId(domain.getUuid());
- response.setDomainName(domain.getName());
- }
-
- response.setObjectName("aclgroup");
- return response;
+ List<AclGroupJoinVO> viewGroups = ApiDBUtils.newAclGroupView(group);
+ List<AclGroupResponse> listGroups = ViewResponseHelper.createAclGroupResponses(viewGroups);
+ assert listGroups != null && listGroups.size() == 1 : "There should be one acl role returned";
+ return listGroups.get(0);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5583506c/server/src/com/cloud/api/query/dao/AclGroupJoinDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/dao/AclGroupJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/AclGroupJoinDaoImpl.java
index 9b70542..a1ffad2 100644
--- a/server/src/com/cloud/api/query/dao/AclGroupJoinDaoImpl.java
+++ b/server/src/com/cloud/api/query/dao/AclGroupJoinDaoImpl.java
@@ -30,6 +30,7 @@ import org.springframework.stereotype.Component;
import org.apache.cloudstack.acl.AclGroup;
import org.apache.cloudstack.acl.AclGroupAccountMapVO;
import org.apache.cloudstack.acl.dao.AclGroupAccountMapDao;
+import org.apache.cloudstack.api.response.AclEntityPermissionResponse;
import org.apache.cloudstack.api.response.AclGroupResponse;
import org.apache.cloudstack.api.response.AclRoleResponse;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
@@ -88,6 +89,13 @@ public class AclGroupJoinDaoImpl extends GenericDaoBase<AclGroupJoinVO, Long> im
roleResp.setName(group.getRoleName());
response.addRole(roleResp);
}
+ if (group.getEntityId() > 0) {
+ AclEntityPermissionResponse permResp = new AclEntityPermissionResponse();
+ permResp.setEntityId(group.getEntityUuid());
+ permResp.setEntityType(group.getEntityType());
+ permResp.setAccessType(group.getAccessType().toString());
+ response.addPermission(permResp);
+ }
response.setObjectName("aclgroup");
@@ -105,6 +113,13 @@ public class AclGroupJoinDaoImpl extends GenericDaoBase<AclGroupJoinVO, Long> im
roleResp.setName(group.getRoleName());
response.addRole(roleResp);
}
+ if (group.getEntityId() > 0) {
+ AclEntityPermissionResponse permResp = new AclEntityPermissionResponse();
+ permResp.setEntityId(group.getEntityUuid());
+ permResp.setEntityType(group.getEntityType());
+ permResp.setAccessType(group.getAccessType().toString());
+ response.addPermission(permResp);
+ }
return response;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5583506c/server/src/com/cloud/api/query/vo/AclGroupJoinVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/vo/AclGroupJoinVO.java b/server/src/com/cloud/api/query/vo/AclGroupJoinVO.java
index dd8e20e..0a32f4d 100644
--- a/server/src/com/cloud/api/query/vo/AclGroupJoinVO.java
+++ b/server/src/com/cloud/api/query/vo/AclGroupJoinVO.java
@@ -20,11 +20,15 @@ import java.util.Date;
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;
+
import com.cloud.utils.db.GenericDao;
@Entity
@@ -80,6 +84,19 @@ public class AclGroupJoinVO extends BaseViewVO {
@Column(name = "account_name")
private String accountName;
+ @Column(name = "entity_type")
+ private String entityType;
+
+ @Column(name = "entity_id")
+ private long entityId;
+
+ @Column(name = "entity_uuid")
+ private String entityUuid;
+
+ @Column(name = "access_type")
+ @Enumerated(value = EnumType.STRING)
+ AccessType accessType;
+
public AclGroupJoinVO() {
}
@@ -154,5 +171,20 @@ public class AclGroupJoinVO extends BaseViewVO {
return accountName;
}
+ public String getEntityType() {
+ return entityType;
+ }
+
+ public long getEntityId() {
+ return entityId;
+ }
+
+ public String getEntityUuid() {
+ return entityUuid;
+ }
+
+ public AccessType getAccessType() {
+ return accessType;
+ }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5583506c/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 3a4fd31..ae06643 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -63,11 +63,13 @@ import org.apache.cloudstack.api.command.admin.acl.CreateAclGroupCmd;
import org.apache.cloudstack.api.command.admin.acl.CreateAclRoleCmd;
import org.apache.cloudstack.api.command.admin.acl.DeleteAclGroupCmd;
import org.apache.cloudstack.api.command.admin.acl.DeleteAclRoleCmd;
+import org.apache.cloudstack.api.command.admin.acl.GrantPermissionToAclGroupCmd;
import org.apache.cloudstack.api.command.admin.acl.GrantPermissionToAclRoleCmd;
import org.apache.cloudstack.api.command.admin.acl.ListAclGroupsCmd;
import org.apache.cloudstack.api.command.admin.acl.ListAclRolesCmd;
import org.apache.cloudstack.api.command.admin.acl.RemoveAccountFromAclGroupCmd;
import org.apache.cloudstack.api.command.admin.acl.RemoveAclRoleFromAclGroupCmd;
+import org.apache.cloudstack.api.command.admin.acl.RevokePermissionFromAclGroupCmd;
import org.apache.cloudstack.api.command.admin.acl.RevokePermissionFromAclRoleCmd;
import org.apache.cloudstack.api.command.admin.autoscale.CreateCounterCmd;
import org.apache.cloudstack.api.command.admin.autoscale.DeleteCounterCmd;
@@ -2877,6 +2879,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
cmdList.add(ListAclGroupsCmd.class);
cmdList.add(AddAccountToAclGroupCmd.class);
cmdList.add(RemoveAccountFromAclGroupCmd.class);
+ cmdList.add(GrantPermissionToAclGroupCmd.class);
+ cmdList.add(RevokePermissionFromAclGroupCmd.class);
return cmdList;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5583506c/server/src/org/apache/cloudstack/acl/AclServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/org/apache/cloudstack/acl/AclServiceImpl.java b/server/src/org/apache/cloudstack/acl/AclServiceImpl.java
index 00d15db..1e5ad15 100644
--- a/server/src/org/apache/cloudstack/acl/AclServiceImpl.java
+++ b/server/src/org/apache/cloudstack/acl/AclServiceImpl.java
@@ -16,6 +16,7 @@
// under the License.
package org.apache.cloudstack.acl;
+import java.util.HashMap;
import java.util.List;
import javax.ejb.Local;
@@ -23,24 +24,31 @@ import javax.inject.Inject;
import org.apache.log4j.Logger;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.acl.dao.AclApiPermissionDao;
import org.apache.cloudstack.acl.dao.AclEntityPermissionDao;
import org.apache.cloudstack.acl.dao.AclGroupAccountMapDao;
import org.apache.cloudstack.acl.dao.AclGroupDao;
import org.apache.cloudstack.acl.dao.AclGroupRoleMapDao;
import org.apache.cloudstack.acl.dao.AclRoleDao;
+import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.context.CallContext;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
+import com.cloud.storage.Snapshot;
+import com.cloud.storage.Volume;
+import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.dao.AccountDao;
+import com.cloud.uservm.UserVm;
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.Transaction;
@Local(value = {AclService.class})
@@ -62,6 +70,9 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager {
AclGroupDao _aclGroupDao;
@Inject
+ EntityManager _entityMgr;
+
+ @Inject
AclGroupRoleMapDao _aclGroupRoleMapDao;
@Inject
@@ -73,6 +84,15 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager {
@Inject
AclEntityPermissionDao _entityPermissionDao;
+ public static HashMap<String, Class> entityClassMap = new HashMap<String, Class>();
+
+ static {
+ entityClassMap.put("VirtualMachine", UserVm.class);
+ entityClassMap.put("Volume", Volume.class);
+ entityClassMap.put("Template", VirtualMachineTemplate.class);
+ entityClassMap.put("Snapshot", Snapshot.class);
+ // To be filled in later depending on the entity permission grant scope
+ }
@DB
@Override
@@ -188,7 +208,7 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager {
Transaction txn = Transaction.currentTxn();
txn.start();
- // add entries in acl_api_permission table
+ // remove entries from acl_api_permission table
for (String api : apiNames) {
AclApiPermissionVO perm = _apiPermissionDao.findByRoleAndApi(aclRoleId, api);
if (perm != null) {
@@ -202,6 +222,80 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager {
@DB
@Override
+ @ActionEvent(eventType = EventTypes.EVENT_ACL_GROUP_GRANT, eventDescription = "Granting entity permission to Acl Group")
+ public AclGroup grantEntityPermissionToAclGroup(long aclGroupId, String entityType, long entityId, AccessType accessType) {
+ Account caller = CallContext.current().getCallingAccount();
+ // get the Acl Group entity
+ AclGroup group = _aclGroupDao.findById(aclGroupId);
+ if (group == null) {
+ throw new InvalidParameterValueException("Unable to find acl group: " + aclGroupId
+ + "; failed to grant permission to group.");
+ }
+ // check permissions
+ _accountMgr.checkAccess(caller, null, true, group);
+
+ // get the entity and check permission
+ Class entityClass = entityClassMap.get(entityType);
+ if (entityClass == null) {
+ throw new InvalidParameterValueException("Entity type " + entityType + " permission granting is not supported yet");
+ }
+ ControlledEntity entity = (ControlledEntity)_entityMgr.findById(entityClass, entityId);
+ if (entity == null) {
+ throw new InvalidParameterValueException("Unable to find entity " + entityType + " by id: " + entityId);
+ }
+ _accountMgr.checkAccess(caller,null, true, entity);
+
+ // add entry in acl_entity_permission table
+ AclEntityPermissionVO perm = _entityPermissionDao.findByGroupAndEntity(aclGroupId, entityType, entityId, accessType);
+ if (perm == null) {
+ // not there already
+ String entityUuid = String.valueOf(entityId);
+ if (entity instanceof Identity) {
+ entityUuid = ((Identity)entity).getUuid();
+ }
+ perm = new AclEntityPermissionVO(aclGroupId, entityType, entityId, entityUuid, accessType);
+ _entityPermissionDao.persist(perm);
+ }
+ return group;
+
+ }
+
+ @DB
+ @Override
+ @ActionEvent(eventType = EventTypes.EVENT_ACL_GROUP_REVOKE, eventDescription = "Revoking entity permission from Acl Group")
+ public AclGroup revokeEntityPermissionFromAclGroup(long aclGroupId, String entityType, long entityId, AccessType accessType) {
+ Account caller = CallContext.current().getCallingAccount();
+ // get the Acl Group entity
+ AclGroup group = _aclGroupDao.findById(aclGroupId);
+ if (group == null) {
+ throw new InvalidParameterValueException("Unable to find acl group: " + aclGroupId
+ + "; failed to revoke permission from group.");
+ }
+ // check permissions
+ _accountMgr.checkAccess(caller, null, true, group);
+
+ // get the entity and check permission
+ Class entityClass = entityClassMap.get(entityType);
+ if (entityClass == null) {
+ throw new InvalidParameterValueException("Entity type " + entityType + " permission revoke is not supported yet");
+ }
+ ControlledEntity entity = (ControlledEntity)_entityMgr.findById(entityClass, entityId);
+ if (entity == null) {
+ throw new InvalidParameterValueException("Unable to find entity " + entityType + " by id: " + entityId);
+ }
+ _accountMgr.checkAccess(caller, null, true, entity);
+
+ // remove entry from acl_entity_permission table
+ AclEntityPermissionVO perm = _entityPermissionDao.findByGroupAndEntity(aclGroupId, entityType, entityId, accessType);
+ if (perm != null) {
+ // not removed yet
+ _entityPermissionDao.remove(perm.getId());
+ }
+ return group;
+ }
+
+ @DB
+ @Override
@ActionEvent(eventType = EventTypes.EVENT_ACL_GROUP_UPDATE, eventDescription = "Adding roles to acl group")
public AclGroup addAclRolesToGroup(List<Long> roleIds, Long groupId) {
Account caller = CallContext.current().getCallingAccount();
@@ -326,7 +420,7 @@ public class AclServiceImpl extends ManagerBase implements AclService, Manager {
Transaction txn = Transaction.currentTxn();
txn.start();
- // add entries in acl_group_account_map table
+ // remove entries from acl_group_account_map table
for (Long acctId : acctIds) {
// check account permissions
Account account = _accountDao.findById(acctId);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5583506c/setup/db/db/schema-420to430.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-420to430.sql b/setup/db/db/schema-420to430.sql
index 78c2afe..c23c498 100644
--- a/setup/db/db/schema-420to430.sql
+++ b/setup/db/db/schema-420to430.sql
@@ -361,6 +361,7 @@ CREATE TABLE `cloud`.`acl_entity_permission` (
`group_id` bigint unsigned NOT NULL,
`entity_type` varchar(100) NOT NULL,
`entity_id` bigint unsigned NOT NULL,
+ `entity_uuid` varchar(40),
`access_type` varchar(40) NOT NULL,
`removed` datetime COMMENT 'date the permission was revoked',
`created` datetime COMMENT 'date the permission was granted',
@@ -414,7 +415,11 @@ CREATE VIEW `cloud`.`acl_group_view` AS
acl_role.name role_name,
account.id account_id,
account.uuid account_uuid,
- account.account_name account_name
+ account.account_name account_name,
+ acl_entity_permission.entity_id entity_id,
+ acl_entity_permission.entity_uuid entity_uuid,
+ acl_entity_permission.entity_type entity_type,
+ acl_entity_permission.access_type access_type
from
`cloud`.`acl_group`
inner join
@@ -426,5 +431,7 @@ CREATE VIEW `cloud`.`acl_group_view` AS
left join
`cloud`.`acl_group_account_map` ON acl_group.id = acl_group_account_map.group_id
left join
- `cloud`.`account` ON acl_group_account_map.account_id = account.id;
+ `cloud`.`account` ON acl_group_account_map.account_id = account.id
+ left join
+ `cloud`.`acl_entity_permission` ON acl_group.id = acl_entity_permission.group_id;
\ No newline at end of file