Skip to content

Commit 62a4272

Browse files
committed
APIAccessChecker: Make it check based on role type and not user
Signed-off-by: Rohit Yadav <[email protected]>
1 parent c6d9877 commit 62a4272

3 files changed

Lines changed: 69 additions & 55 deletions

File tree

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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,14 @@
1616
// under the License.
1717
package org.apache.cloudstack.acl;
1818

19-
import java.util.Properties;
20-
19+
import org.apache.cloudstack.acl.RoleType;
2120
import com.cloud.exception.PermissionDeniedException;
22-
import com.cloud.user.Account;
23-
import com.cloud.user.User;
2421
import com.cloud.utils.component.Adapter;
2522

2623
/**
2724
* APIAccessChecker checks the ownership and access control to API requests
2825
*/
2926
public interface APIAccessChecker extends Adapter {
3027
// Interface for checking access to an API for an user
31-
boolean canAccessAPI(User user, String apiCommandName) throws PermissionDeniedException;
28+
boolean canAccessAPI(RoleType roleType, String apiCommandName) throws PermissionDeniedException;
3229
}

plugins/acl/static-role-based/src/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java

Lines changed: 35 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -27,80 +27,66 @@
2727
import javax.naming.ConfigurationException;
2828

2929
import org.apache.cloudstack.acl.APIAccessChecker;
30+
import org.apache.cloudstack.acl.RoleType;
31+
import static org.apache.cloudstack.acl.RoleType.*;
3032
import org.apache.log4j.Logger;
3133

3234
import com.cloud.exception.PermissionDeniedException;
3335
import com.cloud.server.ManagementServer;
34-
import com.cloud.user.Account;
35-
import com.cloud.user.AccountManager;
36-
import com.cloud.user.User;
3736
import com.cloud.utils.PropertiesUtil;
3837
import com.cloud.utils.component.AdapterBase;
3938
import com.cloud.utils.component.ComponentLocator;
40-
import com.cloud.utils.component.Inject;
4139
import com.cloud.utils.component.PluggableService;
4240

43-
/*
44-
* This is the default API access checker that grab's the user's account
45-
* based on the account type, access is granted referring to commands in all *.properties files.
46-
*/
47-
41+
// This is the default API access checker that grab's the user's account
42+
// based on the account type, access is granted
4843
@Local(value=APIAccessChecker.class)
4944
public class StaticRoleBasedAPIAccessChecker extends AdapterBase implements APIAccessChecker {
5045

5146
protected static final Logger s_logger = Logger.getLogger(StaticRoleBasedAPIAccessChecker.class);
52-
public static final short ADMIN_COMMAND = 1;
53-
public static final short DOMAIN_ADMIN_COMMAND = 4;
54-
public static final short RESOURCE_DOMAIN_ADMIN_COMMAND = 2;
55-
public static final short USER_COMMAND = 8;
56-
private static List<String> s_userCommands = null;
57-
private static List<String> s_resellerCommands = null; // AKA domain-admin
58-
private static List<String> s_adminCommands = null;
59-
private static List<String> s_resourceDomainAdminCommands = null;
60-
private static List<String> s_allCommands = null;
61-
62-
protected @Inject AccountManager _accountMgr;
47+
private static Set<String> s_userCommands = null;
48+
private static Set<String> s_resellerCommands = null; // AKA domain-admin
49+
private static Set<String> s_adminCommands = null;
50+
private static Set<String> s_resourceDomainAdminCommands = null;
51+
private static Set<String> s_allCommands = null;
6352

6453
protected StaticRoleBasedAPIAccessChecker() {
6554
super();
66-
s_allCommands = new ArrayList<String>();
67-
s_userCommands = new ArrayList<String>();
68-
s_resellerCommands = new ArrayList<String>();
69-
s_adminCommands = new ArrayList<String>();
70-
s_resourceDomainAdminCommands = new ArrayList<String>();
55+
s_allCommands = new HashSet<String>();
56+
s_userCommands = new HashSet<String>();
57+
s_resellerCommands = new HashSet<String>();
58+
s_adminCommands = new HashSet<String>();
59+
s_resourceDomainAdminCommands = new HashSet<String>();
7160
}
7261

7362
@Override
74-
public boolean canAccessAPI(User user, String apiCommandName)
63+
public boolean canAccessAPI(RoleType roleType, String apiCommandName)
7564
throws PermissionDeniedException{
7665

7766
boolean commandExists = s_allCommands.contains(apiCommandName);
7867

79-
if(commandExists && user != null){
80-
Long accountId = user.getAccountId();
81-
Account userAccount = _accountMgr.getAccount(accountId);
82-
short accountType = userAccount.getType();
83-
return isCommandAvailableForAccount(accountType, apiCommandName);
68+
if(commandExists) {
69+
return isCommandAvailableForAccount(roleType, apiCommandName);
8470
}
8571

8672
return commandExists;
8773
}
8874

89-
private static boolean isCommandAvailableForAccount(short accountType, String commandName) {
75+
private static boolean isCommandAvailableForAccount(RoleType roleType, String commandName) {
9076
boolean isCommandAvailable = false;
91-
switch (accountType) {
92-
case Account.ACCOUNT_TYPE_ADMIN:
93-
isCommandAvailable = s_adminCommands.contains(commandName);
94-
break;
95-
case Account.ACCOUNT_TYPE_DOMAIN_ADMIN:
96-
isCommandAvailable = s_resellerCommands.contains(commandName);
97-
break;
98-
case Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN:
99-
isCommandAvailable = s_resourceDomainAdminCommands.contains(commandName);
100-
break;
101-
case Account.ACCOUNT_TYPE_NORMAL:
102-
isCommandAvailable = s_userCommands.contains(commandName);
103-
break;
77+
switch (roleType) {
78+
case Admin:
79+
isCommandAvailable = s_adminCommands.contains(commandName);
80+
break;
81+
case DomainAdmin:
82+
isCommandAvailable = s_resellerCommands.contains(commandName);
83+
break;
84+
case ResourceAdmin:
85+
isCommandAvailable = s_resourceDomainAdminCommands.contains(commandName);
86+
break;
87+
case User:
88+
isCommandAvailable = s_userCommands.contains(commandName);
89+
break;
10490
}
10591
return isCommandAvailable;
10692
}
@@ -157,16 +143,16 @@ private void processConfigFiles(List<String> configFiles) {
157143

158144
try {
159145
short cmdPermissions = Short.parseShort(mask);
160-
if ((cmdPermissions & ADMIN_COMMAND) != 0) {
146+
if ((cmdPermissions & Admin.getValue()) != 0) {
161147
s_adminCommands.add((String) key);
162148
}
163-
if ((cmdPermissions & RESOURCE_DOMAIN_ADMIN_COMMAND) != 0) {
149+
if ((cmdPermissions & ResourceAdmin.getValue()) != 0) {
164150
s_resourceDomainAdminCommands.add((String) key);
165151
}
166-
if ((cmdPermissions & DOMAIN_ADMIN_COMMAND) != 0) {
152+
if ((cmdPermissions & DomainAdmin.getValue()) != 0) {
167153
s_resellerCommands.add((String) key);
168154
}
169-
if ((cmdPermissions & USER_COMMAND) != 0) {
155+
if ((cmdPermissions & User.getValue()) != 0) {
170156
s_userCommands.add((String) key);
171157
}
172158
s_allCommands.addAll(s_adminCommands);

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

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import com.cloud.utils.ReflectUtil;
5454
import org.apache.cloudstack.acl.APIAccessChecker;
5555
import org.apache.cloudstack.acl.ControlledEntity;
56+
import org.apache.cloudstack.acl.RoleType;
5657
import org.apache.cloudstack.api.*;
5758
import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
5859
import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
@@ -790,9 +791,39 @@ public boolean verifyUser(Long userId) {
790791
}
791792

792793
private boolean isCommandAvailable(User user, String commandName) {
794+
if (user == null) {
795+
return false;
796+
}
797+
798+
Account account = _accountMgr.getAccount(user.getAccountId());
799+
if (account == null) {
800+
return false;
801+
}
802+
803+
RoleType roleType = RoleType.Unknown;
804+
short accountType = account.getType();
805+
806+
// Account type to role type translation
807+
switch (accountType) {
808+
case Account.ACCOUNT_TYPE_ADMIN:
809+
roleType = RoleType.Admin;
810+
break;
811+
case Account.ACCOUNT_TYPE_DOMAIN_ADMIN:
812+
roleType = RoleType.DomainAdmin;
813+
break;
814+
case Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN:
815+
roleType = RoleType.ResourceAdmin;
816+
break;
817+
case Account.ACCOUNT_TYPE_NORMAL:
818+
roleType = RoleType.User;
819+
break;
820+
default:
821+
return false;
822+
}
823+
793824
for (APIAccessChecker apiChecker : _apiAccessCheckers) {
794825
// Fail the checking if any checker fails to verify
795-
if (!apiChecker.canAccessAPI(user, commandName))
826+
if (!apiChecker.canAccessAPI(roleType, commandName))
796827
return false;
797828
}
798829
return true;

0 commit comments

Comments
 (0)