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: Action.java,v 1.2 2008/06/25 05:47:31 qcheng Exp $
026 *
027 */
028
029
030package com.sun.identity.saml.assertion;
031
032import java.util.*; 
033import org.w3c.dom.*; 
034import com.sun.identity.saml.common.SAMLUtilsCommon;
035import com.sun.identity.saml.common.SAMLConstants;
036import com.sun.identity.saml.common.SAMLException;
037import com.sun.identity.saml.common.SAMLRequesterException;
038import com.sun.identity.shared.xml.XMLUtils;
039
040/**
041 *This class is designed for <code>Action</code> element in SAML core 
042 *assertion. This element specifies an action on specified resource for
043 *which permission is sought. 
044 *@supported.all.api
045 */
046public class Action {
047    //An action sought to be performed on the specified resource 
048    protected String  _action = null; 
049   
050    //represent the attribute NameSpace of the <code>Action</code> element 
051    protected String  _namespace = SAMLConstants.ACTION_NAMESPACE_NEGATION; 
052    
053    /**
054     * Constructs an action element from an existing XML block.
055     *
056     * @param element representing a DOM tree element.
057     * @exception SAMLException f there is an error in the sender or in 
058     *            the element definition.
059     */
060    public Action(Element element) throws SAMLException{
061        // make sure that the input xml block is not null
062        if (element == null) {
063            SAMLUtilsCommon.debug.message("Action: Input is null.");
064            throw new SAMLRequesterException(
065                      SAMLUtilsCommon.bundle.getString("nullInput"));
066        }
067        // Make sure this is as Action.
068        String tag = null;
069        tag = element.getLocalName(); 
070        if ((tag == null) || (!tag.equals("Action"))) {
071            SAMLUtilsCommon.debug.message("Action: wrong input");
072            throw new SAMLRequesterException(
073                      SAMLUtilsCommon.bundle.getString("wrongInput"));
074        }
075        
076        // handle the attribute of <code>Action</code> element  
077        // Note: element attributes are not children of ELEMENT_NODEs but
078        // are properties of their associated ELEMENT_NODE. 
079        NamedNodeMap atts = ((Node)element).getAttributes();  
080        int attrCount = atts.getLength(); 
081        int i = 0; 
082        for (i = 0; i < attrCount; i++) {
083            Node att = atts.item(i);
084            if (att.getNodeType() == Node.ATTRIBUTE_NODE) {
085                String attName = att.getLocalName();
086                if (attName == null || attName.length() == 0) {
087                    if (SAMLUtilsCommon.debug.messageEnabled()) {
088                        SAMLUtilsCommon.debug.message("Action: Attribute Name" +
089                                                "is either null or empty.");
090                    }
091                    throw new SAMLRequesterException(
092                              SAMLUtilsCommon.bundle.getString("nullInput"));
093                }
094                if (attName.equals("Namespace")) {
095                    _namespace = ((Attr)att).getValue().trim(); 
096                }
097                if ((_namespace == null) || (_namespace.length() == 0)) {
098                    _namespace = SAMLConstants.ACTION_NAMESPACE_NEGATION;
099                }
100            }
101        }
102        //handle the children elements of <code>Action</code>
103        NodeList  nodes = element.getChildNodes();
104        int nodeCount = nodes.getLength();
105        if (nodeCount > 0) {
106            for (i = 0; i < nodeCount; i++) {
107                Node currentNode = nodes.item(i);               
108                if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
109                    if (SAMLUtilsCommon.debug.messageEnabled()) {
110                        SAMLUtilsCommon.debug.message("Action: Wrong input");
111                    }
112                    throw new SAMLRequesterException(
113                              SAMLUtilsCommon.bundle.getString("wrongInput"));
114                }
115            }
116        }
117        _action = XMLUtils.getElementValue(element); 
118        // check if the action is null.
119        if (_action == null) {
120            if (SAMLUtilsCommon.debug.messageEnabled()) {
121                SAMLUtilsCommon.debug.message("Action is null.");    
122            }
123            throw new SAMLRequesterException(
124                      SAMLUtilsCommon.bundle.getString("missingElementValue"));
125        }
126        if (!isValid(_action, _namespace)) {
127            if (SAMLUtilsCommon.debug.messageEnabled()) {
128                SAMLUtilsCommon.debug.message("Action is invalid"); 
129            }
130            throw new SAMLRequesterException(
131                      SAMLUtilsCommon.bundle.getString("invalidAction"));
132        }
133    }
134    
135    /**
136     * Convenience constructor of &lt;Action&gt;
137     * @param namespace The attribute "namespace" of
138     *        <code>&lt;Action&gt;</code> element
139     * @param action A String representing an action
140     * @exception SAMLException if there is an error in the sender or in
141     *            the element definition.
142     */
143    public Action(String namespace, String action) throws SAMLException {
144        if (namespace == null || namespace.length() == 0) { 
145            if (SAMLUtilsCommon.debug.messageEnabled()) {
146                SAMLUtilsCommon.debug.message("Action:Take default " + 
147                                              "Attribute Namespace.");
148            }
149        } else {
150            _namespace = namespace;     
151        }
152        if (action == null || action.length() == 0) {
153            if (SAMLUtilsCommon.debug.messageEnabled()) {
154                SAMLUtilsCommon.debug.message("Action:Action is " +
155                                              "null or empty.");
156            }
157            throw new SAMLRequesterException(
158                      SAMLUtilsCommon.bundle.getString("nullInput"));
159        } else {
160            _action = action; 
161        }
162        if (!isValid(_action, _namespace)) {
163            if (SAMLUtilsCommon.debug.messageEnabled()) {
164                SAMLUtilsCommon.debug.message("Action is invalid"); 
165            }
166            throw new SAMLRequesterException(
167                      SAMLUtilsCommon.bundle.getString("invalidAction"));
168        }
169    }
170    
171    /**
172     *Check if the input action string is valid within its specified namespace.
173     *@param action A String representing the action 
174     *@param nameSpace The Actions element's namespace. There are four
175     *          namespaces that are pre-defined. Action will be checked against
176     *          these namespaces.
177     *(1) urn:oasis:names:tc:SAML:1.0:action:rwedc
178     *String used in the ActionNamespace attribute to refer to common sets of 
179     *actions to perform on resources. 
180     *Title: Read/Write/Execute/Delete/Control
181     *Defined actions: Read Write Execute Delete Control 
182     *These actions are interpreted in the normal manner, i.e. 
183     *      Read:  The subject may read the resource 
184     *      Write: The subject may modify the resource 
185     *      Execute: The subject may execute the resource 
186     *      Delete: The subject may delete the resource 
187     *      Control: The subject may specify the access control policy for the 
188     *              resource 
189     *(2) urn:oasis:names:tc:SAML:1.0:action:rwedc-negation
190     *String used in the ActionNamespace attribute to refer to common sets of 
191     *actions to perform on resources. 
192     *Title: Read/Write/Execute/Delete/Control with Negation
193     *Defined actions:
194     *Read Write Execute Delete Control ~Read ~Write ~Execute ~Delete ~Control
195     *      Read:  The subject may read the resource 
196     *      Write: The subject may modify the resource 
197     *      Execute: The subject may execute the resource 
198     *      Delete: The subject may delete the resource 
199     *      Control: The subject may specify the access control policy for the 
200     *              resource 
201     *      ~Read:  The subject may NOT read the resource 
202     *      ~Write: The subject may NOT modify the resource 
203     *      ~Execute: The subject may NOT execute the resource 
204     *      ~Delete: The subject may NOT delete the resource 
205     *      ~Control: The subject may NOT specify the access control policy for
206     *              the resource 
207     *An application MUST NOT authorize both an action and its negated form.
208     *(3) urn:oasis:names:tc:SAML:1.0:ghpp
209     *String used in the ActionNamespace attribute to refer to common sets of 
210     *actions to perform on resources. 
211     *Title: Get/Head/Put/Post
212     *Defined actions: 
213     *          GET HEAD PUT POST 
214     *These actions bind to the corresponding HTTP operations. For example a
215     *subject authorized to perform the GET action on a resource is authorized
216     *to retrieve it. The GET and HEAD actions loosely correspond to the 
217     *conventional read permission and the PUT and POST actions to the write 
218     *permission. The correspondence is not exact however since a HTTP GET 
219     *operation may cause data to be modified and a POST operation may cause
220     *modification to a resource other than the one specified in the request. 
221     *For this reason a separate Action URI specifier is provided. 
222     *(4) urn:oasis:names:tc:SAML:1.0:action:unix
223     *String used in the ActionNamespace attribute to refer to common sets of 
224     *actions to perform on resources. 
225     *Title: UNIX File Permissions
226     *Defined actions: 
227     *The defined actions are the set of UNIX file access permissions expressed
228     *in the numeric (octal) notation. The action string is a four digit numeric
229     *code: extended user group world 
230     *Where the extended access permission has the value  
231     *                  +2 if sgid is set 
232     *                  +4 if suid is set 
233     *The user group and world access permissions have the value 
234     *                  +1 if execute permission is granted 
235     *                  +2 if write permission is granted 
236     *                  +4 if read permission is granted 
237     *For example 0754 denotes the UNIX file access permission:
238     *user read, write 
239     *and execute, group read and execute and world read. 
240     *@return A boolean representation if the action is valid within its 
241     *        specified name space. If the namespace param is not one of the
242     *        four defined actions namespaces, true is returned.
243     */ 
244    private boolean isValid(String action, String namespace) {
245       if (namespace.equals(SAMLConstants.ACTION_NAMESPACE)) {
246           if (action.equals("Read")|| action.equals("Write") ||
247               action.equals("Execute") || action.equals("Delete") ||
248               action.equals("Control")) {
249               return true;
250           } else {
251               return false; 
252           }
253       }
254           
255      if (namespace.equals(SAMLConstants.ACTION_NAMESPACE_NEGATION)) {
256          if (action.equals("Read") || action.equals("~Read") ||
257              action.equals("Write") || action.equals("~Write") ||
258              action.equals("Execute") || action.equals("~Execute") ||
259              action.equals("Delete") ||  action.equals("~Delete") ||
260              action.equals("Control") || action.equals("~Control")) {
261               return true;
262           } else { 
263               return false;
264           }
265      }
266       
267      if (namespace.equals(SAMLConstants.ACTION_NAMESPACE_GHPP)) {
268          if (action.equals("GET") || action.equals("HEAD") ||
269              action.equals("PUT") || action.equals("POST")) {
270               return true;
271           } else {
272               return false; 
273           }
274      }
275       
276      if (namespace.equals(SAMLConstants.ACTION_NAMESPACE_UNIX)) {
277          int permissionNum = 0; 
278          try{
279              permissionNum = Integer.parseInt(action); 
280          } catch (NumberFormatException ne) {
281              if (SAMLUtilsCommon.debug.messageEnabled()) {
282                  SAMLUtilsCommon.debug.message("Actions: Unix " +
283                                        "file permissions " +
284                                        "error:" + ne.getMessage());
285              }
286              return false;
287          }
288          int quota = permissionNum/1000;
289          int remain = permissionNum - 1000 * quota; 
290          int tmp = 0; 
291          if (quota == 0 || quota == 2 || quota == 4 || quota == 6) {
292              for (int i = 0; i < 3; i++) {
293                  tmp = remain / 10;
294                  quota = remain - tmp * 10; 
295                  if (quota < 0 || quota > 7)
296                      return false; 
297                  remain = tmp;
298              } // end of for loop 
299              return true; 
300          } else { 
301              return false;
302          }
303      }
304      return true; 
305    }
306    
307    /** 
308     *Gets the action string
309     *@return A String representing the action
310     */
311    public String getAction() {
312        return  _action;
313    }
314    
315    /** 
316     *Gets the namespace of Action
317     *@return A String representing the name space of the action
318     */             
319    public String getNameSpace() {
320        return _namespace; 
321    }
322    
323    /**
324     *Creates a String representation of the <code>saml:Action</code> element
325     *@return A string containing the valid XML for this element
326     */
327    public String toString() {
328       return (this.toString(true, false)); 
329   }
330   
331   /**  
332    *Creates a String representation of the <code>saml:Action</code> element
333    *@param     includeNS : Determines whether or not the namespace qualifier
334    *                       is prepended to the Element when converted
335    *@param     declareNS : Determines whether or not the namespace 
336    *                       is declared within the Element.
337    *@return A string containing the valid XML for this element
338    */                       
339    public String  toString(boolean includeNS, boolean declareNS) {
340        StringBuffer result = new StringBuffer(1000);
341        String prefix = "";
342        String uri = "";
343        if (includeNS) {
344            prefix = SAMLConstants.ASSERTION_PREFIX;
345        }
346        if (declareNS) {
347            uri = SAMLConstants.assertionDeclareStr;
348        }
349        
350        result.append("<").append(prefix).append("Action ").
351                append(uri).append(" Namespace=\"").append(_namespace).
352                append("\">");  
353        result.append(_action); 
354        result.append("</").append(prefix).append("Action>\n");
355        return ((String)result.toString());
356    }                     
357}
358




























































Copyright © 2010-2017, ForgeRock All Rights Reserved.