You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by an...@apache.org on 2006/03/21 11:36:51 UTC

svn commit: r387482 [1/2] - in /jackrabbit/trunk/jcr-server: server/src/java/org/apache/jackrabbit/server/ webdav/src/java/org/apache/jackrabbit/webdav/ webdav/src/java/org/apache/jackrabbit/webdav/security/ webdav/src/java/org/apache/jackrabbit/webdav...

Author: angela
Date: Tue Mar 21 02:36:49 2006
New Revision: 387482

URL: http://svn.apache.org/viewcvs?rev=387482&view=rev
Log:
JCR-350: Add support for RFC 3744

Added:
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclProperty.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclResource.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclRestrictionsProperty.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/CurrentUserPrivilegeSetProperty.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/Principal.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/Privilege.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SecurityConstants.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SupportedPrivilege.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SupportedPrivilegeSetProperty.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/AbstractSecurityReport.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/AclPrincipalReport.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/PrincipalMatchReport.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/PrincipalSearchReport.java   (with props)
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/SearchablePropertyReport.java   (with props)
Modified:
    jackrabbit/trunk/jcr-server/server/src/java/org/apache/jackrabbit/server/AbstractWebdavServlet.java
    jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/DavMethods.java

Modified: jackrabbit/trunk/jcr-server/server/src/java/org/apache/jackrabbit/server/AbstractWebdavServlet.java
URL: http://svn.apache.org/viewcvs/jackrabbit/trunk/jcr-server/server/src/java/org/apache/jackrabbit/server/AbstractWebdavServlet.java?rev=387482&r1=387481&r2=387482&view=diff
==============================================================================
--- jackrabbit/trunk/jcr-server/server/src/java/org/apache/jackrabbit/server/AbstractWebdavServlet.java (original)
+++ jackrabbit/trunk/jcr-server/server/src/java/org/apache/jackrabbit/server/AbstractWebdavServlet.java Tue Mar 21 02:36:49 2006
@@ -31,6 +31,8 @@
 import org.apache.jackrabbit.webdav.WebdavRequestImpl;
 import org.apache.jackrabbit.webdav.WebdavResponse;
 import org.apache.jackrabbit.webdav.WebdavResponseImpl;
+import org.apache.jackrabbit.webdav.security.AclResource;
+import org.apache.jackrabbit.webdav.security.AclProperty;
 import org.apache.jackrabbit.webdav.io.InputContext;
 import org.apache.jackrabbit.webdav.io.InputContextImpl;
 import org.apache.jackrabbit.webdav.io.OutputContext;
@@ -298,6 +300,9 @@
             case DavMethods.DAV_MKWORKSPACE:
                 doMkWorkspace(request, response, resource);
                 break;
+            case DavMethods.DAV_ACL:
+                doAcl(request, response, resource);
+                break;
             default:
                 // any other method
                 return false;
@@ -864,12 +869,17 @@
     protected void doReport(WebdavRequest request, WebdavResponse response,
                             DavResource resource)
             throws DavException, IOException {
-        if (!(resource instanceof DeltaVResource)) {
+        ReportInfo info = request.getReportInfo();
+        Report report;
+        if (resource instanceof DeltaVResource) {
+            report = ((DeltaVResource) resource).getReport(info);
+        } else if (resource instanceof AclResource) {
+            report = ((AclResource) resource).getReport(info);
+        } else {
             response.sendError(DavServletResponse.SC_METHOD_NOT_ALLOWED);
             return;
         }
-        ReportInfo info = request.getReportInfo();
-        Report report = ((DeltaVResource) resource).getReport(info);
+        
         int statusCode = (report.isMultiStatusReport()) ? DavServletResponse.SC_MULTI_STATUS : DavServletResponse.SC_OK;
         response.sendXmlResponse(report, statusCode);
     }
@@ -1031,6 +1041,29 @@
             // is a 'query' resource.
             response.sendMultiStatus(((SearchResource) resource).search(null));
         }
+    }
+
+    /**
+     * The ACL method
+     *
+     * @param request
+     * @param response
+     * @param resource
+     * @throws DavException
+     * @throws IOException
+     */
+    protected void doAcl(WebdavRequest request, WebdavResponse response,
+                         DavResource resource) throws DavException, IOException {
+        if (!(resource instanceof AclResource)) {
+            response.sendError(DavServletResponse.SC_METHOD_NOT_ALLOWED);
+            return;
+        }
+        Document doc = request.getRequestDocument();
+        if (doc == null) {
+            throw new DavException(DavServletResponse.SC_BAD_REQUEST, "ACL request requires a DAV:acl body.");
+        }
+        AclProperty acl = AclProperty.createFromXml(doc.getDocumentElement());
+        ((AclResource)resource).alterAcl(acl);
     }
 
     /**

Modified: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/DavMethods.java
URL: http://svn.apache.org/viewcvs/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/DavMethods.java?rev=387482&r1=387481&r2=387482&view=diff
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/DavMethods.java (original)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/DavMethods.java Tue Mar 21 02:36:49 2006
@@ -253,6 +253,13 @@
     public static final String METHOD_MKACTIVITY = "MKACTIVITY";
 
     /**
+     * The webdav ACL method and public constant defined by
+     * <a href="http://www.ietf.org/rfc/rfc3744.txt">RFC 3744</a>
+     */
+    public static final int DAV_ACL = DAV_MKACTIVITY + 1;
+    public static final String METHOD_ACL = "ACL";
+
+    /**
      * Returns webdav method type code, error result <= 0
      * Valid type codes > 0
      */
@@ -304,6 +311,7 @@
         addMethodCode(METHOD_MKWORKSPACE, DAV_MKWORKSPACE);
         addMethodCode(METHOD_BASELINE_CONTROL, DAV_BASELINE_CONTROL);
         addMethodCode(METHOD_MKACTIVITY, DAV_MKACTIVITY);
+        addMethodCode(METHOD_ACL, DAV_ACL);
 
         labelMethods = new int[] { DAV_GET, DAV_HEAD, DAV_OPTIONS, DAV_PROPFIND,
                                    DAV_LABEL, DAV_COPY };

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclProperty.java
URL: http://svn.apache.org/viewcvs/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclProperty.java?rev=387482&view=auto
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclProperty.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclProperty.java Tue Mar 21 02:36:49 2006
@@ -0,0 +1,264 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * 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 "AS IS" 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.jackrabbit.webdav.security;
+
+import org.apache.jackrabbit.webdav.property.AbstractDavProperty;
+import org.apache.jackrabbit.webdav.property.DavProperty;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.DavConstants;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.xml.XmlSerializable;
+import org.apache.jackrabbit.webdav.xml.ElementIterator;
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * <code>AclProperty</code> defines a protected property that specifies the list
+ * of access control entries (ACEs). The set of ACEs define the privileges granted
+ * or denied to principals on the resource a given property instance belongs to.
+ * <br>
+ * RFC 3744 defines the following format for this property:
+ * <pre>
+ * &lt;!ELEMENT acl (ace*) &gt;
+ * &lt;!ELEMENT ace ((principal | invert), (grant|deny), protected?, inherited?)&gt;
+ * &lt;!ELEMENT principal (href | all | authenticated | unauthenticated | property | self)&gt;
+ * &lt;!ELEMENT invert (principal)&gt;
+ * &lt;!ELEMENT grant (privilege+)&gt;
+ * &lt;!ELEMENT deny (privilege+)&gt;
+ * &lt;!ELEMENT protected EMPTY&gt;
+ * &lt;!ELEMENT inherited (href)&gt;
+ * </pre>
+ *
+ * @see Principal for details regarding DAV:principal
+ * @see Privilege for details regarding DAV:privilege
+ */
+public class AclProperty extends AbstractDavProperty {
+
+    private final List aces;
+
+    /**
+     * Create a new <code>AclProperty</code> from the given ACEs.
+     *
+     * @see AclProperty#createGrantAce(Principal, Privilege[], boolean, boolean, AclResource) for a factory method to create a grant ACE.
+     * @see AclProperty#createDenyAce(Principal, Privilege[], boolean, boolean, AclResource) for a factory method to create a deny ACE.
+     */
+    public AclProperty(Ace[] accessControlElements) {
+        this((accessControlElements == null) ? new ArrayList() : Arrays.asList(accessControlElements));
+    }
+
+    private AclProperty(List aces) {
+        super(SecurityConstants.ACL, true);
+        this.aces = aces;
+    }
+
+    /**
+     * @return a List of <code>Ace</code> object. If this property defines no ACEs
+     * an empty list is returned.
+     * @see DavProperty#getValue()
+     */
+    public Object getValue() {
+        return aces;
+    }
+
+    /**
+     * Build a new <code>AclProperty</code> object from the request body of the
+     * ACL method call.
+     *
+     * @param aclElement
+     * @return new <code>AclProperty</code>
+     * @throws DavException
+     */
+    public static AclProperty createFromXml(Element aclElement) throws DavException {
+        if (!DomUtil.matches(aclElement, SecurityConstants.ACL.getName(), SecurityConstants.ACL.getNamespace())) {
+            throw new DavException(DavServletResponse.SC_BAD_REQUEST, "ACL request requires a DAV:acl body.");
+        }
+        List aces = new ArrayList();
+        ElementIterator it = DomUtil.getChildren(aclElement, Ace.XML_ACE, SecurityConstants.NAMESPACE);
+        while (it.hasNext()) {
+            Element aceElem = it.nextElement();
+            aces.add(Ace.createFromXml(aceElem));
+        }
+        return new AclProperty(aces);
+    }
+
+    public static Ace createGrantAce(Principal principal, Privilege[] privileges, boolean invert, boolean isProtected, AclResource inheritedFrom) {
+        Ace ace = new Ace(principal, invert, privileges, true, isProtected, inheritedFrom);
+        return ace;
+    }
+
+    public static Ace createDenyAce(Principal principal, Privilege[] privileges, boolean invert, boolean isProtected, AclResource inheritedFrom) {
+        Ace ace = new Ace(principal, invert, privileges, false, isProtected, inheritedFrom);
+        return ace;
+    }
+
+    //--------------------------------------------------------< inner class >---
+    /**
+     * Simple WebDAV ACE implementation
+     */
+    public static class Ace implements XmlSerializable, SecurityConstants {
+
+        private static final String XML_ACE = "ace";
+        private static final String XML_INVERT = "invert";
+        private static final String XML_GRANT = "grant";
+        private static final String XML_DENY = "deny";
+        private static final String XML_PROTECTED = "protected";
+        private static final String XML_INHERITED = "inherited";
+
+        private final Principal principal;
+        private final boolean invert;
+        private final Privilege[] privileges;
+        private final boolean grant;
+        private final boolean isProtected;
+        private final String inheritedHref;
+
+        /**
+         * Private constructor
+         *
+         * @param principal
+         * @param invert
+         * @param privileges
+         * @param grant
+         * @param isProtected
+         * @param inherited
+         */
+        private Ace(Principal principal, boolean invert, Privilege[] privileges,
+                    boolean grant, boolean isProtected, AclResource inherited) {
+            this(principal, invert, privileges, grant, isProtected,
+                    ((inherited != null) ? inherited.getHref() : null));
+        }
+
+        /**
+         * Private constructor
+         *
+         * @param principal
+         * @param invert
+         * @param privileges
+         * @param grant
+         * @param isProtected
+         * @param inheritedHref
+         */
+        private Ace(Principal principal, boolean invert, Privilege[] privileges,
+                    boolean grant, boolean isProtected, String inheritedHref) {
+            if (principal == null) {
+                throw new IllegalArgumentException("Cannot create a new ACE with 'null' principal.");
+            }
+            if (privileges == null || privileges.length == 0) {
+                throw new IllegalArgumentException("Cannot create a new ACE: at least a single privilege must be specified.");
+            }
+            this.principal = principal;
+            this.invert = invert;
+            this.privileges = privileges;
+            this.grant = grant;
+            this.isProtected = isProtected;
+            this.inheritedHref = inheritedHref;
+        }
+
+        public Principal getPrincipal() {
+            return principal;
+        }
+
+        public boolean isInvert() {
+            return invert;
+        }
+
+        public Privilege[] getPrivileges() {
+            return privileges;
+        }
+
+        public boolean isGrant() {
+            return grant;
+        }
+
+        public boolean isDeny() {
+            return !grant;
+        }
+
+        public boolean isProtected() {
+            return isProtected;
+        }
+
+        public String getInheritedHref() {
+            return inheritedHref;
+        }
+
+        /**
+         * @see XmlSerializable#toXml(Document)
+         */
+        public Element toXml(Document document) {
+            Element ace = DomUtil.createElement(document, XML_ACE, SecurityConstants.NAMESPACE);
+            if (invert) {
+                Element inv = DomUtil.addChildElement(ace, XML_INVERT, SecurityConstants.NAMESPACE);
+                inv.appendChild(principal.toXml(document));
+            } else {
+                ace.appendChild(principal.toXml(document));
+            }
+            Element gd = DomUtil.addChildElement(ace, ((grant) ? XML_GRANT : XML_DENY), SecurityConstants.NAMESPACE);
+            for (int i = 0; i < privileges.length; i++) {
+                gd.appendChild(privileges[i].toXml(document));
+            }
+            if (isProtected) {
+                DomUtil.addChildElement(ace, XML_PROTECTED, SecurityConstants.NAMESPACE);
+            }
+            if (inheritedHref != null) {
+                Element inh = DomUtil.addChildElement(ace, XML_INHERITED, SecurityConstants.NAMESPACE);
+                inh.appendChild(DomUtil.hrefToXml(inheritedHref, document));
+            }
+            return ace;
+        }
+
+        private static Ace createFromXml(Element aceElement) throws DavException {
+            boolean invert = DomUtil.hasChildElement(aceElement, XML_INVERT, NAMESPACE);
+            Element pe;
+            if (invert) {
+                Element invertE = DomUtil.getChildElement(aceElement, XML_INVERT, NAMESPACE);
+                pe = DomUtil.getChildElement(invertE, Principal.XML_PRINCIPAL, NAMESPACE);
+            } else {
+                pe = DomUtil.getChildElement(aceElement, Principal.XML_PRINCIPAL, SecurityConstants.NAMESPACE);
+            }
+            Principal principal = Principal.createFromXml(pe);
+
+            boolean grant = DomUtil.hasChildElement(aceElement, Ace.XML_GRANT, SecurityConstants.NAMESPACE);
+            Element gdElem;
+            if (grant) {
+                gdElem = DomUtil.getChildElement(aceElement, XML_GRANT, NAMESPACE);
+            } else {
+                gdElem = DomUtil.getChildElement(aceElement, XML_DENY, NAMESPACE);
+            }
+            List privilegeList = new ArrayList();
+            ElementIterator privIt = DomUtil.getChildren(gdElem, Privilege.XML_PRIVILEGE, NAMESPACE);
+            while (privIt.hasNext()) {
+               Privilege pv = Privilege.getPrivilege(privIt.nextElement());
+               privilegeList.add(pv);
+            }
+            Privilege[] privileges = (Privilege[])privilegeList.toArray(new Privilege[privilegeList.size()]);
+
+            boolean isProtected = DomUtil.hasChildElement(aceElement, XML_PROTECTED, NAMESPACE);
+            String inheritedHref = null;
+            if (DomUtil.hasChildElement(aceElement, XML_INHERITED, NAMESPACE)) {
+                Element inhE = DomUtil.getChildElement(aceElement, XML_INHERITED, NAMESPACE);
+                inheritedHref = DomUtil.getChildText(inhE, DavConstants.XML_HREF, DavConstants.NAMESPACE);
+            }
+
+            Ace ace = new Ace(principal, invert, privileges, grant,  isProtected, inheritedHref);
+            return ace;
+        }
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclProperty.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclProperty.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclResource.java
URL: http://svn.apache.org/viewcvs/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclResource.java?rev=387482&view=auto
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclResource.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclResource.java Tue Mar 21 02:36:49 2006
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * 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 "AS IS" 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.jackrabbit.webdav.security;
+
+import org.apache.jackrabbit.webdav.DavResource;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.version.DeltaVResource;
+import org.apache.jackrabbit.webdav.version.report.Report;
+import org.apache.jackrabbit.webdav.version.report.ReportInfo;
+
+/**
+ * <code>AclResource</code>...
+ */
+public interface AclResource extends DavResource {
+
+    // RFC 3744 defines one additional compliance class for the DAV header.
+    public String COMPLIANCE_CLASS = "access-control";
+
+    /**
+     * The AclResource must support the ACL method and the REPORT method in order
+     * to retrieve various security related reports.
+     *
+     * @see DeltaVResource#METHODS
+     * @see org.apache.jackrabbit.webdav.DavResource#METHODS
+     */
+    public String METHODS = "ACL, REPORT";
+
+    /**
+     * Modify the DAV:acl property of this resource object.<br>
+     * Note: RFC 3744 limits modification of access control elements (ACEs) to
+     * elements that are neither inherited nor protected.
+     *
+     * @param aclProperty DAV:acl property listing the set of ACEs to be modified
+     * by this call. This may be a subset of all access control elements
+     * present on this resource object only.
+     * @throws DavException If the request fails. RFC 3744 defines a set of
+     * preconditions which must be met for a successful ACL request.
+     * If these conditions are violated, this method must fail with
+     * {@link DavServletResponse#SC_FORBIDDEN 403 (Forbidden)} or
+     * {@link DavServletResponse#SC_CONFLICT 409 (Conflict)} and should provide
+     * a detailled error condition in the response body. See
+     * <a href="http://www.ietf.org/rfc/rfc3744.txt">RFC 3744 Section 8.1.1
+     * (ACL Preconditions)</a> for further details.
+     */
+    public void alterAcl(AclProperty aclProperty) throws DavException;
+
+    /**
+     * Same as {@link DeltaVResource#getReport(ReportInfo)}.
+     *
+     * @param reportInfo specifying the report details retrieved from the REPORT
+     * request.
+     * @return the requested report.
+     * @throws DavException in case an error occured or if the specified
+     * <code>ReportInfo</code> is either not valid or cannot be run by this
+     * resource.
+     */
+    public Report getReport(ReportInfo reportInfo) throws DavException;
+}

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclResource.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclResource.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclRestrictionsProperty.java
URL: http://svn.apache.org/viewcvs/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclRestrictionsProperty.java?rev=387482&view=auto
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclRestrictionsProperty.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclRestrictionsProperty.java Tue Mar 21 02:36:49 2006
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * 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 "AS IS" 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.jackrabbit.webdav.security;
+
+import org.apache.jackrabbit.webdav.property.AbstractDavProperty;
+import org.apache.jackrabbit.webdav.property.DavProperty;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+
+/**
+ * <code>AclRestrictionsProperty</code> as defined by RFC 3744 Section 5.6.
+ * DAV:acl-restrictions:
+ * <pre>
+ * &lt;!ELEMENT acl-restrictions (grant-only?, no-invert?, deny-before-grant?, required-principal?)&gt;
+ * &lt;!ELEMENT grant-only EMPTY&gt;
+ * &lt;!ELEMENT no-invert EMPTY&gt;
+ * &lt;!ELEMENT deny-before-grant EMPTY&gt;
+ * &lt;!ELEMENT required-principal (all? | authenticated? | unauthenticated? | self? | href* | property*)&gt;
+ * </pre>
+ *
+ * @see Principal
+ * @see AclProperty
+ */
+public class AclRestrictionsProperty extends AbstractDavProperty {
+
+    // TODO: RFC 3744 defines a distinct structure for required-principal
+    // than for principal. Current 'normal' principal is used instead.
+
+    private static final String XML_GRANT_ONLY = "grant-only";
+    private static final String XML_NO_INVERT = "no-invert";
+    private static final String XML_DENY_BEFORE_GRANT = "deny-before-grant";
+
+    private final boolean grantOnly;
+    private final boolean noInvert;
+    private final boolean denyBeforeGrant;
+    private final Principal requiredPrincipal;
+
+    public AclRestrictionsProperty(boolean grantOnly, boolean noInvert, boolean denyBeforeGrant, Principal requiredPrincipal) {
+        super(SecurityConstants.ACL_RESTRICTIONS, true);
+        this.grantOnly = grantOnly;
+        this.noInvert = noInvert;
+        this.denyBeforeGrant = denyBeforeGrant;
+        this.requiredPrincipal = requiredPrincipal;
+    }
+
+    /**
+     * Not implemented.
+     *
+     * @throws UnsupportedOperationException
+     */
+    public Object getValue() {
+        throw new UnsupportedOperationException("Not implemented. Use the property specific methods instead.");
+    }
+
+   /**
+     * @see DavProperty#toXml(Document)
+     */
+    public Element toXml(Document document) {
+        Element elem = getName().toXml(document);
+        if (grantOnly) {
+            DomUtil.addChildElement(elem, XML_GRANT_ONLY, SecurityConstants.NAMESPACE);
+        }
+        if (noInvert) {
+            DomUtil.addChildElement(elem, XML_NO_INVERT, SecurityConstants.NAMESPACE);
+        }
+        if (denyBeforeGrant) {
+            DomUtil.addChildElement(elem, XML_DENY_BEFORE_GRANT, SecurityConstants.NAMESPACE);
+        }
+        if (requiredPrincipal != null) {
+            elem.appendChild(requiredPrincipal.toXml(document));
+        }
+        return elem;
+    }
+
+    public boolean isGrantOnly() {
+        return grantOnly;
+    }
+
+    public boolean isNoInvert() {
+        return noInvert;
+    }
+
+    public boolean isDenyBeforeGrant() {
+        return denyBeforeGrant;
+    }
+
+    public Principal getRequiredPrincipal() {
+        // TODO: check of should be replaced by specific required-principal...
+        return requiredPrincipal;
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclRestrictionsProperty.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/AclRestrictionsProperty.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/CurrentUserPrivilegeSetProperty.java
URL: http://svn.apache.org/viewcvs/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/CurrentUserPrivilegeSetProperty.java?rev=387482&view=auto
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/CurrentUserPrivilegeSetProperty.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/CurrentUserPrivilegeSetProperty.java Tue Mar 21 02:36:49 2006
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * 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 "AS IS" 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.jackrabbit.webdav.security;
+
+import org.apache.jackrabbit.webdav.property.AbstractDavProperty;
+import org.apache.jackrabbit.webdav.property.DavProperty;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * <code>CurrentUserPrivilegeSetProperty</code>...
+ */
+public class CurrentUserPrivilegeSetProperty extends AbstractDavProperty {
+
+    private final Set privileges;
+
+    /**
+     * Create a new instance of this property.
+     *
+     * @param privileges array privileges.
+     */
+    public CurrentUserPrivilegeSetProperty(Privilege[] privileges) {
+        super(SecurityConstants.CURRENT_USER_PRIVILEGE_SET, true);
+
+        this.privileges = new HashSet();
+        for (int i = 0; i < privileges.length; i++) {
+            if (privileges[i] != null) {
+                this.privileges.add(privileges[i]);
+            }
+        }
+    }
+
+    /**
+     * Create a new <code>CurrentUserPrivilegeSetProperty</code> from a DavProperty
+     * as obtained from a MultiStatusResponse.
+     *
+     * @param xmlDavProperty
+     * @throws DavException
+     */
+    public CurrentUserPrivilegeSetProperty(DavProperty xmlDavProperty) throws DavException {
+        super(xmlDavProperty.getName(), xmlDavProperty.isProtected());
+        if (!SecurityConstants.CURRENT_USER_PRIVILEGE_SET.equals(getName()) || !isProtected()) {
+            throw new DavException(DavServletResponse.SC_BAD_REQUEST, "DAV:current-user-privilege-set expected.");
+        }
+        privileges = new HashSet();
+
+        // parse property value
+        Object value = xmlDavProperty.getValue();
+        if (value != null) {
+            if (value instanceof Element) {
+                privileges.add(Privilege.getPrivilege((Element)value));
+            } else if (value instanceof Collection) {
+                Iterator it = ((Collection)value).iterator();
+                while (it.hasNext()) {
+                    Object entry = it.next();
+                    if (entry instanceof Element) {
+                        privileges.add(Privilege.getPrivilege((Element)entry));
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * @return a Collection of <code>Privilege</code> objects use for xml serialization.
+     * @see DavProperty#getValue()
+     * @see AbstractDavProperty#toXml(Document)
+     */
+    public Object getValue() {
+        return privileges;
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/CurrentUserPrivilegeSetProperty.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/CurrentUserPrivilegeSetProperty.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/Principal.java
URL: http://svn.apache.org/viewcvs/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/Principal.java?rev=387482&view=auto
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/Principal.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/Principal.java Tue Mar 21 02:36:49 2006
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * 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 "AS IS" 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.jackrabbit.webdav.security;
+
+import org.apache.jackrabbit.webdav.xml.XmlSerializable;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.DavConstants;
+import org.apache.jackrabbit.webdav.property.DavPropertyName;
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <code>Principal</code> encapsulates the DAV:principal element which identifies
+ * the principal to which this ACE applies.
+ * RFC 3744 defines the following structure for this element:
+ * <pre>
+ * &lt;!ELEMENT principal (href | all | authenticated | unauthenticated | property | self)&gt;
+ * </pre>
+ */
+public class Principal implements XmlSerializable, SecurityConstants {
+
+    public static final String XML_PRINCIPAL = "principal";
+    
+    private static final String XML_ALL = "all";
+    private static final String XML_AUTHENTICATED  = "authenticated";
+    private static final String XML_UNAUTHENTICATED = "unauthenticated";
+    private static final String XML_SELF = "self";
+    private static final String XML_PROPERTY = "property";
+
+    private static final int TYPE_ALL = 0;
+    private static final int TYPE_AUTHENTICATED = 1;
+    private static final int TYPE_UNAUTHENTICATED = 2;
+    private static final int TYPE_SELF = 3;
+    private static final int TYPE_PROPERTY = 4;
+    private static final int TYPE_HREF = 5;
+
+    private static final Principal ALL_PRINCIPAL = new Principal(TYPE_ALL);
+    private static final Principal AUTHENTICATED_PRINCIPAL = new Principal(TYPE_AUTHENTICATED);
+    private static final Principal UNAUTHENTICATED_PRINCIPAL = new Principal(TYPE_UNAUTHENTICATED);
+    private static final Principal SELF_PRINCIPAL = new Principal(TYPE_SELF);
+
+    private static final Map PROP_PRINCIPALS = new HashMap();
+
+    private final int type;
+    private DavPropertyName propertyName;
+    private String href;
+
+    private Principal(int type) {
+        this.type = type;
+    }
+
+    private Principal(DavPropertyName propertyName) {
+        this.type = TYPE_PROPERTY;
+        this.propertyName = propertyName;
+    }
+
+    private Principal(String href) {
+        this.type = TYPE_HREF;
+        this.href = href;
+    }
+
+    /**
+     * @return href if this Principal is a href-typed principal, <code>null</code>
+     * otherwise.
+     */
+    public String getHref() {
+        return href;
+    }
+
+    /**
+     * @return propertyName if this Principal is a property-principal,
+     * <code>null</code> otherwise.
+     */
+    public DavPropertyName getPropertyName() {
+        return propertyName;
+    }
+
+    /**
+     * @see XmlSerializable#toXml(Document)
+     */
+    public Element toXml(Document document) {
+        Element pEl = DomUtil.createElement(document, XML_PRINCIPAL, NAMESPACE);
+        switch (type) {
+            case TYPE_ALL:
+                DomUtil.addChildElement(pEl, XML_ALL, NAMESPACE);
+                break;
+            case TYPE_AUTHENTICATED:
+                DomUtil.addChildElement(pEl, XML_AUTHENTICATED, NAMESPACE);
+                break;
+            case TYPE_UNAUTHENTICATED:
+                DomUtil.addChildElement(pEl, XML_UNAUTHENTICATED, NAMESPACE);
+                break;
+            case TYPE_SELF:
+                DomUtil.addChildElement(pEl, XML_SELF, NAMESPACE);
+                break;
+            case TYPE_PROPERTY:
+                Element prop = DomUtil.addChildElement(pEl, XML_PROPERTY, NAMESPACE);
+                prop.appendChild(propertyName.toXml(document));
+                break;
+            case TYPE_HREF:
+                Element hrefEl = DomUtil.hrefToXml(href, document);
+                pEl.appendChild(hrefEl);
+                break;
+            // no default
+        }
+        return pEl;
+    }
+
+    public static Principal getAllPrincipal() {
+        return ALL_PRINCIPAL;
+    }
+
+    public static Principal getAuthenticatedPrincipal() {
+        return AUTHENTICATED_PRINCIPAL;
+    }
+
+    public static Principal getUnauthenticatedPrincipal() {
+        return UNAUTHENTICATED_PRINCIPAL;
+    }
+
+    public static Principal getSelfPrincipal() {
+        return SELF_PRINCIPAL;
+    }
+
+    public static Principal getPropertyPrincipal(DavPropertyName propertyName) {
+        if (propertyName == null) {
+            throw new IllegalArgumentException("Property-Principal must contain a valid property name.");
+        }
+        // there is a limited amount of properties, that can be used
+        // for a Property-Principal
+        if (PROP_PRINCIPALS.containsKey(propertyName)) {
+            return (Principal) PROP_PRINCIPALS.get(propertyName);
+        } else {
+            Principal p = new Principal(propertyName);
+            PROP_PRINCIPALS.put(propertyName, p);
+            return p;
+        }
+    }
+
+    public static Principal getHrefPrincipal(String href) {
+        if (href == null) {
+            throw new IllegalArgumentException("Href-Principal must contain a valid href.");
+        }
+        return new Principal(href);
+    }
+
+    public static Principal createFromXml(Element principalElement) throws DavException {
+        if (!DomUtil.matches(principalElement, XML_PRINCIPAL, NAMESPACE)) {
+            throw new DavException(DavServletResponse.SC_BAD_REQUEST, "DAV:principal element expected.");
+        }
+        if (DomUtil.hasChildElement(principalElement, XML_ALL, NAMESPACE)) {
+            return ALL_PRINCIPAL;
+        } else if (DomUtil.hasChildElement(principalElement, XML_SELF, NAMESPACE)) {
+            return SELF_PRINCIPAL;
+        } else if (DomUtil.hasChildElement(principalElement, XML_AUTHENTICATED, NAMESPACE)) {
+            return AUTHENTICATED_PRINCIPAL;
+        } else if (DomUtil.hasChildElement(principalElement, XML_UNAUTHENTICATED, NAMESPACE)) {
+            return UNAUTHENTICATED_PRINCIPAL;
+        } else if (DomUtil.hasChildElement(principalElement, DavConstants.XML_HREF, DavConstants.NAMESPACE)) {
+            String href = DomUtil.getChildText(principalElement, DavConstants.XML_HREF, DavConstants.NAMESPACE);
+            return getHrefPrincipal(href);
+        } else if (DomUtil.hasChildElement(principalElement, XML_PROPERTY, NAMESPACE)) {
+            Element propEl = DomUtil.getChildElement(principalElement, XML_PROPERTY, NAMESPACE);
+            DavPropertyName pn = DavPropertyName.createFromXml(DomUtil.getFirstChildElement(propEl));
+            return getPropertyPrincipal(pn);
+        } else {
+            throw new DavException(DavServletResponse.SC_BAD_REQUEST, "Invalid structure inside DAV:principal element.");
+        }
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/Principal.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/Principal.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/Privilege.java
URL: http://svn.apache.org/viewcvs/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/Privilege.java?rev=387482&view=auto
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/Privilege.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/Privilege.java Tue Mar 21 02:36:49 2006
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * 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 "AS IS" 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.jackrabbit.webdav.security;
+
+import org.apache.jackrabbit.webdav.xml.XmlSerializable;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.xml.Namespace;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * <code>Privilege</code>
+ */
+public class Privilege implements XmlSerializable {
+
+    public static final String XML_PRIVILEGE = "privilege";
+
+    /**
+     * Map for registered privileges
+     */
+    private static final Map REGISTERED_PRIVILEGES = new HashMap();
+
+    //-------------------------------------< Privileges defined by RFC 3744 >---
+    /**
+     * The read privilege controls methods that return information about the
+     * state of the resource, including the resource's properties. Affected
+     * methods include GET and PROPFIND and OPTIONS.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc3744.txt">RFC 3744 Section 3.1. DAV:read Privilege</a>
+     */
+    public static final Privilege PRIVILEGE_READ = getPrivilege("read", SecurityConstants.NAMESPACE);
+    /**
+     * The write privilege controls methods that lock a resource or modify the
+     * content, dead properties, or (in the case of a collection) membership of
+     * the resource, such as PUT and PROPPATCH.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc3744.txt">RFC 3744 Section 3.2. DAV:write Privilege</a>
+     */
+    public static final Privilege PRIVILEGE_WRITE = getPrivilege("write", SecurityConstants.NAMESPACE);
+    /**
+     * The DAV:write-properties privilege controls methods that modify the dead
+     * properties of the resource, such as PROPPATCH. Whether this privilege may
+     * be used to control access to any live properties is determined by the
+     * implementation.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc3744.txt">RFC 3744 Section 3.3. DAV:write-properties Privilege</a>
+     */
+    public static final Privilege PRIVILEGE_WRITE_PROPERTIES = getPrivilege("write-properties", SecurityConstants.NAMESPACE);
+    /**
+     * The DAV:write-content privilege controls methods that modify the content
+     * of an existing resource, such as PUT.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc3744.txt">RFC 3744 Section 3.4. DAV:write-content Privilege</a>
+     */
+    public static final Privilege PRIVILEGE_WRITE_CONTENT = getPrivilege("write-content", SecurityConstants.NAMESPACE);
+    /**
+     * The DAV:unlock privilege controls the use of the UNLOCK method by a
+     * principal other than the lock owner (the principal that created a lock
+     * can always perform an UNLOCK).
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc3744.txt">RFC 3744 Section 3.5. DAV:unlock Privilege</a>
+     */
+    public static final Privilege PRIVILEGE_UNLOCK = getPrivilege("unlock", SecurityConstants.NAMESPACE);
+    /**
+     * The DAV:read-acl privilege controls the use of PROPFIND to retrieve the
+     * DAV:acl property of the resource.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc3744.txt">RFC 3744 Section 3.6. DAV:read-acl Privilege</a>
+     */
+    public static final Privilege PRIVILEGE_READ_ACL = getPrivilege("read-acl", SecurityConstants.NAMESPACE);
+    /**
+     * The DAV:read-current-user-privilege-set privilege controls the use of
+     * PROPFIND to retrieve the DAV:current-user-privilege-set property of the
+     * resource.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc3744.txt">RFC 3744 Section 3.7. DAV:"read-current-user-privilege-set Privilege</a>
+     */
+    public static final Privilege PRIVILEGE_READ_CURRENT_USER_PRIVILEGE_SET = getPrivilege("read-current-user-privilege-set", SecurityConstants.NAMESPACE);
+    /**
+     * The DAV:write-acl privilege controls use of the ACL method to modify the
+     * DAV:acl property of the resource.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc3744.txt">RFC 3744 Section 3.8. DAV:write-acl Privilege</a>
+     */
+    public static final Privilege PRIVILEGE_WRITE_ACL = getPrivilege("write-acl", SecurityConstants.NAMESPACE);
+    /**
+     * The DAV:bind privilege allows a method to add a new member URL to the
+     * specified collection (for example via PUT or MKCOL). It is ignored for
+     * resources that are not collections.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc3744.txt">RFC 3744 Section 3.9. DAV:bind Privilege</a>
+     */
+    public static final Privilege PRIVILEGE_BIND = getPrivilege("bind", SecurityConstants.NAMESPACE);
+    /**
+     * The DAV:unbind privilege allows a method to remove a member URL from the
+     * specified collection (for example via DELETE or MOVE). It is ignored for
+     * resources that are not collections.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc3744.txt">RFC 3744 Section 3.10. DAV:unbind Privilege</a>
+     */
+    public static final Privilege PRIVILEGE_UNBIND = getPrivilege("unbind", SecurityConstants.NAMESPACE);
+    /**
+     * DAV:all is an aggregate privilege that contains the entire set of
+     * privileges that can be applied to the resource.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc3744.txt">RFC 3744 Section 3.11. DAV:all Privilege</a>
+     */
+    public static final Privilege PRIVILEGE_ALL = getPrivilege("all", SecurityConstants.NAMESPACE);
+
+    private final String privilege;
+    private final Namespace namespace;
+
+    /**
+     * Private constructor
+     *
+     * @param privilege
+     * @param namespace
+     */
+    private Privilege(String privilege, Namespace namespace) {
+        this.privilege = privilege;
+        this.namespace = namespace;
+    }
+
+    /**
+     * @see XmlSerializable#toXml(Document)
+     */
+    public Element toXml(Document document) {
+        Element privEl =  DomUtil.createElement(document, XML_PRIVILEGE, SecurityConstants.NAMESPACE);
+        DomUtil.addChildElement(privEl, privilege, namespace);
+        return privEl;
+    }
+
+    /**
+     * Factory method to create/retrieve a <code>Privilege</code>.
+     *
+     * @param privilege
+     * @param namespace
+     * @return
+     */
+    public static Privilege getPrivilege(String privilege, Namespace namespace) {
+        if (privilege == null) {
+            throw new IllegalArgumentException("'null' is not a valid privilege.");
+        }
+        if (namespace == null) {
+            namespace = Namespace.EMPTY_NAMESPACE;
+        }
+        String key = "{" + namespace.getURI() + "}" + privilege;
+        if (REGISTERED_PRIVILEGES.containsKey(key)) {
+            return (Privilege) REGISTERED_PRIVILEGES.get(key);
+        } else {
+            Privilege p = new Privilege(privilege, namespace);
+            REGISTERED_PRIVILEGES.put(key, p);
+            return p;
+        }
+    }
+
+    /**
+     * Factory method to create/retrieve a <code>Privilege</code> from the given
+     * DAV:privilege element.
+     *
+     * @param privilege
+     * @return
+     */
+    public static Privilege getPrivilege(Element privilege) throws DavException {
+        if (!DomUtil.matches(privilege, XML_PRIVILEGE, SecurityConstants.NAMESPACE)) {
+            throw new DavException(DavServletResponse.SC_BAD_REQUEST, "DAV:privilege element expected.");
+        }
+        Element el = DomUtil.getFirstChildElement(privilege);
+        return getPrivilege(el.getLocalName(), DomUtil.getNamespace(el));
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/Privilege.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/Privilege.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SecurityConstants.java
URL: http://svn.apache.org/viewcvs/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SecurityConstants.java?rev=387482&view=auto
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SecurityConstants.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SecurityConstants.java Tue Mar 21 02:36:49 2006
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * 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 "AS IS" 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.jackrabbit.webdav.security;
+
+import org.apache.jackrabbit.webdav.xml.Namespace;
+import org.apache.jackrabbit.webdav.DavConstants;
+import org.apache.jackrabbit.webdav.DavMethods;
+import org.apache.jackrabbit.webdav.property.DavPropertyName;
+import org.apache.jackrabbit.webdav.property.ResourceType;
+import org.apache.jackrabbit.webdav.property.HrefProperty;
+
+/**
+ * <code>SecurityConstants</code> interface lists constants defined by
+ * <a href="http://www.ietf.org/rfc/rfc3744.txt">RFC 3744</a> (WebDAV Access
+ * Control Protocol).
+ */
+public interface SecurityConstants {
+
+    /**
+     * Default Namespace constant
+     */
+    public static final Namespace NAMESPACE = DavConstants.NAMESPACE;
+
+    /**
+     * Principal resources must define DAV:principal XML element in the value
+     * of the DAV:resourcetype property.
+     */
+    public static int PRINCIPAL_RESOURCETYPE = ResourceType.registerResourceType("principal", NAMESPACE);
+
+    //---< Property Names for Principal Resource >------------------------------
+    /**
+     * Protected href property DAV:principal-URL for principal resources.
+     * @see HrefProperty
+     */
+    public static final DavPropertyName PRINCIPAL_URL = DavPropertyName.create("principal-URL", NAMESPACE);
+    /**
+     * Protected href property DAV:alternate-URI-set for principal resources.
+     * @see HrefProperty
+     */
+    public static final DavPropertyName ALTERNATE_URI_SET = DavPropertyName.create("alternate-URI-set", NAMESPACE);
+    /**
+     * Protected href property DAV:group-member-set for principal resources.
+     * @see HrefProperty
+     */
+    public static final DavPropertyName GROUP_MEMBER_SET = DavPropertyName.create("group-member-set", NAMESPACE);
+    /**
+     * Protected href property DAV:group-membership for principal resources.
+     * @see HrefProperty
+     */
+    public static final DavPropertyName GROUP_MEMBERSHIP = DavPropertyName.create("group-membership", NAMESPACE);
+
+    //---< Property Names for DavResource >-------------------------------------
+    /**
+     * Protected href property DAV:owner
+     * @see HrefProperty
+     */
+    public static final DavPropertyName OWNER = DavPropertyName.create("owner", NAMESPACE);
+    /**
+     * Protected href property DAV:group
+     * @see HrefProperty
+     */
+    public static final DavPropertyName GROUP = DavPropertyName.create("group", NAMESPACE);
+    /**
+     * Protected property DAV:supported-privilege-set
+     * @see CurrentUserPrivilegeSetProperty
+     */
+    public static final DavPropertyName SUPPORTED_PRIVILEGE_SET = DavPropertyName.create("supported-privilege-set", NAMESPACE);
+    /**
+     * Protected property DAV:current-user-privilege-set
+     * @see CurrentUserPrivilegeSetProperty
+     */
+    public static final DavPropertyName CURRENT_USER_PRIVILEGE_SET = DavPropertyName.create("current-user-privilege-set", NAMESPACE);
+    /**
+     * Protected property DAV:acl. Note, that DAV:acl property may be altered
+     * with a ACL request.
+     *
+     * @see AclProperty
+     * @see DavMethods#METHOD_ACL
+     */
+    public static final DavPropertyName ACL = DavPropertyName.create("acl", NAMESPACE);
+    /**
+     * Protected property DAV:acl-restrictions
+     * @see AclRestrictionsProperty
+     */
+    public static final DavPropertyName ACL_RESTRICTIONS = DavPropertyName.create("acl-restrictions", NAMESPACE);
+    /**
+     * Protected href property DAV:inherited-acl-set
+     * @see HrefProperty
+     */
+    public static final DavPropertyName INHERITED_ACL_SET = DavPropertyName.create("inherited-acl-set", NAMESPACE);
+    /**
+     * Protected href property DAV:principal-collection-set
+     * @see HrefProperty
+     */
+    public static final DavPropertyName PRINCIPAL_COLLECTION_SET = DavPropertyName.create("principal-collection-set", NAMESPACE);
+}

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SecurityConstants.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SecurityConstants.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SupportedPrivilege.java
URL: http://svn.apache.org/viewcvs/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SupportedPrivilege.java?rev=387482&view=auto
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SupportedPrivilege.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SupportedPrivilege.java Tue Mar 21 02:36:49 2006
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * 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 "AS IS" 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.jackrabbit.webdav.security;
+
+import org.apache.jackrabbit.webdav.xml.XmlSerializable;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.xml.Namespace;
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+
+/**
+ * <code>SupportedPrivilege</code>...
+ */
+public class SupportedPrivilege implements XmlSerializable {
+
+    private static final String XML_SUPPORTED_PRIVILEGE = "supported-privilege";
+    private static final String XML_ABSTRACT = "abstract";
+    private static final String XML_DESCRIPTION = "description";
+
+    private final Privilege privilege;
+    private final boolean isAbstract;
+    private final String description;
+    private final String descriptionLanguage;
+    private final SupportedPrivilege[] supportedPrivileges;
+
+    /**
+     *
+     * @param privilege
+     * @param description
+     * @param descriptionLanguage
+     * @param isAbstract
+     * @param supportedPrivileges
+     */
+    public SupportedPrivilege(Privilege privilege, String description,
+                              String descriptionLanguage, boolean isAbstract,
+                              SupportedPrivilege[] supportedPrivileges) {
+        if (privilege == null) {
+            throw new IllegalArgumentException("DAV:supported-privilege element must contain a single privilege.");
+        }
+        this.privilege = privilege;
+        this.description = description;
+        this.descriptionLanguage = descriptionLanguage;
+        this.isAbstract = isAbstract;
+        this.supportedPrivileges = supportedPrivileges;
+    }
+
+    /**
+     * @see XmlSerializable#toXml(Document)
+     */
+    public Element toXml(Document document) {
+        Element spElem = DomUtil.createElement(document, XML_SUPPORTED_PRIVILEGE, SecurityConstants.NAMESPACE);
+        spElem.appendChild(privilege.toXml(document));
+        if (isAbstract) {
+            DomUtil.addChildElement(spElem, XML_ABSTRACT, SecurityConstants.NAMESPACE);
+        }
+        if (description != null) {
+            Element desc = DomUtil.addChildElement(spElem, XML_DESCRIPTION, SecurityConstants.NAMESPACE, description);
+            if (descriptionLanguage != null) {
+                DomUtil.setAttribute(desc, "lang", Namespace.XML_NAMESPACE, descriptionLanguage);
+            }
+        }
+        if (supportedPrivileges != null) {
+            for (int i = 0; i < supportedPrivileges.length; i++) {
+                spElem.appendChild(supportedPrivileges[i].toXml(document));
+            }
+        }
+        return spElem;
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SupportedPrivilege.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SupportedPrivilege.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SupportedPrivilegeSetProperty.java
URL: http://svn.apache.org/viewcvs/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SupportedPrivilegeSetProperty.java?rev=387482&view=auto
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SupportedPrivilegeSetProperty.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SupportedPrivilegeSetProperty.java Tue Mar 21 02:36:49 2006
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * 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 "AS IS" 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.jackrabbit.webdav.security;
+
+import org.apache.jackrabbit.webdav.property.AbstractDavProperty;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * <code>SupportedPrivilegeSetProperty</code> defines the
+ * {@link SecurityConstants#SUPPORTED_PRIVILEGE_SET} property, used to identify
+ * the privileges defined for the resource. RFC 3744 defines the the following
+ * structure for this property:
+ * <pre>
+ * &lt;!ELEMENT supported-privilege-set (supported-privilege*)&gt;
+ * &lt;!ELEMENT supported-privilege (privilege, abstract?, description, supported-privilege*)&gt;
+ * &lt;!ELEMENT privilege ANY&gt;
+ * &lt;!ELEMENT abstract EMPTY&gt;
+ * &lt;!ELEMENT description #PCDATA&gt;
+ * </pre>
+ *
+ * @see SupportedPrivilege
+ * @see Privilege
+ */
+public class SupportedPrivilegeSetProperty extends AbstractDavProperty {
+
+    private final SupportedPrivilege[] supportedPrivileges;
+
+    /**
+     * Create a new <code>SupportedPrivilegeSetProperty</code>.
+     *
+     * @param supportedPrivileges
+     */
+    public SupportedPrivilegeSetProperty(SupportedPrivilege[] supportedPrivileges) {
+        super(SecurityConstants.SUPPORTED_PRIVILEGE_SET, true);
+        this.supportedPrivileges = supportedPrivileges;
+    }
+
+    /**
+     * @return List of {@link SupportedPrivilege}s.
+     */
+    public Object getValue() {
+        return (supportedPrivileges == null) ? new ArrayList() : Arrays.asList(supportedPrivileges);
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SupportedPrivilegeSetProperty.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/SupportedPrivilegeSetProperty.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/AbstractSecurityReport.java
URL: http://svn.apache.org/viewcvs/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/AbstractSecurityReport.java?rev=387482&view=auto
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/AbstractSecurityReport.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/AbstractSecurityReport.java Tue Mar 21 02:36:49 2006
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * 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 "AS IS" 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.jackrabbit.webdav.security.report;
+
+import org.apache.jackrabbit.webdav.version.report.Report;
+import org.apache.jackrabbit.webdav.version.report.ReportInfo;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.DavConstants;
+import org.apache.jackrabbit.webdav.DavResource;
+import org.apache.jackrabbit.webdav.MultiStatus;
+import org.apache.jackrabbit.webdav.MultiStatusResponse;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * <code>AbstractSecurityReport</code> covers basic validation and utilities
+ * common to the majority of the reports defined within RFC 3744.
+ */
+public abstract class AbstractSecurityReport implements Report {
+
+    protected MultiStatusResponse[] responses;
+
+    /**
+     * Always returns true.
+     *
+     * @return true
+     */
+    public boolean isMultiStatusReport() {
+        return true;
+    }
+
+    /**
+     * Checks if the given resource and report info are not <code>null</code>,
+     * that the requested report type matches this implementation and that no
+     * other Depth header than 0 is present.
+     *
+     * @param resource
+     * @param info
+     * @throws DavException
+     */
+    public void init(DavResource resource, ReportInfo info) throws DavException {
+        if (resource == null || info == null) {
+            throw new DavException(DavServletResponse.SC_BAD_REQUEST, "Unable to run report: WebDAV Resource and ReportInfo must not be null.");
+        }
+        if (!getType().isRequestedReportType(info)) {
+            throw new DavException(DavServletResponse.SC_BAD_REQUEST, "Expected report type: '" + getType().getReportName() + "', found: '" + info.getReportName() + ";" + "'.");
+        }
+        if (info.getDepth() > DavConstants.DEPTH_0) {
+            throw new DavException(DavServletResponse.SC_BAD_REQUEST, "Invalid Depth header: " + info.getDepth());
+        }
+    }
+
+    /**
+     * @return DAV:multistatus element listing the matching resources.
+     * @see Report#toXml(Document)
+     */
+    public Element toXml(Document document) {
+        MultiStatus ms = new MultiStatus();
+        if (responses != null) {
+            for (int i = 0; i < responses.length; i++) {
+                ms.addResponse(responses[i]);
+            }
+        }
+        return ms.toXml(document);
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/AbstractSecurityReport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/AbstractSecurityReport.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/AclPrincipalReport.java
URL: http://svn.apache.org/viewcvs/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/AclPrincipalReport.java?rev=387482&view=auto
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/AclPrincipalReport.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/AclPrincipalReport.java Tue Mar 21 02:36:49 2006
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * 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 "AS IS" 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.jackrabbit.webdav.security.report;
+
+import org.apache.jackrabbit.webdav.version.report.ReportType;
+import org.apache.jackrabbit.webdav.version.report.Report;
+import org.apache.jackrabbit.webdav.version.report.ReportInfo;
+import org.apache.jackrabbit.webdav.security.SecurityConstants;
+import org.apache.jackrabbit.webdav.security.AclProperty;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.MultiStatusResponse;
+import org.apache.jackrabbit.webdav.DavResource;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavResourceLocator;
+import org.apache.jackrabbit.webdav.property.DavProperty;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Iterator;
+
+/**
+ * The AclPrincipalReport report returns the requested property set
+ * for all principals in the DAV:acl property, that are identified by http(s)
+ * URLs or by a DAV:property principal.
+ * <p/>
+ * The request body MUST be a DAV:acl-principal-prop-set XML element:
+ * <pre>
+ * &lt;!ELEMENT acl-principal-prop-set ANY&gt;
+ * ANY value: a sequence of one or more elements, with at most one
+ *            DAV:prop element.
+ * prop: see RFC 2518, Section 12.11
+ * </pre>
+ * The response body MUST be a DAV:multistatus element containing a
+ * DAV:response element for each principal identified by a http(s) URL listed
+ * in a DAV:principal XML element of an ACE within the DAV:acl property of the
+ * resource this report is requested for.
+ */
+public class AclPrincipalReport extends AbstractSecurityReport {
+
+    public static final String REPORT_NAME = "acl-principal-prop-set";
+
+    /**
+     * The report type
+     */
+    public static final ReportType REPORT_TYPE = ReportType.register(REPORT_NAME, SecurityConstants.NAMESPACE, AclPrincipalReport.class);
+
+    /**
+     * @see Report#getType()
+     */
+    public ReportType getType() {
+        return REPORT_TYPE;
+    }
+
+    /**
+     * @see Report#init(DavResource, ReportInfo)
+     */
+    public void init(DavResource resource, ReportInfo info) throws DavException {
+        super.init(resource, info);
+        // build the DAV:responses objects.
+        DavProperty acl = resource.getProperty(SecurityConstants.ACL);
+        if (!(acl instanceof AclProperty)) {
+            throw new DavException(DavServletResponse.SC_INTERNAL_SERVER_ERROR, "DAV:acl property expected.");
+        }
+
+        DavResourceLocator loc = resource.getLocator();
+        Map principalMap = new HashMap();
+        Iterator aceIt = ((List)((AclProperty)acl).getValue()).iterator();
+        while (aceIt.hasNext()) {
+            AclProperty.Ace ace = (AclProperty.Ace) aceIt.next();
+            String href = ace.getPrincipal().getHref();
+            if (href == null && principalMap.containsKey(href)) {
+                // ignore non-href principals and principals that have been listed before
+                continue;
+            }
+            // href-principal that has not been found before
+            DavResourceLocator princLocator = loc.getFactory().createResourceLocator(loc.getPrefix(), href);
+            DavResource principalResource = resource.getFactory().createResource(princLocator, resource.getSession());
+            principalMap.put(href, new MultiStatusResponse(principalResource, info.getPropertyNameSet()));
+        }
+        this.responses = (MultiStatusResponse[]) principalMap.values().toArray(new MultiStatusResponse[principalMap.size()]);
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/AclPrincipalReport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/AclPrincipalReport.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/PrincipalMatchReport.java
URL: http://svn.apache.org/viewcvs/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/PrincipalMatchReport.java?rev=387482&view=auto
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/PrincipalMatchReport.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/PrincipalMatchReport.java Tue Mar 21 02:36:49 2006
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * 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 "AS IS" 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.jackrabbit.webdav.security.report;
+
+import org.apache.jackrabbit.webdav.version.report.ReportType;
+import org.apache.jackrabbit.webdav.version.report.Report;
+import org.apache.jackrabbit.webdav.version.report.ReportInfo;
+import org.apache.jackrabbit.webdav.security.SecurityConstants;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.DavResource;
+import org.apache.jackrabbit.webdav.MultiStatusResponse;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.property.DavPropertyName;
+import org.w3c.dom.Element;
+
+/**
+ * <code>PrincipalMatchReport</code> can be request for any collection resources.
+ * The resulting report identifies member resources that either represent the
+ * requesting principal ("principal resources") or contain a specified property
+ * that matches the requesting principal in its value. For the first match
+ * the request body must contain a DAV:self element, for the latter a
+ * DAV:principal-property element which in turn specifies the property to
+ * be examined.
+ * <p/>
+ * The request body MUST be a DAV:principal-match XML element:
+ * <pre>
+ * &lt;!ELEMENT principal-match ((principal-property | self), prop?)&gt;
+ * &lt;!ELEMENT principal-property ANY&gt;
+ * ANY value: an element whose value identifies a property. The value of this
+ * property typically contains an href element refering to a principal.
+ * &lt;!ELEMENT self EMPTY&gt;
+ * prop: see RFC 2518, Section 12.11
+ * </pre>
+ * The response body of a successful report must contain a DAV:multistatus
+ * element. Each matching member is present with a separate DAV:response element.
+ */
+public class PrincipalMatchReport extends AbstractSecurityReport {
+
+    public static String XML_PRINCIPAL_PROPERTY = "principal-property";
+    public static String XML_SELF = "self";
+
+    /**
+     * The report name
+     */
+    public static final String REPORT_NAME = "principal-match";
+
+    /**
+     * The report type
+     */
+    public static final ReportType REPORT_TYPE = ReportType.register(REPORT_NAME, SecurityConstants.NAMESPACE, PrincipalMatchReport.class);
+
+    private DavPropertyName principalPropertyName;
+
+    /**
+     * @see Report#getType()
+     */
+    public ReportType getType() {
+        return REPORT_TYPE;
+    }
+
+    /**
+     * @see Report#init(DavResource, ReportInfo)
+     */
+    public void init(DavResource resource, ReportInfo info) throws DavException {
+        super.init(resource, info);
+        if (info.containsContentElement(XML_PRINCIPAL_PROPERTY, SecurityConstants.NAMESPACE)) {
+            Element pp = info.getContentElement(XML_PRINCIPAL_PROPERTY, SecurityConstants.NAMESPACE);
+            principalPropertyName = DavPropertyName.createFromXml(DomUtil.getFirstChildElement(pp));
+        } else if (info.containsContentElement(XML_SELF, SecurityConstants.NAMESPACE)) {
+            principalPropertyName = SecurityConstants.PRINCIPAL_URL;
+        } else {
+            throw new DavException(DavServletResponse.SC_BAD_REQUEST, "DAV:self or DAV:principal-property element required within report info.");
+        }
+    }
+
+    //------------------------------------< implementation specific methods >---
+    /**
+     * Retrieve the property name that indicates which property must be search
+     * for matching principals.<br>
+     * Note, that the search result must be converted to {@link MultiStatusResponse}s
+     * that must be returned back to this report.
+     *
+     * @return property name which should be check for match with the current
+     * user.
+     * @see #setResponses(MultiStatusResponse[])
+     */
+    public DavPropertyName getPrincipalPropertyName() {
+        return principalPropertyName;
+    }
+
+    /**
+     * Write the result(s) of the match back to the report.
+     *
+     * @param responses
+     */
+    public void setResponses(MultiStatusResponse[] responses) {
+       this.responses = responses;
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/PrincipalMatchReport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/PrincipalMatchReport.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url

Added: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/PrincipalSearchReport.java
URL: http://svn.apache.org/viewcvs/jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/PrincipalSearchReport.java?rev=387482&view=auto
==============================================================================
--- jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/PrincipalSearchReport.java (added)
+++ jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/PrincipalSearchReport.java Tue Mar 21 02:36:49 2006
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * 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 "AS IS" 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.jackrabbit.webdav.security.report;
+
+import org.apache.log4j.Logger;
+import org.apache.jackrabbit.webdav.version.report.ReportType;
+import org.apache.jackrabbit.webdav.version.report.Report;
+import org.apache.jackrabbit.webdav.version.report.ReportInfo;
+import org.apache.jackrabbit.webdav.security.SecurityConstants;
+import org.apache.jackrabbit.webdav.xml.DomUtil;
+import org.apache.jackrabbit.webdav.DavConstants;
+import org.apache.jackrabbit.webdav.DavResource;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavServletResponse;
+import org.apache.jackrabbit.webdav.MultiStatusResponse;
+import org.apache.jackrabbit.webdav.property.HrefProperty;
+import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
+import org.w3c.dom.Element;
+
+import java.util.List;
+import java.util.Iterator;
+
+/**
+ * The <code>PrincipalSearchReport</code> performs a search for all principals
+ * that match the search criteria specified in the request.<p/>
+ * The following XML structure is required in the request body:
+ * <pre>
+ * &lt;!ELEMENT principal-property-search ((property-search+), prop?, apply-to-principal-collection-set?) &gt;
+ * &lt;!ELEMENT property-search (prop, match) >
+ *  prop: see RFC 2518, Section 12.11
+ * &lt;!ELEMENT match #PCDATA &gt;
+ * &lt;!ELEMENT apply-to-principal-collection-set #EMPTY &gt;
+ * </pre>
+ * <strong>DAV:property-search</strong> contains lists the properties to be
+ * searched inside the DAV:prop element and the query string inside the DAV:match
+ * element. Multiple DAV:property-search elements or multiple elements within the
+ * DAV:prop element will be interpreted with a logical AND.
+ * <p/>
+ * <strong>DAV:prop</strong> lists the property names to be reported in the
+ * response for each of the principle resources found.
+ * <p/>
+ * <strong>DAV:apply-to-principal-collection-set</strong>: Optional empty element.
+ * If present in the request body the search will be executed over all members
+ * of the collections that are listed as values in the DAV:principal-collection-set
+ * property present on the resource the report has been requested for.
+ * Otherwise the search is limited to all members (at any depth) of that resource
+ * itself.
+ * <p/>
+ * The response body must contain a single DAV:multistatus XML element.
+ */
+public class PrincipalSearchReport extends AbstractSecurityReport {
+
+    private static Logger log = Logger.getLogger(PrincipalSearchReport.class);
+
+    public static final String XML_APPLY_TO_PRINCIPAL_COLLECTION_SET = "apply-to-principal-collection-set";
+    public static final String XML_PROPERTY_SEARCH = "property-search";
+    public static final String XML_MATCH = "match";
+
+    /**
+     * The report name
+     */
+    public static final String REPORT_NAME = "principal-property-search";
+
+    /**
+     * The report type
+     */
+    public static final ReportType REPORT_TYPE = ReportType.register(REPORT_NAME, SecurityConstants.NAMESPACE, PrincipalSearchReport.class);
+
+    private String[] searchRoots;
+    private SearchArgument[] searchArguments;
+
+    /**
+     * @see Report#getType()
+     */
+    public ReportType getType() {
+        return REPORT_TYPE;
+    }
+
+    /**
+     * @see Report#init(DavResource, ReportInfo)
+     */
+    public void init(DavResource resource, ReportInfo info) throws DavException {
+        super.init(resource, info);
+        // make sure the request body contains all mandator elements
+        if (!info.containsContentElement(XML_PROPERTY_SEARCH, SecurityConstants.NAMESPACE)) {
+            throw new DavException(DavServletResponse.SC_BAD_REQUEST, "Request body must contain at least a single DAV:property-search element.");
+        }
+        List psElements = info.getContentElements(XML_PROPERTY_SEARCH, SecurityConstants.NAMESPACE);
+        searchArguments = new SearchArgument[psElements.size()];
+        Iterator it = psElements.iterator();
+        int i = 0;
+        while (it.hasNext()) {
+            searchArguments[i++] = new SearchArgument((Element)it.next());
+        }
+
+        if (info.containsContentElement(XML_APPLY_TO_PRINCIPAL_COLLECTION_SET, SecurityConstants.NAMESPACE)) {
+            HrefProperty p = new HrefProperty(resource.getProperty(SecurityConstants.PRINCIPAL_COLLECTION_SET));
+            searchRoots = (String[]) p.getHrefs().toArray(new String[0]);
+        } else {
+            searchRoots = new String[] {resource.getHref()};
+        }
+    }
+
+    //------------------------------------< implementation specific methods >---
+    /**
+     * Retrieve the the locations where the search should be performed.<br>
+     * Note, that the search result must be converted to {@link MultiStatusResponse}s
+     * that must be returned back to this report.
+     *
+     * @return href of collections that act as start for the search.
+     * @see #setResponses(MultiStatusResponse[])
+     */
+    public String[] getSearchRoots() {
+        return searchRoots;
+    }
+
+    /**
+     * Retrive the search arguments used to run the search for principals.<br>
+     * Note, that the search result must be converted to {@link MultiStatusResponse}s
+     * that must be returned back to this report.
+     *
+     * @return array of <code>SearchArgument</code> used to run the principal
+     * search.
+     * @see #setResponses(MultiStatusResponse[])
+     */
+    public SearchArgument[] getSearchArguments() {
+        return searchArguments;
+    }
+
+    /**
+     * Write the search result back to the report.
+     *
+     * @param responses
+     */
+    public void setResponses(MultiStatusResponse[] responses) {
+       this.responses = responses;
+    }
+
+    //--------------------------------< implementation specific inner class >---
+    /**
+     * Inner utility class preparing the query arguments present in the
+     * DAV:property-search element(s).
+     */
+    protected class SearchArgument {
+
+        private final DavPropertyNameSet searchProps;
+        private final String searchString;
+
+        private SearchArgument(Element propSearch) {
+            searchProps = new DavPropertyNameSet(DomUtil.getChildElement(propSearch, DavConstants.XML_PROP, DavConstants.NAMESPACE));
+            searchString = DomUtil.getChildText(propSearch, XML_MATCH, SecurityConstants.NAMESPACE);
+        }
+
+        /**
+         * @return property name set used to restrict the search to a limited
+         * amount of properties.
+         */
+        protected DavPropertyNameSet getSearchProperties() {
+            return searchProps;
+        }
+
+        /**
+         * @return query string as present in the DAV:match element.
+         */
+        protected String getSearchString() {
+            return searchString;
+        }
+    }
+}
\ No newline at end of file

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/PrincipalSearchReport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/trunk/jcr-server/webdav/src/java/org/apache/jackrabbit/webdav/security/report/PrincipalSearchReport.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision url