Skip to content
This repository was archived by the owner on Jan 15, 2020. It is now read-only.

Commit 96a64b9

Browse files
author
Prachi Damle
committed
- Adding OperateEntry during loading of commands
- Replace ListEntry By OperateEntry - ApiDispatcher should pass on the API name
1 parent 39c0a30 commit 96a64b9

11 files changed

Lines changed: 75 additions & 34 deletions

File tree

api/src/com/cloud/user/AccountService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ UserAccount createUserAccount(String userName, String password, String firstName
108108

109109
void checkAccess(Account account, AccessType accessType, boolean sameOwner, ControlledEntity... entities) throws PermissionDeniedException;
110110

111+
void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName,
112+
ControlledEntity... entities) throws PermissionDeniedException;
113+
111114
//TO be implemented, to check accessibility for an entity owned by domain
112115
void checkAccess(Account account, AccessType accessType, boolean sameOwner, PartOf... entities) throws PermissionDeniedException;
113116
}

api/src/org/apache/cloudstack/acl/SecurityChecker.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ public enum AccessType {
3636
ModifyProject,
3737
UseNetwork,
3838
DeleteEntry,
39-
OperateEntry
39+
OperateEntry,
40+
UseEntry
4041
}
4142

4243
/**

server/src/com/cloud/api/ApiDispatcher.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.apache.cloudstack.acl.RoleType;
4141
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
4242
import org.apache.cloudstack.api.ACL;
43+
import org.apache.cloudstack.api.APICommand;
4344
import org.apache.cloudstack.api.ApiConstants;
4445
import org.apache.cloudstack.api.ApiErrorCode;
4546
import org.apache.cloudstack.api.BaseAsyncCmd;
@@ -107,19 +108,14 @@ public void dispatchCreateCmd(BaseAsyncCreateCmd cmd, Map<String, String> params
107108

108109
private void doAccessChecks(BaseCmd cmd, Map<Object, AccessType> entitiesToAccess) {
109110
Account caller = CallContext.current().getCallingAccount();
110-
Account owner = _accountMgr.getActiveAccountById(cmd.getEntityOwnerId());
111111

112-
if (cmd instanceof BaseAsyncCreateCmd) {
113-
//check that caller can access the owner account.
114-
_accountMgr.checkAccess(caller, null, true, owner);
115-
}
112+
APICommand commandAnnotation = cmd.getClass().getAnnotation(APICommand.class);
113+
String apiName = commandAnnotation != null ? commandAnnotation.name() : null;
116114

117115
if (!entitiesToAccess.isEmpty()) {
118-
//check that caller can access the owner account.
119-
_accountMgr.checkAccess(caller, null, true, owner);
120116
for (Object entity : entitiesToAccess.keySet()) {
121117
if (entity instanceof ControlledEntity) {
122-
_accountMgr.checkAccess(caller, entitiesToAccess.get(entity), true, (ControlledEntity)entity);
118+
_accountMgr.checkAccess(caller, entitiesToAccess.get(entity), false, apiName, (ControlledEntity) entity);
123119
} else if (entity instanceof InfrastructureEntity) {
124120
//FIXME: Move this code in adapter, remove code from Account manager
125121
}

server/src/com/cloud/user/AccountManagerImpl.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,11 @@ public void checkAccess(Account account, AccessType accessType, boolean sameOwne
447447

448448
@Override
449449
public void checkAccess(Account caller, AccessType accessType, boolean sameOwner, ControlledEntity... entities) {
450+
checkAccess(caller, accessType, sameOwner, null, entities);
451+
}
452+
453+
@Override
454+
public void checkAccess(Account caller, AccessType accessType, boolean sameOwner, String apiName, ControlledEntity... entities) {
450455
//check for the same owner
451456
Long ownerId = null;
452457
ControlledEntity prevEntity = null;
@@ -492,7 +497,7 @@ public void checkAccess(Account caller, AccessType accessType, boolean sameOwner
492497
}
493498
boolean granted = false;
494499
for (SecurityChecker checker : _securityCheckers) {
495-
if (checker.checkAccess(caller, entity, accessType)) {
500+
if (checker.checkAccess(caller, entity, accessType, apiName)) {
496501
if (s_logger.isDebugEnabled()) {
497502
s_logger.debug("Access to " + entity + " granted to " + caller + " by " + checker.getName());
498503
}

services/iam/plugin/src/org/apache/cloudstack/acl/RoleBasedAPIAccessChecker.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@
3030

3131
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
3232
import org.apache.cloudstack.api.APICommand;
33+
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
3334
import org.apache.cloudstack.api.BaseCmd;
3435
import org.apache.cloudstack.api.BaseListCmd;
3536
import org.apache.cloudstack.iam.api.AclPolicy;
37+
import org.apache.cloudstack.iam.api.AclPolicyPermission;
3638
import org.apache.cloudstack.iam.api.AclPolicyPermission.Permission;
3739
import org.apache.cloudstack.iam.api.IAMService;
3840

@@ -205,7 +207,9 @@ private void addDefaultAclPolicyPermission(String apiName, Class<?> cmdClass, Ro
205207
try {
206208
cmdObj = (BaseCmd) cmdClass.newInstance();
207209
if (cmdObj instanceof BaseListCmd) {
208-
accessType = AccessType.ListEntry;
210+
accessType = AccessType.UseEntry;
211+
} else if (!(cmdObj instanceof BaseAsyncCreateCmd)) {
212+
accessType = AccessType.OperateEntry;
209213
}
210214
} catch (Exception e) {
211215
throw new CloudRuntimeException(String.format(
@@ -238,11 +242,11 @@ private void addDefaultAclPolicyPermission(String apiName, Class<?> cmdClass, Ro
238242

239243

240244
if (entityTypes == null || entityTypes.length == 0) {
241-
_iamSrv.addAclPermissionToAclPolicy(policyId, null, permissionScope.toString(), new Long(-1),
245+
_iamSrv.addAclPermissionToAclPolicy(policyId, null, permissionScope.toString(), new Long(AclPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER),
242246
apiName, (accessType == null) ? null : accessType.toString(), Permission.Allow);
243247
} else {
244248
for (AclEntityType entityType : entityTypes) {
245-
_iamSrv.addAclPermissionToAclPolicy(policyId, entityType.toString(), permissionScope.toString(), new Long(-1),
249+
_iamSrv.addAclPermissionToAclPolicy(policyId, entityType.toString(), permissionScope.toString(), new Long(AclPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER),
246250
apiName, (accessType == null) ? null : accessType.toString(), Permission.Allow);
247251
}
248252
}

services/iam/plugin/src/org/apache/cloudstack/acl/RoleBasedEntityAccessChecker.java

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import org.apache.log4j.Logger;
2626

27+
import org.apache.cloudstack.api.InternalIdentity;
2728
import org.apache.cloudstack.iam.api.AclPolicy;
2829
import org.apache.cloudstack.iam.api.AclPolicyPermission;
2930
import org.apache.cloudstack.iam.api.IAMService;
@@ -71,7 +72,7 @@ public boolean checkAccess(Account caller, ControlledEntity entity, AccessType a
7172
String entityType = entity.getEntityType().toString();
7273

7374
if (accessType == null) {
74-
accessType = AccessType.ListEntry;
75+
accessType = AccessType.UseEntry;
7576
}
7677

7778
// get all Policies of this caller w.r.t the entity
@@ -82,13 +83,21 @@ public boolean checkAccess(Account caller, ControlledEntity entity, AccessType a
8283
List<AclPolicyPermission> permissions = new ArrayList<AclPolicyPermission>();
8384

8485
if (action != null) {
85-
permissions = _iamSrv.listPolicyPermissionByEntityType(policy.getId(), action, entityType);
86+
permissions = _iamSrv.listPolicyPermissionByActionAndEntity(policy.getId(), action, entityType);
87+
if (permissions.isEmpty()) {
88+
if (accessType != null) {
89+
permissions.addAll(_iamSrv.listPolicyPermissionByAccessAndEntity(policy.getId(),
90+
accessType.toString(), entityType));
91+
}
92+
}
8693
} else {
87-
permissions = _iamSrv.listPolicyPermissionByAccessType(policy.getId(), accessType.toString(),
88-
entityType, action);
94+
if (accessType != null) {
95+
permissions.addAll(_iamSrv.listPolicyPermissionByAccessAndEntity(policy.getId(),
96+
accessType.toString(), entityType));
97+
}
8998
}
9099
for (AclPolicyPermission permission : permissions) {
91-
if (checkPermissionScope(caller, permission.getScope(), entity)) {
100+
if (checkPermissionScope(caller, permission.getScope(), permission.getScopeId(), entity)) {
92101
if (permission.getEntityType().equals(entityType)) {
93102
policyPermissionMap.put(policy, permission.getPermission().isGranted());
94103
break;
@@ -114,18 +123,38 @@ public boolean checkAccess(Account caller, ControlledEntity entity, AccessType a
114123
return false;
115124
}
116125

117-
private boolean checkPermissionScope(Account caller, String scope, ControlledEntity entity) {
126+
private boolean checkPermissionScope(Account caller, String scope, Long scopeId, ControlledEntity entity) {
118127

119-
if (scope.equals(PermissionScope.ACCOUNT.name())) {
120-
if(caller.getAccountId() == entity.getAccountId()){
121-
return true;
128+
if(scopeId != null && !scopeId.equals(new Long(AclPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER))){
129+
//scopeId is set
130+
if (scope.equals(PermissionScope.ACCOUNT.name())) {
131+
if(scopeId == entity.getAccountId()){
132+
return true;
133+
}
134+
} else if (scope.equals(PermissionScope.DOMAIN.name())) {
135+
if (_domainDao.isChildDomain(scopeId, entity.getDomainId())) {
136+
return true;
137+
}
138+
} else if (scope.equals(PermissionScope.RESOURCE.name())) {
139+
if (entity instanceof InternalIdentity) {
140+
InternalIdentity entityWithId = (InternalIdentity) entity;
141+
if(scopeId.equals(entityWithId.getId())){
142+
return true;
143+
}
144+
}
122145
}
123-
} else if (scope.equals(PermissionScope.DOMAIN.name())) {
124-
if (_domainDao.isChildDomain(caller.getDomainId(), entity.getDomainId())) {
125-
return true;
146+
} else if (scopeId == null || scopeId.equals(new Long(AclPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER))) {
147+
if (scope.equals(PermissionScope.ACCOUNT.name())) {
148+
if(caller.getAccountId() == entity.getAccountId()){
149+
return true;
150+
}
151+
} else if (scope.equals(PermissionScope.DOMAIN.name())) {
152+
if (_domainDao.isChildDomain(caller.getDomainId(), entity.getDomainId())) {
153+
return true;
154+
}
126155
}
127156
}
128-
157+
129158
return false;
130159
}
131160

services/iam/server/src/org/apache/cloudstack/iam/api/AclPolicyPermission.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,5 @@ public boolean isGranted() {
4949

5050
long getId();
5151

52+
public static final long PERMISSION_SCOPE_ID_CURRENT_CALLER = -1;
5253
}

services/iam/server/src/org/apache/cloudstack/iam/api/IAMService.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,15 @@ AclPolicy removeAclPermissionFromAclPolicy(long aclPolicyId, String entityType,
6666

6767
List<AclPolicyPermission> listPolicyPermissionsByScope(long policyId, String action, String scope);
6868

69-
List<AclPolicyPermission> listPolicyPermissionByEntityType(long policyId, String action, String entityType);
69+
List<AclPolicyPermission> listPolicyPermissionByActionAndEntity(long policyId, String action, String entityType);
7070

7171
boolean isActionAllowedForPolicies(String action, List<AclPolicy> policies);
7272

7373
List<Long> getGrantedEntities(long accountId, String action, String scope);
7474

7575
AclPolicy resetAclPolicy(long aclPolicyId);
7676

77-
List<AclPolicyPermission> listPolicyPermissionByAccessType(long policyId, String accessType, String entityType, String action);
77+
List<AclPolicyPermission> listPolicyPermissionByAccessAndEntity(long policyId, String accessType,
78+
String entityType);
7879

7980
}

services/iam/server/src/org/apache/cloudstack/iam/server/IAMServiceImpl.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -670,17 +670,19 @@ public List<AclPolicyPermission> listPolicyPermissionsByScope(long policyId, Str
670670

671671
@SuppressWarnings("unchecked")
672672
@Override
673-
public List<AclPolicyPermission> listPolicyPermissionByEntityType(long policyId, String action, String entityType) {
673+
public List<AclPolicyPermission> listPolicyPermissionByActionAndEntity(long policyId, String action,
674+
String entityType) {
674675
@SuppressWarnings("rawtypes")
675676
List pp = _policyPermissionDao.listByPolicyActionAndEntity(policyId, action, entityType);
676677
return pp;
677678
}
678679

679680
@SuppressWarnings("unchecked")
680681
@Override
681-
public List<AclPolicyPermission> listPolicyPermissionByAccessType(long policyId, String accessType, String entityType, String action) {
682+
public List<AclPolicyPermission> listPolicyPermissionByAccessAndEntity(long policyId, String accessType,
683+
String entityType) {
682684
@SuppressWarnings("rawtypes")
683-
List pp = _policyPermissionDao.listByPolicyAccessAndEntity(policyId, accessType, entityType, action);
685+
List pp = _policyPermissionDao.listByPolicyAccessAndEntity(policyId, accessType, entityType);
684686
return pp;
685687
}
686688

services/iam/server/src/org/apache/cloudstack/iam/server/dao/AclPolicyPermissionDao.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,6 @@ AclPolicyPermissionVO findByPolicyAndEntity(long policyId, String entityType, St
3333

3434
List<AclPolicyPermissionVO> listByPolicyActionAndEntity(long policyId, String action, String entityType);
3535

36-
List<AclPolicyPermissionVO> listByPolicyAccessAndEntity(long id, String accessType, String entityType, String action);
36+
List<AclPolicyPermissionVO> listByPolicyAccessAndEntity(long policyId, String accessType, String entityType);
3737

3838
}

0 commit comments

Comments
 (0)