| <?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 :: All (aggregate jar)</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> |
| } |
| |
| private static boolean isEmpty(PrincipalCollection pc) { |
| <span class="pc bpc" id="L126" title="1 of 4 branches missed."> return pc == null || pc.isEmpty();</span> |
| } |
| |
| protected boolean hasPrincipals() { |
| <span class="fc bfc" id="L130" title="All 2 branches covered."> return !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="L139"> return this.host;</span> |
| } |
| |
| private Object getPrimaryPrincipal(PrincipalCollection principals) { |
| <span class="fc bfc" id="L143" title="All 2 branches covered."> if (!isEmpty(principals)) {</span> |
| <span class="fc" id="L144"> return principals.getPrimaryPrincipal();</span> |
| } |
| <span class="fc" id="L146"> return null;</span> |
| } |
| |
| /** |
| * @see Subject#getPrincipal() |
| */ |
| public Object getPrincipal() { |
| <span class="fc" id="L153"> return getPrimaryPrincipal(getPrincipals());</span> |
| } |
| |
| public PrincipalCollection getPrincipals() { |
| <span class="fc" id="L157"> List<PrincipalCollection> runAsPrincipals = getRunAsPrincipalsStack();</span> |
| <span class="fc bfc" id="L158" 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="L162" title="1 of 4 branches missed."> return hasPrincipals() && securityManager.isPermitted(getPrincipals(), permission);</span> |
| } |
| |
| public boolean isPermitted(Permission permission) { |
| <span class="nc bnc" id="L166" title="All 4 branches missed."> return hasPrincipals() && securityManager.isPermitted(getPrincipals(), permission);</span> |
| } |
| |
| public boolean[] isPermitted(String... permissions) { |
| <span class="nc bnc" id="L170" title="All 2 branches missed."> if (hasPrincipals()) {</span> |
| <span class="nc" id="L171"> return securityManager.isPermitted(getPrincipals(), permissions);</span> |
| } else { |
| <span class="nc" id="L173"> return new boolean[permissions.length];</span> |
| } |
| } |
| |
| public boolean[] isPermitted(List<Permission> permissions) { |
| <span class="nc bnc" id="L178" title="All 2 branches missed."> if (hasPrincipals()) {</span> |
| <span class="nc" id="L179"> return securityManager.isPermitted(getPrincipals(), permissions);</span> |
| } else { |
| <span class="nc" id="L181"> return new boolean[permissions.size()];</span> |
| } |
| } |
| |
| public boolean isPermittedAll(String... permissions) { |
| <span class="nc bnc" id="L186" title="All 4 branches missed."> return hasPrincipals() && securityManager.isPermittedAll(getPrincipals(), permissions);</span> |
| } |
| |
| public boolean isPermittedAll(Collection<Permission> permissions) { |
| <span class="nc bnc" id="L190" title="All 4 branches missed."> return hasPrincipals() && securityManager.isPermittedAll(getPrincipals(), permissions);</span> |
| } |
| |
| protected void assertAuthzCheckPossible() throws AuthorizationException { |
| <span class="fc bfc" id="L194" title="All 2 branches covered."> if (!hasPrincipals()) {</span> |
| <span class="fc" id="L195"> 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="L198"> "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="L203"> throw new UnauthenticatedException(msg);</span> |
| } |
| <span class="fc" id="L205"> }</span> |
| |
| public void checkPermission(String permission) throws AuthorizationException { |
| <span class="fc" id="L208"> assertAuthzCheckPossible();</span> |
| <span class="fc" id="L209"> securityManager.checkPermission(getPrincipals(), permission);</span> |
| <span class="fc" id="L210"> }</span> |
| |
| public void checkPermission(Permission permission) throws AuthorizationException { |
| <span class="nc" id="L213"> assertAuthzCheckPossible();</span> |
| <span class="nc" id="L214"> securityManager.checkPermission(getPrincipals(), permission);</span> |
| <span class="nc" id="L215"> }</span> |
| |
| public void checkPermissions(String... permissions) throws AuthorizationException { |
| <span class="nc" id="L218"> assertAuthzCheckPossible();</span> |
| <span class="nc" id="L219"> securityManager.checkPermissions(getPrincipals(), permissions);</span> |
| <span class="nc" id="L220"> }</span> |
| |
| public void checkPermissions(Collection<Permission> permissions) throws AuthorizationException { |
| <span class="nc" id="L223"> assertAuthzCheckPossible();</span> |
| <span class="nc" id="L224"> securityManager.checkPermissions(getPrincipals(), permissions);</span> |
| <span class="nc" id="L225"> }</span> |
| |
| public boolean hasRole(String roleIdentifier) { |
| <span class="pc bpc" id="L228" title="1 of 4 branches missed."> return hasPrincipals() && securityManager.hasRole(getPrincipals(), roleIdentifier);</span> |
| } |
| |
| public boolean[] hasRoles(List<String> roleIdentifiers) { |
| <span class="nc bnc" id="L232" title="All 2 branches missed."> if (hasPrincipals()) {</span> |
| <span class="nc" id="L233"> return securityManager.hasRoles(getPrincipals(), roleIdentifiers);</span> |
| } else { |
| <span class="nc" id="L235"> return new boolean[roleIdentifiers.size()];</span> |
| } |
| } |
| |
| public boolean hasAllRoles(Collection<String> roleIdentifiers) { |
| <span class="nc bnc" id="L240" title="All 4 branches missed."> return hasPrincipals() && securityManager.hasAllRoles(getPrincipals(), roleIdentifiers);</span> |
| } |
| |
| public void checkRole(String role) throws AuthorizationException { |
| <span class="nc" id="L244"> assertAuthzCheckPossible();</span> |
| <span class="nc" id="L245"> securityManager.checkRole(getPrincipals(), role);</span> |
| <span class="nc" id="L246"> }</span> |
| |
| public void checkRoles(String... roleIdentifiers) throws AuthorizationException { |
| <span class="nc" id="L249"> assertAuthzCheckPossible();</span> |
| <span class="nc" id="L250"> securityManager.checkRoles(getPrincipals(), roleIdentifiers);</span> |
| <span class="nc" id="L251"> }</span> |
| |
| public void checkRoles(Collection<String> roles) throws AuthorizationException { |
| <span class="nc" id="L254"> assertAuthzCheckPossible();</span> |
| <span class="nc" id="L255"> securityManager.checkRoles(getPrincipals(), roles);</span> |
| <span class="nc" id="L256"> }</span> |
| |
| public void login(AuthenticationToken token) throws AuthenticationException { |
| <span class="fc" id="L259"> clearRunAsIdentitiesInternal();</span> |
| <span class="fc" id="L260"> Subject subject = securityManager.login(this, token);</span> |
| |
| PrincipalCollection principals; |
| |
| <span class="fc" id="L264"> String host = null;</span> |
| |
| <span class="pc bpc" id="L266" title="1 of 2 branches missed."> if (subject instanceof DelegatingSubject) {</span> |
| <span class="fc" id="L267"> 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="L269"> principals = delegating.principals;</span> |
| <span class="fc" id="L270"> host = delegating.host;</span> |
| <span class="fc" id="L271"> } else {</span> |
| <span class="nc" id="L272"> principals = subject.getPrincipals();</span> |
| } |
| |
| <span class="pc bpc" id="L275" title="2 of 4 branches missed."> if (principals == null || principals.isEmpty()) {</span> |
| <span class="nc" id="L276"> 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="L278"> throw new IllegalStateException(msg);</span> |
| } |
| <span class="fc" id="L280"> this.principals = principals;</span> |
| <span class="fc" id="L281"> this.authenticated = true;</span> |
| <span class="pc bpc" id="L282" title="1 of 2 branches missed."> if (token instanceof HostAuthenticationToken) {</span> |
| <span class="fc" id="L283"> host = ((HostAuthenticationToken) token).getHost();</span> |
| } |
| <span class="fc bfc" id="L285" title="All 2 branches covered."> if (host != null) {</span> |
| <span class="fc" id="L286"> this.host = host;</span> |
| } |
| <span class="fc" id="L288"> Session session = subject.getSession(false);</span> |
| <span class="fc bfc" id="L289" title="All 2 branches covered."> if (session != null) {</span> |
| <span class="fc" id="L290"> this.session = decorate(session);</span> |
| } else { |
| <span class="fc" id="L292"> this.session = null;</span> |
| } |
| <span class="fc" id="L294"> }</span> |
| |
| public boolean isAuthenticated() { |
| <span class="fc" id="L297"> return authenticated;</span> |
| } |
| |
| public boolean isRemembered() { |
| <span class="nc" id="L301"> PrincipalCollection principals = getPrincipals();</span> |
| <span class="nc bnc" id="L302" 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="L312"> return this.sessionCreationEnabled;</span> |
| } |
| |
| public Session getSession() { |
| <span class="fc" id="L316"> return getSession(true);</span> |
| } |
| |
| public Session getSession(boolean create) { |
| <span class="fc bfc" id="L320" title="All 2 branches covered."> if (log.isTraceEnabled()) {</span> |
| <span class="fc bfc" id="L321" 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="L323" title="1 of 2 branches missed."> "; session has id = " + (this.session != null && session.getId() != null));</span> |
| } |
| |
| <span class="fc bfc" id="L326" title="All 4 branches covered."> if (this.session == null && create) {</span> |
| |
| //added in 1.2: |
| <span class="pc bpc" id="L329" title="1 of 2 branches missed."> if (!isSessionCreationEnabled()) {</span> |
| <span class="nc" id="L330"> 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="L333"> "for the current Subject. See the " + DisabledSessionException.class.getName() + " JavaDoc " +</span> |
| "for more."; |
| <span class="nc" id="L335"> throw new DisabledSessionException(msg);</span> |
| } |
| |
| <span class="fc" id="L338"> log.trace("Starting session for host {}", getHost());</span> |
| <span class="fc" id="L339"> SessionContext sessionContext = createSessionContext();</span> |
| <span class="fc" id="L340"> Session session = this.securityManager.start(sessionContext);</span> |
| <span class="fc" id="L341"> this.session = decorate(session);</span> |
| } |
| <span class="fc" id="L343"> return this.session;</span> |
| } |
| |
| protected SessionContext createSessionContext() { |
| <span class="fc" id="L347"> SessionContext sessionContext = new DefaultSessionContext();</span> |
| <span class="fc bfc" id="L348" title="All 2 branches covered."> if (StringUtils.hasText(host)) {</span> |
| <span class="fc" id="L349"> sessionContext.setHost(host);</span> |
| } |
| <span class="fc" id="L351"> return sessionContext;</span> |
| } |
| |
| private void clearRunAsIdentitiesInternal() { |
| //try/catch added for SHIRO-298 |
| try { |
| <span class="fc" id="L357"> clearRunAsIdentities();</span> |
| <span class="nc" id="L358"> } catch (SessionException se) {</span> |
| <span class="nc" id="L359"> log.debug("Encountered session exception trying to clear 'runAs' identities during logout. This " +</span> |
| "can generally safely be ignored.", se); |
| <span class="fc" id="L361"> }</span> |
| <span class="fc" id="L362"> }</span> |
| |
| public void logout() { |
| try { |
| <span class="fc" id="L366"> clearRunAsIdentitiesInternal();</span> |
| <span class="fc" id="L367"> this.securityManager.logout(this);</span> |
| } finally { |
| <span class="fc" id="L369"> this.session = null;</span> |
| <span class="fc" id="L370"> this.principals = null;</span> |
| <span class="fc" id="L371"> 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="L378"> }</span> |
| |
| private void sessionStopped() { |
| <span class="fc" id="L381"> this.session = null;</span> |
| <span class="fc" id="L382"> }</span> |
| |
| public <V> V execute(Callable<V> callable) throws ExecutionException { |
| <span class="fc" id="L385"> Callable<V> associated = associateWith(callable);</span> |
| try { |
| <span class="fc" id="L387"> return associated.call();</span> |
| <span class="nc" id="L388"> } catch (Throwable t) {</span> |
| <span class="nc" id="L389"> throw new ExecutionException(t);</span> |
| } |
| } |
| |
| public void execute(Runnable runnable) { |
| <span class="fc" id="L394"> Runnable associated = associateWith(runnable);</span> |
| <span class="fc" id="L395"> associated.run();</span> |
| <span class="fc" id="L396"> }</span> |
| |
| public <V> Callable<V> associateWith(Callable<V> callable) { |
| <span class="fc" id="L399"> return new SubjectCallable<V>(this, callable);</span> |
| } |
| |
| public Runnable associateWith(Runnable runnable) { |
| <span class="pc bpc" id="L403" title="1 of 2 branches missed."> if (runnable instanceof Thread) {</span> |
| <span class="nc" id="L404"> 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="L408"> throw new UnsupportedOperationException(msg);</span> |
| } |
| <span class="fc" id="L410"> return new SubjectRunnable(this, runnable);</span> |
| } |
| |
| private class StoppingAwareProxiedSession extends ProxiedSession { |
| |
| private final DelegatingSubject owner; |
| |
| <span class="fc" id="L417"> private StoppingAwareProxiedSession(Session target, DelegatingSubject owningSubject) {</span> |
| <span class="fc" id="L418"> super(target);</span> |
| <span class="fc" id="L419"> owner = owningSubject;</span> |
| <span class="fc" id="L420"> }</span> |
| |
| public void stop() throws InvalidSessionException { |
| <span class="fc" id="L423"> super.stop();</span> |
| <span class="fc" id="L424"> owner.sessionStopped();</span> |
| <span class="fc" id="L425"> }</span> |
| } |
| |
| |
| // ====================================== |
| // 'Run As' support implementations |
| // ====================================== |
| |
| public void runAs(PrincipalCollection principals) { |
| <span class="pc bpc" id="L434" title="1 of 2 branches missed."> if (!hasPrincipals()) {</span> |
| <span class="nc" id="L435"> 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="L437"> "first, or using the " + Subject.Builder.class.getName() + " to build ad hoc Subject instances " +</span> |
| "with identities as necessary."; |
| <span class="nc" id="L439"> throw new IllegalStateException(msg);</span> |
| } |
| <span class="fc" id="L441"> pushIdentity(principals);</span> |
| <span class="fc" id="L442"> }</span> |
| |
| public boolean isRunAs() { |
| <span class="fc" id="L445"> List<PrincipalCollection> stack = getRunAsPrincipalsStack();</span> |
| <span class="fc bfc" id="L446" title="All 2 branches covered."> return !CollectionUtils.isEmpty(stack);</span> |
| } |
| |
| public PrincipalCollection getPreviousPrincipals() { |
| <span class="fc" id="L450"> PrincipalCollection previousPrincipals = null;</span> |
| <span class="fc" id="L451"> List<PrincipalCollection> stack = getRunAsPrincipalsStack();</span> |
| <span class="fc bfc" id="L452" title="All 2 branches covered."> int stackSize = stack != null ? stack.size() : 0;</span> |
| <span class="fc bfc" id="L453" title="All 2 branches covered."> if (stackSize > 0) {</span> |
| <span class="fc bfc" id="L454" title="All 2 branches covered."> if (stackSize == 1) {</span> |
| <span class="fc" id="L455"> previousPrincipals = this.principals;</span> |
| } else { |
| //always get the one behind the current: |
| <span class="pc bpc" id="L458" title="2 of 4 branches missed."> assert stack != null;</span> |
| <span class="fc" id="L459"> previousPrincipals = stack.get(1);</span> |
| } |
| } |
| <span class="fc" id="L462"> return previousPrincipals;</span> |
| } |
| |
| public PrincipalCollection releaseRunAs() { |
| <span class="fc" id="L466"> return popIdentity();</span> |
| } |
| |
| @SuppressWarnings("unchecked") |
| private List<PrincipalCollection> getRunAsPrincipalsStack() { |
| <span class="fc" id="L471"> Session session = getSession(false);</span> |
| <span class="fc bfc" id="L472" title="All 2 branches covered."> if (session != null) {</span> |
| <span class="fc" id="L473"> return (List<PrincipalCollection>) session.getAttribute(RUN_AS_PRINCIPALS_SESSION_KEY);</span> |
| } |
| <span class="fc" id="L475"> return null;</span> |
| } |
| |
| private void clearRunAsIdentities() { |
| <span class="fc" id="L479"> Session session = getSession(false);</span> |
| <span class="fc bfc" id="L480" title="All 2 branches covered."> if (session != null) {</span> |
| <span class="fc" id="L481"> session.removeAttribute(RUN_AS_PRINCIPALS_SESSION_KEY);</span> |
| } |
| <span class="fc" id="L483"> }</span> |
| |
| private void pushIdentity(PrincipalCollection principals) throws NullPointerException { |
| <span class="pc bpc" id="L486" title="1 of 2 branches missed."> if (isEmpty(principals)) {</span> |
| <span class="nc" id="L487"> String msg = "Specified Subject principals cannot be null or empty for 'run as' functionality.";</span> |
| <span class="nc" id="L488"> throw new NullPointerException(msg);</span> |
| } |
| <span class="fc" id="L490"> List<PrincipalCollection> stack = getRunAsPrincipalsStack();</span> |
| <span class="fc bfc" id="L491" title="All 2 branches covered."> if (stack == null) {</span> |
| <span class="fc" id="L492"> stack = new CopyOnWriteArrayList<PrincipalCollection>();</span> |
| } |
| <span class="fc" id="L494"> stack.add(0, principals);</span> |
| <span class="fc" id="L495"> Session session = getSession();</span> |
| <span class="fc" id="L496"> session.setAttribute(RUN_AS_PRINCIPALS_SESSION_KEY, stack);</span> |
| <span class="fc" id="L497"> }</span> |
| |
| private PrincipalCollection popIdentity() { |
| <span class="fc" id="L500"> PrincipalCollection popped = null;</span> |
| |
| <span class="fc" id="L502"> List<PrincipalCollection> stack = getRunAsPrincipalsStack();</span> |
| <span class="pc bpc" id="L503" title="1 of 2 branches missed."> if (!CollectionUtils.isEmpty(stack)) {</span> |
| <span class="fc" id="L504"> popped = stack.remove(0);</span> |
| Session session; |
| <span class="fc bfc" id="L506" title="All 2 branches covered."> if (!CollectionUtils.isEmpty(stack)) {</span> |
| //persist the changed stack to the session |
| <span class="fc" id="L508"> session = getSession();</span> |
| <span class="fc" id="L509"> session.setAttribute(RUN_AS_PRINCIPALS_SESSION_KEY, stack);</span> |
| } else { |
| //stack is empty, remove it from the session: |
| <span class="fc" id="L512"> clearRunAsIdentities();</span> |
| } |
| } |
| |
| <span class="fc" id="L516"> return popped;</span> |
| } |
| } |
| </pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.3.201901230119</span></div></body></html> |