Package org.apache.slide.webdav.method

Source Code of org.apache.slide.webdav.method.AclMethod

/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/AclMethod.java,v 1.11 2001/09/21 00:38:34 dirkv Exp $
* $Revision: 1.11 $
* $Date: 2001/09/21 00:38:34 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation.  All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution, if
*    any, must include the following acknowlegement:
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowlegement may appear in the software itself,
*    if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
*    Foundation" must not be used to endorse or promote products derived
*    from this software without prior written permission. For written
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
*    nor may "Apache" appear in their names without prior written
*    permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation.  For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/

package org.apache.slide.webdav.method;

import java.security.Principal;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.*;
import org.xml.sax.SAXException;

import org.apache.util.XMLPrinter;
import org.apache.util.WebdavStatus;
import org.apache.util.DOMWriter;
import org.apache.slide.authenticate.CredentialsToken;
import org.apache.slide.common.*;
import org.apache.slide.security.AccessDeniedException;
import org.apache.slide.security.NodePermission;
import org.apache.slide.webdav.*;
import org.apache.slide.structure.*;
import org.apache.slide.lock.*;
import org.apache.slide.content.*;

/**
* ACL method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
* @author Dirk Verbeeck
*/
public class AclMethod extends WebdavMethod {
   
   
    // -------------------------------------------------------------- Constants
   
   
    protected static final int PRIVILEGE_ALL = 0;
    protected static final int PRIVILEGE_READ = 1;
    protected static final int PRIVILEGE_READ_OBJECT = 2;
    protected static final int PRIVILEGE_READ_REVISION_METADATA = 3;
    protected static final int PRIVILEGE_READ_REVISION_CONTENT = 4;
    protected static final int PRIVILEGE_WRITE = 5;
    protected static final int PRIVILEGE_CREATE_OBJECT = 6;
    protected static final int PRIVILEGE_REMOVE_OBJECT = 7;
    protected static final int PRIVILEGE_LOCK_OBJECT = 8;
    protected static final int PRIVILEGE_READ_LOCKS = 9;
    protected static final int PRIVILEGE_CREATE_REVISION_METADATA = 10;
    protected static final int PRIVILEGE_MODIFY_REVISION_METADATA = 11;
    protected static final int PRIVILEGE_REMOVE_REVISION_METADATA = 12;
    protected static final int PRIVILEGE_CREATE_REVISION_CONTENT = 13;
    protected static final int PRIVILEGE_MODIFY_REVISION_CONTENT = 14;
    protected static final int PRIVILEGE_REMOVE_REVISION_CONTENT = 15;
    protected static final int PRIVILEGE_READ_ACL = 16;
    protected static final int PRIVILEGE_WRITE_ACL = 17;
    protected static final int PRIVILEGE_GRANT_PERMISSION = 18;
    protected static final int PRIVILEGE_REVOKE_PERMISSION = 19;
   
   
    // ----------------------------------------------------- Instance Variables
   
   
    /**
     * Resource on which permissions will be modified.
     */
    protected String resourcePath;
   
   
    /**
     * Permissions to set.
     */
    protected Vector permissions = new Vector();
   
   
    /**
     * Namespace configuration.
     */
    protected NamespaceConfig config;
   
   
    // ----------------------------------------------------------- Constructors
   
   
    /**
     * ACL method constructor.
     *
     * @param token Namespace access token
     * @param req HTTP request
     * @param resp HTTP response
     */
    public AclMethod(NamespaceAccessToken token, HttpServletRequest req,
                     HttpServletResponse resp, WebdavServletConfig config) {
        super(token, req, resp, config);
        readRequestContent();
        this.config = token.getNamespaceConfig();
    }
   
   
    // ------------------------------------------------------ Protected Methods
   
   
    /**
     * Parse the request.
     *
     * @exception WebdavException Bad request
     */
    protected void parseRequest()
        throws WebdavException {
       
        resourcePath = requestUri;
        if (resourcePath == null) {
            resourcePath = "/";
        }
       
        if (requestBody.length() != 0) {
            try {
               
                Document document = parseRequestContent();
               
                // Get the root element of the document
                Element acl = document.getDocumentElement();
               
                NodeList aceList = acl.getElementsByTagNameNS
                    (NodeProperty.DEFAULT_NAMESPACE, "ace");
               
                for (int i = 0; i < aceList.getLength(); i++) {
                   
                    Element ace = (Element) aceList.item(i);
                   
                    // Ingnore inherited permissions
                    int inheritedCount = ace.getElementsByTagNameNS
                        (NodeProperty.DEFAULT_NAMESPACE, "inherited")
                        .getLength();
                    if (inheritedCount == 1)
                        continue;
                    if (inheritedCount > 1) {
                        resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
                        throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
                    }
                   
                    // Ignore protected (protected <-> inherited for Slide)
                    int protectedCount = ace.getElementsByTagNameNS
                        (NodeProperty.DEFAULT_NAMESPACE, "protected")
                        .getLength();
                    if (protectedCount == 1)
                        continue;
                    if (protectedCount > 1) {
                        resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
                        throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
                    }
                   
                    NodeList principalList = ace.getElementsByTagNameNS
                        (NodeProperty.DEFAULT_NAMESPACE, "principal");
                    if (principalList.getLength() != 1) {
                        resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
                        throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
                    }
                   
                    Element principalElement = (Element) principalList.item(0);
                    String principal = parsePrincipal(principalElement);
                   
                    NodeList grantList = ace.getElementsByTagNameNS
                        (NodeProperty.DEFAULT_NAMESPACE, "grant");
                    NodeList denyList = ace.getElementsByTagNameNS
                        (NodeProperty.DEFAULT_NAMESPACE, "deny");
                   
                    // there must be only ONE grant or deny element
                    if ((grantList.getLength()+denyList.getLength())!=1) {
                        resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
                        throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
                    }
                   
                    boolean negative = (denyList.getLength() > 0);
                   
                    NodeList privilegeList = null;
                   
                    if (negative) {
                        Element denyElement=(Element) denyList.item(0);
                        privilegeList = denyElement.getElementsByTagNameNS
                            (NodeProperty.DEFAULT_NAMESPACE, "privilege");
                    } else {
                        Element grantElement=(Element) grantList.item(0);
                        privilegeList = grantElement.getElementsByTagNameNS
                            (NodeProperty.DEFAULT_NAMESPACE, "privilege");
                    }
                   
                    boolean inheritable = true;
                    // FIXME : Use the very unofficial Advanced ACL spec here.
                   
                    for (int j = 0; j < privilegeList.getLength(); j++) {
                       
                        Element privilegeElement =
                            (Element) privilegeList.item(j);
                        int privilege = parsePrivilege(privilegeElement);
                       
                        switch (privilege) {
                        case PRIVILEGE_ALL:
                            addPermission(principal, "/",
                                          negative, inheritable);
                            break;
                        case PRIVILEGE_READ:
                            addPermission
                                (principal,
                                 config.getReadObjectAction().getUri(),
                                 negative, inheritable);
                            addPermission
                                (principal,
                                 config.getReadRevisionMetadataAction()
                                 .getUri(),
                                 negative, inheritable);
                            addPermission
                                (principal,
                                 config.getReadRevisionContentAction()
                                 .getUri(),
                                 negative, inheritable);
                            addPermission
                                (principal,
                                 config.getReadLocksAction().getUri(),
                                 negative, inheritable);
                            break;
                        case PRIVILEGE_READ_OBJECT:
                            addPermission
                                (principal,
                                 config.getReadObjectAction().getUri(),
                                 negative, inheritable);
                            break;
                        case PRIVILEGE_READ_REVISION_METADATA:
                            addPermission
                                (principal,
                                 config.getReadRevisionMetadataAction()
                                 .getUri(),
                                 negative, inheritable);
                            break;
                        case PRIVILEGE_READ_REVISION_CONTENT:
                            addPermission
                                (principal,
                                 config.getReadRevisionContentAction()
                                 .getUri(),
                                 negative, inheritable);
                            break;
                        case PRIVILEGE_WRITE:
                            addPermission
                                (principal,
                                 config.getCreateObjectAction().getUri(),
                                 negative, inheritable);
                            addPermission
                                (principal,
                                 config.getRemoveObjectAction().getUri(),
                                 negative, inheritable);
                            addPermission
                                (principal,
                                 config.getLockObjectAction().getUri(),
                                 negative, inheritable);
                            addPermission
                                (principal,
                                 config.getCreateRevisionMetadataAction()
                                 .getUri(),
                                 negative, inheritable);
                            addPermission
                                (principal,
                                 config.getModifyRevisionMetadataAction()
                                 .getUri(),
                                 negative, inheritable);
                            addPermission
                                (principal,
                                 config.getRemoveRevisionMetadataAction()
                                 .getUri(),
                                 negative, inheritable);
                            addPermission
                                (principal,
                                 config.getCreateRevisionContentAction()
                                 .getUri(),
                                 negative, inheritable);
                            addPermission
                                (principal,
                                 config.getModifyRevisionContentAction()
                                 .getUri(),
                                 negative, inheritable);
                            break;
                        case PRIVILEGE_READ_ACL:
                            addPermission
                                (principal,
                                 config.getReadPermissionsAction().getUri(),
                                 negative, inheritable);
                            break;
                        case PRIVILEGE_WRITE_ACL:
                            addPermission
                                (principal,
                                 config.getGrantPermissionAction().getUri(),
                                 negative, inheritable);
                            addPermission
                                (principal,
                                 config.getRevokePermissionAction().getUri(),
                                 negative, inheritable);
                            break;
                        case PRIVILEGE_GRANT_PERMISSION:
                            addPermission
                                (principal,
                                 config.getGrantPermissionAction().getUri(),
                                 negative, inheritable);
                            break;
                        case PRIVILEGE_REVOKE_PERMISSION:
                            addPermission
                                (principal,
                                 config.getRevokePermissionAction().getUri(),
                                 negative, inheritable);
                            break;
                        default:
                           // FIXME: ignore the other permissions ???
                           // System.out.println("Error: Unknown internal privilege code !!!");
                           // resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
                           // throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
                        }
                    }
                }
            } catch (AbstractMethodError e) {
                System.err.println("You are using using an incorrect older parser");
                System.err.println("that doesn't provide Element::getElementsByTagNameNS");
                System.err.println("consult the documentation for a list of valid parsers.");
                e.printStackTrace();
                resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
                throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
            } catch (SAXException e) {
                System.err.println("Error parsing requestBody:");
                System.err.println(requestBody);
                e.printStackTrace();
                resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
                throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
            } catch (ParserConfigurationException e) {
                System.err.println(e.getMessage());
                resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
                throw new WebdavException
                    (WebdavStatus.SC_INTERNAL_SERVER_ERROR);
            } catch (IOException e) {
                e.printStackTrace();
                resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
                throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
            }
        } else {
            try {
                resp.sendError(WebdavStatus.SC_BAD_REQUEST,
                                WebdavStatus.getStatusText
                               (WebdavStatus.SC_BAD_REQUEST));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
       
    }
   
   
    /**
     * Execute the request.
     *
     * @exception WebdavException
     */
    protected void executeRequest()
        throws WebdavException {
       
        try {
           
            security.setPermissions(slideToken, resourcePath,
                                    permissions.elements());
           
        } catch (Exception e) {
            resp.setStatus(getErrorCode(e)); // the default handling was good enough
            throw new WebdavException(WebdavStatus.SC_ACCEPTED, false); // abort the TA
        }
       
    }
   
   
    /**
     * Returns true
     */
    protected boolean methodNeedsTransactionSupport() {
        return true;
    }
   
   
    /**
     * Parse principal.
     *
     * @return the URI of the principal
     */
    protected String parsePrincipal(Element principal) throws WebdavException {

        // FIXME: make constants and make sure they are used in
        // AclMethod:parsePrincipal and PropFindMethod:writePrincipal
        NodeList hrefList = principal.getElementsByTagNameNS(NodeProperty.DEFAULT_NAMESPACE, "href");
        if (hrefList.getLength() == 1) {
            Element href = (Element) hrefList.item(0);
            if (href.getFirstChild().getNodeType() == Node.TEXT_NODE)
                return getSlidePath(href.getFirstChild().getNodeValue());
        } else if (hasChild(principal, NodeProperty.DEFAULT_NAMESPACE, "all")) {
            return "nobody";
        } else if (hasChild(principal, NodeProperty.DEFAULT_NAMESPACE, "self")) {
            return "~";
        } else if (hasChild(principal, NodeProperty.DEFAULT_NAMESPACE, "unauthenticated")) {
            return token.getNamespaceConfig().getUsersPath() + "/" +
                   token.getNamespaceConfig().getGuestPath();
        }
        throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
    }
   
   
    /**
     * Parse privilege.
     *
     * @return privilege
     */
    protected int parsePrivilege(Element privilege)
        throws WebdavException {
       
        if (hasChild(privilege, NodeProperty.DEFAULT_NAMESPACE, "all")) {
            return PRIVILEGE_ALL;
        } else if (hasChild(privilege, NodeProperty.DEFAULT_NAMESPACE,
                            "read")) {
            return PRIVILEGE_READ;
        } else if (hasChild(privilege, NodeProperty.DEFAULT_NAMESPACE,
                            "write")) {
            return PRIVILEGE_WRITE;
        } else if (hasChild(privilege, NodeProperty.DEFAULT_NAMESPACE,
                            "read-acl")) {
            return PRIVILEGE_READ_ACL;
        } else if (hasChild(privilege, NodeProperty.DEFAULT_NAMESPACE,
                            "write-acl")) {
            return PRIVILEGE_WRITE_ACL;
        } else if (hasChild(privilege, SLIDE_NAMESPACE, "read-object")) {
            return PRIVILEGE_READ_OBJECT;
        } else if (hasChild(privilege, SLIDE_NAMESPACE,
                            "read-revision-metadata")) {
            return PRIVILEGE_READ_REVISION_METADATA;
        } else if (hasChild(privilege, SLIDE_NAMESPACE,
                            "read-revision-content")) {
            return PRIVILEGE_READ_REVISION_CONTENT;
        } else if (hasChild(privilege, SLIDE_NAMESPACE, "create-object")) {
            return PRIVILEGE_CREATE_OBJECT;
        } else if (hasChild(privilege, SLIDE_NAMESPACE, "remove-object")) {
            return PRIVILEGE_REMOVE_OBJECT;
        } else if (hasChild(privilege, SLIDE_NAMESPACE, "lock-object")) {
            return PRIVILEGE_LOCK_OBJECT;
        } else if (hasChild(privilege, SLIDE_NAMESPACE, "read-locks")) {
            return PRIVILEGE_READ_LOCKS;
        } else if (hasChild(privilege, SLIDE_NAMESPACE,
                            "create-revision-metadata")) {
            return PRIVILEGE_CREATE_REVISION_METADATA;
        } else if (hasChild(privilege, SLIDE_NAMESPACE,
                            "modify-revision-metadata")) {
            return PRIVILEGE_MODIFY_REVISION_METADATA;
        } else if (hasChild(privilege, SLIDE_NAMESPACE,
                            "remove-revision-metadata")) {
            return PRIVILEGE_REMOVE_REVISION_METADATA;
        } else if (hasChild(privilege, SLIDE_NAMESPACE,
                            "create-revision-content")) {
            return PRIVILEGE_CREATE_REVISION_CONTENT;
        } else if (hasChild(privilege, SLIDE_NAMESPACE,
                            "modify-revision-content")) {
            return PRIVILEGE_MODIFY_REVISION_CONTENT;
        } else if (hasChild(privilege, SLIDE_NAMESPACE,
                            "remove-revision-content")) {
            return PRIVILEGE_REMOVE_REVISION_CONTENT;
        } else if (hasChild(privilege, SLIDE_NAMESPACE,
                            "grant-permission")) {
            return PRIVILEGE_GRANT_PERMISSION;
        } else if (hasChild(privilege, SLIDE_NAMESPACE,
                            "revoke-permission")) {
            return PRIVILEGE_REVOKE_PERMISSION;
        } else {
            System.err.println("Error: Unknown privilege !!!");
            throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
        }
       
    }
   
   
    /**
     * Has specified child element ?
     */
    protected boolean hasChild(Element element, String namespace,
                               String name) {
        return
            (element.getElementsByTagNameNS(namespace, name).getLength() == 1);
    }
   
   
       
    /**
     * Add permission to the list of permissions to set.
     */
    protected void addPermission(String principal, String action,
                                 boolean negative, boolean inheritable) {
        NodePermission permission = new NodePermission
            (resourcePath, principal, action, inheritable, negative);
        if (!permissions.contains(permission))
            permissions.addElement(permission);
    }
   
   
}
TOP

Related Classes of org.apache.slide.webdav.method.AclMethod

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.