APIAccessChecker: Make it check based on role type and not user

Signed-off-by: Rohit Yadav <bhaisaab@apache.org>
This commit is contained in:
Rohit Yadav 2013-01-10 11:49:15 -08:00
parent c6d9877d64
commit 62a42723f9
3 changed files with 69 additions and 55 deletions

View File

@ -16,11 +16,8 @@
// under the License. // under the License.
package org.apache.cloudstack.acl; package org.apache.cloudstack.acl;
import java.util.Properties; import org.apache.cloudstack.acl.RoleType;
import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.PermissionDeniedException;
import com.cloud.user.Account;
import com.cloud.user.User;
import com.cloud.utils.component.Adapter; import com.cloud.utils.component.Adapter;
/** /**
@ -28,5 +25,5 @@ import com.cloud.utils.component.Adapter;
*/ */
public interface APIAccessChecker extends Adapter { public interface APIAccessChecker extends Adapter {
// Interface for checking access to an API for an user // 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;
} }

View File

@ -27,78 +27,64 @@ import javax.ejb.Local;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import org.apache.cloudstack.acl.APIAccessChecker; 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 org.apache.log4j.Logger;
import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.PermissionDeniedException;
import com.cloud.server.ManagementServer; 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.PropertiesUtil;
import com.cloud.utils.component.AdapterBase; import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.component.Inject;
import com.cloud.utils.component.PluggableService; import com.cloud.utils.component.PluggableService;
/* // This is the default API access checker that grab's the user's account
* This is the default API access checker that grab's the user's account // based on the account type, access is granted
* based on the account type, access is granted referring to commands in all *.properties files.
*/
@Local(value=APIAccessChecker.class) @Local(value=APIAccessChecker.class)
public class StaticRoleBasedAPIAccessChecker extends AdapterBase implements APIAccessChecker { public class StaticRoleBasedAPIAccessChecker extends AdapterBase implements APIAccessChecker {
protected static final Logger s_logger = Logger.getLogger(StaticRoleBasedAPIAccessChecker.class); protected static final Logger s_logger = Logger.getLogger(StaticRoleBasedAPIAccessChecker.class);
public static final short ADMIN_COMMAND = 1; private static Set<String> s_userCommands = null;
public static final short DOMAIN_ADMIN_COMMAND = 4; private static Set<String> s_resellerCommands = null; // AKA domain-admin
public static final short RESOURCE_DOMAIN_ADMIN_COMMAND = 2; private static Set<String> s_adminCommands = null;
public static final short USER_COMMAND = 8; private static Set<String> s_resourceDomainAdminCommands = null;
private static List<String> s_userCommands = null; private static Set<String> s_allCommands = null;
private static List<String> s_resellerCommands = null; // AKA domain-admin
private static List<String> s_adminCommands = null;
private static List<String> s_resourceDomainAdminCommands = null;
private static List<String> s_allCommands = null;
protected @Inject AccountManager _accountMgr;
protected StaticRoleBasedAPIAccessChecker() { protected StaticRoleBasedAPIAccessChecker() {
super(); super();
s_allCommands = new ArrayList<String>(); s_allCommands = new HashSet<String>();
s_userCommands = new ArrayList<String>(); s_userCommands = new HashSet<String>();
s_resellerCommands = new ArrayList<String>(); s_resellerCommands = new HashSet<String>();
s_adminCommands = new ArrayList<String>(); s_adminCommands = new HashSet<String>();
s_resourceDomainAdminCommands = new ArrayList<String>(); s_resourceDomainAdminCommands = new HashSet<String>();
} }
@Override @Override
public boolean canAccessAPI(User user, String apiCommandName) public boolean canAccessAPI(RoleType roleType, String apiCommandName)
throws PermissionDeniedException{ throws PermissionDeniedException{
boolean commandExists = s_allCommands.contains(apiCommandName); boolean commandExists = s_allCommands.contains(apiCommandName);
if(commandExists && user != null){ if(commandExists) {
Long accountId = user.getAccountId(); return isCommandAvailableForAccount(roleType, apiCommandName);
Account userAccount = _accountMgr.getAccount(accountId);
short accountType = userAccount.getType();
return isCommandAvailableForAccount(accountType, apiCommandName);
} }
return commandExists; return commandExists;
} }
private static boolean isCommandAvailableForAccount(short accountType, String commandName) { private static boolean isCommandAvailableForAccount(RoleType roleType, String commandName) {
boolean isCommandAvailable = false; boolean isCommandAvailable = false;
switch (accountType) { switch (roleType) {
case Account.ACCOUNT_TYPE_ADMIN: case Admin:
isCommandAvailable = s_adminCommands.contains(commandName); isCommandAvailable = s_adminCommands.contains(commandName);
break; break;
case Account.ACCOUNT_TYPE_DOMAIN_ADMIN: case DomainAdmin:
isCommandAvailable = s_resellerCommands.contains(commandName); isCommandAvailable = s_resellerCommands.contains(commandName);
break; break;
case Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN: case ResourceAdmin:
isCommandAvailable = s_resourceDomainAdminCommands.contains(commandName); isCommandAvailable = s_resourceDomainAdminCommands.contains(commandName);
break; break;
case Account.ACCOUNT_TYPE_NORMAL: case User:
isCommandAvailable = s_userCommands.contains(commandName); isCommandAvailable = s_userCommands.contains(commandName);
break; break;
} }
@ -157,16 +143,16 @@ public class StaticRoleBasedAPIAccessChecker extends AdapterBase implements APIA
try { try {
short cmdPermissions = Short.parseShort(mask); short cmdPermissions = Short.parseShort(mask);
if ((cmdPermissions & ADMIN_COMMAND) != 0) { if ((cmdPermissions & Admin.getValue()) != 0) {
s_adminCommands.add((String) key); s_adminCommands.add((String) key);
} }
if ((cmdPermissions & RESOURCE_DOMAIN_ADMIN_COMMAND) != 0) { if ((cmdPermissions & ResourceAdmin.getValue()) != 0) {
s_resourceDomainAdminCommands.add((String) key); s_resourceDomainAdminCommands.add((String) key);
} }
if ((cmdPermissions & DOMAIN_ADMIN_COMMAND) != 0) { if ((cmdPermissions & DomainAdmin.getValue()) != 0) {
s_resellerCommands.add((String) key); s_resellerCommands.add((String) key);
} }
if ((cmdPermissions & USER_COMMAND) != 0) { if ((cmdPermissions & User.getValue()) != 0) {
s_userCommands.add((String) key); s_userCommands.add((String) key);
} }
s_allCommands.addAll(s_adminCommands); s_allCommands.addAll(s_adminCommands);

View File

@ -53,6 +53,7 @@ import javax.servlet.http.HttpSession;
import com.cloud.utils.ReflectUtil; import com.cloud.utils.ReflectUtil;
import org.apache.cloudstack.acl.APIAccessChecker; import org.apache.cloudstack.acl.APIAccessChecker;
import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.*; import org.apache.cloudstack.api.*;
import org.apache.cloudstack.api.command.user.account.ListAccountsCmd; import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd; 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) { 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) { for (APIAccessChecker apiChecker : _apiAccessCheckers) {
// Fail the checking if any checker fails to verify // Fail the checking if any checker fails to verify
if (!apiChecker.canAccessAPI(user, commandName)) if (!apiChecker.canAccessAPI(roleType, commandName))
return false; return false;
} }
return true; return true;