Coverage Report - org.apache.shiro.authz.ModularRealmAuthorizer
 
Classes in this File Line Coverage Branch Coverage Complexity
ModularRealmAuthorizer
30%
41/134
19%
20/104
3.407
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements.  See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership.  The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License.  You may obtain a copy of the License at
 9  
  *
 10  
  *     http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied.  See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package org.apache.shiro.authz;
 20  
 
 21  
 import org.apache.shiro.authz.permission.PermissionResolver;
 22  
 import org.apache.shiro.authz.permission.PermissionResolverAware;
 23  
 import org.apache.shiro.authz.permission.RolePermissionResolver;
 24  
 import org.apache.shiro.authz.permission.RolePermissionResolverAware;
 25  
 import org.apache.shiro.realm.Realm;
 26  
 import org.apache.shiro.subject.PrincipalCollection;
 27  
 
 28  
 import java.util.Collection;
 29  
 import java.util.List;
 30  
 
 31  
 
 32  
 /**
 33  
  * A <tt>ModularRealmAuthorizer</tt> is an <tt>Authorizer</tt> implementation that consults one or more configured
 34  
  * {@link Realm Realm}s during an authorization operation.
 35  
  *
 36  
  * @since 0.2
 37  
  */
 38  
 public class ModularRealmAuthorizer implements Authorizer, PermissionResolverAware, RolePermissionResolverAware {
 39  
 
 40  
     /**
 41  
      * The realms to consult during any authorization check.
 42  
      */
 43  
     protected Collection<Realm> realms;
 44  
 
 45  
     /**
 46  
      * A PermissionResolver to be used by <em>all</em> configured realms.  Leave <code>null</code> if you wish
 47  
      * to configure different resolvers for different realms.
 48  
      */
 49  
     protected PermissionResolver permissionResolver;
 50  
 
 51  
     /**
 52  
      * A RolePermissionResolver to be used by <em>all</em> configured realms.  Leave <code>null</code> if you wish
 53  
      * to configure different resolvers for different realms.
 54  
      */
 55  
     protected RolePermissionResolver rolePermissionResolver;
 56  
 
 57  
     /**
 58  
      * Default no-argument constructor, does nothing.
 59  
      */
 60  37
     public ModularRealmAuthorizer() {
 61  37
     }
 62  
 
 63  
     /**
 64  
      * Constructor that accepts the <code>Realm</code>s to consult during an authorization check.  Immediately calls
 65  
      * {@link #setRealms setRealms(realms)}.
 66  
      *
 67  
      * @param realms the realms to consult during an authorization check.
 68  
      */
 69  0
     public ModularRealmAuthorizer(Collection<Realm> realms) {
 70  0
         setRealms(realms);
 71  0
     }
 72  
 
 73  
     /**
 74  
      * Returns the realms wrapped by this <code>Authorizer</code> which are consulted during an authorization check.
 75  
      *
 76  
      * @return the realms wrapped by this <code>Authorizer</code> which are consulted during an authorization check.
 77  
      */
 78  
     public Collection<Realm> getRealms() {
 79  115
         return this.realms;
 80  
     }
 81  
 
 82  
     /**
 83  
      * Sets the realms wrapped by this <code>Authorizer</code> which are consulted during an authorization check.
 84  
      *
 85  
      * @param realms the realms wrapped by this <code>Authorizer</code> which are consulted during an authorization check.
 86  
      */
 87  
     public void setRealms(Collection<Realm> realms) {
 88  34
         this.realms = realms;
 89  34
         applyPermissionResolverToRealms();
 90  34
         applyRolePermissionResolverToRealms();
 91  34
     }
 92  
 
 93  
     /**
 94  
      * Returns the PermissionResolver to be used on <em>all</em> configured realms, or <code>null</code (the default)
 95  
      * if all realm instances will each configure their own permission resolver.
 96  
      *
 97  
      * @return the PermissionResolver to be used on <em>all</em> configured realms, or <code>null</code (the default)
 98  
      *         if realm instances will each configure their own permission resolver.
 99  
      * @since 1.0
 100  
      */
 101  
     public PermissionResolver getPermissionResolver() {
 102  34
         return this.permissionResolver;
 103  
     }
 104  
 
 105  
     /**
 106  
      * Sets the specified {@link PermissionResolver PermissionResolver} on <em>all</em> of the wrapped realms that
 107  
      * implement the {@link org.apache.shiro.authz.permission.PermissionResolverAware PermissionResolverAware} interface.
 108  
      * <p/>
 109  
      * Only call this method if you want the permission resolver to be passed to all realms that implement the
 110  
      * <code>PermissionResolver</code> interface.  If you do not want this to occur, the realms must
 111  
      * configure themselves individually (or be configured individually).
 112  
      *
 113  
      * @param permissionResolver the permissionResolver to set on all of the wrapped realms that implement the
 114  
      *                           {@link org.apache.shiro.authz.permission.PermissionResolverAware PermissionResolverAware} interface.
 115  
      */
 116  
     public void setPermissionResolver(PermissionResolver permissionResolver) {
 117  0
         this.permissionResolver = permissionResolver;
 118  0
         applyPermissionResolverToRealms();
 119  0
     }
 120  
 
 121  
     /**
 122  
      * Sets the internal {@link #getPermissionResolver} on any internal configured
 123  
      * {@link #getRealms Realms} that implement the {@link org.apache.shiro.authz.permission.PermissionResolverAware PermissionResolverAware} interface.
 124  
      * <p/>
 125  
      * This method is called after setting a permissionResolver on this ModularRealmAuthorizer via the
 126  
      * {@link #setPermissionResolver(org.apache.shiro.authz.permission.PermissionResolver) setPermissionResolver} method.
 127  
      * <p/>
 128  
      * It is also called after setting one or more realms via the {@link #setRealms setRealms} method to allow these
 129  
      * newly available realms to be given the <code>PermissionResolver</code> already in use.
 130  
      *
 131  
      * @since 1.0
 132  
      */
 133  
     protected void applyPermissionResolverToRealms() {
 134  34
         PermissionResolver resolver = getPermissionResolver();
 135  34
         Collection<Realm> realms = getRealms();
 136  34
         if (resolver != null && realms != null && !realms.isEmpty()) {
 137  0
             for (Realm realm : realms) {
 138  0
                 if (realm instanceof PermissionResolverAware) {
 139  0
                     ((PermissionResolverAware) realm).setPermissionResolver(resolver);
 140  
                 }
 141  0
             }
 142  
         }
 143  34
     }
 144  
 
 145  
     /**
 146  
      * Returns the RolePermissionResolver to be used on <em>all</em> configured realms, or <code>null</code (the default)
 147  
      * if all realm instances will each configure their own permission resolver.
 148  
      *
 149  
      * @return the RolePermissionResolver to be used on <em>all</em> configured realms, or <code>null</code (the default)
 150  
      *         if realm instances will each configure their own role permission resolver.
 151  
      * @since 1.0
 152  
      */
 153  
     public RolePermissionResolver getRolePermissionResolver() {
 154  35
         return this.rolePermissionResolver;
 155  
     }
 156  
 
 157  
     /**
 158  
      * Sets the specified {@link RolePermissionResolver RolePermissionResolver} on <em>all</em> of the wrapped realms that
 159  
      * implement the {@link org.apache.shiro.authz.permission.RolePermissionResolverAware PermissionResolverAware} interface.
 160  
      * <p/>
 161  
      * Only call this method if you want the permission resolver to be passed to all realms that implement the
 162  
      * <code>RolePermissionResolver</code> interface.  If you do not want this to occur, the realms must
 163  
      * configure themselves individually (or be configured individually).
 164  
      *
 165  
      * @param rolePermissionResolver the rolePermissionResolver to set on all of the wrapped realms that implement the
 166  
      *                               {@link org.apache.shiro.authz.permission.RolePermissionResolverAware RolePermissionResolverAware} interface.
 167  
      */
 168  
     public void setRolePermissionResolver(RolePermissionResolver rolePermissionResolver) {
 169  1
         this.rolePermissionResolver = rolePermissionResolver;
 170  1
         applyRolePermissionResolverToRealms();
 171  1
     }
 172  
 
 173  
 
 174  
     /**
 175  
      * Sets the internal {@link #getRolePermissionResolver} on any internal configured
 176  
      * {@link #getRealms Realms} that implement the {@link org.apache.shiro.authz.permission.RolePermissionResolverAware RolePermissionResolverAware} interface.
 177  
      * <p/>
 178  
      * This method is called after setting a rolePermissionResolver on this ModularRealmAuthorizer via the
 179  
      * {@link #setRolePermissionResolver(org.apache.shiro.authz.permission.RolePermissionResolver) setRolePermissionResolver} method.
 180  
      * <p/>
 181  
      * It is also called after setting one or more realms via the {@link #setRealms setRealms} method to allow these
 182  
      * newly available realms to be given the <code>RolePermissionResolver</code> already in use.
 183  
      *
 184  
      * @since 1.0
 185  
      */
 186  
     protected void applyRolePermissionResolverToRealms() {
 187  35
         RolePermissionResolver resolver = getRolePermissionResolver();
 188  35
         Collection<Realm> realms = getRealms();
 189  35
         if (resolver != null && realms != null && !realms.isEmpty()) {
 190  2
             for (Realm realm : realms) {
 191  5
                 if (realm instanceof RolePermissionResolverAware) {
 192  5
                     ((RolePermissionResolverAware) realm).setRolePermissionResolver(resolver);
 193  
                 }
 194  5
             }
 195  
         }
 196  35
     }
 197  
 
 198  
 
 199  
     /**
 200  
      * Used by the {@link Authorizer Authorizer} implementation methods to ensure that the {@link #setRealms realms}
 201  
      * has been set.  The default implementation ensures the property is not null and not empty.
 202  
      *
 203  
      * @throws IllegalStateException if the <tt>realms</tt> property is configured incorrectly.
 204  
      */
 205  
     protected void assertRealmsConfigured() throws IllegalStateException {
 206  23
         Collection<Realm> realms = getRealms();
 207  23
         if (realms == null || realms.isEmpty()) {
 208  0
             String msg = "Configuration error:  No realms have been configured!  One or more realms must be " +
 209  
                     "present to execute an authorization operation.";
 210  0
             throw new IllegalStateException(msg);
 211  
         }
 212  23
     }
 213  
 
 214  
     /**
 215  
      * Returns <code>true</code> if any of the configured realms'
 216  
      * {@link #isPermitted(org.apache.shiro.subject.PrincipalCollection, String)} returns <code>true</code>,
 217  
      * <code>false</code> otherwise.
 218  
      */
 219  
     public boolean isPermitted(PrincipalCollection principals, String permission) {
 220  2
         assertRealmsConfigured();
 221  2
         for (Realm realm : getRealms()) {
 222  2
             if (!(realm instanceof Authorizer)) continue;
 223  2
             if (((Authorizer) realm).isPermitted(principals, permission)) {
 224  1
                 return true;
 225  
             }
 226  1
         }
 227  1
         return false;
 228  
     }
 229  
 
 230  
     /**
 231  
      * Returns <code>true</code> if any of the configured realms'
 232  
      * {@link #isPermitted(org.apache.shiro.subject.PrincipalCollection, Permission)} call returns <code>true</code>,
 233  
      * <code>false</code> otherwise.
 234  
      */
 235  
     public boolean isPermitted(PrincipalCollection principals, Permission permission) {
 236  0
         assertRealmsConfigured();
 237  0
         for (Realm realm : getRealms()) {
 238  0
             if (!(realm instanceof Authorizer)) continue;
 239  0
             if (((Authorizer) realm).isPermitted(principals, permission)) {
 240  0
                 return true;
 241  
             }
 242  0
         }
 243  0
         return false;
 244  
     }
 245  
 
 246  
     /**
 247  
      * Returns <code>true</code> if any of the configured realms'
 248  
      * {@link #isPermittedAll(org.apache.shiro.subject.PrincipalCollection, String...)} call returns
 249  
      * <code>true</code>, <code>false</code> otherwise.
 250  
      */
 251  
     public boolean[] isPermitted(PrincipalCollection principals, String... permissions) {
 252  0
         assertRealmsConfigured();
 253  0
         if (permissions != null && permissions.length > 0) {
 254  0
             boolean[] isPermitted = new boolean[permissions.length];
 255  0
             for (int i = 0; i < permissions.length; i++) {
 256  0
                 isPermitted[i] = isPermitted(principals, permissions[i]);
 257  
             }
 258  0
             return isPermitted;
 259  
         }
 260  0
         return new boolean[0];
 261  
     }
 262  
 
 263  
     /**
 264  
      * Returns <code>true</code> if any of the configured realms'
 265  
      * {@link #isPermitted(org.apache.shiro.subject.PrincipalCollection, List)} call returns <code>true</code>,
 266  
      * <code>false</code> otherwise.
 267  
      */
 268  
     public boolean[] isPermitted(PrincipalCollection principals, List<Permission> permissions) {
 269  0
         assertRealmsConfigured();
 270  0
         if (permissions != null && !permissions.isEmpty()) {
 271  0
             boolean[] isPermitted = new boolean[permissions.size()];
 272  0
             int i = 0;
 273  0
             for (Permission p : permissions) {
 274  0
                 isPermitted[i++] = isPermitted(principals, p);
 275  0
             }
 276  0
             return isPermitted;
 277  
         }
 278  
 
 279  0
         return new boolean[0];
 280  
     }
 281  
 
 282  
     /**
 283  
      * Returns <code>true</code> if any of the configured realms'
 284  
      * {@link #isPermitted(org.apache.shiro.subject.PrincipalCollection, String)} call returns <code>true</code>
 285  
      * for <em>all</em> of the specified string permissions, <code>false</code> otherwise.
 286  
      */
 287  
     public boolean isPermittedAll(PrincipalCollection principals, String... permissions) {
 288  0
         assertRealmsConfigured();
 289  0
         if (permissions != null && permissions.length > 0) {
 290  0
             for (String perm : permissions) {
 291  0
                 if (!isPermitted(principals, perm)) {
 292  0
                     return false;
 293  
                 }
 294  
             }
 295  
         }
 296  0
         return true;
 297  
     }
 298  
 
 299  
     /**
 300  
      * Returns <code>true</code> if any of the configured realms'
 301  
      * {@link #isPermitted(org.apache.shiro.subject.PrincipalCollection, Permission)} call returns <code>true</code>
 302  
      * for <em>all</em> of the specified Permissions, <code>false</code> otherwise.
 303  
      */
 304  
     public boolean isPermittedAll(PrincipalCollection principals, Collection<Permission> permissions) {
 305  0
         assertRealmsConfigured();
 306  0
         if (permissions != null && !permissions.isEmpty()) {
 307  0
             for (Permission permission : permissions) {
 308  0
                 if (!isPermitted(principals, permission)) {
 309  0
                     return false;
 310  
                 }
 311  0
             }
 312  
         }
 313  0
         return true;
 314  
     }
 315  
 
 316  
     /**
 317  
      * If !{@link #isPermitted(org.apache.shiro.subject.PrincipalCollection, String) isPermitted(permission)}, throws
 318  
      * an <code>UnauthorizedException</code> otherwise returns quietly.
 319  
      */
 320  
     public void checkPermission(PrincipalCollection principals, String permission) throws AuthorizationException {
 321  0
         assertRealmsConfigured();
 322  0
         if (!isPermitted(principals, permission)) {
 323  0
             throw new UnauthorizedException("Subject does not have permission [" + permission + "]");
 324  
         }
 325  0
     }
 326  
 
 327  
     /**
 328  
      * If !{@link #isPermitted(org.apache.shiro.subject.PrincipalCollection, Permission) isPermitted(permission)}, throws
 329  
      * an <code>UnauthorizedException</code> otherwise returns quietly.
 330  
      */
 331  
     public void checkPermission(PrincipalCollection principals, Permission permission) throws AuthorizationException {
 332  0
         assertRealmsConfigured();
 333  0
         if (!isPermitted(principals, permission)) {
 334  0
             throw new UnauthorizedException("Subject does not have permission [" + permission + "]");
 335  
         }
 336  0
     }
 337  
 
 338  
     /**
 339  
      * If !{@link #isPermitted(org.apache.shiro.subject.PrincipalCollection, String...) isPermitted(permission)},
 340  
      * throws an <code>UnauthorizedException</code> otherwise returns quietly.
 341  
      */
 342  
     public void checkPermissions(PrincipalCollection principals, String... permissions) throws AuthorizationException {
 343  0
         assertRealmsConfigured();
 344  0
         if (permissions != null && permissions.length > 0) {
 345  0
             for (String perm : permissions) {
 346  0
                 checkPermission(principals, perm);
 347  
             }
 348  
         }
 349  0
     }
 350  
 
 351  
     /**
 352  
      * If !{@link #isPermitted(org.apache.shiro.subject.PrincipalCollection, Permission) isPermitted(permission)} for
 353  
      * <em>all</em> the given Permissions, throws
 354  
      * an <code>UnauthorizedException</code> otherwise returns quietly.
 355  
      */
 356  
     public void checkPermissions(PrincipalCollection principals, Collection<Permission> permissions) throws AuthorizationException {
 357  0
         assertRealmsConfigured();
 358  0
         if (permissions != null) {
 359  0
             for (Permission permission : permissions) {
 360  0
                 checkPermission(principals, permission);
 361  0
             }
 362  
         }
 363  0
     }
 364  
 
 365  
     /**
 366  
      * Returns <code>true</code> if any of the configured realms'
 367  
      * {@link #hasRole(org.apache.shiro.subject.PrincipalCollection, String)} call returns <code>true</code>,
 368  
      * <code>false</code> otherwise.
 369  
      */
 370  
     public boolean hasRole(PrincipalCollection principals, String roleIdentifier) {
 371  21
         assertRealmsConfigured();
 372  21
         for (Realm realm : getRealms()) {
 373  21
             if (!(realm instanceof Authorizer)) continue;
 374  21
             if (((Authorizer) realm).hasRole(principals, roleIdentifier)) {
 375  10
                 return true;
 376  
             }
 377  11
         }
 378  11
         return false;
 379  
     }
 380  
 
 381  
     /**
 382  
      * Calls {@link #hasRole(org.apache.shiro.subject.PrincipalCollection, String)} for each role name in the specified
 383  
      * collection and places the return value from each call at the respective location in the returned array.
 384  
      */
 385  
     public boolean[] hasRoles(PrincipalCollection principals, List<String> roleIdentifiers) {
 386  0
         assertRealmsConfigured();
 387  0
         if (roleIdentifiers != null && !roleIdentifiers.isEmpty()) {
 388  0
             boolean[] hasRoles = new boolean[roleIdentifiers.size()];
 389  0
             int i = 0;
 390  0
             for (String roleId : roleIdentifiers) {
 391  0
                 hasRoles[i++] = hasRole(principals, roleId);
 392  0
             }
 393  0
             return hasRoles;
 394  
         }
 395  
 
 396  0
         return new boolean[0];
 397  
     }
 398  
 
 399  
     /**
 400  
      * Returns <code>true</code> iff any of the configured realms'
 401  
      * {@link #hasRole(org.apache.shiro.subject.PrincipalCollection, String)} call returns <code>true</code> for
 402  
      * <em>all</em> roles specified, <code>false</code> otherwise.
 403  
      */
 404  
     public boolean hasAllRoles(PrincipalCollection principals, Collection<String> roleIdentifiers) {
 405  0
         assertRealmsConfigured();
 406  0
         for (String roleIdentifier : roleIdentifiers) {
 407  0
             if (!hasRole(principals, roleIdentifier)) {
 408  0
                 return false;
 409  
             }
 410  0
         }
 411  0
         return true;
 412  
     }
 413  
 
 414  
     /**
 415  
      * If !{@link #hasRole(org.apache.shiro.subject.PrincipalCollection, String) hasRole(role)}, throws
 416  
      * an <code>UnauthorizedException</code> otherwise returns quietly.
 417  
      */
 418  
     public void checkRole(PrincipalCollection principals, String role) throws AuthorizationException {
 419  0
         assertRealmsConfigured();
 420  0
         if (!hasRole(principals, role)) {
 421  0
             throw new UnauthorizedException("Subject does not have role [" + role + "]");
 422  
         }
 423  0
     }
 424  
 
 425  
     /**
 426  
      * Calls {@link #checkRoles(PrincipalCollection principals, String... roles) checkRoles(PrincipalCollection principals, String... roles) }.
 427  
      */
 428  
     public void checkRoles(PrincipalCollection principals, Collection<String> roles) throws AuthorizationException {
 429  
         //SHIRO-234 - roles.toArray() -> roles.toArray(new String[roles.size()])
 430  0
         if (roles != null && !roles.isEmpty()) checkRoles(principals, roles.toArray(new String[roles.size()]));
 431  0
     }
 432  
 
 433  
     /**
 434  
      * Calls {@link #checkRole(org.apache.shiro.subject.PrincipalCollection, String) checkRole} for each role specified.
 435  
      */
 436  
     public void checkRoles(PrincipalCollection principals, String... roles) throws AuthorizationException {
 437  0
         assertRealmsConfigured();
 438  0
         if (roles != null) {
 439  0
             for (String role : roles) {
 440  0
                 checkRole(principals, role);
 441  
             }
 442  
         }
 443  0
     }
 444  
 }