<?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="../.resources/report.css" type="text/css"/><link rel="shortcut icon" href="../.resources/report.gif" type="image/gif"/><title>TokenCancelerImpl.java</title><link rel="stylesheet" href="../.resources/prettify.css" type="text/css"/><script type="text/javascript" src="../.resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../.sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Coverage Report</a> &gt; <a href="index.source.html" class="el_package">org.apache.rahas.impl</a> &gt; <span class="el_source">TokenCancelerImpl.java</span></div><h1>TokenCancelerImpl.java</h1><pre class="source lang-java linenums">/*                                                                             
 * Copyright 2004,2005 The Apache Software Foundation.                         
 *                                                                             
 * Licensed 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.rahas.impl;

import org.apache.rahas.TokenCanceler;
import org.apache.rahas.RahasData;
import org.apache.rahas.TrustException;
import org.apache.rahas.TrustUtil;
import org.apache.rahas.RahasConstants;
import org.apache.rahas.TokenStorage;
import org.apache.rahas.Token;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.message.token.Reference;
import org.apache.ws.security.message.token.SecurityTokenReference;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMAttribute;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.context.MessageContext;

import javax.xml.namespace.QName;

/**
 * 
 */
<span class="fc" id="L39">public class TokenCancelerImpl implements TokenCanceler {</span>

    private String configFile;
    private OMElement configElement;
    private String configParamName;
    
    /**
     * Cancel the token specified in the request.
     *
     * @param data A populated &lt;code&gt;RahasData&lt;/code&gt; instance
     * @return Response SOAPEnveloper
     * @throws org.apache.rahas.TrustException
     *
     */
    public SOAPEnvelope cancel(RahasData data) throws TrustException {
<span class="fc" id="L54">        TokenCancelerConfig config = null;</span>
<span class="pc bpc" id="L55" title="1 of 2 branches missed.">        if (this.configElement != null) {</span>
<span class="nc" id="L56">            config = TokenCancelerConfig.load(configElement.</span>
                    getFirstChildWithName(SCTIssuerConfig.SCT_ISSUER_CONFIG));
        }

        // Look for the file
<span class="pc bpc" id="L61" title="2 of 4 branches missed.">        if (config == null &amp;&amp; this.configFile != null) {</span>
<span class="nc" id="L62">            config = TokenCancelerConfig.load(this.configFile);</span>
        }

        // Look for the param
<span class="pc bpc" id="L66" title="2 of 4 branches missed.">        if (config == null &amp;&amp; this.configParamName != null) {</span>
<span class="fc" id="L67">            Parameter param = data.getInMessageContext().getParameter(this.configParamName);</span>
<span class="pc bpc" id="L68" title="2 of 4 branches missed.">            if (param != null &amp;&amp; param.getParameterElement() != null) {</span>
<span class="fc" id="L69">                config = TokenCancelerConfig.load(param.getParameterElement()</span>
                        .getFirstChildWithName(SCTIssuerConfig.SCT_ISSUER_CONFIG));
            } else {
<span class="nc" id="L72">                throw new TrustException(&quot;expectedParameterMissing&quot;,</span>
                                         new String[]{this.configParamName});
            }
        }

<span class="pc bpc" id="L77" title="1 of 2 branches missed.">        if (config == null) {</span>
<span class="nc" id="L78">            throw new TrustException(&quot;missingConfiguration&quot;,</span>
                                     new String[]{SCTIssuerConfig.SCT_ISSUER_CONFIG
                                             .getLocalPart()});
        }

<span class="fc" id="L83">        OMElement rstEle = data.getRstElement();</span>
<span class="fc" id="L84">        QName cancelTagetQName = new QName(data.getWstNs(), RahasConstants.CancelBindingLocalNames.CANCEL_TARGET);</span>
<span class="fc" id="L85">        OMElement cancelTargetEle = rstEle.getFirstChildWithName(cancelTagetQName);</span>
<span class="pc bpc" id="L86" title="1 of 2 branches missed.">        if (cancelTargetEle == null) {</span>
<span class="nc" id="L87">            throw new TrustException(&quot;requiredElementNotFound&quot;,</span>
                                     new String[]{cancelTagetQName.toString()});
        }
<span class="fc" id="L90">        OMElement secTokenRefEle = cancelTargetEle</span>
                .getFirstChildWithName(new QName(WSConstants.WSSE_NS,
                        SecurityTokenReference.SECURITY_TOKEN_REFERENCE));
        String tokenId;
<span class="pc bpc" id="L94" title="1 of 2 branches missed.">        if (secTokenRefEle != null) {</span>

            /*
            &lt;o:SecurityTokenReference
                 xmlns:o=&quot;http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd&quot;&gt;
              &lt;o:Reference URI=&quot;urn:uuid:8e6a3a95-fd1b-4c24-96d4-28e875025ff7&quot;
                           ValueType=&quot;http://schemas.xmlsoap.org/ws/2005/02/sc/sct&quot; /&gt;
            &lt;/o:SecurityTokenReference&gt;
            */
<span class="fc" id="L103">            OMElement referenceEle = secTokenRefEle.getFirstChildWithName(Reference.TOKEN);</span>
<span class="pc bpc" id="L104" title="1 of 2 branches missed.">            if (referenceEle != null) {</span>
<span class="fc" id="L105">                OMAttribute uri = referenceEle.getAttribute(new QName(</span>
                        RahasConstants.CancelBindingLocalNames.URI));
<span class="pc bpc" id="L107" title="1 of 2 branches missed.">                if (uri != null) {</span>

<span class="fc" id="L109">                    tokenId = uri.getAttributeValue();</span>
<span class="pc bpc" id="L110" title="1 of 2 branches missed.">                    if (tokenId.charAt(0) == '#') {</span>
<span class="nc" id="L111">                        tokenId = tokenId.substring(1);</span>
                    }
                } else {
<span class="nc" id="L114">                    throw new TrustException(&quot;cannotDetermineTokenId&quot;);</span>
                }
<span class="fc" id="L116">            } else {</span>
<span class="nc" id="L117">                throw new TrustException(&quot;cannotDetermineTokenId&quot;);</span>
            }
<span class="fc" id="L119">        } else {</span>
            // TODO: we need to handle situation where the token itself is contained within the
            // TODO:  &lt;wst:CancelTarget&gt; element
<span class="nc" id="L122">            throw new TrustException(&quot;cannotDetermineTokenId&quot;);</span>
        }

        // Cancel the token
<span class="fc" id="L126">        MessageContext inMsgCtx = data.getInMessageContext();</span>
<span class="fc" id="L127">        TokenStorage tokenStore = TrustUtil.getTokenStore(inMsgCtx);</span>
<span class="fc" id="L128">        Token token = tokenStore.getToken(tokenId);</span>
<span class="pc bpc" id="L129" title="1 of 2 branches missed.">        if (token == null) {</span>
<span class="nc" id="L130">            throw new TrustException(&quot;tokenNotFound&quot;, new String[]{tokenId});</span>
        }
<span class="fc" id="L132">        token.setState(Token.CANCELLED);</span>
<span class="fc" id="L133">        tokenStore.update(token);</span>

        // Create the response SOAP Envelope
<span class="fc" id="L136">        SOAPEnvelope responseEnv =</span>
                TrustUtil.
                        createSOAPEnvelope(inMsgCtx.getEnvelope().getNamespace().getNamespaceURI());
        OMElement rstrElem;
<span class="fc" id="L140">        int version = data.getVersion();</span>
<span class="fc bfc" id="L141" title="All 2 branches covered.">        if (RahasConstants.VERSION_05_02 == version) {</span>
<span class="fc" id="L142">            rstrElem = TrustUtil</span>
                    .createRequestSecurityTokenResponseElement(version, responseEnv.getBody());
        } else {
<span class="fc" id="L145">            OMElement rstrcElem = TrustUtil</span>
                    .createRequestSecurityTokenResponseCollectionElement(
                            version, responseEnv.getBody());

<span class="fc" id="L149">            rstrElem = TrustUtil.createRequestSecurityTokenResponseElement(version, rstrcElem);</span>
        }
<span class="fc" id="L151">        TrustUtil.createRequestedTokenCanceledElement(version, rstrElem);</span>
<span class="fc" id="L152">        return responseEnv;</span>
    }

    /**
     * Set the configuration file of this TokenCanceller.
     * &lt;p&gt;
     * This is the text value of the &amp;lt;configuration-file&amp;gt; element of the
     * token-dispatcher-configuration
     *
     * @param configFile
     */
    public void setConfigurationFile(String configFile) {
<span class="fc" id="L164">        this.configFile = configFile;</span>
<span class="fc" id="L165">    }</span>

    /**
     * Set the configuration element of this TokenCanceller.
     * &lt;p&gt;
     * This is the &amp;lt;configuration&amp;gt; element of the
     * token-dispatcher-configuration
     *
     * @param configElement &lt;code&gt;OMElement&lt;/code&gt; representing the configuation
     */
    public void setConfigurationElement(OMElement configElement) {
<span class="fc" id="L176">        this.configElement = configElement;</span>
<span class="fc" id="L177">    }</span>

    /**
     * Set the name of the configuration parameter.
     * &lt;p&gt;
     * If this is used then there must be a
     * &lt;code&gt;org.apache.axis2.description.Parameter&lt;/code&gt; object available in
     * the via the messageContext when the &lt;code&gt;TokenIssuer&lt;/code&gt; is called.
     *
     * @param configParamName
     * @see org.apache.axis2.description.Parameter
     */
    public void setConfigurationParamName(String configParamName) {
<span class="fc" id="L190">        this.configParamName = configParamName;</span>
<span class="fc" id="L191">    }</span>

    /**
     * Returns the &lt;code&gt;wsa:Action&lt;/code&gt; of the response.
     *
     * @param data A populated &lt;code&gt;RahasData&lt;/code&gt; instance
     * @return Returns the &lt;code&gt;wsa:Action&lt;/code&gt; of the response
     * @throws org.apache.rahas.TrustException
     *
     */
    public String getResponseAction(RahasData data) throws TrustException {
<span class="fc" id="L202">        return TrustUtil.getActionValue(data.getVersion(), RahasConstants.RSTR_ACTION_CANCEL);</span>
    }
}
</pre><div class="footer"><span class="right">Created with <a href="http://www.eclemma.org/jacoco">JaCoCo</a> 0.7.5.201505241946</span></div></body></html>