| <?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>DelegatingSubject.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> > <a href="../index.html" class="el_bundle">shiro-core</a> > <a href="index.source.html" class="el_package">org.apache.shiro.subject.support</a> > <span class="el_source">DelegatingSubject.java</span></div><h1>DelegatingSubject.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 |
| * "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.shiro.subject.support; |
| |
| import org.apache.shiro.authc.AuthenticationException; |
| import org.apache.shiro.authc.AuthenticationToken; |
| import org.apache.shiro.authc.HostAuthenticationToken; |
| import org.apache.shiro.authz.AuthorizationException; |
| import org.apache.shiro.authz.Permission; |
| import org.apache.shiro.authz.UnauthenticatedException; |
| import org.apache.shiro.mgt.SecurityManager; |
| import org.apache.shiro.session.InvalidSessionException; |
| import org.apache.shiro.session.ProxiedSession; |
| import org.apache.shiro.session.Session; |
| import org.apache.shiro.session.SessionException; |
| import org.apache.shiro.session.mgt.DefaultSessionContext; |
| import org.apache.shiro.session.mgt.SessionContext; |
| import org.apache.shiro.subject.ExecutionException; |
| import org.apache.shiro.subject.PrincipalCollection; |
| import org.apache.shiro.subject.Subject; |
| import org.apache.shiro.util.CollectionUtils; |
| import org.apache.shiro.util.StringUtils; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.util.Collection; |
| import java.util.List; |
| import java.util.concurrent.Callable; |
| import java.util.concurrent.CopyOnWriteArrayList; |
| |
| /** |
| * Implementation of the {@code Subject} interface that delegates |
| * method calls to an underlying {@link org.apache.shiro.mgt.SecurityManager SecurityManager} instance for security checks. |
| * It is essentially a {@code SecurityManager} proxy. |
| * <p/> |
| * This implementation does not maintain state such as roles and permissions (only {@code Subject} |
| * {@link #getPrincipals() principals}, such as usernames or user primary keys) for better performance in a stateless |
| * architecture. It instead asks the underlying {@code SecurityManager} every time to perform |
| * the authorization check. |
| * <p/> |
| * A common misconception in using this implementation is that an EIS resource (RDBMS, etc) would |
| * be &quot;hit&quot; every time a method is called. This is not necessarily the case and is |
| * up to the implementation of the underlying {@code SecurityManager} instance. If caching of authorization |
| * data is desired (to eliminate EIS round trips and therefore improve database performance), it is considered |
| * much more elegant to let the underlying {@code SecurityManager} implementation or its delegate components |
| * manage caching, not this class. A {@code SecurityManager} is considered a business-tier component, |
| * where caching strategies are better managed. |
| * <p/> |
| * Applications from large and clustered to simple and JVM-local all benefit from |
| * stateless architectures. This implementation plays a part in the stateless programming |
| * paradigm and should be used whenever possible. |
| * |
| * @since 0.1 |
| */ |
| <span class="pc bpc" id="L71" title="1 of 2 branches missed.">public class DelegatingSubject implements Subject {</span> |
| |
| <span class="fc" id="L73"> private static final Logger log = LoggerFactory.getLogger(DelegatingSubject.class);</span> |
| |
| <span class="fc" id="L75"> private static final String RUN_AS_PRINCIPALS_SESSION_KEY =</span> |
| <span class="fc" id="L76"> DelegatingSubject.class.getName() + ".RUN_AS_PRINCIPALS_SESSION_KEY";</span> |
| |
| protected PrincipalCollection principals; |
| protected boolean authenticated; |
| protected String host; |
| protected Session session; |
| /** |
| * @since 1.2 |
| */ |
| protected boolean sessionCreationEnabled; |
| |
| protected transient SecurityManager securityManager; |
| |
| public DelegatingSubject(SecurityManager securityManager) { |
| <span class="fc" id="L90"> this(null, false, null, null, securityManager);</span> |
| <span class="fc" id="L91"> }</span> |
| |
| public DelegatingSubject(PrincipalCollection principals, boolean authenticated, String host, |
| Session session, SecurityManager securityManager) { |
| <span class="fc" id="L95"> this(principals, authenticated, host, session, true, securityManager);</span> |
| <span class="fc" id="L96"> }</span> |
| |
| //since 1.2 |
| public DelegatingSubject(PrincipalCollection principals, boolean authenticated, String host, |
| <span class="fc" id="L100"> Session session, boolean sessionCreationEnabled, SecurityManager securityManager) {</span> |
| <span class="pc bpc" id="L101" title="1 of 2 branches missed."> if (securityManager == null) {</span> |
| <span class="nc" id="L102"> throw new IllegalArgumentException("SecurityManager argument cannot be null.");</span> |
| } |
| <span class="fc" id="L104"> this.securityManager = securityManager;</span> |
| <span class="fc" id="L105"> this.principals = principals;</span> |
| <span class="fc" id="L106"> this.authenticated = authenticated;</span> |
| <span class="fc" id="L107"> this.host = host;</span> |
| <span class="fc bfc" id="L108" title="All 2 branches covered."> if (session != null) {</span> |
| <span class="fc" id="L109"> this.session = decorate(session);</span> |
| } |
| <span class="fc" id="L111"> this.sessionCreationEnabled = sessionCreationEnabled;</span> |
| <span class="fc" id="L112"> }</span> |
| |
| protected Session decorate(Session session) { |
| <span class="pc bpc" id="L115" title="1 of 2 branches missed."> if (session == null) {</span> |
| <span class="nc" id="L116"> throw new IllegalArgumentException("session cannot be null");</span> |
| } |
| <span class="fc" id="L118"> return new StoppingAwareProxiedSession(session, this);</span> |
| } |
| |
| public SecurityManager getSecurityManager() { |
| <span class="fc" id="L122"> return securityManager;</span> |
| } |
| |
| protected boolean hasPrincipals() { |
| <span class="fc bfc" id="L126" title="All 2 branches covered."> return !CollectionUtils.isEmpty(getPrincipals());</span> |
| } |
| |
| /** |
| * Returns the host name or IP associated with the client who created/is interacting with this Subject. |
| * |
| * @return the host name or IP associated with the client who created/is interacting with this Subject. |
| */ |
| public String getHost() { |
| <span class="fc" id="L135"> return this.host;</span> |
| } |
| |
| private Object getPrimaryPrincipal(PrincipalCollection principals) { |
| <span class="fc bfc" id="L139" title="All 2 branches covered."> if (!CollectionUtils.isEmpty(principals)) {</span> |
| <span class="fc" id="L140"> return principals.getPrimaryPrincipal();</span> |
| } |
| <span class="fc" id="L142"> return null;</span> |
| } |
| |
| /** |
| * @see Subject#getPrincipal() |
| */ |
| public Object getPrincipal() { |
| <span class="fc" id="L149"> return getPrimaryPrincipal(getPrincipals());</span> |
| } |
| |
| public PrincipalCollection getPrincipals() { |
| <span class="fc" id="L153"> List<PrincipalCollection> runAsPrincipals = getRunAsPrincipalsStack();</span> |
| <span class="fc bfc" id="L154" title="All 2 branches covered."> return CollectionUtils.isEmpty(runAsPrincipals) ? this.principals : runAsPrincipals.get(0);</span> |
| } |
| |
| public boolean isPermitted(String permission) { |
| <span class="pc bpc" id="L158" title="1 of 4 branches missed."> return hasPrincipals() && securityManager.isPermitted(getPrincipals(), permission);</span> |
| } |
| |
| public boolean isPermitted(Permission permission) { |
| <span class="nc bnc" id="L162" title="All 4 branches missed."> return hasPrincipals() && securityManager.isPermitted(getPrincipals(), permission);</span> |
| } |
| |
| public boolean[] isPermitted(String... permissions) { |
| <span class="nc bnc" id="L166" title="All 2 branches missed."> if (hasPrincipals()) {</span> |
| <span class="nc" id="L167"> return securityManager.isPermitted(getPrincipals(), permissions);</span> |
| } else { |
| <span class="nc" id="L169"> return new boolean[permissions.length];</span> |
| } |
| } |
| |
| public boolean[] isPermitted(List<Permission> permissions) { |
| <span class="nc bnc" id="L174" title="All 2 branches missed."> if (hasPrincipals()) {</span> |
| <span class="nc" id="L175"> return securityManager.isPermitted(getPrincipals(), permissions);</span> |
| } else { |
| <span class="nc" id="L177"> return new boolean[permissions.size()];</span> |
| } |
| } |
| |
| public boolean isPermittedAll(String... permissions) { |
| <span class="nc bnc" id="L182" title="All 4 branches missed."> return hasPrincipals() && securityManager.isPermittedAll(getPrincipals(), permissions);</span> |
| } |
| |
| public boolean isPermittedAll(Collection<Permission> permissions) { |
| <span class="nc bnc" id="L186" title="All 4 branches missed."> return hasPrincipals() && securityManager.isPermittedAll(getPrincipals(), permissions);</span> |
| } |
| |
| protected void assertAuthzCheckPossible() throws AuthorizationException { |
| <span class="pc bpc" id="L190" title="1 of 2 branches missed."> if (!hasPrincipals()) {</span> |
| <span class="fc" id="L191"> String msg = "This subject is anonymous - it does not have any identifying principals and " +</span> |
| "authorization operations require an identity to check against. A Subject instance will " + |
| "acquire these identifying principals automatically after a successful login is performed " + |
| <span class="fc" id="L194"> "be executing " + Subject.class.getName() + ".login(AuthenticationToken) or when 'Remember Me' " +</span> |
| "functionality is enabled by the SecurityManager. This exception can also occur when a " + |
| "previously logged-in Subject has logged out which " + |
| "makes it anonymous again. Because an identity is currently not known due to any of these " + |
| "conditions, authorization is denied."; |
| <span class="fc" id="L199"> throw new UnauthenticatedException(msg);</span> |
| } |
| <span class="nc" id="L201"> }</span> |
| |
| public void checkPermission(String permission) throws AuthorizationException { |
| <span class="nc" id="L204"> assertAuthzCheckPossible();</span> |
| <span class="nc" id="L205"> securityManager.checkPermission(getPrincipals(), permission);</span> |
| <span class="nc" id="L206"> }</span> |
| |
| public void checkPermission(Permission permission) throws AuthorizationException { |
| <span class="nc" id="L209"> assertAuthzCheckPossible();</span> |
| <span class="nc" id="L210"> securityManager.checkPermission(getPrincipals(), permission);</span> |
| <span class="nc" id="L211"> }</span> |
| |
| public void checkPermissions(String... permissions) throws AuthorizationException { |
| <span class="nc" id="L214"> assertAuthzCheckPossible();</span> |
| <span class="nc" id="L215"> securityManager.checkPermissions(getPrincipals(), permissions);</span> |
| <span class="nc" id="L216"> }</span> |
| |
| public void checkPermissions(Collection<Permission> permissions) throws AuthorizationException { |
| <span class="nc" id="L219"> assertAuthzCheckPossible();</span> |
| <span class="nc" id="L220"> securityManager.checkPermissions(getPrincipals(), permissions);</span> |
| <span class="nc" id="L221"> }</span> |
| |
| public boolean hasRole(String roleIdentifier) { |
| <span class="pc bpc" id="L224" title="1 of 4 branches missed."> return hasPrincipals() && securityManager.hasRole(getPrincipals(), roleIdentifier);</span> |
| } |
| |
| public boolean[] hasRoles(List<String> roleIdentifiers) { |
| <span class="nc bnc" id="L228" title="All 2 branches missed."> if (hasPrincipals()) {</span> |
| <span class="nc" id="L229"> return securityManager.hasRoles(getPrincipals(), roleIdentifiers);</span> |
| } else { |
| <span class="nc" id="L231"> return new boolean[roleIdentifiers.size()];</span> |
| } |
| } |
| |
| public boolean hasAllRoles(Collection<String> roleIdentifiers) { |
| <span class="nc bnc" id="L236" title="All 4 branches missed."> return hasPrincipals() && securityManager.hasAllRoles(getPrincipals(), roleIdentifiers);</span> |
| } |
| |
| public void checkRole(String role) throws AuthorizationException { |
| <span class="nc" id="L240"> assertAuthzCheckPossible();</span> |
| <span class="nc" id="L241"> securityManager.checkRole(getPrincipals(), role);</span> |
| <span class="nc" id="L242"> }</span> |
| |
| public void checkRoles(String... roleIdentifiers) throws AuthorizationException { |
| <span class="nc" id="L245"> assertAuthzCheckPossible();</span> |
| <span class="nc" id="L246"> securityManager.checkRoles(getPrincipals(), roleIdentifiers);</span> |
| <span class="nc" id="L247"> }</span> |
| |
| public void checkRoles(Collection<String> roles) throws AuthorizationException { |
| <span class="nc" id="L250"> assertAuthzCheckPossible();</span> |
| <span class="nc" id="L251"> securityManager.checkRoles(getPrincipals(), roles);</span> |
| <span class="nc" id="L252"> }</span> |
| |
| public void login(AuthenticationToken token) throws AuthenticationException { |
| <span class="fc" id="L255"> clearRunAsIdentitiesInternal();</span> |
| <span class="fc" id="L256"> Subject subject = securityManager.login(this, token);</span> |
| |
| PrincipalCollection principals; |
| |
| <span class="fc" id="L260"> String host = null;</span> |
| |
| <span class="pc bpc" id="L262" title="1 of 2 branches missed."> if (subject instanceof DelegatingSubject) {</span> |
| <span class="fc" id="L263"> DelegatingSubject delegating = (DelegatingSubject) subject;</span> |
| //we have to do this in case there are assumed identities - we don't want to lose the 'real' principals: |
| <span class="fc" id="L265"> principals = delegating.principals;</span> |
| <span class="fc" id="L266"> host = delegating.host;</span> |
| <span class="fc" id="L267"> } else {</span> |
| <span class="nc" id="L268"> principals = subject.getPrincipals();</span> |
| } |
| |
| <span class="pc bpc" id="L271" title="2 of 4 branches missed."> if (principals == null || principals.isEmpty()) {</span> |
| <span class="nc" id="L272"> String msg = "Principals returned from securityManager.login( token ) returned a null or " +</span> |
| "empty value. This value must be non null and populated with one or more elements."; |
| <span class="nc" id="L274"> throw new IllegalStateException(msg);</span> |
| } |
| <span class="fc" id="L276"> this.principals = principals;</span> |
| <span class="fc" id="L277"> this.authenticated = true;</span> |
| <span class="pc bpc" id="L278" title="1 of 2 branches missed."> if (token instanceof HostAuthenticationToken) {</span> |
| <span class="fc" id="L279"> host = ((HostAuthenticationToken) token).getHost();</span> |
| } |
| <span class="fc bfc" id="L281" title="All 2 branches covered."> if (host != null) {</span> |
| <span class="fc" id="L282"> this.host = host;</span> |
| } |
| <span class="fc" id="L284"> Session session = subject.getSession(false);</span> |
| <span class="pc bpc" id="L285" title="1 of 2 branches missed."> if (session != null) {</span> |
| <span class="fc" id="L286"> this.session = decorate(session);</span> |
| } else { |
| <span class="nc" id="L288"> this.session = null;</span> |
| } |
| <span class="fc" id="L290"> }</span> |
| |
| public boolean isAuthenticated() { |
| <span class="fc" id="L293"> return authenticated;</span> |
| } |
| |
| public boolean isRemembered() { |
| <span class="nc" id="L297"> PrincipalCollection principals = getPrincipals();</span> |
| <span class="nc bnc" id="L298" title="All 6 branches missed."> return principals != null && !principals.isEmpty() && !isAuthenticated();</span> |
| } |
| |
| /** |
| * Returns {@code true} if this Subject is allowed to create sessions, {@code false} otherwise. |
| * |
| * @return {@code true} if this Subject is allowed to create sessions, {@code false} otherwise. |
| * @since 1.2 |
| */ |
| protected boolean isSessionCreationEnabled() { |
| <span class="fc" id="L308"> return this.sessionCreationEnabled;</span> |
| } |
| |
| public Session getSession() { |
| <span class="fc" id="L312"> return getSession(true);</span> |
| } |
| |
| public Session getSession(boolean create) { |
| <span class="fc bfc" id="L316" title="All 2 branches covered."> if (log.isTraceEnabled()) {</span> |
| <span class="fc bfc" id="L317" title="All 4 branches covered."> log.trace("attempting to get session; create = " + create +</span> |
| "; session is null = " + (this.session == null) + |
| <span class="pc bpc" id="L319" title="1 of 2 branches missed."> "; session has id = " + (this.session != null && session.getId() != null));</span> |
| } |
| |
| <span class="fc bfc" id="L322" title="All 4 branches covered."> if (this.session == null && create) {</span> |
| |
| //added in 1.2: |
| <span class="pc bpc" id="L325" title="1 of 2 branches missed."> if (!isSessionCreationEnabled()) {</span> |
| <span class="nc" id="L326"> String msg = "Session creation has been disabled for the current subject. This exception indicates " +</span> |
| "that there is either a programming error (using a session when it should never be " + |
| "used) or that Shiro's configuration needs to be adjusted to allow Sessions to be created " + |
| <span class="nc" id="L329"> "for the current Subject. See the " + DisabledSessionException.class.getName() + " JavaDoc " +</span> |
| "for more."; |
| <span class="nc" id="L331"> throw new DisabledSessionException(msg);</span> |
| } |
| |
| <span class="fc" id="L334"> log.trace("Starting session for host {}", getHost());</span> |
| <span class="fc" id="L335"> SessionContext sessionContext = createSessionContext();</span> |
| <span class="fc" id="L336"> Session session = this.securityManager.start(sessionContext);</span> |
| <span class="fc" id="L337"> this.session = decorate(session);</span> |
| } |
| <span class="fc" id="L339"> return this.session;</span> |
| } |
| |
| protected SessionContext createSessionContext() { |
| <span class="fc" id="L343"> SessionContext sessionContext = new DefaultSessionContext();</span> |
| <span class="fc bfc" id="L344" title="All 2 branches covered."> if (StringUtils.hasText(host)) {</span> |
| <span class="fc" id="L345"> sessionContext.setHost(host);</span> |
| } |
| <span class="fc" id="L347"> return sessionContext;</span> |
| } |
| |
| private void clearRunAsIdentitiesInternal() { |
| //try/catch added for SHIRO-298 |
| try { |
| <span class="fc" id="L353"> clearRunAsIdentities();</span> |
| <span class="nc" id="L354"> } catch (SessionException se) {</span> |
| <span class="nc" id="L355"> log.debug("Encountered session exception trying to clear 'runAs' identities during logout. This " +</span> |
| "can generally safely be ignored.", se); |
| <span class="fc" id="L357"> }</span> |
| <span class="fc" id="L358"> }</span> |
| |
| public void logout() { |
| try { |
| <span class="fc" id="L362"> clearRunAsIdentitiesInternal();</span> |
| <span class="fc" id="L363"> this.securityManager.logout(this);</span> |
| } finally { |
| <span class="pc" id="L365"> this.session = null;</span> |
| <span class="pc" id="L366"> this.principals = null;</span> |
| <span class="pc" id="L367"> this.authenticated = false;</span> |
| //Don't set securityManager to null here - the Subject can still be |
| //used, it is just considered anonymous at this point. The SecurityManager instance is |
| //necessary if the subject would log in again or acquire a new session. This is in response to |
| //https://issues.apache.org/jira/browse/JSEC-22 |
| //this.securityManager = null; |
| <span class="fc" id="L373"> }</span> |
| <span class="fc" id="L374"> }</span> |
| |
| private void sessionStopped() { |
| <span class="fc" id="L377"> this.session = null;</span> |
| <span class="fc" id="L378"> }</span> |
| |
| public <V> V execute(Callable<V> callable) throws ExecutionException { |
| <span class="fc" id="L381"> Callable<V> associated = associateWith(callable);</span> |
| try { |
| <span class="fc" id="L383"> return associated.call();</span> |
| <span class="nc" id="L384"> } catch (Throwable t) {</span> |
| <span class="nc" id="L385"> throw new ExecutionException(t);</span> |
| } |
| } |
| |
| public void execute(Runnable runnable) { |
| <span class="fc" id="L390"> Runnable associated = associateWith(runnable);</span> |
| <span class="fc" id="L391"> associated.run();</span> |
| <span class="fc" id="L392"> }</span> |
| |
| public <V> Callable<V> associateWith(Callable<V> callable) { |
| <span class="fc" id="L395"> return new SubjectCallable<V>(this, callable);</span> |
| } |
| |
| public Runnable associateWith(Runnable runnable) { |
| <span class="pc bpc" id="L399" title="1 of 2 branches missed."> if (runnable instanceof Thread) {</span> |
| <span class="nc" id="L400"> String msg = "This implementation does not support Thread arguments because of JDK ThreadLocal " +</span> |
| "inheritance mechanisms required by Shiro. Instead, the method argument should be a non-Thread " + |
| "Runnable and the return value from this method can then be given to an ExecutorService or " + |
| "another Thread."; |
| <span class="nc" id="L404"> throw new UnsupportedOperationException(msg);</span> |
| } |
| <span class="fc" id="L406"> return new SubjectRunnable(this, runnable);</span> |
| } |
| |
| private class StoppingAwareProxiedSession extends ProxiedSession { |
| |
| private final DelegatingSubject owner; |
| |
| <span class="fc" id="L413"> private StoppingAwareProxiedSession(Session target, DelegatingSubject owningSubject) {</span> |
| <span class="fc" id="L414"> super(target);</span> |
| <span class="fc" id="L415"> owner = owningSubject;</span> |
| <span class="fc" id="L416"> }</span> |
| |
| public void stop() throws InvalidSessionException { |
| <span class="fc" id="L419"> super.stop();</span> |
| <span class="fc" id="L420"> owner.sessionStopped();</span> |
| <span class="fc" id="L421"> }</span> |
| } |
| |
| |
| // ====================================== |
| // 'Run As' support implementations |
| // ====================================== |
| |
| public void runAs(PrincipalCollection principals) { |
| <span class="pc bpc" id="L430" title="1 of 2 branches missed."> if (!hasPrincipals()) {</span> |
| <span class="nc" id="L431"> String msg = "This subject does not yet have an identity. Assuming the identity of another " +</span> |
| "Subject is only allowed for Subjects with an existing identity. Try logging this subject in " + |
| <span class="nc" id="L433"> "first, or using the " + Subject.Builder.class.getName() + " to build ad hoc Subject instances " +</span> |
| "with identities as necessary."; |
| <span class="nc" id="L435"> throw new IllegalStateException(msg);</span> |
| } |
| <span class="fc" id="L437"> pushIdentity(principals);</span> |
| <span class="fc" id="L438"> }</span> |
| |
| public boolean isRunAs() { |
| <span class="fc" id="L441"> List<PrincipalCollection> stack = getRunAsPrincipalsStack();</span> |
| <span class="fc bfc" id="L442" title="All 2 branches covered."> return !CollectionUtils.isEmpty(stack);</span> |
| } |
| |
| public PrincipalCollection getPreviousPrincipals() { |
| <span class="fc" id="L446"> PrincipalCollection previousPrincipals = null;</span> |
| <span class="fc" id="L447"> List<PrincipalCollection> stack = getRunAsPrincipalsStack();</span> |
| <span class="fc bfc" id="L448" title="All 2 branches covered."> int stackSize = stack != null ? stack.size() : 0;</span> |
| <span class="fc bfc" id="L449" title="All 2 branches covered."> if (stackSize > 0) {</span> |
| <span class="fc bfc" id="L450" title="All 2 branches covered."> if (stackSize == 1) {</span> |
| <span class="fc" id="L451"> previousPrincipals = this.principals;</span> |
| } else { |
| //always get the one behind the current: |
| <span class="pc bpc" id="L454" title="2 of 4 branches missed."> assert stack != null;</span> |
| <span class="fc" id="L455"> previousPrincipals = stack.get(1);</span> |
| } |
| } |
| <span class="fc" id="L458"> return previousPrincipals;</span> |
| } |
| |
| public PrincipalCollection releaseRunAs() { |
| <span class="fc" id="L462"> return popIdentity();</span> |
| } |
| |
| @SuppressWarnings("unchecked") |
| private List<PrincipalCollection> getRunAsPrincipalsStack() { |
| <span class="fc" id="L467"> Session session = getSession(false);</span> |
| <span class="fc bfc" id="L468" title="All 2 branches covered."> if (session != null) {</span> |
| <span class="fc" id="L469"> return (List<PrincipalCollection>) session.getAttribute(RUN_AS_PRINCIPALS_SESSION_KEY);</span> |
| } |
| <span class="fc" id="L471"> return null;</span> |
| } |
| |
| private void clearRunAsIdentities() { |
| <span class="fc" id="L475"> Session session = getSession(false);</span> |
| <span class="fc bfc" id="L476" title="All 2 branches covered."> if (session != null) {</span> |
| <span class="fc" id="L477"> session.removeAttribute(RUN_AS_PRINCIPALS_SESSION_KEY);</span> |
| } |
| <span class="fc" id="L479"> }</span> |
| |
| private void pushIdentity(PrincipalCollection principals) throws NullPointerException { |
| <span class="pc bpc" id="L482" title="1 of 2 branches missed."> if (CollectionUtils.isEmpty(principals)) {</span> |
| <span class="nc" id="L483"> String msg = "Specified Subject principals cannot be null or empty for 'run as' functionality.";</span> |
| <span class="nc" id="L484"> throw new NullPointerException(msg);</span> |
| } |
| <span class="fc" id="L486"> List<PrincipalCollection> stack = getRunAsPrincipalsStack();</span> |
| <span class="fc bfc" id="L487" title="All 2 branches covered."> if (stack == null) {</span> |
| <span class="fc" id="L488"> stack = new CopyOnWriteArrayList<PrincipalCollection>();</span> |
| } |
| <span class="fc" id="L490"> stack.add(0, principals);</span> |
| <span class="fc" id="L491"> Session session = getSession();</span> |
| <span class="fc" id="L492"> session.setAttribute(RUN_AS_PRINCIPALS_SESSION_KEY, stack);</span> |
| <span class="fc" id="L493"> }</span> |
| |
| private PrincipalCollection popIdentity() { |
| <span class="fc" id="L496"> PrincipalCollection popped = null;</span> |
| |
| <span class="fc" id="L498"> List<PrincipalCollection> stack = getRunAsPrincipalsStack();</span> |
| <span class="pc bpc" id="L499" title="1 of 2 branches missed."> if (!CollectionUtils.isEmpty(stack)) {</span> |
| <span class="fc" id="L500"> popped = stack.remove(0);</span> |
| Session session; |
| <span class="fc bfc" id="L502" title="All 2 branches covered."> if (!CollectionUtils.isEmpty(stack)) {</span> |
| //persist the changed stack to the session |
| <span class="fc" id="L504"> session = getSession();</span> |
| <span class="fc" id="L505"> session.setAttribute(RUN_AS_PRINCIPALS_SESSION_KEY, stack);</span> |
| } else { |
| //stack is empty, remove it from the session: |
| <span class="fc" id="L508"> clearRunAsIdentities();</span> |
| } |
| } |
| |
| <span class="fc" id="L512"> return popped;</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> |