You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by re...@apache.org on 2001/03/26 09:06:20 UTC
cvs commit: jakarta-slide/src/webdav/server/org/apache/slide/webdav/method AclMethod.java
remm 01/03/25 23:06:20
Added: src/webdav/server/org/apache/slide/webdav/method
AclMethod.java
Log:
- Support for WebDAV ACL ACL method.
Revision Changes Path
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/AclMethod.java
Index: AclMethod.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/AclMethod.java,v 1.1 2001/03/26 07:06:20 remm Exp $
* $Revision: 1.1 $
* $Date: 2001/03/26 07:06:20 $
*
* ====================================================================
*
* 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 org.w3c.dom.*;
import org.xml.sax.InputSource;
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.*;
import javax.xml.parsers.DocumentBuilder;
/**
* ACL method.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
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_READ_ACL = 15;
protected static final int PRIVILEGE_WRITE_ACL = 16;
protected static final int PRIVILEGE_GRANT_PERMISSION = 17;
protected static final int PRIVILEGE_REVOKE_PERMISSION = 18;
// ----------------------------------------------------- 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(GenericServlet servlet, NamespaceAccessToken token,
HttpServletRequest req, HttpServletResponse resp) {
super(servlet, token, req, resp);
readRequestContent();
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 = documentBuilder.parse(new InputSource(
(new StringReader(requestBody))));
// Get the root element of the document
Element rootElement = document.getDocumentElement();
//NodeList childList = rootElement.getChildNodes();
NodeList aclList =
rootElement.getElementsByTagNameNS
(NodeProperty.DEFAULT_NAMESPACE, "acl");
if (aclList.getLength() != 1) {
resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
}
Element acl = (Element) aclList.item(0);
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");
if ((grantList.getLength() > 0) &&
(denyList.getLength() > 0)) {
resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
}
if ((grantList.getLength() == 0) &&
(denyList.getLength() == 0)) {
resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
}
boolean negative = (denyList.getLength() > 0);
NodeList privilegeList = null;
if (negative) {
privilegeList = denyList;
} else {
privilegeList = grantList;
}
boolean inheritable = true;
// FIXME : Use the very unofficial Advanced ACL spec here.
for (int j = 0; i < 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;
}
}
}
} catch (SAXException e) {
resp.setStatus(WebdavStatus.SC_BAD_REQUEST);
throw new WebdavException(WebdavStatus.SC_BAD_REQUEST);
} 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 (ObjectNotFoundException e) {
// 404 - Not found
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_NOT_FOUND);
} catch (AccessDeniedException e) {
// 403 - Forbidden
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_FORBIDDEN);
} catch (ServiceAccessException e) {
// 500 - Internal server error
System.out.println(e.getMessage());
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
} catch (RuntimeException e) {
// 500 - Internal server error
e.printStackTrace();
resp.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
}
/**
* Returns true
*/
protected boolean methodNeedsTransactionSupport() {
return true;
}
/**
* Parse principal.
*
* @return the URI of the principal
*/
protected String parsePrincipal(Element principal)
throws WebdavException {
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 href.getFirstChild().getNodeValue();
} else if (hasChild(principal, NodeProperty.DEFAULT_NAMESPACE,
"all")) {
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,
"grant-permission")) {
return PRIVILEGE_GRANT_PERMISSION;
} else if (hasChild(privilege, SLIDE_NAMESPACE,
"revoke-permission")) {
return PRIVILEGE_REVOKE_PERMISSION;
} else {
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);
}
}