Author: rgodfrey Date: Thu Jun 23 21:05:10 2016 New Revision: 1750020 URL: http://svn.apache.org/viewvc?rev=1750020&view=rev Log: QPID-7318 : Refactor ACL implementation to separate concept of ruls based ACL from parsing file
Added: qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclFileParser.java - copied, changed from r1750019, qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleBasedAccessControl.java - copied, changed from r1750019, qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControl.java qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSetCreator.java (with props) qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclFileParserTest.java - copied, changed from r1750019, qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/PlainConfigurationTest.java qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/RuleBasedAccessControlTest.java - copied, changed from r1750019, qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlTest.java qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/RuleSetTest.java - copied, changed from r1750019, qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java Removed: qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ConfigurationFile.java qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControl.java qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/PlainConfigurationTest.java qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlTest.java qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/AccessControl.java qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderFactoryTest.java Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/AccessControl.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/AccessControl.java?rev=1750020&r1=1750019&r2=1750020&view=diff ============================================================================== --- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/AccessControl.java (original) +++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/security/AccessControl.java Thu Jun 23 21:05:10 2016 @@ -38,26 +38,4 @@ public interface AccessControl */ Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties); - /** - * Called to open any resources required by the implementation. - */ - void open(); - - boolean validate(); - - /** - * Called to close any resources required by the implementation. - */ - void close(); - - /** - * Called when deleting to allow clearing any resources used by the implementation. - */ - void onDelete(); - - /** - * Called when first creating (but not when recovering after startup) to allow - * creating any resources required by the implementation. - */ - void onCreate(); } Copied: qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclFileParser.java (from r1750019, qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java) URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclFileParser.java?p2=qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclFileParser.java&p1=qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java&r1=1750019&r2=1750020&rev=1750020&view=diff ============================================================================== --- qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java (original) +++ qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclFileParser.java Thu Jun 23 21:05:10 2016 @@ -21,10 +21,13 @@ package org.apache.qpid.server.security.access.config; import java.io.BufferedReader; -import java.io.FileNotFoundException; +import java.io.File; import java.io.IOException; +import java.io.InputStreamReader; import java.io.Reader; import java.io.StreamTokenizer; +import java.net.MalformedURLException; +import java.net.URL; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -36,81 +39,112 @@ import org.slf4j.LoggerFactory; import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.logging.EventLoggerProvider; +import org.apache.qpid.server.security.Result; import org.apache.qpid.server.security.access.ObjectType; import org.apache.qpid.server.security.access.Operation; import org.apache.qpid.server.security.access.Permission; -public class PlainConfiguration implements ConfigurationFile +public final class AclFileParser { - private static final Logger _logger = LoggerFactory.getLogger(PlainConfiguration.class); + private static final Logger _logger = LoggerFactory.getLogger(AclFileParser.class); + private static final String DEFAULT_ALLOW = "defaultallow"; + private static final String DEFAULT_DENY = "defaultdeny"; - public static final Character COMMENT = '#'; - public static final Character CONTINUATION = '\\'; + private static final Character COMMENT = '#'; + private static final Character CONTINUATION = '\\'; public static final String ACL = "acl"; - public static final String CONFIG = "config"; + private static final String CONFIG = "config"; - static final String UNRECOGNISED_INITIAL_MSG = "Unrecognised initial token '%s' at line %d"; + private static final String UNRECOGNISED_INITIAL_MSG = "Unrecognised initial token '%s' at line %d"; static final String NOT_ENOUGH_TOKENS_MSG = "Not enough tokens at line %d"; - static final String NUMBER_NOT_ALLOWED_MSG = "Number not allowed before '%s' at line %d"; - static final String CANNOT_LOAD_MSG = "Cannot load config file %s"; - static final String CANNOT_CLOSE_MSG = "Cannot close config file %s"; + private static final String NUMBER_NOT_ALLOWED_MSG = "Number not allowed before '%s' at line %d"; + private static final String CANNOT_LOAD_MSG = "I/O Error while reading configuration"; static final String PREMATURE_CONTINUATION_MSG = "Premature continuation character at line %d"; - static final String PREMATURE_EOF_MSG = "Premature end of file reached at line %d"; + private static final String PREMATURE_EOF_MSG = "Premature end of file reached at line %d"; static final String PARSE_TOKEN_FAILED_MSG = "Failed to parse token at line %d"; - static final String CONFIG_NOT_FOUND_MSG = "Cannot find config file %s"; static final String NOT_ENOUGH_ACL_MSG = "Not enough data for an acl at line %d"; - static final String NOT_ENOUGH_CONFIG_MSG = "Not enough data for config at line %d"; - static final String BAD_ACL_RULE_NUMBER_MSG = "Invalid rule number at line %d"; + private static final String NOT_ENOUGH_CONFIG_MSG = "Not enough data for config at line %d"; + private static final String BAD_ACL_RULE_NUMBER_MSG = "Invalid rule number at line %d"; static final String PROPERTY_KEY_ONLY_MSG = "Incomplete property (key only) at line %d"; static final String PROPERTY_NO_EQUALS_MSG = "Incomplete property (no equals) at line %d"; static final String PROPERTY_NO_VALUE_MSG = "Incomplete property (no value) at line %d"; - private final EventLoggerProvider _eventLogger; - private final String _name; - private StreamTokenizer _st; - private RuleSet _config; - public PlainConfiguration(String name, final EventLoggerProvider eventLogger) + private AclFileParser() { - _eventLogger = eventLogger; - _name = name; } - @Override - public RuleSet load(final Reader configReader) + private static Reader getReaderFromURLString(String urlString) { - _config = new RuleSet(_eventLogger); + try + { + URL url; + + try + { + url = new URL(urlString); + } + catch (MalformedURLException e) + { + File file = new File(urlString); + try + { + url = file.toURI().toURL(); + } + catch (MalformedURLException notAFile) + { + throw new IllegalConfigurationException("Cannot convert " + urlString + " to a readable resource", notAFile); + } + + } + return new InputStreamReader(url.openStream()); + } + catch (IOException e) + { + throw new IllegalConfigurationException("Cannot convert " + urlString + " to a readable resource", e); + } + } + + public static RuleSet parse(String name, EventLoggerProvider eventLoggerProvider) + { + return parse(getReaderFromURLString(name), eventLoggerProvider); + } + + public static RuleSet parse(final Reader configReader, EventLoggerProvider eventLogger) + { + RuleSetCreator ruleSetCreator = new RuleSetCreator(); + int line = 0; try(Reader fileReader = configReader) { _logger.debug("About to load ACL file"); + StreamTokenizer tokenizer = new StreamTokenizer(new BufferedReader(fileReader)); + tokenizer.resetSyntax(); // setup the tokenizer - _st = new StreamTokenizer(new BufferedReader(fileReader)); - _st.resetSyntax(); // setup the tokenizer - - _st.commentChar(COMMENT); // single line comments - _st.eolIsSignificant(true); // return EOL as a token - _st.ordinaryChar('='); // equals is a token - _st.ordinaryChar(CONTINUATION); // continuation character (when followed by EOL) - _st.quoteChar('"'); // double quote - _st.quoteChar('\''); // single quote - _st.whitespaceChars('\u0000', '\u0020'); // whitespace (to be ignored) TODO properly - _st.wordChars('a', 'z'); // unquoted token characters [a-z] - _st.wordChars('A', 'Z'); // [A-Z] - _st.wordChars('0', '9'); // [0-9] - _st.wordChars('_', '_'); // underscore - _st.wordChars('-', '-'); // dash - _st.wordChars('.', '.'); // dot - _st.wordChars('*', '*'); // star - _st.wordChars('@', '@'); // at - _st.wordChars(':', ':'); // colon + tokenizer.commentChar(COMMENT); // single line comments + tokenizer.eolIsSignificant(true); // return EOL as a token + tokenizer.ordinaryChar('='); // equals is a token + tokenizer.ordinaryChar(CONTINUATION); // continuation character (when followed by EOL) + tokenizer.quoteChar('"'); // double quote + tokenizer.quoteChar('\''); // single quote + tokenizer.whitespaceChars('\u0000', '\u0020'); // whitespace (to be ignored) TODO properly + tokenizer.wordChars('a', 'z'); // unquoted token characters [a-z] + tokenizer.wordChars('A', 'Z'); // [A-Z] + tokenizer.wordChars('0', '9'); // [0-9] + tokenizer.wordChars('_', '_'); // underscore + tokenizer.wordChars('-', '-'); // dash + tokenizer.wordChars('.', '.'); // dot + tokenizer.wordChars('*', '*'); // star + tokenizer.wordChars('@', '@'); // at + tokenizer.wordChars(':', ':'); // colon // parse the acl file lines Stack<String> stack = new Stack<String>(); int current; do { - current = _st.nextToken(); + current = tokenizer.nextToken(); + line = tokenizer.lineno()-1; switch (current) { case StreamTokenizer.TT_EOF: @@ -125,7 +159,7 @@ public class PlainConfiguration implemen stack.removeElementAt(0); if (stack.isEmpty()) { - throw new IllegalConfigurationException(String.format(NOT_ENOUGH_TOKENS_MSG, getLine())); + throw new IllegalConfigurationException(String.format(NOT_ENOUGH_TOKENS_MSG, line)); } // check for and parse optional initial number for ACL lines @@ -140,123 +174,133 @@ public class PlainConfiguration implemen if (ACL.equalsIgnoreCase(first)) { - parseAcl(number, stack); + parseAcl(number, stack, ruleSetCreator, line); } else if (number == null) { if("GROUP".equalsIgnoreCase(first)) { - throw new IllegalConfigurationException(String.format("GROUP keyword not supported at line %d. Groups should defined via a Group Provider, not in the ACL file.", getLine())); + throw new IllegalConfigurationException(String.format("GROUP keyword not supported at " + + "line %d. Groups should defined " + + "via a Group Provider, not in " + + "the ACL file.", + line)); } else if (CONFIG.equalsIgnoreCase(first)) { - parseConfig(stack); + parseConfig(stack, ruleSetCreator, line); } else { - throw new IllegalConfigurationException(String.format(UNRECOGNISED_INITIAL_MSG, first, getLine())); + throw new IllegalConfigurationException(String.format(UNRECOGNISED_INITIAL_MSG, first, line)); } } else { - throw new IllegalConfigurationException(String.format(NUMBER_NOT_ALLOWED_MSG, first, getLine())); + throw new IllegalConfigurationException(String.format(NUMBER_NOT_ALLOWED_MSG, first, line)); } // reset stack, start next line stack.clear(); break; case StreamTokenizer.TT_NUMBER: - stack.push(Integer.toString(Double.valueOf(_st.nval).intValue())); + stack.push(Integer.toString(Double.valueOf(tokenizer.nval).intValue())); break; case StreamTokenizer.TT_WORD: - stack.push(_st.sval); // token + stack.push(tokenizer.sval); // token break; default: - if (_st.ttype == CONTINUATION) + if (tokenizer.ttype == CONTINUATION) { - int next = _st.nextToken(); + int next = tokenizer.nextToken(); + line = tokenizer.lineno()-1; if (next == StreamTokenizer.TT_EOL) { break; // continue reading next line } // invalid location for continuation character (add one to line because we ate the EOL) - throw new IllegalConfigurationException(String.format(PREMATURE_CONTINUATION_MSG, getLine() + 1)); + throw new IllegalConfigurationException(String.format(PREMATURE_CONTINUATION_MSG, line + 1)); } - else if (_st.ttype == '\'' || _st.ttype == '"') + else if (tokenizer.ttype == '\'' || tokenizer.ttype == '"') { - stack.push(_st.sval); // quoted token + stack.push(tokenizer.sval); // quoted token } else { - stack.push(Character.toString((char) _st.ttype)); // single character + stack.push(Character.toString((char) tokenizer.ttype)); // single character } } } while (current != StreamTokenizer.TT_EOF); if (!stack.isEmpty()) { - throw new IllegalConfigurationException(String.format(PREMATURE_EOF_MSG, getLine())); + throw new IllegalConfigurationException(String.format(PREMATURE_EOF_MSG, line)); } } catch (IllegalArgumentException iae) { - throw new IllegalConfigurationException(String.format(PARSE_TOKEN_FAILED_MSG, getLine()), iae); - } - catch (FileNotFoundException fnfe) - { - throw new IllegalConfigurationException(String.format(CONFIG_NOT_FOUND_MSG, _name), fnfe); + throw new IllegalConfigurationException(String.format(PARSE_TOKEN_FAILED_MSG, line), iae); } catch (IOException ioe) { - throw new IllegalConfigurationException(String.format(CANNOT_LOAD_MSG, _name), ioe); + throw new IllegalConfigurationException(CANNOT_LOAD_MSG, ioe); } - - return _config; + return ruleSetCreator.createRuleSet(eventLogger); } - private void parseAcl(Integer number, List<String> args) + private static void parseAcl(Integer number, List<String> args, final RuleSetCreator ruleSetCreator, final int line) { if (args.size() < 3) { - throw new IllegalConfigurationException(String.format(NOT_ENOUGH_ACL_MSG, getLine())); + throw new IllegalConfigurationException(String.format(NOT_ENOUGH_ACL_MSG, line)); } Permission permission = Permission.parse(args.get(0)); String identity = args.get(1); Operation operation = Operation.parse(args.get(2)); - if (number != null && !getConfiguration().isValidNumber(number)) + if (number != null && !ruleSetCreator.isValidNumber(number)) { - throw new IllegalConfigurationException(String.format(BAD_ACL_RULE_NUMBER_MSG, getLine())); + throw new IllegalConfigurationException(String.format(BAD_ACL_RULE_NUMBER_MSG, line)); } if (args.size() == 3) { - getConfiguration().grant(number, identity, permission, operation); + ruleSetCreator.grant(number, identity, permission, operation); } else { ObjectType object = ObjectType.parse(args.get(3)); - AclRulePredicates predicates = toRulePredicates(args.subList(4, args.size())); + AclRulePredicates predicates = toRulePredicates(args.subList(4, args.size()), line); - getConfiguration().grant(number, identity, permission, operation, object, predicates); + ruleSetCreator.grant(number, identity, permission, operation, object, predicates); } } - private void parseConfig(List<String> args) + private static void parseConfig(List<String> args, final RuleSetCreator ruleSetCreator, final int line) { if (args.size() < 3) { - throw new IllegalConfigurationException(String.format(NOT_ENOUGH_CONFIG_MSG, getLine())); + throw new IllegalConfigurationException(String.format(NOT_ENOUGH_CONFIG_MSG, line)); } - Map<String, Boolean> properties = toPluginProperties(args); + Map<String, Boolean> properties = toPluginProperties(args, line); + + + + if (Boolean.TRUE.equals(properties.get(DEFAULT_ALLOW))) + { + ruleSetCreator.setDefaultResult(Result.ALLOWED); + } + if (Boolean.TRUE.equals(properties.get(DEFAULT_DENY))) + { + ruleSetCreator.setDefaultResult(Result.DENIED); + } - getConfiguration().configure(properties); } - private AclRulePredicates toRulePredicates(List<String> args) + private static AclRulePredicates toRulePredicates(List<String> args, final int line) { AclRulePredicates predicates = new AclRulePredicates(); Iterator<String> i = args.iterator(); @@ -265,15 +309,15 @@ public class PlainConfiguration implemen String key = i.next(); if (!i.hasNext()) { - throw new IllegalConfigurationException(String.format(PROPERTY_KEY_ONLY_MSG, getLine())); + throw new IllegalConfigurationException(String.format(PROPERTY_KEY_ONLY_MSG, line)); } if (!"=".equals(i.next())) { - throw new IllegalConfigurationException(String.format(PROPERTY_NO_EQUALS_MSG, getLine())); + throw new IllegalConfigurationException(String.format(PROPERTY_NO_EQUALS_MSG, line)); } if (!i.hasNext()) { - throw new IllegalConfigurationException(String.format(PROPERTY_NO_VALUE_MSG, getLine())); + throw new IllegalConfigurationException(String.format(PROPERTY_NO_VALUE_MSG, line)); } String value = i.next(); @@ -283,7 +327,7 @@ public class PlainConfiguration implemen } /** Converts a {@link List} of "name", "=", "value" tokens into a {@link Map}. */ - protected Map<String, Boolean> toPluginProperties(List<String> args) + private static Map<String, Boolean> toPluginProperties(List<String> args, final int line) { Map<String, Boolean> properties = new HashMap<String, Boolean>(); Iterator<String> i = args.iterator(); @@ -292,15 +336,15 @@ public class PlainConfiguration implemen String key = i.next().toLowerCase(); if (!i.hasNext()) { - throw new IllegalConfigurationException(String.format(PROPERTY_KEY_ONLY_MSG, getLine())); + throw new IllegalConfigurationException(String.format(PROPERTY_KEY_ONLY_MSG, line)); } if (!"=".equals(i.next())) { - throw new IllegalConfigurationException(String.format(PROPERTY_NO_EQUALS_MSG, getLine())); + throw new IllegalConfigurationException(String.format(PROPERTY_NO_EQUALS_MSG, line)); } if (!i.hasNext()) { - throw new IllegalConfigurationException(String.format(PROPERTY_NO_VALUE_MSG, getLine())); + throw new IllegalConfigurationException(String.format(PROPERTY_NO_VALUE_MSG, line)); } // parse property value and save @@ -310,14 +354,9 @@ public class PlainConfiguration implemen return properties; } - protected int getLine() - { - return _st.lineno() - 1; - } - - public RuleSet getConfiguration() + private static int getLine(final StreamTokenizer tokenizer) { - return _config; + return tokenizer.lineno() - 1; } } Modified: qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java?rev=1750020&r1=1750019&r2=1750020&view=diff ============================================================================== --- qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java (original) +++ qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java Thu Jun 23 21:05:10 2016 @@ -28,58 +28,20 @@ import org.apache.qpid.server.security.a * A rule consists of {@link Permission} for a particular identity to perform an {@link Action}. The identity * may be either a user or a group. */ -public class Rule +class Rule { /** String indicating all identified. */ public static final String ALL = "all"; - private Integer _number; - private String _identity; - private AclAction _action; - private Permission _permission; - private Boolean _enabled = Boolean.TRUE; - - public Rule(Integer number, String identity, AclAction action, Permission permission) - { - setNumber(number); - setIdentity(identity); - setAction(action); - setPermission(permission); - } + private final String _identity; + private final AclAction _action; + private final Permission _permission; public Rule(String identity, AclAction action, Permission permission) { - this(null, identity, action, permission); - } - - public boolean isEnabled() - { - return _enabled; - } - - public void setEnabled(boolean enabled) - { - _enabled = enabled; - } - - public void enable() - { - _enabled = Boolean.TRUE; - } - - public void disable() - { - _enabled = Boolean.FALSE; - } - - public Integer getNumber() - { - return _number; - } - - public void setNumber(Integer number) - { - _number = number; + _identity = identity; + _action = action; + _permission = permission; } public String getIdentity() @@ -87,11 +49,6 @@ public class Rule return _identity; } - public void setIdentity(String identity) - { - _identity = identity; - } - public Action getAction() { return _action.getAction(); @@ -102,21 +59,11 @@ public class Rule return _action; } - public void setAction(AclAction action) - { - _action = action; - } - public Permission getPermission() { return _permission; } - public void setPermission(Permission permission) - { - _permission = permission; - } - @Override public boolean equals(final Object o) { @@ -131,10 +78,6 @@ public class Rule final Rule rule = (Rule) o; - if (getNumber() != null ? !getNumber().equals(rule.getNumber()) : rule.getNumber() != null) - { - return false; - } if (getIdentity() != null ? !getIdentity().equals(rule.getIdentity()) : rule.getIdentity() != null) { return false; @@ -150,8 +93,7 @@ public class Rule @Override public int hashCode() { - int result = getNumber() != null ? getNumber().hashCode() : 0; - result = 31 * result + (getIdentity() != null ? getIdentity().hashCode() : 0); + int result = (getIdentity() != null ? getIdentity().hashCode() : 0); result = 31 * result + (getAction() != null ? getAction().hashCode() : 0); result = 31 * result + (getPermission() != null ? getPermission().hashCode() : 0); return result; @@ -161,11 +103,9 @@ public class Rule public String toString() { return "Rule[" + - "#=" + _number + - ", identity='" + _identity + '\'' + + "identity='" + _identity + '\'' + ", action=" + _action + ", permission=" + _permission + - ", enabled=" + _enabled + ']'; } Copied: qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleBasedAccessControl.java (from r1750019, qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControl.java) URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleBasedAccessControl.java?p2=qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleBasedAccessControl.java&p1=qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControl.java&r1=1750019&r2=1750020&rev=1750020&view=diff ============================================================================== --- qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControl.java (original) +++ qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleBasedAccessControl.java Thu Jun 23 21:05:10 2016 @@ -18,17 +18,11 @@ * under the License. * */ -package org.apache.qpid.server.security.access.plugins; +package org.apache.qpid.server.security.access.config; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; import java.net.InetAddress; import java.net.InetSocketAddress; -import java.net.MalformedURLException; import java.net.SocketAddress; -import java.net.URL; import java.security.AccessController; import java.util.Set; @@ -37,116 +31,22 @@ import javax.security.auth.Subject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.connection.ConnectionPrincipal; -import org.apache.qpid.server.logging.EventLoggerProvider; import org.apache.qpid.server.security.AccessControl; import org.apache.qpid.server.security.Result; import org.apache.qpid.server.security.access.ObjectProperties; import org.apache.qpid.server.security.access.ObjectType; import org.apache.qpid.server.security.access.Operation; -import org.apache.qpid.server.security.access.config.ConfigurationFile; -import org.apache.qpid.server.security.access.config.PlainConfiguration; -import org.apache.qpid.server.security.access.config.RuleSet; -public class DefaultAccessControl implements AccessControl +public class RuleBasedAccessControl implements AccessControl { - private static final Logger _logger = LoggerFactory.getLogger(DefaultAccessControl.class); - private final String _fileName; + private static final Logger _logger = LoggerFactory.getLogger(RuleBasedAccessControl.class); private RuleSet _ruleSet; - private final EventLoggerProvider _eventLogger; - public DefaultAccessControl(String name, final EventLoggerProvider eventLogger) + public RuleBasedAccessControl(RuleSet rs) { - _fileName = name; - _eventLogger = eventLogger; - - _logger.debug("Creating AccessControl instance"); - } - - DefaultAccessControl(RuleSet rs) - { - _fileName = null; _ruleSet = rs; - _eventLogger = rs; - } - - public void open() - { - if(_fileName != null) - { - ConfigurationFile configFile = new PlainConfiguration(_fileName, _eventLogger); - _ruleSet = configFile.load(getReaderFromURLString(_fileName)); - } - } - - @Override - public boolean validate() - { - try - { - getReaderFromURLString(_fileName); - return true; - } - catch(IllegalConfigurationException e) - { - return false; - } - } - - - private static Reader getReaderFromURLString(String urlString) - { - try - { - URL url; - - try - { - url = new URL(urlString); - } - catch (MalformedURLException e) - { - File file = new File(urlString); - try - { - url = file.toURI().toURL(); - } - catch (MalformedURLException notAFile) - { - throw new IllegalConfigurationException("Cannot convert " + urlString + " to a readable resource", notAFile); - } - - } - return new InputStreamReader(url.openStream()); - } - catch (IOException e) - { - throw new IllegalConfigurationException("Cannot convert " + urlString + " to a readable resource", e); - } - } - - @Override - public void close() - { - //no-op - } - - @Override - public void onDelete() - { - //no-op - } - - @Override - public void onCreate() - { - if(_fileName != null) - { - //verify it is parsable - new PlainConfiguration(_fileName, _eventLogger).load(getReaderFromURLString(_fileName)); - } } public Result getDefault() Modified: qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java?rev=1750020&r1=1750019&r2=1750020&view=diff ============================================================================== --- qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java (original) +++ qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java Thu Jun 23 21:05:10 2016 @@ -20,7 +20,7 @@ package org.apache.qpid.server.security. import java.net.InetAddress; import java.security.Principal; -import java.util.Arrays; +import java.util.ArrayList; import java.util.Collections; import java.util.EnumMap; import java.util.HashMap; @@ -30,7 +30,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; -import java.util.TreeMap; import java.util.WeakHashMap; import javax.security.auth.Subject; @@ -50,31 +49,36 @@ import org.apache.qpid.server.security.a /** * Models the rule configuration for the access control plugin. */ -public class RuleSet implements EventLoggerProvider +class RuleSet implements EventLoggerProvider { private static final Logger _logger = LoggerFactory.getLogger(RuleSet.class); - private static final String AT = "@"; - private static final String SLASH = "/"; - public static final String DEFAULT_ALLOW = "defaultallow"; public static final String DEFAULT_DENY = "defaultdeny"; - public static final List<String> CONFIG_PROPERTIES = Arrays.asList(DEFAULT_ALLOW, DEFAULT_DENY); - private static final Integer _increment = 10; - private final SortedMap<Integer, Rule> _rules = new TreeMap<Integer, Rule>(); + private final List<Rule> _rules; private final Map<Subject, Map<Operation, Map<ObjectType, List<Rule>>>> _cache = Collections.synchronizedMap(new WeakHashMap<Subject, Map<Operation, Map<ObjectType, List<Rule>>>>()); private final Map<String, Boolean> _config = new HashMap<String, Boolean>(); private final EventLoggerProvider _eventLogger; + private Result _defaultResult = Result.DENIED; public RuleSet(EventLoggerProvider eventLogger) { _eventLogger = eventLogger; // set some default configuration properties - configure(DEFAULT_DENY, Boolean.TRUE); + _rules = new ArrayList<>(); + } + + public RuleSet(final EventLoggerProvider eventLogger, + final SortedMap<Integer, Rule> rules, + final Result defaultResult) + { + _eventLogger = eventLogger; + _rules = new ArrayList<>(rules.values()); + _defaultResult = defaultResult; } /** @@ -84,7 +88,6 @@ public class RuleSet implements EventLog { _rules.clear(); _cache.clear(); - _config.clear(); } public int getRuleCount() @@ -108,11 +111,10 @@ public class RuleSet implements EventLog final Set<Principal> principals = subject.getPrincipals(); boolean controlled = false; List<Rule> filtered = new LinkedList<Rule>(); - for (Rule rule : _rules.values()) + for (Rule rule : _rules) { final Action ruleAction = rule.getAction(); - if (rule.isEnabled() - && (ruleAction.getOperation() == Operation.ALL || ruleAction.getOperation() == operation) + if ((ruleAction.getOperation() == Operation.ALL || ruleAction.getOperation() == operation) && (ruleAction.getObjectType() == ObjectType.ALL || ruleAction.getObjectType() == objectType)) { controlled = true; @@ -144,125 +146,6 @@ public class RuleSet implements EventLog return rules; } - public boolean isValidNumber(Integer number) - { - return !_rules.containsKey(number); - } - - public void grant(Integer number, String identity, Permission permission, Operation operation) - { - AclAction action = new AclAction(operation); - addRule(number, identity, permission, action); - } - - public void grant(Integer number, String identity, Permission permission, Operation operation, ObjectType object, ObjectProperties properties) - { - AclAction action = new AclAction(operation, object, properties); - addRule(number, identity, permission, action); - } - - public void grant(Integer number, String identity, Permission permission, Operation operation, ObjectType object, AclRulePredicates predicates) - { - AclAction aclAction = new AclAction(operation, object, predicates); - addRule(number, identity, permission, aclAction); - } - - public boolean ruleExists(String identity, AclAction action) - { - for (Rule rule : _rules.values()) - { - if (rule.getIdentity().equals(identity) && rule.getAclAction().equals(action)) - { - return true; - } - } - return false; - } - - public void addRule(Integer number, String identity, Permission permission, AclAction action) - { - - if (!action.isAllowed()) - { - throw new IllegalArgumentException("Action is not allowed: " + action); - } - if (ruleExists(identity, action)) - { - return; - } - - // set rule number if needed - Rule rule = new Rule(number, identity, action, permission); - if (rule.getNumber() == null) - { - if (_rules.isEmpty()) - { - rule.setNumber(0); - } - else - { - rule.setNumber(_rules.lastKey() + _increment); - } - } - - // save rule - _cache.clear(); - _rules.put(rule.getNumber(), rule); - } - - public void enableRule(int ruleNumber) - { - _rules.get(Integer.valueOf(ruleNumber)).enable(); - } - - public void disableRule(int ruleNumber) - { - _rules.get(Integer.valueOf(ruleNumber)).disable(); - } - - /** Return true if the name is well-formed (contains legal characters). */ - protected boolean checkName(String name) - { - for (int i = 0; i < name.length(); i++) - { - Character c = name.charAt(i); - if (!Character.isLetterOrDigit(c) && c != '-' && c != '_' && c != '@' && c != '.' && c != '/') - { - return false; - } - } - return true; - } - - /** Returns true if a username has the name[@domain][/realm] format */ - protected boolean isvalidUserName(String name) - { - // check for '@' and '/' in name - int atPos = name.indexOf(AT); - int slashPos = name.indexOf(SLASH); - boolean atFound = atPos != -1 && atPos == name.lastIndexOf(AT); - boolean slashFound = slashPos != -1 && slashPos == name.lastIndexOf(SLASH); - - // must be at least one character after '@' or '/' - if (atFound && atPos > name.length() - 2) - { - return false; - } - if (slashFound && slashPos > name.length() - 2) - { - return false; - } - - // must be at least one character between '@' and '/' - if (atFound && slashFound) - { - return (atPos < (slashPos - 1)); - } - - // otherwise all good - return true; - } - /** * Checks for the case when the client's address is not known. * @@ -337,23 +220,8 @@ public class RuleSet implements EventLog /** Default deny. */ public Result getDefault() { - if (isSet(DEFAULT_ALLOW)) - { - return Result.ALLOWED; - } - if (isSet(DEFAULT_DENY)) - { - return Result.DENIED; - } - return Result.ABSTAIN; - } + return _defaultResult; - /** - * Check if a configuration property is set. - */ - protected boolean isSet(String key) - { - return Boolean.TRUE.equals(_config.get(key)); } /** @@ -367,23 +235,12 @@ public class RuleSet implements EventLog } /** - * Configure a single property for the plugin instance. - * - * @param key - * @param value - */ - public void configure(String key, Boolean value) - { - _config.put(key, value); - } - - /** * Returns all rules in the {@link RuleSet}. Primarily intended to support unit-testing. * @return map of rules */ - public Map<Integer, Rule> getAllRules() + public List<Rule> getAllRules() { - return Collections.unmodifiableMap(_rules); + return Collections.unmodifiableList(_rules); } private boolean isRelevant(final Set<Principal> principals, final Rule rule) Added: qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSetCreator.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSetCreator.java?rev=1750020&view=auto ============================================================================== --- qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSetCreator.java (added) +++ qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSetCreator.java Thu Jun 23 21:05:10 2016 @@ -0,0 +1,139 @@ +/* + * + * 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.qpid.server.security.access.config; + +import java.util.SortedMap; +import java.util.TreeMap; + +import org.apache.qpid.server.logging.EventLoggerProvider; +import org.apache.qpid.server.security.Result; +import org.apache.qpid.server.security.access.ObjectProperties; +import org.apache.qpid.server.security.access.ObjectType; +import org.apache.qpid.server.security.access.Operation; +import org.apache.qpid.server.security.access.Permission; + +final class RuleSetCreator +{ + private final SortedMap<Integer, Rule> _rules = new TreeMap<Integer, Rule>(); + private static final Integer INCREMENT = 10; + private Result _defaultResult = Result.DENIED; + + RuleSetCreator() + { + } + + + boolean isValidNumber(Integer number) + { + return !_rules.containsKey(number); + } + + void grant(Integer number, String identity, Permission permission, Operation operation) + { + AclAction action = new AclAction(operation); + addRule(number, identity, permission, action); + } + + void grant(Integer number, + String identity, + Permission permission, + Operation operation, + ObjectType object, + ObjectProperties properties) + { + AclAction action = new AclAction(operation, object, properties); + addRule(number, identity, permission, action); + } + + void grant(Integer number, + String identity, + Permission permission, + Operation operation, + ObjectType object, + AclRulePredicates predicates) + { + AclAction aclAction = new AclAction(operation, object, predicates); + addRule(number, identity, permission, aclAction); + } + + private boolean ruleExists(String identity, AclAction action) + { + for (Rule rule : _rules.values()) + { + if (rule.getIdentity().equals(identity) && rule.getAclAction().equals(action)) + { + return true; + } + } + return false; + } + + + private void addRule(Integer number, String identity, Permission permission, AclAction action) + { + + if (!action.isAllowed()) + { + throw new IllegalArgumentException("Action is not allowed: " + action); + } + if (ruleExists(identity, action)) + { + return; + } + + // set rule number if needed + Rule rule = new Rule(identity, action, permission); + if (number == null) + { + if (_rules.isEmpty()) + { + number = 0; + } + else + { + number = _rules.lastKey() + INCREMENT; + } + } + + // save rule + _rules.put(number, rule); + } + + void setDefaultResult(final Result defaultResult) + { + _defaultResult = defaultResult; + } + + Result getDefaultResult() + { + return _defaultResult; + } + + SortedMap<Integer, Rule> getRules() + { + return _rules; + } + + RuleSet createRuleSet(EventLoggerProvider eventLoggerProvider) + { + return new RuleSet(eventLoggerProvider, _rules, _defaultResult); + } +} Propchange: qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSetCreator.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java?rev=1750020&r1=1750019&r2=1750020&view=diff ============================================================================== --- qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java (original) +++ qpid/java/trunk/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java Thu Jun 23 21:05:10 2016 @@ -37,6 +37,8 @@ import org.apache.qpid.server.model.Mana import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.StateTransition; import org.apache.qpid.server.security.AccessControl; +import org.apache.qpid.server.security.access.config.AclFileParser; +import org.apache.qpid.server.security.access.config.RuleBasedAccessControl; import org.apache.qpid.server.util.urlstreamhandler.data.Handler; public class ACLFileAccessControlProviderImpl @@ -50,7 +52,7 @@ public class ACLFileAccessControlProvide Handler.register(); } - private volatile DefaultAccessControl _accessControl; + private volatile RuleBasedAccessControl _accessControl; private final Broker _broker; private final EventLogger _eventLogger; @@ -81,31 +83,21 @@ public class ACLFileAccessControlProvide @Override protected void validateOnCreate() { - DefaultAccessControl accessControl = null; try { - accessControl = new DefaultAccessControl(getPath(), _broker); - accessControl.validate(); - accessControl.open(); + new RuleBasedAccessControl(AclFileParser.parse(getPath(), _broker)); } catch(RuntimeException e) { throw new IllegalConfigurationException(e.getMessage(), e); } - finally - { - if (accessControl != null) - { - accessControl.close(); - } - } + } @Override protected void onOpen() { super.onOpen(); - _accessControl = new DefaultAccessControl(getPath(), _broker); } @Override @@ -119,15 +111,10 @@ public class ACLFileAccessControlProvide { try { - DefaultAccessControl accessControl = new DefaultAccessControl(getPath(), _broker); - accessControl.open(); - DefaultAccessControl oldAccessControl = _accessControl; + RuleBasedAccessControl accessControl = new RuleBasedAccessControl(AclFileParser.parse(getPath(), _broker)); _accessControl = accessControl; _eventLogger.message(AccessControlMessages.LOADED(String.valueOf(getPath()).startsWith("data:") ? "data:..." : getPath())); - if(oldAccessControl != null) - { - oldAccessControl.close(); - } + } catch(RuntimeException e) { @@ -146,29 +133,21 @@ public class ACLFileAccessControlProvide private ListenableFuture<Void> activate() { - if(_broker.isManagementMode()) + try { - - setState(_accessControl.validate() ? State.QUIESCED : State.ERRORED); + _accessControl = new RuleBasedAccessControl(AclFileParser.parse(getPath(), _broker)); + setState(_broker.isManagementMode() ? State.QUIESCED : State.ACTIVE); } - else + catch (RuntimeException e) { - try + setState(State.ERRORED); + if (_broker.isManagementMode()) { - _accessControl.open(); - setState(State.ACTIVE); + LOGGER.warn("Failed to activate ACL provider: " + getName(), e); } - catch (RuntimeException e) + else { - setState(State.ERRORED); - if (_broker.isManagementMode()) - { - LOGGER.warn("Failed to activate ACL provider: " + getName(), e); - } - else - { - throw e; - } + throw e; } } return Futures.immediateFuture(null); @@ -178,10 +157,7 @@ public class ACLFileAccessControlProvide protected void onClose() { super.onClose(); - if (_accessControl != null) - { - _accessControl.close(); - } + } @StateTransition(currentState = State.UNINITIALIZED, desiredState = State.QUIESCED) Copied: qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclFileParserTest.java (from r1750019, qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/PlainConfigurationTest.java) URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclFileParserTest.java?p2=qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclFileParserTest.java&p1=qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/PlainConfigurationTest.java&r1=1750019&r2=1750020&rev=1750020&view=diff ============================================================================== --- qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/PlainConfigurationTest.java (original) +++ qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclFileParserTest.java Thu Jun 23 21:05:10 2016 @@ -24,6 +24,7 @@ import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.PrintWriter; +import java.util.List; import java.util.Map; import org.apache.qpid.server.configuration.IllegalConfigurationException; @@ -34,9 +35,9 @@ import org.apache.qpid.server.security.a import org.apache.qpid.server.security.access.Operation; import org.apache.qpid.test.utils.QpidTestCase; -public class PlainConfigurationTest extends QpidTestCase +public class AclFileParserTest extends QpidTestCase { - private PlainConfiguration writeACLConfig(String...aclData) throws Exception + private RuleSet writeACLConfig(String...aclData) throws Exception { File acl = File.createTempFile(getClass().getName() + getName(), "acl"); acl.deleteOnExit(); @@ -50,9 +51,8 @@ public class PlainConfigurationTest exte aclWriter.close(); // Load ruleset - PlainConfiguration configFile = new PlainConfiguration(acl.getName(), mock(EventLoggerProvider.class)); - configFile.load(new FileReader(acl)); - return configFile; + return AclFileParser.parse(new FileReader(acl), mock(EventLoggerProvider.class)); + } public void testACLFileSyntaxContinuation() throws Exception @@ -64,7 +64,7 @@ public class PlainConfigurationTest exte } catch (IllegalConfigurationException ce) { - assertEquals(String.format(PlainConfiguration.PREMATURE_CONTINUATION_MSG, 1), ce.getMessage()); + assertEquals(String.format(AclFileParser.PREMATURE_CONTINUATION_MSG, 1), ce.getMessage()); } } @@ -77,7 +77,7 @@ public class PlainConfigurationTest exte } catch (IllegalConfigurationException ce) { - assertEquals(String.format(PlainConfiguration.PARSE_TOKEN_FAILED_MSG, 1), ce.getMessage()); + assertEquals(String.format(AclFileParser.PARSE_TOKEN_FAILED_MSG, 1), ce.getMessage()); assertTrue(ce.getCause() instanceof IllegalArgumentException); assertEquals("Not a valid permission: unparsed", ce.getCause().getMessage()); } @@ -92,7 +92,7 @@ public class PlainConfigurationTest exte } catch (IllegalConfigurationException ce) { - assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_ACL_MSG, 1), ce.getMessage()); + assertEquals(String.format(AclFileParser.NOT_ENOUGH_ACL_MSG, 1), ce.getMessage()); } } @@ -105,7 +105,7 @@ public class PlainConfigurationTest exte } catch (IllegalConfigurationException ce) { - assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_TOKENS_MSG, 1), ce.getMessage()); + assertEquals(String.format(AclFileParser.NOT_ENOUGH_TOKENS_MSG, 1), ce.getMessage()); } } @@ -118,7 +118,7 @@ public class PlainConfigurationTest exte } catch (IllegalConfigurationException ce) { - assertEquals(String.format(PlainConfiguration.NOT_ENOUGH_TOKENS_MSG, 1), ce.getMessage()); + assertEquals(String.format(AclFileParser.NOT_ENOUGH_TOKENS_MSG, 1), ce.getMessage()); } } @@ -131,7 +131,7 @@ public class PlainConfigurationTest exte } catch (IllegalConfigurationException ce) { - assertEquals(String.format(PlainConfiguration.PROPERTY_KEY_ONLY_MSG, 1), ce.getMessage()); + assertEquals(String.format(AclFileParser.PROPERTY_KEY_ONLY_MSG, 1), ce.getMessage()); } } @@ -144,7 +144,7 @@ public class PlainConfigurationTest exte } catch (IllegalConfigurationException ce) { - assertEquals(String.format(PlainConfiguration.PROPERTY_NO_EQUALS_MSG, 1), ce.getMessage()); + assertEquals(String.format(AclFileParser.PROPERTY_NO_EQUALS_MSG, 1), ce.getMessage()); } } @@ -157,7 +157,7 @@ public class PlainConfigurationTest exte } catch (IllegalConfigurationException ce) { - assertEquals(String.format(PlainConfiguration.PROPERTY_NO_VALUE_MSG, 1), ce.getMessage()); + assertEquals(String.format(AclFileParser.PROPERTY_NO_VALUE_MSG, 1), ce.getMessage()); } } @@ -167,11 +167,10 @@ public class PlainConfigurationTest exte */ public void testValidRule() throws Exception { - final PlainConfiguration config = writeACLConfig("ACL DENY-LOG user1 ACCESS VIRTUALHOST"); - final RuleSet rs = config.getConfiguration(); + final RuleSet rs = writeACLConfig("ACL DENY-LOG user1 ACCESS VIRTUALHOST"); assertEquals(1, rs.getRuleCount()); - final Map<Integer, Rule> rules = rs.getAllRules(); + final List<Rule> rules = rs.getAllRules(); assertEquals(1, rules.size()); final Rule rule = rules.get(0); assertEquals("Rule has unexpected identity", "user1", rule.getIdentity()); @@ -185,11 +184,10 @@ public class PlainConfigurationTest exte */ public void testValidRuleWithSingleQuotedProperty() throws Exception { - final PlainConfiguration config = writeACLConfig("ACL ALLOW all CREATE EXCHANGE name = \'value\'"); - final RuleSet rs = config.getConfiguration(); + final RuleSet rs = writeACLConfig("ACL ALLOW all CREATE EXCHANGE name = \'value\'"); assertEquals(1, rs.getRuleCount()); - final Map<Integer, Rule> rules = rs.getAllRules(); + final List<Rule> rules = rs.getAllRules(); assertEquals(1, rules.size()); final Rule rule = rules.get(0); assertEquals("Rule has unexpected identity", "all", rule.getIdentity()); @@ -205,11 +203,10 @@ public class PlainConfigurationTest exte */ public void testValidRuleWithDoubleQuotedProperty() throws Exception { - final PlainConfiguration config = writeACLConfig("ACL ALLOW all CREATE EXCHANGE name = \"value\""); - final RuleSet rs = config.getConfiguration(); + final RuleSet rs = writeACLConfig("ACL ALLOW all CREATE EXCHANGE name = \"value\""); assertEquals(1, rs.getRuleCount()); - final Map<Integer, Rule> rules = rs.getAllRules(); + final List<Rule> rules = rs.getAllRules(); assertEquals(1, rules.size()); final Rule rule = rules.get(0); assertEquals("Rule has unexpected identity", "all", rule.getIdentity()); @@ -225,11 +222,10 @@ public class PlainConfigurationTest exte */ public void testValidRuleWithManyProperties() throws Exception { - final PlainConfiguration config = writeACLConfig("ACL ALLOW admin DELETE QUEUE name=name1 owner = owner1"); - final RuleSet rs = config.getConfiguration(); + final RuleSet rs = writeACLConfig("ACL ALLOW admin DELETE QUEUE name=name1 owner = owner1"); assertEquals(1, rs.getRuleCount()); - final Map<Integer, Rule> rules = rs.getAllRules(); + final List<Rule> rules = rs.getAllRules(); assertEquals(1, rules.size()); final Rule rule = rules.get(0); assertEquals("Rule has unexpected identity", "admin", rule.getIdentity()); @@ -247,13 +243,12 @@ public class PlainConfigurationTest exte */ public void testValidRuleWithWildcardProperties() throws Exception { - final PlainConfiguration config = writeACLConfig("ACL ALLOW all CREATE EXCHANGE routingKey = \'news.#\'", + final RuleSet rs = writeACLConfig("ACL ALLOW all CREATE EXCHANGE routingKey = \'news.#\'", "ACL ALLOW all CREATE EXCHANGE routingKey = \'news.co.#\'", "ACL ALLOW all CREATE EXCHANGE routingKey = *.co.medellin"); - final RuleSet rs = config.getConfiguration(); assertEquals(3, rs.getRuleCount()); - final Map<Integer, Rule> rules = rs.getAllRules(); + final List<Rule> rules = rs.getAllRules(); assertEquals(3, rules.size()); final Rule rule1 = rules.get(0); assertEquals("Rule has unexpected identity", "all", rule1.getIdentity()); @@ -263,12 +258,12 @@ public class PlainConfigurationTest exte expectedProperties1.put(Property.ROUTING_KEY,"news.#"); assertEquals("Rule has unexpected object properties", expectedProperties1, rule1.getAction().getProperties()); - final Rule rule2 = rules.get(10); + final Rule rule2 = rules.get(1); final ObjectProperties expectedProperties2 = new ObjectProperties(); expectedProperties2.put(Property.ROUTING_KEY,"news.co.#"); assertEquals("Rule has unexpected object properties", expectedProperties2, rule2.getAction().getProperties()); - final Rule rule3 = rules.get(20); + final Rule rule3 = rules.get(2); final ObjectProperties expectedProperties3 = new ObjectProperties(); expectedProperties3.put(Property.ROUTING_KEY,"*.co.medellin"); assertEquals("Rule has unexpected object properties", expectedProperties3, rule3.getAction().getProperties()); @@ -279,11 +274,10 @@ public class PlainConfigurationTest exte */ public void testMixedCaseRuleInterpretation() throws Exception { - final PlainConfiguration config = writeACLConfig("AcL deny-LOG User1 BiND Exchange Name=AmQ.dIrect"); - final RuleSet rs = config.getConfiguration(); + final RuleSet rs = writeACLConfig("AcL deny-LOG User1 BiND Exchange Name=AmQ.dIrect"); assertEquals(1, rs.getRuleCount()); - final Map<Integer, Rule> rules = rs.getAllRules(); + final List<Rule> rules = rs.getAllRules(); assertEquals(1, rules.size()); final Rule rule = rules.get(0); assertEquals("Rule has unexpected identity", "User1", rule.getIdentity()); @@ -300,13 +294,12 @@ public class PlainConfigurationTest exte */ public void testCommentsSupported() throws Exception { - final PlainConfiguration config = writeACLConfig("#Comment", + final RuleSet rs = writeACLConfig("#Comment", "ACL DENY-LOG user1 ACCESS VIRTUALHOST # another comment", " # final comment with leading whitespace"); - final RuleSet rs = config.getConfiguration(); assertEquals(1, rs.getRuleCount()); - final Map<Integer, Rule> rules = rs.getAllRules(); + final List<Rule> rules = rs.getAllRules(); assertEquals(1, rules.size()); final Rule rule = rules.get(0); assertEquals("Rule has unexpected identity", "user1", rule.getIdentity()); @@ -321,11 +314,10 @@ public class PlainConfigurationTest exte */ public void testWhitespace() throws Exception { - final PlainConfiguration config = writeACLConfig("ACL\tDENY-LOG\t\t user1\t \tACCESS VIRTUALHOST"); - final RuleSet rs = config.getConfiguration(); + final RuleSet rs = writeACLConfig("ACL\tDENY-LOG\t\t user1\t \tACCESS VIRTUALHOST"); assertEquals(1, rs.getRuleCount()); - final Map<Integer, Rule> rules = rs.getAllRules(); + final List<Rule> rules = rs.getAllRules(); assertEquals(1, rules.size()); final Rule rule = rules.get(0); assertEquals("Rule has unexpected identity", "user1", rule.getIdentity()); @@ -339,12 +331,11 @@ public class PlainConfigurationTest exte */ public void testLineContinuation() throws Exception { - final PlainConfiguration config = writeACLConfig("ACL DENY-LOG user1 \\", + final RuleSet rs = writeACLConfig("ACL DENY-LOG user1 \\", "ACCESS VIRTUALHOST"); - final RuleSet rs = config.getConfiguration(); assertEquals(1, rs.getRuleCount()); - final Map<Integer, Rule> rules = rs.getAllRules(); + final List<Rule> rules = rs.getAllRules(); assertEquals(1, rules.size()); final Rule rule = rules.get(0); assertEquals("Rule has unexpected identity", "user1", rule.getIdentity()); @@ -429,12 +420,11 @@ public class PlainConfigurationTest exte validateRule(writeACLConfig("ACL ALLOW user1 ALL BROKER"), "user1", Operation.ALL, ObjectType.BROKER, ObjectProperties.EMPTY); } - private void validateRule(final PlainConfiguration config, String username, Operation operation, ObjectType objectType, ObjectProperties objectProperties) + private void validateRule(final RuleSet rs, String username, Operation operation, ObjectType objectType, ObjectProperties objectProperties) { - final RuleSet rs = config.getConfiguration(); assertEquals(1, rs.getRuleCount()); - final Map<Integer, Rule> rules = rs.getAllRules(); + final List<Rule> rules = rs.getAllRules(); assertEquals(1, rules.size()); final Rule rule = rules.get(0); assertEquals("Rule has unexpected identity", username, rule.getIdentity()); Copied: qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/RuleBasedAccessControlTest.java (from r1750019, qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlTest.java) URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/RuleBasedAccessControlTest.java?p2=qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/RuleBasedAccessControlTest.java&p1=qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlTest.java&r1=1750019&r2=1750020&rev=1750020&view=diff ============================================================================== --- qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlTest.java (original) +++ qpid/java/trunk/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/RuleBasedAccessControlTest.java Thu Jun 23 21:05:10 2016 @@ -18,7 +18,7 @@ * under the License. * */ -package org.apache.qpid.server.security.access.plugins; +package org.apache.qpid.server.security.access.config; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -40,8 +40,6 @@ import org.apache.qpid.server.security.a import org.apache.qpid.server.security.access.ObjectType; import org.apache.qpid.server.security.access.Operation; import org.apache.qpid.server.security.access.Permission; -import org.apache.qpid.server.security.access.config.Rule; -import org.apache.qpid.server.security.access.config.RuleSet; import org.apache.qpid.server.security.auth.TestPrincipalUtils; import org.apache.qpid.server.transport.AMQPConnection; import org.apache.qpid.test.utils.QpidTestCase; @@ -51,12 +49,12 @@ import org.apache.qpid.test.utils.QpidTe * * @see RuleSetTest */ -public class DefaultAccessControlTest extends QpidTestCase +public class RuleBasedAccessControlTest extends QpidTestCase { private static final String ALLOWED_GROUP = "allowed_group"; private static final String DENIED_GROUP = "denied_group"; - private DefaultAccessControl _plugin = null; // Class under test + private RuleBasedAccessControl _plugin = null; // Class under test private UnitTestMessageLogger _messageLogger; private EventLogger _eventLogger; @@ -75,24 +73,24 @@ public class DefaultAccessControlTest ex private void configureAccessControl(final RuleSet rs) { - _plugin = new DefaultAccessControl(rs); + _plugin = new RuleBasedAccessControl(rs); } private RuleSet createGroupRuleSet() { final EventLoggerProvider provider = mock(EventLoggerProvider.class); when(provider.getEventLogger()).thenReturn(_eventLogger); - final RuleSet rs = new RuleSet(provider); + RuleSetCreator rsc = new RuleSetCreator(); // Rule expressed with username - rs.grant(0, "user1", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY); + rsc.grant(0, "user1", Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY); // Rules expressed with groups - rs.grant(1, ALLOWED_GROUP, Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY); - rs.grant(2, DENIED_GROUP, Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY); + rsc.grant(1, ALLOWED_GROUP, Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY); + rsc.grant(2, DENIED_GROUP, Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY); // Catch all rule - rs.grant(3, Rule.ALL, Permission.DENY_LOG, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY); + rsc.grant(3, Rule.ALL, Permission.DENY_LOG, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY); - return rs; + return new RuleSet(provider, rsc.getRules(), rsc.getDefaultResult()); } /** @@ -179,11 +177,11 @@ public class DefaultAccessControlTest ex */ public void testAuthoriseAccessMethodWhenAllAccessOperationsAllowedOnAllComponents() { - final RuleSet rs = new RuleSet(mock(EventLoggerProvider.class)); + final RuleSetCreator rs = new RuleSetCreator(); // grant user4 access right on any method in any component rs.grant(1, "user4", Permission.ALLOW, Operation.ACCESS, ObjectType.METHOD, new ObjectProperties(ObjectProperties.WILD_CARD)); - configureAccessControl(rs); + configureAccessControl(rs.createRuleSet(mock(EventLoggerProvider.class))); Subject.doAs(TestPrincipalUtils.createTestSubject("user4"), new PrivilegedAction<Object>() { @Override @@ -205,13 +203,13 @@ public class DefaultAccessControlTest ex */ public void testAuthoriseAccessMethodWhenAllAccessOperationsAllowedOnSpecifiedComponent() { - final RuleSet rs = new RuleSet(mock(EventLoggerProvider.class)); + final RuleSetCreator rs = new RuleSetCreator(); // grant user5 access right on any methods in "Test" component ObjectProperties ruleProperties = new ObjectProperties(ObjectProperties.WILD_CARD); ruleProperties.put(ObjectProperties.Property.COMPONENT, "Test"); rs.grant(1, "user5", Permission.ALLOW, Operation.ACCESS, ObjectType.METHOD, ruleProperties); - configureAccessControl(rs); + configureAccessControl(rs.createRuleSet(mock(EventLoggerProvider.class))); Subject.doAs(TestPrincipalUtils.createTestSubject("user5"), new PrivilegedAction<Object>() { @Override @@ -251,7 +249,7 @@ public class DefaultAccessControlTest ex { RuleSet mockRuleSet = mock(RuleSet.class); - DefaultAccessControl accessControl = new DefaultAccessControl(mockRuleSet); + RuleBasedAccessControl accessControl = new RuleBasedAccessControl(mockRuleSet); ObjectProperties properties = new ObjectProperties(testVirtualHost); accessControl.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, properties); @@ -289,7 +287,7 @@ public class DefaultAccessControlTest ex ObjectProperties.EMPTY, inetAddress)).thenThrow(new RuntimeException()); - DefaultAccessControl accessControl = new DefaultAccessControl(mockRuleSet); + RuleBasedAccessControl accessControl = new RuleBasedAccessControl(mockRuleSet); Result result = accessControl.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY); assertEquals(Result.DENIED, result); @@ -305,13 +303,13 @@ public class DefaultAccessControlTest ex */ public void testAuthoriseAccessMethodWhenSpecifiedAccessOperationsAllowedOnSpecifiedComponent() { - final RuleSet rs = new RuleSet(mock(EventLoggerProvider.class)); + final RuleSetCreator rs = new RuleSetCreator(); // grant user6 access right on "getAttribute" method in "Test" component ObjectProperties ruleProperties = new ObjectProperties("getAttribute"); ruleProperties.put(ObjectProperties.Property.COMPONENT, "Test"); rs.grant(1, "user6", Permission.ALLOW, Operation.ACCESS, ObjectType.METHOD, ruleProperties); - configureAccessControl(rs); + configureAccessControl(rs.createRuleSet(mock(EventLoggerProvider.class))); Subject.doAs(TestPrincipalUtils.createTestSubject("user6"), new PrivilegedAction<Object>() { @Override @@ -342,11 +340,11 @@ public class DefaultAccessControlTest ex */ public void testAuthoriseAccessUpdateMethodWhenAllRightsGrantedOnSpecifiedMethodForAllComponents() { - final RuleSet rs = new RuleSet(mock(EventLoggerProvider.class)); + final RuleSetCreator rs = new RuleSetCreator(); // grant user8 all rights on method queryNames in all component rs.grant(1, "user8", Permission.ALLOW, Operation.ALL, ObjectType.METHOD, new ObjectProperties("queryNames")); - configureAccessControl(rs); + configureAccessControl(rs.createRuleSet(mock(EventLoggerProvider.class))); Subject.doAs(TestPrincipalUtils.createTestSubject("user8"), new PrivilegedAction<Object>() { @Override @@ -381,11 +379,11 @@ public class DefaultAccessControlTest ex */ public void testAuthoriseAccessUpdateMethodWhenAllRightsGrantedOnAllMethodsInAllComponents() { - final RuleSet rs = new RuleSet(mock(EventLoggerProvider.class)); + final RuleSetCreator rs = new RuleSetCreator(); // grant user9 all rights on any method in all component rs.grant(1, "user9", Permission.ALLOW, Operation.ALL, ObjectType.METHOD, new ObjectProperties()); - configureAccessControl(rs); + configureAccessControl(rs.createRuleSet(mock(EventLoggerProvider.class))); Subject.doAs(TestPrincipalUtils.createTestSubject("user9"), new PrivilegedAction<Object>() { @Override @@ -419,7 +417,7 @@ public class DefaultAccessControlTest ex */ public void testAuthoriseAccessMethodWhenMatchingAccessOperationsAllowedOnSpecifiedComponent() { - final RuleSet rs = new RuleSet(mock(EventLoggerProvider.class)); + final RuleSetCreator rs = new RuleSetCreator(); // grant user9 all rights on "getAttribute*" methods in Test component ObjectProperties ruleProperties = new ObjectProperties(); @@ -427,7 +425,7 @@ public class DefaultAccessControlTest ex ruleProperties.put(ObjectProperties.Property.NAME, "getAttribute*"); rs.grant(1, "user9", Permission.ALLOW, Operation.ACCESS, ObjectType.METHOD, ruleProperties); - configureAccessControl(rs); + configureAccessControl(rs.createRuleSet(mock(EventLoggerProvider.class))); Subject.doAs(TestPrincipalUtils.createTestSubject("user9"), new PrivilegedAction<Object>() { @Override --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org