001/**
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
005 *
006 * The contents of this file are subject to the terms
007 * of the Common Development and Distribution License
008 * (the License). You may not use this file except in
009 * compliance with the License.
010 *
011 * You can obtain a copy of the License at
012 * https://opensso.dev.java.net/public/CDDLv1.0.html or
013 * opensso/legal/CDDLv1.0.txt
014 * See the License for the specific language governing
015 * permission and limitations under the License.
016 *
017 * When distributing Covered Code, include this CDDL
018 * Header Notice in each file and include the License file
019 * at opensso/legal/CDDLv1.0.txt.
020 * If applicable, add the following below the CDDL Header,
021 * with the fields enclosed by brackets [] replaced by
022 * your own identifying information:
023 * "Portions Copyrighted [year] [name of copyright owner]"
024 *
025 * $Id: ResourceAccessStatement.java,v 1.2 2008/06/25 05:47:20 qcheng Exp $
026 *
027 */
028
029
030package com.sun.identity.liberty.ws.security;
031
032import com.sun.identity.liberty.ws.common.wsse.WSSEConstants;
033import com.sun.identity.liberty.ws.disco.EncryptedResourceID;
034import com.sun.identity.liberty.ws.disco.ResourceID;
035
036import com.sun.identity.saml.assertion.Subject;
037import com.sun.identity.saml.assertion.SubjectStatement;
038
039import com.sun.identity.saml.common.SAMLRequesterException;
040import com.sun.identity.saml.common.SAMLConstants;
041import com.sun.identity.saml.common.SAMLException;
042import com.sun.identity.saml.common.SAMLUtils;
043
044import org.w3c.dom.Element;
045import org.w3c.dom.Node;
046import org.w3c.dom.NodeList;
047
048/**
049 * The <code>ResourceAccessStatement</code> class conveys information regarding
050 * the accessing entities and the resource for which access is being attempted.
051 *
052 * @supported.all.api
053 */
054public class ResourceAccessStatement extends SubjectStatement {
055    /**
056     * The Statement is an Resource Access Statement.
057     */
058    public final static int RESOURCEACCESS_STATEMENT = 4;
059    private ResourceID _resourceID = null;
060    private EncryptedResourceID _encryptedResourceID = null;
061    
062    protected ProxySubject _proxySubject = null;
063    protected SessionContext _sessionContext = null;
064    
065    /**
066     * Constructs an <code>ResourceAccessStatement</code> object from a DOM
067     * Element.
068     *
069     * @param element representing a DOM tree element
070     * @throws SAMLException if there is an error in the sender or in the
071     *         element definition.
072     */
073    public ResourceAccessStatement(Element element) throws SAMLException {
074        // make sure input is not null
075        if (element == null) {
076            SAMLUtils.debug.message("ResourceAccessStatement: null input.");
077            throw new SAMLRequesterException(
078                    SAMLUtils.bundle.getString("nullInput"));
079        }
080        // check if it's an ResourceAccessStatement
081        boolean valid = SAMLUtils.checkStatement(element,
082                "ResourceAccessStatement");
083        if (!valid) {
084            SAMLUtils.debug.message("ResourceAccessStatement: Wrong input.");
085            throw new SAMLRequesterException(
086                    SAMLUtils.bundle.getString("wrongInput"));
087        }
088        
089        //Handle the children elements of ResourceAccessStatement
090        NodeList nodes = element.getChildNodes();
091        int nodeCount = nodes.getLength();
092        if (nodeCount > 0) {
093            for (int i = 0; i < nodeCount; i++) {
094                Node currentNode = nodes.item(i);
095                if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
096                    String tagName = currentNode.getLocalName();
097                    String tagNS = currentNode.getNamespaceURI();
098                    if ((tagName == null) || tagName.length() == 0 ||
099                            tagNS == null || tagNS.length() == 0) {
100                        if (SAMLUtils.debug.messageEnabled()) {
101                            SAMLUtils.debug.message("ResourceAccessStatement:" +
102                                    "The tag name or tag namespace of child" +
103                                    " element is either null or empty.");
104                        }
105                        throw new SAMLRequesterException(
106                                SAMLUtils.bundle.getString("nullInput"));
107                    }
108                    if (tagName.equals("Subject") &&
109                            tagNS.equals(
110                                    SAMLConstants.assertionSAMLNameSpaceURI)) {
111                        if (this._subject != null) {
112                            if (SAMLUtils.debug.messageEnabled()) {
113                                SAMLUtils.debug.message("ResourceAccess" +
114                                   "Statement:should only contain one subject");
115                            }
116                            throw new SAMLRequesterException(
117                                    SAMLUtils.bundle.getString("oneElement"));
118                        } else {
119                            this._subject = new Subject((Element) currentNode);
120                        }
121                    } else if (tagName.equals("ResourceID") &&
122                            tagNS.equals(WSSEConstants.NS_DISCO)) {
123                        if (_resourceID != null ||
124                                _encryptedResourceID != null) {
125                            if (SAMLUtils.debug.messageEnabled()) {
126                                SAMLUtils.debug.message("ResourceAccess"+
127                                        "Statement: should at most " +
128                                        "contain one ResourceIDGroup.");
129                            }
130                            throw new SAMLRequesterException(
131                                    SAMLUtils.bundle.getString("oneElement"));
132                        }
133                        try {
134                            _resourceID = new ResourceID((Element)currentNode);
135                        } catch (Exception ex) {
136                            throw new SAMLRequesterException(ex.getMessage());
137                        }
138                    } else if (tagName.equals("EncryptedResourceID") &&
139                            tagNS.equals(WSSEConstants.NS_DISCO)) {
140                        if (_resourceID != null ||
141                                _encryptedResourceID != null) {
142                            if (SAMLUtils.debug.messageEnabled()) {
143                                SAMLUtils.debug.message("ResourceAccess"+
144                                        "Statement: should at most " +
145                                        "contain one ResourceIDGroup.");
146                            }
147                            throw new SAMLRequesterException(
148                                    SAMLUtils.bundle.getString("oneElement"));
149                        }
150                        try {
151                            _encryptedResourceID =
152                                 new EncryptedResourceID((Element)currentNode);
153                        } catch (Exception ex) {
154                            throw new SAMLRequesterException(ex.getMessage());
155                        }
156                    } else if (tagName.equals("ProxySubject") &&
157                            tagNS.equals(WSSEConstants.NS_SEC)) {
158                        if (_proxySubject != null) {
159                            if (SAMLUtils.debug.messageEnabled()) {
160                                SAMLUtils.debug.message("ResourceAccess"+
161                                        "Statement: should at most " +
162                                        "contain one ProxySubject.");
163                            }
164                            throw new SAMLRequesterException(
165                                    SAMLUtils.bundle.getString("oneElement"));
166                        } else {
167                            _proxySubject = new ProxySubject((Element)
168                            currentNode);
169                        }
170                    } else if (tagName.equals("SessionContext") &&
171                            tagNS.equals(WSSEConstants.NS_SEC)) {
172                        if (_sessionContext != null) {
173                            if (SAMLUtils.debug.messageEnabled()) {
174                                SAMLUtils.debug.message("ResourceAccess"+
175                                        "Statement: should at most " +
176                                        "contain one SessionContext.");
177                            }
178                            throw new SAMLRequesterException(
179                                    SAMLUtils.bundle.getString("oneElement"));
180                        } else {
181                            _sessionContext = new SessionContext((Element)
182                            currentNode);
183                        }
184                    } else {
185                        if (SAMLUtils.debug.messageEnabled()) {
186                            SAMLUtils.debug.message("ResourceAccessStatement:"+
187                                    "Wrong element " + tagName + "included.");
188                        }
189                        throw new SAMLRequesterException(
190                                SAMLUtils.bundle.getString("wrongInput"));
191                    }
192                } // end of if (currentNode.getNodeType() == Node.ELEMENT_NODE)
193            } // end of for loop
194        }  // end of if (nodeCount > 0)
195        
196        // check if the subject is null
197        if (this._subject == null) {
198            if (SAMLUtils.debug.messageEnabled()) {
199                SAMLUtils.debug.message("ResourceAccessStatement should " +
200                        "contain one subject.");
201            }
202            throw new SAMLRequesterException(
203                    SAMLUtils.bundle.getString("missingElement"));
204        }
205    }
206    
207    /**
208     * Constructs a <code>ResourceAccessStatement</code> object from a
209     * <code>String</code> object and a <code>Subject</code>.
210     *
211     * @param resourceID <code>String</code>.
212     * @param subject <code>Subject</code> object.
213     * @throws SAMLException if subject is null.
214     */
215    public ResourceAccessStatement(String resourceID,
216            Subject subject) throws SAMLException {
217        // check if the subject is null
218        if (subject == null) {
219            if (SAMLUtils.debug.messageEnabled()) {
220                SAMLUtils.debug.message("ResourceAccessStatement: should" +
221                        " contain one subject.");
222            }
223            throw new SAMLRequesterException(
224                    SAMLUtils.bundle.getString("oneElement"));
225        } else {
226            this._subject = subject;
227        }
228        _resourceID = new ResourceID(resourceID);
229    }
230    
231    /**
232     * Constructs a <code>ResourceAccessStatement</code> object from a
233     * <code>String</code> object, <code>ProxySubject</code> object and
234     * a <code>Subject</code>.
235     *
236     * @param resourceID <code>String</code>.
237     * @param proxySubject <code>ProxySubject</code> object.
238     * @param subject <code>Subject</code> object.
239     * @throws SAMLException if subject is null.
240     */
241    public ResourceAccessStatement(String resourceID,
242            ProxySubject proxySubject,
243            Subject subject) throws SAMLException {
244        if (subject == null) {
245            if (SAMLUtils.debug.messageEnabled()) {
246                SAMLUtils.debug.message("ResourceAccessStatement: should" +
247                        " contain one subject.");
248            }
249            throw new SAMLRequesterException(
250                    SAMLUtils.bundle.getString("oneElement"));
251        } else {
252            this._subject = subject;
253        }
254        _resourceID = new ResourceID(resourceID);
255        _proxySubject = proxySubject;
256    }
257    
258    /**
259     * Constructs a <code>ResourceAccessStatement</code> object from a
260     * <code>String</code> object, <code>ProxySubject</code> object, a
261     * <code>SessionContext</code> object and a <code>Subject</code>.
262     *
263     * @param resourceID resource ID.
264     * @param proxySubject <code>ProxySubject</code> object.
265     * @param sessionContext <code>SessionContext</code> object.
266     * @param subject <code>Subject</code> object.
267     * @throws SAMLException if subject is null.
268     */
269    public ResourceAccessStatement(String resourceID,
270            ProxySubject proxySubject,
271            SessionContext sessionContext,
272            Subject subject) throws SAMLException {
273        // check if the subject is null
274        if (subject == null) {
275            if (SAMLUtils.debug.messageEnabled()) {
276                SAMLUtils.debug.message("ResourceAccessStatement: should" +
277                        " contain one subject.");
278            }
279            throw new SAMLRequesterException(
280                    SAMLUtils.bundle.getString("oneElement"));
281        } else {
282            this._subject = subject;
283        }
284        _resourceID = new ResourceID(resourceID);
285        _proxySubject = proxySubject;
286        _sessionContext = sessionContext;
287        
288    }
289    
290    
291    /**
292     * Constructs a <code>ResourceAccessStatement</code> object from a
293     * <code>ResourceID</code> object, <code>ProxySubject</code> object, a
294     * <code>SessionContext</code> object and a <code>Subject</code>.
295     *
296     * @param resourceID resource ID.
297     * @param proxySubject <code>ProxySubject</code> object.
298     * @param sessionContext <code>SessionContext</code> object.
299     * @param subject <code>Subject</code> object.
300     * @throws SAMLException if subject is null.
301     */
302    public ResourceAccessStatement(ResourceID resourceID,
303            ProxySubject proxySubject,
304            SessionContext sessionContext,
305            Subject subject) throws SAMLException {
306        // check if the subject is null
307        if (subject == null) {
308            if (SAMLUtils.debug.messageEnabled()) {
309                SAMLUtils.debug.message("ResourceAccessStatement: should" +
310                        " contain one subject.");
311            }
312            throw new SAMLRequesterException(
313                    SAMLUtils.bundle.getString("oneElement"));
314        } else {
315            this._subject = subject;
316        }
317        _resourceID = resourceID;
318        _proxySubject = proxySubject;
319        _sessionContext = sessionContext;
320        
321    }
322    
323    /**
324     * Constructs a <code>ResourceAccessStatement</code> object from a
325     * <code>EncryptedResourceID</code> object, <code>ProxySubject</code>
326     * object, a <code>SessionContext</code> object and a <code>Subject</code>.
327     *
328     * @param encryptedResourceID the encrypted resource ID.
329     * @param proxySubject <code>ProxySubject</code> object.
330     * @param sessionContext <code>SessionContext</code> object.
331     * @param subject <code>Subject</code> object.
332     * @throws SAMLException if subject is null.
333     */
334    public ResourceAccessStatement(EncryptedResourceID encryptedResourceID,
335            ProxySubject proxySubject,
336            SessionContext sessionContext,
337            Subject subject) throws SAMLException {
338        // check if the subject is null
339        if (subject == null) {
340            if (SAMLUtils.debug.messageEnabled()) {
341                SAMLUtils.debug.message("ResourceAccessStatement: should" +
342                        " contain one subject.");
343            }
344            throw new SAMLRequesterException(
345                    SAMLUtils.bundle.getString("oneElement"));
346        } else {
347            this._subject = subject;
348        }
349        _encryptedResourceID = encryptedResourceID;
350        _proxySubject = proxySubject;
351        _sessionContext = sessionContext;
352        
353    }
354    
355    
356    /**
357     * Gets the <code>ResourceID</code> from this
358     * <code>ResourceAccessStatement</code> object.
359     * @return resource ID
360     */
361    public String getResourceID() {
362        return _resourceID == null ? null : _resourceID.getResourceID();
363    }
364    
365    /**
366     * Gets the <code>ResourceID</code> object from this
367     * <code>ResourceAccessStatement</code> object.
368     * @return resource ID
369     */
370    public ResourceID getResourceIDObject() {
371        return _resourceID;
372    }
373    
374    /**
375     * Gets the <code>EncryptedResourceID</code> object from this
376     * <code>ResourceAccessStatement</code> object.
377     * @return encrypted resource ID
378     */
379    public EncryptedResourceID getEncryptedResourceID() {
380        return _encryptedResourceID;
381    }
382    
383    
384    /**
385     * Sets the <code>ResourceID</code> for this
386     * <code>ResourceAccessStatement</code> object.
387     *
388     * @param resourceID Resource ID.
389     * @return true if the operation is successful. Otherwise return false.
390     */
391    public boolean setResourceID(String resourceID) {
392        if (resourceID == null) {
393            if (SAMLUtils.debug.messageEnabled()) {
394                SAMLUtils.debug.message("ResourceAccessStatement: " +
395                        "setResourceID:Input is null.");
396            }
397            return false;
398        }
399        _resourceID = new ResourceID(resourceID);
400        return true;
401    }
402    
403    
404    /**
405     * Sets the <code>ResourceID</code> for this
406     * <code>ResourceAccessStatement</code> object.
407     *
408     * @param resourceID Resource ID.
409     */
410    public void setResourceID(ResourceID resourceID) {
411        _resourceID = resourceID;
412    }
413    
414    /**
415     * Sets the <code>EncryptedResourceID</code> for this
416     * <code>ResourceAccessStatement</code> object.
417     *
418     * @param resourceID encrypted Resource ID.
419     */
420    public void setEncryptedResourceID(EncryptedResourceID resourceID) {
421        _encryptedResourceID = resourceID;
422    }
423    
424    /**
425     * Returns the type of the Statement.
426     *
427     * @return An integer which represents <code>ResourceAccessStatement</code>
428     * internally.
429     */
430    public int getStatementType() {
431        return RESOURCEACCESS_STATEMENT;
432    }
433    
434    /**
435     * Sets the <code>SessionContext</code> for this
436     * <code>ResourceAccessStatement</code> object.
437     *
438     * @param sessionContext Session context object
439     * @return true if the operation is successful. Otherwise return false.
440     */
441    public boolean setSessionContext(SessionContext sessionContext) {
442        if (sessionContext == null) {
443            if (SAMLUtils.debug.messageEnabled()) {
444                SAMLUtils.debug.message("ResourceAccessStatement: " +
445                        "setSessionContext: Input is null.");
446            }
447            return false;
448        }
449        _sessionContext = sessionContext;
450        return true;
451    }
452    
453    /**
454     * Gets the <code>SessionContext</code> from this
455     * <code>ResourceAccessStatement</code> object.
456     *
457     * @return <code>SessionContext</code>.
458     */
459    public SessionContext getSessionContext() {
460        return _sessionContext;
461    }
462    
463    /**
464     * Returns the <code>ProxySubject</code> in the
465     * <code>ResourceAccessStatement</code>.
466     *
467     * @return <code>ProxySubject</code>.
468     */
469    public ProxySubject getProxySubject() {
470        return _proxySubject;
471    }
472
473    /**
474     * Returns a String representation of the
475     * <code>ResourceAccessStatement</code>.
476     *
477     * @return A String representation of the
478     *         <code>ResourceAccessStatement</code> element.
479     */
480    public String toString()  {
481        return toString(true, false);
482    }
483    
484    /**
485     * Returns a String representation of the
486     * <code>ResourceAccessStatement</code>.
487     *
488     * @param includeNS Determines whether or not the namespace qualifier is
489     *        prepended  to the Element when converted.
490     * @param declareNS Determines whether or not the namespace is declared
491     *        within the Element.
492     * @return A string representation of the
493     *         <code>ResourceAccessStatement</code> element.
494     */
495    public  String  toString(boolean includeNS, boolean declareNS)  {
496        
497        StringBuffer result = new StringBuffer(1000);
498        result.append("<").append(WSSEConstants.TAG_SEC + ":").
499                append(WSSEConstants.TAG_RESOURCEACCESSSTATEMENT).append(" ").
500                append(WSSEConstants.TAG_XML_SEC).append("=").
501                append("\"").append(WSSEConstants.NS_SEC).append("\"");
502        
503        result.append(">\n").append(this._subject.toString(includeNS, true));
504        
505        if (_resourceID != null) {
506            result.append(_resourceID);
507        } else if (_encryptedResourceID != null) {
508            result.append(_encryptedResourceID);
509        }
510        
511        if (_proxySubject!=null) {
512            result.append(_proxySubject.toString(includeNS, true));
513            if (_sessionContext!=null) {
514                try {
515                    result.append(
516                            _sessionContext.toXMLString(includeNS, true));
517                } catch (Exception e) {
518                }
519            }
520        }
521        
522        result.append("</").append(WSSEConstants.TAG_SEC + ":").
523                append(WSSEConstants.TAG_RESOURCEACCESSSTATEMENT).append(">\n");
524        return(result.toString());
525    }
526}