diff --git a/api/src/org/apache/cloudstack/acl/APIAccessChecker.java b/api/src/org/apache/cloudstack/acl/APIAccessChecker.java index 3194bd11d17..a5c656d731a 100644 --- a/api/src/org/apache/cloudstack/acl/APIAccessChecker.java +++ b/api/src/org/apache/cloudstack/acl/APIAccessChecker.java @@ -16,11 +16,8 @@ // under the License. package org.apache.cloudstack.acl; -import java.util.Properties; - +import org.apache.cloudstack.acl.RoleType; import com.cloud.exception.PermissionDeniedException; -import com.cloud.user.Account; -import com.cloud.user.User; import com.cloud.utils.component.Adapter; /** @@ -28,5 +25,5 @@ import com.cloud.utils.component.Adapter; */ public interface APIAccessChecker extends Adapter { // Interface for checking access to an API for an user - boolean canAccessAPI(User user, String apiCommandName) throws PermissionDeniedException; + boolean canAccessAPI(RoleType roleType, String apiCommandName) throws PermissionDeniedException; } diff --git a/plugins/acl/static-role-based/src/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java b/plugins/acl/static-role-based/src/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java index d39f87f1048..43ca403f890 100644 --- a/plugins/acl/static-role-based/src/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java +++ b/plugins/acl/static-role-based/src/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java @@ -27,80 +27,66 @@ import javax.ejb.Local; import javax.naming.ConfigurationException; import org.apache.cloudstack.acl.APIAccessChecker; +import org.apache.cloudstack.acl.RoleType; +import static org.apache.cloudstack.acl.RoleType.*; import org.apache.log4j.Logger; import com.cloud.exception.PermissionDeniedException; import com.cloud.server.ManagementServer; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.User; import com.cloud.utils.PropertiesUtil; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.component.ComponentLocator; -import com.cloud.utils.component.Inject; 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 referring to commands in all *.properties files. - */ - +// This is the default API access checker that grab's the user's account +// based on the account type, access is granted @Local(value=APIAccessChecker.class) public class StaticRoleBasedAPIAccessChecker extends AdapterBase implements APIAccessChecker { protected static final Logger s_logger = Logger.getLogger(StaticRoleBasedAPIAccessChecker.class); - public static final short ADMIN_COMMAND = 1; - public static final short DOMAIN_ADMIN_COMMAND = 4; - public static final short RESOURCE_DOMAIN_ADMIN_COMMAND = 2; - public static final short USER_COMMAND = 8; - private static List s_userCommands = null; - private static List s_resellerCommands = null; // AKA domain-admin - private static List s_adminCommands = null; - private static List s_resourceDomainAdminCommands = null; - private static List s_allCommands = null; - - protected @Inject AccountManager _accountMgr; + private static Set s_userCommands = null; + private static Set s_resellerCommands = null; // AKA domain-admin + private static Set s_adminCommands = null; + private static Set s_resourceDomainAdminCommands = null; + private static Set s_allCommands = null; protected StaticRoleBasedAPIAccessChecker() { super(); - s_allCommands = new ArrayList(); - s_userCommands = new ArrayList(); - s_resellerCommands = new ArrayList(); - s_adminCommands = new ArrayList(); - s_resourceDomainAdminCommands = new ArrayList(); + s_allCommands = new HashSet(); + s_userCommands = new HashSet(); + s_resellerCommands = new HashSet(); + s_adminCommands = new HashSet(); + s_resourceDomainAdminCommands = new HashSet(); } @Override - public boolean canAccessAPI(User user, String apiCommandName) + public boolean canAccessAPI(RoleType roleType, String apiCommandName) throws PermissionDeniedException{ boolean commandExists = s_allCommands.contains(apiCommandName); - if(commandExists && user != null){ - Long accountId = user.getAccountId(); - Account userAccount = _accountMgr.getAccount(accountId); - short accountType = userAccount.getType(); - return isCommandAvailableForAccount(accountType, apiCommandName); + if(commandExists) { + return isCommandAvailableForAccount(roleType, apiCommandName); } return commandExists; } - private static boolean isCommandAvailableForAccount(short accountType, String commandName) { + private static boolean isCommandAvailableForAccount(RoleType roleType, String commandName) { boolean isCommandAvailable = false; - switch (accountType) { - case Account.ACCOUNT_TYPE_ADMIN: - isCommandAvailable = s_adminCommands.contains(commandName); - break; - case Account.ACCOUNT_TYPE_DOMAIN_ADMIN: - isCommandAvailable = s_resellerCommands.contains(commandName); - break; - case Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN: - isCommandAvailable = s_resourceDomainAdminCommands.contains(commandName); - break; - case Account.ACCOUNT_TYPE_NORMAL: - isCommandAvailable = s_userCommands.contains(commandName); - break; + switch (roleType) { + case Admin: + isCommandAvailable = s_adminCommands.contains(commandName); + break; + case DomainAdmin: + isCommandAvailable = s_resellerCommands.contains(commandName); + break; + case ResourceAdmin: + isCommandAvailable = s_resourceDomainAdminCommands.contains(commandName); + break; + case User: + isCommandAvailable = s_userCommands.contains(commandName); + break; } return isCommandAvailable; } @@ -157,16 +143,16 @@ public class StaticRoleBasedAPIAccessChecker extends AdapterBase implements APIA try { short cmdPermissions = Short.parseShort(mask); - if ((cmdPermissions & ADMIN_COMMAND) != 0) { + if ((cmdPermissions & Admin.getValue()) != 0) { s_adminCommands.add((String) key); } - if ((cmdPermissions & RESOURCE_DOMAIN_ADMIN_COMMAND) != 0) { + if ((cmdPermissions & ResourceAdmin.getValue()) != 0) { s_resourceDomainAdminCommands.add((String) key); } - if ((cmdPermissions & DOMAIN_ADMIN_COMMAND) != 0) { + if ((cmdPermissions & DomainAdmin.getValue()) != 0) { s_resellerCommands.add((String) key); } - if ((cmdPermissions & USER_COMMAND) != 0) { + if ((cmdPermissions & User.getValue()) != 0) { s_userCommands.add((String) key); } s_allCommands.addAll(s_adminCommands); diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index 17a2b29638b..1c1e8ca0e96 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -53,6 +53,7 @@ import javax.servlet.http.HttpSession; import com.cloud.utils.ReflectUtil; import org.apache.cloudstack.acl.APIAccessChecker; import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.*; import org.apache.cloudstack.api.command.user.account.ListAccountsCmd; import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd; @@ -790,9 +791,39 @@ public class ApiServer implements HttpRequestHandler { } private boolean isCommandAvailable(User user, String commandName) { + if (user == null) { + return false; + } + + Account account = _accountMgr.getAccount(user.getAccountId()); + if (account == null) { + return false; + } + + RoleType roleType = RoleType.Unknown; + short accountType = account.getType(); + + // Account type to role type translation + switch (accountType) { + case Account.ACCOUNT_TYPE_ADMIN: + roleType = RoleType.Admin; + break; + case Account.ACCOUNT_TYPE_DOMAIN_ADMIN: + roleType = RoleType.DomainAdmin; + break; + case Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN: + roleType = RoleType.ResourceAdmin; + break; + case Account.ACCOUNT_TYPE_NORMAL: + roleType = RoleType.User; + break; + default: + return false; + } + for (APIAccessChecker apiChecker : _apiAccessCheckers) { // Fail the checking if any checker fails to verify - if (!apiChecker.canAccessAPI(user, commandName)) + if (!apiChecker.canAccessAPI(roleType, commandName)) return false; } return true;