blob: 4c9ca4b31c70b81512ef2c8ec5f619d5035fb8d9 [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../../jacoco-resources/report.gif" type="image/gif"/><title>AuthorizingRealm.java</title><link rel="stylesheet" href="../../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../../index.html" class="el_report">Apache Shiro :: Jar Bundle</a> &gt; <a href="../index.html" class="el_bundle">shiro-core</a> &gt; <a href="index.source.html" class="el_package">org.apache.shiro.realm</a> &gt; <span class="el_source">AuthorizingRealm.java</span></div><h1>AuthorizingRealm.java</h1><pre class="source lang-java linenums">/*
* 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
* &quot;License&quot;); 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
* &quot;AS IS&quot; 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.shiro.realm;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.*;
import org.apache.shiro.authz.permission.*;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.util.Initializable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* An {@code AuthorizingRealm} extends the {@code AuthenticatingRealm}'s capabilities by adding Authorization
* (access control) support.
* &lt;p/&gt;
* This implementation will perform all role and permission checks automatically (and subclasses do not have to
* write this logic) as long as the
* {@link #getAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection)} method returns an
* {@link AuthorizationInfo}. Please see that method's JavaDoc for an in-depth explanation.
* &lt;p/&gt;
* If you find that you do not want to utilize the {@link AuthorizationInfo AuthorizationInfo} construct,
* you are of course free to subclass the {@link AuthenticatingRealm AuthenticatingRealm} directly instead and
* implement the remaining Realm interface methods directly. You might do this if you want have better control
* over how the Role and Permission checks occur for your specific data source. However, using AuthorizationInfo
* (and its default implementation {@link org.apache.shiro.authz.SimpleAuthorizationInfo SimpleAuthorizationInfo}) is sufficient in the large
* majority of Realm cases.
*
* @see org.apache.shiro.authz.SimpleAuthorizationInfo
* @since 0.2
*/
public abstract class AuthorizingRealm extends AuthenticatingRealm
implements Authorizer, Initializable, PermissionResolverAware, RolePermissionResolverAware {
//TODO - complete JavaDoc
/*-------------------------------------------
| C O N S T A N T S |
============================================*/
<span class="fc" id="L63"> private static final Logger log = LoggerFactory.getLogger(AuthorizingRealm.class);</span>
/**
* The default suffix appended to the realm name for caching AuthorizationInfo instances.
*/
private static final String DEFAULT_AUTHORIZATION_CACHE_SUFFIX = &quot;.authorizationCache&quot;;
<span class="fc" id="L70"> private static final AtomicInteger INSTANCE_COUNT = new AtomicInteger();</span>
/*-------------------------------------------
| I N S T A N C E V A R I A B L E S |
============================================*/
/**
* The cache used by this realm to store AuthorizationInfo instances associated with individual Subject principals.
*/
private boolean authorizationCachingEnabled;
private Cache&lt;Object, AuthorizationInfo&gt; authorizationCache;
private String authorizationCacheName;
private PermissionResolver permissionResolver;
private RolePermissionResolver permissionRoleResolver;
/*-------------------------------------------
| C O N S T R U C T O R S |
============================================*/
public AuthorizingRealm() {
<span class="fc" id="L91"> this(null, null);</span>
<span class="fc" id="L92"> }</span>
public AuthorizingRealm(CacheManager cacheManager) {
<span class="nc" id="L95"> this(cacheManager, null);</span>
<span class="nc" id="L96"> }</span>
public AuthorizingRealm(CredentialsMatcher matcher) {
<span class="nc" id="L99"> this(null, matcher);</span>
<span class="nc" id="L100"> }</span>
public AuthorizingRealm(CacheManager cacheManager, CredentialsMatcher matcher) {
<span class="fc" id="L103"> super();</span>
<span class="pc bpc" id="L104" title="1 of 2 branches missed."> if (cacheManager != null) setCacheManager(cacheManager);</span>
<span class="pc bpc" id="L105" title="1 of 2 branches missed."> if (matcher != null) setCredentialsMatcher(matcher);</span>
<span class="fc" id="L107"> this.authorizationCachingEnabled = true;</span>
<span class="fc" id="L108"> this.permissionResolver = new WildcardPermissionResolver();</span>
<span class="fc" id="L110"> int instanceNumber = INSTANCE_COUNT.getAndIncrement();</span>
<span class="fc" id="L111"> this.authorizationCacheName = getClass().getName() + DEFAULT_AUTHORIZATION_CACHE_SUFFIX;</span>
<span class="fc bfc" id="L112" title="All 2 branches covered."> if (instanceNumber &gt; 0) {</span>
<span class="fc" id="L113"> this.authorizationCacheName = this.authorizationCacheName + &quot;.&quot; + instanceNumber;</span>
}
<span class="fc" id="L115"> }</span>
/*-------------------------------------------
| A C C E S S O R S / M O D I F I E R S |
============================================*/
public void setName(String name) {
<span class="fc" id="L122"> super.setName(name);</span>
<span class="fc" id="L123"> String authzCacheName = this.authorizationCacheName;</span>
<span class="pc bpc" id="L124" title="2 of 4 branches missed."> if (authzCacheName != null &amp;&amp; authzCacheName.startsWith(getClass().getName())) {</span>
//get rid of the default class-name based cache name. Create a more meaningful one
//based on the application-unique Realm name:
<span class="fc" id="L127"> this.authorizationCacheName = name + DEFAULT_AUTHORIZATION_CACHE_SUFFIX;</span>
}
<span class="fc" id="L129"> }</span>
public void setAuthorizationCache(Cache&lt;Object, AuthorizationInfo&gt; authorizationCache) {
<span class="nc" id="L132"> this.authorizationCache = authorizationCache;</span>
<span class="nc" id="L133"> }</span>
public Cache&lt;Object, AuthorizationInfo&gt; getAuthorizationCache() {
<span class="fc" id="L136"> return this.authorizationCache;</span>
}
public String getAuthorizationCacheName() {
<span class="nc" id="L140"> return authorizationCacheName;</span>
}
@SuppressWarnings({&quot;UnusedDeclaration&quot;})
public void setAuthorizationCacheName(String authorizationCacheName) {
<span class="nc" id="L145"> this.authorizationCacheName = authorizationCacheName;</span>
<span class="nc" id="L146"> }</span>
/**
* Returns {@code true} if authorization caching should be utilized if a {@link CacheManager} has been
* {@link #setCacheManager(org.apache.shiro.cache.CacheManager) configured}, {@code false} otherwise.
* &lt;p/&gt;
* The default value is {@code true}.
*
* @return {@code true} if authorization caching should be utilized, {@code false} otherwise.
*/
public boolean isAuthorizationCachingEnabled() {
<span class="pc bpc" id="L157" title="1 of 4 branches missed."> return isCachingEnabled() &amp;&amp; authorizationCachingEnabled;</span>
}
/**
* Sets whether or not authorization caching should be utilized if a {@link CacheManager} has been
* {@link #setCacheManager(org.apache.shiro.cache.CacheManager) configured}, {@code false} otherwise.
* &lt;p/&gt;
* The default value is {@code true}.
*
* @param authenticationCachingEnabled the value to set
*/
@SuppressWarnings({&quot;UnusedDeclaration&quot;})
public void setAuthorizationCachingEnabled(boolean authenticationCachingEnabled) {
<span class="nc" id="L170"> this.authorizationCachingEnabled = authenticationCachingEnabled;</span>
<span class="nc bnc" id="L171" title="All 2 branches missed."> if (authenticationCachingEnabled) {</span>
<span class="nc" id="L172"> setCachingEnabled(true);</span>
}
<span class="nc" id="L174"> }</span>
public PermissionResolver getPermissionResolver() {
<span class="fc" id="L177"> return permissionResolver;</span>
}
public void setPermissionResolver(PermissionResolver permissionResolver) {
<span class="pc bpc" id="L181" title="1 of 2 branches missed."> if (permissionResolver == null) throw new IllegalArgumentException(&quot;Null PermissionResolver is not allowed&quot;);</span>
<span class="fc" id="L182"> this.permissionResolver = permissionResolver;</span>
<span class="fc" id="L183"> }</span>
public RolePermissionResolver getRolePermissionResolver() {
<span class="fc" id="L186"> return permissionRoleResolver;</span>
}
public void setRolePermissionResolver(RolePermissionResolver permissionRoleResolver) {
<span class="fc" id="L190"> this.permissionRoleResolver = permissionRoleResolver;</span>
<span class="fc" id="L191"> }</span>
/*--------------------------------------------
| M E T H O D S |
============================================*/
/**
* Initializes this realm and potentially enables a cache, depending on configuration.
* &lt;p/&gt;
* When this method is called, the following logic is executed:
* &lt;ol&gt;
* &lt;li&gt;If the {@link #setAuthorizationCache cache} property has been set, it will be
* used to cache the AuthorizationInfo objects returned from {@link #getAuthorizationInfo}
* method invocations.
* All future calls to {@code getAuthorizationInfo} will attempt to use this cache first
* to alleviate any potentially unnecessary calls to an underlying data store.&lt;/li&gt;
* &lt;li&gt;If the {@link #setAuthorizationCache cache} property has &lt;b&gt;not&lt;/b&gt; been set,
* the {@link #setCacheManager cacheManager} property will be checked.
* If a {@code cacheManager} has been set, it will be used to create an authorization
* {@code cache}, and this newly created cache which will be used as specified in #1.&lt;/li&gt;
* &lt;li&gt;If neither the {@link #setAuthorizationCache (org.apache.shiro.cache.Cache) cache}
* or {@link #setCacheManager(org.apache.shiro.cache.CacheManager) cacheManager}
* properties are set, caching will be disabled and authorization look-ups will be delegated to
* subclass implementations for each authorization check.&lt;/li&gt;
* &lt;/ol&gt;
*/
protected void onInit() {
<span class="fc" id="L218"> super.onInit();</span>
//trigger obtaining the authorization cache if possible
<span class="fc" id="L220"> getAvailableAuthorizationCache();</span>
<span class="fc" id="L221"> }</span>
protected void afterCacheManagerSet() {
<span class="fc" id="L224"> super.afterCacheManagerSet();</span>
//trigger obtaining the authorization cache if possible
<span class="fc" id="L226"> getAvailableAuthorizationCache();</span>
<span class="fc" id="L227"> }</span>
private Cache&lt;Object, AuthorizationInfo&gt; getAuthorizationCacheLazy() {
<span class="pc bpc" id="L231" title="1 of 2 branches missed."> if (this.authorizationCache == null) {</span>
<span class="pc bpc" id="L233" title="1 of 2 branches missed."> if (log.isDebugEnabled()) {</span>
<span class="fc" id="L234"> log.debug(&quot;No authorizationCache instance set. Checking for a cacheManager...&quot;);</span>
}
<span class="fc" id="L237"> CacheManager cacheManager = getCacheManager();</span>
<span class="pc bpc" id="L239" title="1 of 2 branches missed."> if (cacheManager != null) {</span>
<span class="nc" id="L240"> String cacheName = getAuthorizationCacheName();</span>
<span class="nc bnc" id="L241" title="All 2 branches missed."> if (log.isDebugEnabled()) {</span>
<span class="nc" id="L242"> log.debug(&quot;CacheManager [&quot; + cacheManager + &quot;] has been configured. Building &quot; +</span>
&quot;authorization cache named [&quot; + cacheName + &quot;]&quot;);
}
<span class="nc" id="L245"> this.authorizationCache = cacheManager.getCache(cacheName);</span>
<span class="nc" id="L246"> } else {</span>
<span class="pc bpc" id="L247" title="1 of 2 branches missed."> if (log.isDebugEnabled()) {</span>
<span class="fc" id="L248"> log.debug(&quot;No cache or cacheManager properties have been set. Authorization cache cannot &quot; +</span>
&quot;be obtained.&quot;);
}
}
}
<span class="fc" id="L254"> return this.authorizationCache;</span>
}
private Cache&lt;Object, AuthorizationInfo&gt; getAvailableAuthorizationCache() {
<span class="fc" id="L258"> Cache&lt;Object, AuthorizationInfo&gt; cache = getAuthorizationCache();</span>
<span class="pc bpc" id="L259" title="1 of 4 branches missed."> if (cache == null &amp;&amp; isAuthorizationCachingEnabled()) {</span>
<span class="fc" id="L260"> cache = getAuthorizationCacheLazy();</span>
}
<span class="fc" id="L262"> return cache;</span>
}
/**
* Returns an account's authorization-specific information for the specified {@code principals},
* or {@code null} if no account could be found. The resulting {@code AuthorizationInfo} object is used
* by the other method implementations in this class to automatically perform access control checks for the
* corresponding {@code Subject}.
* &lt;p/&gt;
* This implementation obtains the actual {@code AuthorizationInfo} object from the subclass's
* implementation of
* {@link #doGetAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection) doGetAuthorizationInfo}, and then
* caches it for efficient reuse if caching is enabled (see below).
* &lt;p/&gt;
* Invocations of this method should be thought of as completely orthogonal to acquiring
* {@link #getAuthenticationInfo(org.apache.shiro.authc.AuthenticationToken) authenticationInfo}, since either could
* occur in any order.
* &lt;p/&gt;
* For example, in &amp;quot;Remember Me&amp;quot; scenarios, the user identity is remembered (and
* assumed) for their current session and an authentication attempt during that session might never occur.
* But because their identity would be remembered, that is sufficient enough information to call this method to
* execute any necessary authorization checks. For this reason, authentication and authorization should be
* loosely coupled and not depend on each other.
* &lt;h3&gt;Caching&lt;/h3&gt;
* The {@code AuthorizationInfo} values returned from this method are cached for efficient reuse
* if caching is enabled. Caching is enabled automatically when an {@link #setAuthorizationCache authorizationCache}
* instance has been explicitly configured, or if a {@link #setCacheManager cacheManager} has been configured, which
* will be used to lazily create the {@code authorizationCache} as needed.
* &lt;p/&gt;
* If caching is enabled, the authorization cache will be checked first and if found, will return the cached
* {@code AuthorizationInfo} immediately. If caching is disabled, or there is a cache miss, the authorization
* info will be looked up from the underlying data store via the
* {@link #doGetAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection)} method, which must be implemented
* by subclasses.
* &lt;h4&gt;Changed Data&lt;/h4&gt;
* If caching is enabled and if any authorization data for an account is changed at
* runtime, such as adding or removing roles and/or permissions, the subclass implementation should clear the
* cached AuthorizationInfo for that account via the
* {@link #clearCachedAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection) clearCachedAuthorizationInfo}
* method. This ensures that the next call to {@code getAuthorizationInfo(PrincipalCollection)} will
* acquire the account's fresh authorization data, where it will then be cached for efficient reuse. This
* ensures that stale authorization data will not be reused.
*
* @param principals the corresponding Subject's identifying principals with which to look up the Subject's
* {@code AuthorizationInfo}.
* @return the authorization information for the account associated with the specified {@code principals},
* or {@code null} if no account could be found.
*/
protected AuthorizationInfo getAuthorizationInfo(PrincipalCollection principals) {
<span class="pc bpc" id="L312" title="1 of 2 branches missed."> if (principals == null) {</span>
<span class="nc" id="L313"> return null;</span>
}
<span class="fc" id="L316"> AuthorizationInfo info = null;</span>
<span class="pc bpc" id="L318" title="1 of 2 branches missed."> if (log.isTraceEnabled()) {</span>
<span class="fc" id="L319"> log.trace(&quot;Retrieving AuthorizationInfo for principals [&quot; + principals + &quot;]&quot;);</span>
}
<span class="fc" id="L322"> Cache&lt;Object, AuthorizationInfo&gt; cache = getAvailableAuthorizationCache();</span>
<span class="pc bpc" id="L323" title="1 of 2 branches missed."> if (cache != null) {</span>
<span class="nc bnc" id="L324" title="All 2 branches missed."> if (log.isTraceEnabled()) {</span>
<span class="nc" id="L325"> log.trace(&quot;Attempting to retrieve the AuthorizationInfo from cache.&quot;);</span>
}
<span class="nc" id="L327"> Object key = getAuthorizationCacheKey(principals);</span>
<span class="nc" id="L328"> info = cache.get(key);</span>
<span class="nc bnc" id="L329" title="All 2 branches missed."> if (log.isTraceEnabled()) {</span>
<span class="nc bnc" id="L330" title="All 2 branches missed."> if (info == null) {</span>
<span class="nc" id="L331"> log.trace(&quot;No AuthorizationInfo found in cache for principals [&quot; + principals + &quot;]&quot;);</span>
} else {
<span class="nc" id="L333"> log.trace(&quot;AuthorizationInfo found in cache for principals [&quot; + principals + &quot;]&quot;);</span>
}
}
}
<span class="pc bpc" id="L339" title="1 of 2 branches missed."> if (info == null) {</span>
// Call template method if the info was not found in a cache
<span class="fc" id="L341"> info = doGetAuthorizationInfo(principals);</span>
// If the info is not null and the cache has been created, then cache the authorization info.
<span class="pc bpc" id="L343" title="1 of 4 branches missed."> if (info != null &amp;&amp; cache != null) {</span>
<span class="nc bnc" id="L344" title="All 2 branches missed."> if (log.isTraceEnabled()) {</span>
<span class="nc" id="L345"> log.trace(&quot;Caching authorization info for principals: [&quot; + principals + &quot;].&quot;);</span>
}
<span class="nc" id="L347"> Object key = getAuthorizationCacheKey(principals);</span>
<span class="nc" id="L348"> cache.put(key, info);</span>
}
}
<span class="fc" id="L352"> return info;</span>
}
protected Object getAuthorizationCacheKey(PrincipalCollection principals) {
<span class="nc" id="L356"> return principals;</span>
}
/**
* Clears out the AuthorizationInfo cache entry for the specified account.
* &lt;p/&gt;
* This method is provided as a convenience to subclasses so they can invalidate a cache entry when they
* change an account's authorization data (add/remove roles or permissions) during runtime. Because an account's
* AuthorizationInfo can be cached, there needs to be a way to invalidate the cache for only that account so that
* subsequent authorization operations don't used the (old) cached value if account data changes.
* &lt;p/&gt;
* After this method is called, the next authorization check for that same account will result in a call to
* {@link #getAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection) getAuthorizationInfo}, and the
* resulting return value will be cached before being returned so it can be reused for later authorization checks.
* &lt;p/&gt;
* If you wish to clear out all associated cached data (and not just authorization data), use the
* {@link #clearCache(org.apache.shiro.subject.PrincipalCollection)} method instead (which will in turn call this
* method by default).
*
* @param principals the principals of the account for which to clear the cached AuthorizationInfo.
*/
protected void clearCachedAuthorizationInfo(PrincipalCollection principals) {
<span class="pc bpc" id="L378" title="1 of 2 branches missed."> if (principals == null) {</span>
<span class="nc" id="L379"> return;</span>
}
<span class="fc" id="L382"> Cache&lt;Object, AuthorizationInfo&gt; cache = getAvailableAuthorizationCache();</span>
//cache instance will be non-null if caching is enabled:
<span class="pc bpc" id="L384" title="1 of 2 branches missed."> if (cache != null) {</span>
<span class="nc" id="L385"> Object key = getAuthorizationCacheKey(principals);</span>
<span class="nc" id="L386"> cache.remove(key);</span>
}
<span class="fc" id="L388"> }</span>
/**
* Retrieves the AuthorizationInfo for the given principals from the underlying data store. When returning
* an instance from this method, you might want to consider using an instance of
* {@link org.apache.shiro.authz.SimpleAuthorizationInfo SimpleAuthorizationInfo}, as it is suitable in most cases.
*
* @param principals the primary identifying principals of the AuthorizationInfo that should be retrieved.
* @return the AuthorizationInfo associated with this principals.
* @see org.apache.shiro.authz.SimpleAuthorizationInfo
*/
protected abstract AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals);
//changed visibility from private to protected for SHIRO-332
protected Collection&lt;Permission&gt; getPermissions(AuthorizationInfo info) {
<span class="fc" id="L403"> Set&lt;Permission&gt; permissions = new HashSet&lt;Permission&gt;();</span>
<span class="fc bfc" id="L405" title="All 2 branches covered."> if (info != null) {</span>
<span class="fc" id="L406"> Collection&lt;Permission&gt; perms = info.getObjectPermissions();</span>
<span class="fc bfc" id="L407" title="All 2 branches covered."> if (!CollectionUtils.isEmpty(perms)) {</span>
<span class="fc" id="L408"> permissions.addAll(perms);</span>
}
<span class="fc" id="L410"> perms = resolvePermissions(info.getStringPermissions());</span>
<span class="fc bfc" id="L411" title="All 2 branches covered."> if (!CollectionUtils.isEmpty(perms)) {</span>
<span class="fc" id="L412"> permissions.addAll(perms);</span>
}
<span class="fc" id="L415"> perms = resolveRolePermissions(info.getRoles());</span>
<span class="fc bfc" id="L416" title="All 2 branches covered."> if (!CollectionUtils.isEmpty(perms)) {</span>
<span class="fc" id="L417"> permissions.addAll(perms);</span>
}
}
<span class="fc bfc" id="L421" title="All 2 branches covered."> if (permissions.isEmpty()) {</span>
<span class="fc" id="L422"> return Collections.emptySet();</span>
} else {
<span class="fc" id="L424"> return Collections.unmodifiableSet(permissions);</span>
}
}
private Collection&lt;Permission&gt; resolvePermissions(Collection&lt;String&gt; stringPerms) {
<span class="fc" id="L429"> Collection&lt;Permission&gt; perms = Collections.emptySet();</span>
<span class="fc" id="L430"> PermissionResolver resolver = getPermissionResolver();</span>
<span class="pc bpc" id="L431" title="1 of 4 branches missed."> if (resolver != null &amp;&amp; !CollectionUtils.isEmpty(stringPerms)) {</span>
<span class="fc" id="L432"> perms = new LinkedHashSet&lt;Permission&gt;(stringPerms.size());</span>
<span class="fc bfc" id="L433" title="All 2 branches covered."> for (String strPermission : stringPerms) {</span>
<span class="fc" id="L434"> Permission permission = getPermissionResolver().resolvePermission(strPermission);</span>
<span class="fc" id="L435"> perms.add(permission);</span>
<span class="fc" id="L436"> }</span>
}
<span class="fc" id="L438"> return perms;</span>
}
private Collection&lt;Permission&gt; resolveRolePermissions(Collection&lt;String&gt; roleNames) {
<span class="fc" id="L442"> Collection&lt;Permission&gt; perms = Collections.emptySet();</span>
<span class="fc" id="L443"> RolePermissionResolver resolver = getRolePermissionResolver();</span>
<span class="pc bpc" id="L444" title="1 of 4 branches missed."> if (resolver != null &amp;&amp; !CollectionUtils.isEmpty(roleNames)) {</span>
<span class="fc" id="L445"> perms = new LinkedHashSet&lt;Permission&gt;(roleNames.size());</span>
<span class="fc bfc" id="L446" title="All 2 branches covered."> for (String roleName : roleNames) {</span>
<span class="fc" id="L447"> Collection&lt;Permission&gt; resolved = resolver.resolvePermissionsInRole(roleName);</span>
<span class="pc bpc" id="L448" title="1 of 2 branches missed."> if (!CollectionUtils.isEmpty(resolved)) {</span>
<span class="fc" id="L449"> perms.addAll(resolved);</span>
}
<span class="fc" id="L451"> }</span>
}
<span class="fc" id="L453"> return perms;</span>
}
public boolean isPermitted(PrincipalCollection principals, String permission) {
<span class="fc" id="L457"> Permission p = getPermissionResolver().resolvePermission(permission);</span>
<span class="fc" id="L458"> return isPermitted(principals, p);</span>
}
public boolean isPermitted(PrincipalCollection principals, Permission permission) {
<span class="fc" id="L462"> AuthorizationInfo info = getAuthorizationInfo(principals);</span>
<span class="fc" id="L463"> return isPermitted(permission, info);</span>
}
//changed visibility from private to protected for SHIRO-332
protected boolean isPermitted(Permission permission, AuthorizationInfo info) {
<span class="fc" id="L468"> Collection&lt;Permission&gt; perms = getPermissions(info);</span>
<span class="pc bpc" id="L469" title="1 of 4 branches missed."> if (perms != null &amp;&amp; !perms.isEmpty()) {</span>
<span class="fc bfc" id="L470" title="All 2 branches covered."> for (Permission perm : perms) {</span>
<span class="fc bfc" id="L471" title="All 2 branches covered."> if (perm.implies(permission)) {</span>
<span class="fc" id="L472"> return true;</span>
}
<span class="fc" id="L474"> }</span>
}
<span class="fc" id="L476"> return false;</span>
}
public boolean[] isPermitted(PrincipalCollection subjectIdentifier, String... permissions) {
<span class="fc" id="L480"> List&lt;Permission&gt; perms = new ArrayList&lt;Permission&gt;(permissions.length);</span>
<span class="fc bfc" id="L481" title="All 2 branches covered."> for (String permString : permissions) {</span>
<span class="fc" id="L482"> perms.add(getPermissionResolver().resolvePermission(permString));</span>
}
<span class="fc" id="L484"> return isPermitted(subjectIdentifier, perms);</span>
}
public boolean[] isPermitted(PrincipalCollection principals, List&lt;Permission&gt; permissions) {
<span class="fc" id="L488"> AuthorizationInfo info = getAuthorizationInfo(principals);</span>
<span class="fc" id="L489"> return isPermitted(permissions, info);</span>
}
protected boolean[] isPermitted(List&lt;Permission&gt; permissions, AuthorizationInfo info) {
boolean[] result;
<span class="pc bpc" id="L494" title="2 of 4 branches missed."> if (permissions != null &amp;&amp; !permissions.isEmpty()) {</span>
<span class="fc" id="L495"> int size = permissions.size();</span>
<span class="fc" id="L496"> result = new boolean[size];</span>
<span class="fc" id="L497"> int i = 0;</span>
<span class="fc bfc" id="L498" title="All 2 branches covered."> for (Permission p : permissions) {</span>
<span class="fc" id="L499"> result[i++] = isPermitted(p, info);</span>
<span class="fc" id="L500"> }</span>
<span class="fc" id="L501"> } else {</span>
<span class="nc" id="L502"> result = new boolean[0];</span>
}
<span class="fc" id="L504"> return result;</span>
}
public boolean isPermittedAll(PrincipalCollection subjectIdentifier, String... permissions) {
<span class="pc bpc" id="L508" title="2 of 4 branches missed."> if (permissions != null &amp;&amp; permissions.length &gt; 0) {</span>
<span class="fc" id="L509"> Collection&lt;Permission&gt; perms = new ArrayList&lt;Permission&gt;(permissions.length);</span>
<span class="fc bfc" id="L510" title="All 2 branches covered."> for (String permString : permissions) {</span>
<span class="fc" id="L511"> perms.add(getPermissionResolver().resolvePermission(permString));</span>
}
<span class="fc" id="L513"> return isPermittedAll(subjectIdentifier, perms);</span>
}
<span class="nc" id="L515"> return false;</span>
}
public boolean isPermittedAll(PrincipalCollection principal, Collection&lt;Permission&gt; permissions) {
<span class="fc" id="L519"> AuthorizationInfo info = getAuthorizationInfo(principal);</span>
<span class="pc bpc" id="L520" title="1 of 4 branches missed."> return info != null &amp;&amp; isPermittedAll(permissions, info);</span>
}
protected boolean isPermittedAll(Collection&lt;Permission&gt; permissions, AuthorizationInfo info) {
<span class="pc bpc" id="L524" title="2 of 4 branches missed."> if (permissions != null &amp;&amp; !permissions.isEmpty()) {</span>
<span class="fc bfc" id="L525" title="All 2 branches covered."> for (Permission p : permissions) {</span>
<span class="pc bpc" id="L526" title="1 of 2 branches missed."> if (!isPermitted(p, info)) {</span>
<span class="nc" id="L527"> return false;</span>
}
<span class="fc" id="L529"> }</span>
}
<span class="fc" id="L531"> return true;</span>
}
public void checkPermission(PrincipalCollection subjectIdentifier, String permission) throws AuthorizationException {
<span class="fc" id="L535"> Permission p = getPermissionResolver().resolvePermission(permission);</span>
<span class="fc" id="L536"> checkPermission(subjectIdentifier, p);</span>
<span class="fc" id="L537"> }</span>
public void checkPermission(PrincipalCollection principal, Permission permission) throws AuthorizationException {
<span class="fc" id="L540"> AuthorizationInfo info = getAuthorizationInfo(principal);</span>
<span class="fc" id="L541"> checkPermission(permission, info);</span>
<span class="fc" id="L542"> }</span>
protected void checkPermission(Permission permission, AuthorizationInfo info) {
<span class="fc bfc" id="L545" title="All 2 branches covered."> if (!isPermitted(permission, info)) {</span>
<span class="fc" id="L546"> String msg = &quot;User is not permitted [&quot; + permission + &quot;]&quot;;</span>
<span class="fc" id="L547"> throw new UnauthorizedException(msg);</span>
}
<span class="fc" id="L549"> }</span>
public void checkPermissions(PrincipalCollection subjectIdentifier, String... permissions) throws AuthorizationException {
<span class="pc bpc" id="L552" title="1 of 2 branches missed."> if (permissions != null) {</span>
<span class="fc bfc" id="L553" title="All 2 branches covered."> for (String permString : permissions) {</span>
<span class="fc" id="L554"> checkPermission(subjectIdentifier, permString);</span>
}
}
<span class="fc" id="L557"> }</span>
public void checkPermissions(PrincipalCollection principal, Collection&lt;Permission&gt; permissions) throws AuthorizationException {
<span class="fc" id="L560"> AuthorizationInfo info = getAuthorizationInfo(principal);</span>
<span class="nc" id="L561"> checkPermissions(permissions, info);</span>
<span class="nc" id="L562"> }</span>
protected void checkPermissions(Collection&lt;Permission&gt; permissions, AuthorizationInfo info) {
<span class="pc bpc" id="L565" title="2 of 4 branches missed."> if (permissions != null &amp;&amp; !permissions.isEmpty()) {</span>
<span class="pc bpc" id="L566" title="1 of 2 branches missed."> for (Permission p : permissions) {</span>
<span class="nc" id="L567"> checkPermission(p, info);</span>
<span class="nc" id="L568"> }</span>
}
<span class="nc" id="L570"> }</span>
public boolean hasRole(PrincipalCollection principal, String roleIdentifier) {
<span class="fc" id="L573"> AuthorizationInfo info = getAuthorizationInfo(principal);</span>
<span class="fc" id="L574"> return hasRole(roleIdentifier, info);</span>
}
protected boolean hasRole(String roleIdentifier, AuthorizationInfo info) {
<span class="pc bpc" id="L578" title="1 of 6 branches missed."> return info != null &amp;&amp; info.getRoles() != null &amp;&amp; info.getRoles().contains(roleIdentifier);</span>
}
public boolean[] hasRoles(PrincipalCollection principal, List&lt;String&gt; roleIdentifiers) {
<span class="fc" id="L582"> AuthorizationInfo info = getAuthorizationInfo(principal);</span>
<span class="pc bpc" id="L583" title="1 of 2 branches missed."> boolean[] result = new boolean[roleIdentifiers != null ? roleIdentifiers.size() : 0];</span>
<span class="pc bpc" id="L584" title="1 of 2 branches missed."> if (info != null) {</span>
<span class="nc" id="L585"> result = hasRoles(roleIdentifiers, info);</span>
}
<span class="fc" id="L587"> return result;</span>
}
protected boolean[] hasRoles(List&lt;String&gt; roleIdentifiers, AuthorizationInfo info) {
boolean[] result;
<span class="nc bnc" id="L592" title="All 4 branches missed."> if (roleIdentifiers != null &amp;&amp; !roleIdentifiers.isEmpty()) {</span>
<span class="nc" id="L593"> int size = roleIdentifiers.size();</span>
<span class="nc" id="L594"> result = new boolean[size];</span>
<span class="nc" id="L595"> int i = 0;</span>
<span class="nc bnc" id="L596" title="All 2 branches missed."> for (String roleName : roleIdentifiers) {</span>
<span class="nc" id="L597"> result[i++] = hasRole(roleName, info);</span>
<span class="nc" id="L598"> }</span>
<span class="nc" id="L599"> } else {</span>
<span class="nc" id="L600"> result = new boolean[0];</span>
}
<span class="nc" id="L602"> return result;</span>
}
public boolean hasAllRoles(PrincipalCollection principal, Collection&lt;String&gt; roleIdentifiers) {
<span class="fc" id="L606"> AuthorizationInfo info = getAuthorizationInfo(principal);</span>
<span class="pc bpc" id="L607" title="1 of 4 branches missed."> return info != null &amp;&amp; hasAllRoles(roleIdentifiers, info);</span>
}
private boolean hasAllRoles(Collection&lt;String&gt; roleIdentifiers, AuthorizationInfo info) {
<span class="pc bpc" id="L611" title="2 of 4 branches missed."> if (roleIdentifiers != null &amp;&amp; !roleIdentifiers.isEmpty()) {</span>
<span class="fc bfc" id="L612" title="All 2 branches covered."> for (String roleName : roleIdentifiers) {</span>
<span class="pc bpc" id="L613" title="1 of 2 branches missed."> if (!hasRole(roleName, info)) {</span>
<span class="nc" id="L614"> return false;</span>
}
<span class="fc" id="L616"> }</span>
}
<span class="fc" id="L618"> return true;</span>
}
public void checkRole(PrincipalCollection principal, String role) throws AuthorizationException {
<span class="fc" id="L622"> AuthorizationInfo info = getAuthorizationInfo(principal);</span>
<span class="nc" id="L623"> checkRole(role, info);</span>
<span class="nc" id="L624"> }</span>
protected void checkRole(String role, AuthorizationInfo info) {
<span class="fc bfc" id="L627" title="All 2 branches covered."> if (!hasRole(role, info)) {</span>
<span class="fc" id="L628"> String msg = &quot;User does not have role [&quot; + role + &quot;]&quot;;</span>
<span class="fc" id="L629"> throw new UnauthorizedException(msg);</span>
}
<span class="fc" id="L631"> }</span>
public void checkRoles(PrincipalCollection principal, Collection&lt;String&gt; roles) throws AuthorizationException {
<span class="fc" id="L634"> AuthorizationInfo info = getAuthorizationInfo(principal);</span>
<span class="fc" id="L635"> checkRoles(roles, info);</span>
<span class="fc" id="L636"> }</span>
public void checkRoles(PrincipalCollection principal, String... roles) throws AuthorizationException {
<span class="fc" id="L639"> checkRoles(principal, Arrays.asList(roles));</span>
<span class="fc" id="L640"> }</span>
protected void checkRoles(Collection&lt;String&gt; roles, AuthorizationInfo info) {
<span class="pc bpc" id="L643" title="2 of 4 branches missed."> if (roles != null &amp;&amp; !roles.isEmpty()) {</span>
<span class="fc bfc" id="L644" title="All 2 branches covered."> for (String roleName : roles) {</span>
<span class="fc" id="L645"> checkRole(roleName, info);</span>
<span class="fc" id="L646"> }</span>
}
<span class="fc" id="L648"> }</span>
/**
* Calls {@code super.doClearCache} to ensure any cached authentication data is removed and then calls
* {@link #clearCachedAuthorizationInfo(org.apache.shiro.subject.PrincipalCollection)} to remove any cached
* authorization data.
* &lt;p/&gt;
* If overriding in a subclass, be sure to call {@code super.doClearCache} to ensure this behavior is maintained.
*
* @param principals the principals of the account for which to clear any cached AuthorizationInfo
* @since 1.2
*/
@Override
protected void doClearCache(PrincipalCollection principals) {
<span class="fc" id="L662"> super.doClearCache(principals);</span>
<span class="fc" id="L663"> clearCachedAuthorizationInfo(principals);</span>
<span class="fc" id="L664"> }</span>
}
</pre><div class="footer"><span class="right">Created with <a href="http://www.eclemma.org/jacoco">JaCoCo</a> 0.7.7.201606060606</span></div></body></html>