2 * Copyright (c) 2015 Brocade Communications Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.aaa.shiro.authorization;
10 import com.google.common.base.Preconditions;
11 import com.google.common.collect.Sets;
12 import java.util.Arrays;
13 import java.util.Collection;
14 import java.util.HashSet;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
19 * A container for RBAC Rules. An RBAC Rule is composed of a url pattern which
20 * may contain asterisk characters (*), and a collection of roles. These are
21 * represented in shiro.ini in the following format:
22 * <code>urlPattern=roles[atLeastOneCommaSeperatedRole]</code>
24 * RBACRules are immutable; that is, you cannot change the url pattern or the
25 * roles after creation. This is done for security purposes. RBACRules are
26 * created through utilizing a static factory method:
27 * <code>RBACRule.createRBACRule()</code>
29 * @author Ryan Goulding (ryandgoulding@gmail.com)
32 public class RBACRule {
34 private static final Logger LOG = LoggerFactory.getLogger(RBACRule.class);
37 * a url pattern that can optional contain asterisk characters (*)
39 private String urlPattern;
42 * a collection of role names, such as "admin" and "user"
44 private Collection<String> roles = new HashSet<String>();
47 * Creates an RBAC Rule. Made private for static factory method.
50 * Cannot be null or the empty string.
52 * Must contain at least one role.
53 * @throws NullPointerException
54 * if <code>urlPattern</code> or <code>roles</code> is null
55 * @throws IllegalArgumentException
56 * if <code>urlPattern</code> is an empty string or
57 * <code>roles</code> is an empty collection.
59 private RBACRule(final String urlPattern, final Collection<String> roles)
60 throws NullPointerException, IllegalArgumentException {
62 this.setUrlPattern(urlPattern);
67 * The static factory method used to create RBACRules.
70 * Cannot be null or the empty string.
72 * Cannot be null or an emtpy collection.
73 * @return An immutable RBACRule
75 public static RBACRule createAuthorizationRule(final String urlPattern,
76 final Collection<String> roles) {
78 RBACRule authorizationRule = null;
80 authorizationRule = new RBACRule(urlPattern, roles);
81 } catch (Exception e) {
82 LOG.error("Cannot instantiate the AuthorizationRule", e);
84 return authorizationRule;
89 * @return the urlPattern for the RBACRule
91 public String getUrlPattern() {
96 * helper to ensure the url pattern is not the empty string
98 private static void checkUrlPatternLength(final String urlPattern)
99 throws IllegalArgumentException {
101 final String EXCEPTION_MESSAGE = "Empty String is not allowed for urlPattern";
102 if (urlPattern.isEmpty()) {
103 throw new IllegalArgumentException(EXCEPTION_MESSAGE);
107 private void setUrlPattern(final String urlPattern) throws NullPointerException,
108 IllegalArgumentException {
110 Preconditions.checkNotNull(urlPattern);
111 checkUrlPatternLength(urlPattern);
112 this.urlPattern = urlPattern;
117 * @return a copy of the rule, so any modifications to the returned
118 * reference do not affect the immutable <code>RBACRule</code>.
120 public Collection<String> getRoles() {
121 // Returns a copy of the roles collection such that the original set
123 // its contract of remaining immutable.
125 // Since this method is only called at shiro initialiation time,
126 // memory consumption of creating a new set is a non-issue.
127 return Sets.newHashSet(roles);
131 * check to ensure the roles collection is not empty
133 private static void checkRolesCollectionSize(final Collection<String> roles)
134 throws IllegalArgumentException {
136 final String EXCEPTION_MESSAGE = "roles must contain at least 1 role";
137 if (roles.isEmpty()) {
138 throw new IllegalArgumentException(EXCEPTION_MESSAGE);
142 private void setRoles(final Collection<String> roles) throws NullPointerException,
143 IllegalArgumentException {
145 Preconditions.checkNotNull(roles);
146 checkRolesCollectionSize(roles);
151 * Generates a string representation of the <code>RBACRule</code> roles in
154 * @return roles string representation in the form
155 * <code>roles[roleOne,roleTwo]</code>
157 public String getRolesInShiroFormat() {
158 final String ROLES_STRING = "roles";
159 return ROLES_STRING + Arrays.toString(roles.toArray());
163 * Generates the string representation of the <code>RBACRule</code> in shiro
164 * form. For example: <code>urlPattern=roles[admin,user]</code>
167 public String toString() {
168 return String.format("%s=%s", urlPattern, getRolesInShiroFormat());