Updated Branches: refs/heads/api_refactoring d23585916 -> bc8e0af0a
plugin: ACL Static Role Based api access checker Signed-off-by: Rohit Yadav <bhais...@apache.org> Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/bc8e0af0 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/bc8e0af0 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/bc8e0af0 Branch: refs/heads/api_refactoring Commit: bc8e0af0a3eff4d3e73796ffd4a8481b6f8c2f6e Parents: d235859 Author: Rohit Yadav <bhais...@apache.org> Authored: Wed Jan 2 16:56:48 2013 -0800 Committer: Rohit Yadav <bhais...@apache.org> Committed: Wed Jan 2 17:06:19 2013 -0800 ---------------------------------------------------------------------- client/pom.xml | 5 + client/tomcatconf/components.xml.in | 2 +- plugins/acl/static-role-based/pom.xml | 32 +++ .../acl/StaticRoleBasedAPIAccessChecker.java | 192 +++++++++++++++ plugins/pom.xml | 1 + .../cloud/acl/StaticRoleBasedAPIAccessChecker.java | 188 -------------- 6 files changed, 231 insertions(+), 189 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bc8e0af0/client/pom.xml ---------------------------------------------------------------------- diff --git a/client/pom.xml b/client/pom.xml index 7707706..897aa2c 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -27,6 +27,11 @@ </dependency> <dependency> <groupId>org.apache.cloudstack</groupId> + <artifactId>cloud-plugin-acl-static-role-based</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.cloudstack</groupId> <artifactId>cloud-plugin-user-authenticator-ldap</artifactId> <version>${project.version}</version> </dependency> http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bc8e0af0/client/tomcatconf/components.xml.in ---------------------------------------------------------------------- diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index 990bf6a..ef6274e 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -54,7 +54,7 @@ under the License. <param name="premium">true</param> </dao> <adapters key="com.cloud.acl.APIAccessChecker"> - <adapter name="StaticRoleBasedAPIAccessChecker" class="com.cloud.acl.StaticRoleBasedAPIAccessChecker"/> + <adapter name="StaticRoleBasedAPIAccessChecker" class="org.apache.cloudstack.acl.StaticRoleBasedAPIAccessChecker"/> </adapters> <adapters key="com.cloud.agent.manager.allocator.HostAllocator"> <adapter name="FirstFitRouting" class="com.cloud.agent.manager.allocator.impl.FirstFitRoutingAllocator"/> http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bc8e0af0/plugins/acl/static-role-based/pom.xml ---------------------------------------------------------------------- diff --git a/plugins/acl/static-role-based/pom.xml b/plugins/acl/static-role-based/pom.xml new file mode 100644 index 0000000..a2e8d05 --- /dev/null +++ b/plugins/acl/static-role-based/pom.xml @@ -0,0 +1,32 @@ +<!-- + 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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 + http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>cloud-plugin-acl-static-role-based</artifactId> + <name>Apache CloudStack Plugin - ACL Static Role Based</name> + <parent> + <groupId>org.apache.cloudstack</groupId> + <artifactId>cloudstack-plugins</artifactId> + <version>4.1.0-SNAPSHOT</version> + <relativePath>../../pom.xml</relativePath> + </parent> +</project> http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bc8e0af0/plugins/acl/static-role-based/src/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java ---------------------------------------------------------------------- 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 new file mode 100644 index 0000000..5a7af55 --- /dev/null +++ b/plugins/acl/static-role-based/src/org/apache/cloudstack/acl/StaticRoleBasedAPIAccessChecker.java @@ -0,0 +1,192 @@ +// 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.acl; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.*; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import com.cloud.acl.APIAccessChecker; +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. + */ + +@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<String> s_userCommands = 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; + private Properties _apiCommands = null; + + protected @Inject AccountManager _accountMgr; + + protected StaticRoleBasedAPIAccessChecker() { + super(); + s_allCommands = new ArrayList<String>(); + s_userCommands = new ArrayList<String>(); + s_resellerCommands = new ArrayList<String>(); + s_adminCommands = new ArrayList<String>(); + s_resourceDomainAdminCommands = new ArrayList<String>(); + } + + @Override + public boolean canAccessAPI(User user, 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); + } + + return commandExists; + } + + @Override + public Properties getApiCommands() { + return _apiCommands; + } + + private static boolean isCommandAvailableForAccount(short accountType, 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; + } + return isCommandAvailable; + } + + @Override + public boolean configure(String name, Map<String, Object> params) throws ConfigurationException { + super.configure(name, params); + + // Read command properties files to build the static map per role. + ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); + List<PluggableService> services = locator.getAllPluggableServices(); + services.add((PluggableService) ComponentLocator.getComponent(ManagementServer.Name)); + + List<String> configFiles = new ArrayList<String>(); + for (PluggableService service : services) { + configFiles.addAll(Arrays.asList(service.getPropertiesFiles())); + } + + processConfigFiles(configFiles); + return true; + } + + private void processConfigFiles(List<String> configFiles) { + if (_apiCommands == null) + _apiCommands = new Properties(); + + Properties preProcessedCommands = new Properties(); + + for (String configFile : configFiles) { + File commandsFile = PropertiesUtil.findConfigFile(configFile); + if (commandsFile != null) { + try { + preProcessedCommands.load(new FileInputStream(commandsFile)); + } catch (FileNotFoundException fnfex) { + // in case of a file within a jar in classpath, try to open stream using url + InputStream stream = PropertiesUtil.openStreamFromURL(configFile); + if (stream != null) { + try { + preProcessedCommands.load(stream); + } catch (IOException e) { + s_logger.error("IO Exception, unable to find properties file:", fnfex); + } + } else { + s_logger.error("Unable to find properites file", fnfex); + } + } catch (IOException ioe) { + s_logger.error("IO Exception loading properties file", ioe); + } + } + } + + for (Object key : preProcessedCommands.keySet()) { + String preProcessedCommand = preProcessedCommands.getProperty((String) key); + String[] commandParts = preProcessedCommand.split(";"); + _apiCommands.setProperty(key.toString(), commandParts[0]); + + if (commandParts.length > 1) { + try { + short cmdPermissions = Short.parseShort(commandParts[1]); + if ((cmdPermissions & ADMIN_COMMAND) != 0) { + s_adminCommands.add((String) key); + } + if ((cmdPermissions & RESOURCE_DOMAIN_ADMIN_COMMAND) != 0) { + s_resourceDomainAdminCommands.add((String) key); + } + if ((cmdPermissions & DOMAIN_ADMIN_COMMAND) != 0) { + s_resellerCommands.add((String) key); + } + if ((cmdPermissions & USER_COMMAND) != 0) { + s_userCommands.add((String) key); + } + s_allCommands.addAll(s_adminCommands); + s_allCommands.addAll(s_resourceDomainAdminCommands); + s_allCommands.addAll(s_userCommands); + s_allCommands.addAll(s_resellerCommands); + } catch (NumberFormatException nfe) { + s_logger.info("Malformed command.properties permissions value, key = " + key + ", value = " + preProcessedCommand); + } + } + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bc8e0af0/plugins/pom.xml ---------------------------------------------------------------------- diff --git a/plugins/pom.xml b/plugins/pom.xml index 820e76f..f0589a1 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -32,6 +32,7 @@ <testSourceDirectory>test</testSourceDirectory> </build> <modules> + <module>acl/static-role-based</module> <module>deployment-planners/user-concentrated-pod</module> <module>deployment-planners/user-dispersing</module> <module>host-allocators/random</module> http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/bc8e0af0/server/src/com/cloud/acl/StaticRoleBasedAPIAccessChecker.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/acl/StaticRoleBasedAPIAccessChecker.java b/server/src/com/cloud/acl/StaticRoleBasedAPIAccessChecker.java deleted file mode 100644 index 816b0de..0000000 --- a/server/src/com/cloud/acl/StaticRoleBasedAPIAccessChecker.java +++ /dev/null @@ -1,188 +0,0 @@ -// 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 com.cloud.acl; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.*; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -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. - */ - -@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<String> s_userCommands = 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; - private Properties _apiCommands = null; - - protected @Inject AccountManager _accountMgr; - - protected StaticRoleBasedAPIAccessChecker() { - super(); - s_allCommands = new ArrayList<String>(); - s_userCommands = new ArrayList<String>(); - s_resellerCommands = new ArrayList<String>(); - s_adminCommands = new ArrayList<String>(); - s_resourceDomainAdminCommands = new ArrayList<String>(); - } - - @Override - public boolean canAccessAPI(User user, 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); - } - - return commandExists; - } - - @Override - public Properties getApiCommands() { - return _apiCommands; - } - - private static boolean isCommandAvailableForAccount(short accountType, 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; - } - return isCommandAvailable; - } - - @Override - public boolean configure(String name, Map<String, Object> params) throws ConfigurationException { - super.configure(name, params); - - // Read command properties files to build the static map per role. - ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); - List<PluggableService> services = locator.getAllPluggableServices(); - services.add((PluggableService) ComponentLocator.getComponent(ManagementServer.Name)); - - List<String> configFiles = new ArrayList<String>(); - for (PluggableService service : services) { - configFiles.addAll(Arrays.asList(service.getPropertiesFiles())); - } - - processConfigFiles(configFiles); - return true; - } - - private void processConfigFiles(List<String> configFiles) { - try { - if (_apiCommands == null) - _apiCommands = new Properties(); - - Properties preProcessedCommands = new Properties(); - for (String configFile : configFiles) { - File commandsFile = PropertiesUtil.findConfigFile(configFile); - if (commandsFile != null) { - try { - preProcessedCommands.load(new FileInputStream(commandsFile)); - } catch (FileNotFoundException fnfex) { - // in case of a file within a jar in classpath, try to open stream using url - InputStream stream = PropertiesUtil.openStreamFromURL(configFile); - if (stream != null) { - preProcessedCommands.load(stream); - } else { - s_logger.error("Unable to find properites file", fnfex); - } - } - } - } - for (Object key : preProcessedCommands.keySet()) { - String preProcessedCommand = preProcessedCommands.getProperty((String) key); - String[] commandParts = preProcessedCommand.split(";"); - _apiCommands.setProperty(key.toString(), commandParts[0]); - - if (commandParts.length > 1) { - try { - short cmdPermissions = Short.parseShort(commandParts[1]); - if ((cmdPermissions & ADMIN_COMMAND) != 0) { - s_adminCommands.add((String) key); - } - if ((cmdPermissions & RESOURCE_DOMAIN_ADMIN_COMMAND) != 0) { - s_resourceDomainAdminCommands.add((String) key); - } - if ((cmdPermissions & DOMAIN_ADMIN_COMMAND) != 0) { - s_resellerCommands.add((String) key); - } - if ((cmdPermissions & USER_COMMAND) != 0) { - s_userCommands.add((String) key); - } - s_allCommands.addAll(s_adminCommands); - s_allCommands.addAll(s_resourceDomainAdminCommands); - s_allCommands.addAll(s_userCommands); - s_allCommands.addAll(s_resellerCommands); - } catch (NumberFormatException nfe) { - s_logger.info("Malformed command.properties permissions value, key = " + key + ", value = " + preProcessedCommand); - } - } - } - } catch (FileNotFoundException fnfex) { - s_logger.error("Unable to find properties file", fnfex); - } catch (IOException ioex) { - s_logger.error("IO Exception loading properties file", ioex); - } - } -}