[CalendarServer-changes] [62] CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted

source_changes at macosforge.org source_changes at macosforge.org
Thu Aug 24 13:38:01 PDT 2006


Revision: 62
Author:   cdaboo at apple.com
Date:     2006-08-24 13:37:57 -0700 (Thu, 24 Aug 2006)

Log Message:
-----------
Oops - need .patch file extension on these.

Added Paths:
-----------
    CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.acl.patch
    CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.auth.patch
    CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.http.patch
    CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.method.report_acl_principal_prop_set.patch
    CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.resource.patch

Removed Paths:
-------------
    CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.acl
    CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.auth
    CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.http
    CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.method.report_acl_principal_prop_set
    CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.resource

Deleted: CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.acl
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.acl	2006-08-24 20:23:40 UTC (rev 61)
+++ CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.acl	2006-08-24 20:37:57 UTC (rev 62)
@@ -1,16 +0,0 @@
-Index: twisted/web2/dav/acl.py
-===================================================================
---- twisted/web2/dav/acl.py	(revision 17935)
-+++ twisted/web2/dav/acl.py	(working copy)
-@@ -161,9 +161,9 @@
-         Check whether the supplied principal matches this principal or is a
-         member of this principal resource.
-         @param href: the L{HRef} to test.
--        @return:     True if there is a matchg, False otherwise
-+        @return:     True if there is a match, False otherwise
-         """
--        uri = str(href) 
-+        uri = str(href)
-         if self.principalURL() == uri:
-             return True
-         else:

Copied: CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.acl.patch (from rev 57, CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.acl)
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.acl.patch	                        (rev 0)
+++ CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.acl.patch	2006-08-24 20:37:57 UTC (rev 62)
@@ -0,0 +1,16 @@
+Index: twisted/web2/dav/acl.py
+===================================================================
+--- twisted/web2/dav/acl.py	(revision 17935)
++++ twisted/web2/dav/acl.py	(working copy)
+@@ -161,9 +161,9 @@
+         Check whether the supplied principal matches this principal or is a
+         member of this principal resource.
+         @param href: the L{HRef} to test.
+-        @return:     True if there is a matchg, False otherwise
++        @return:     True if there is a match, False otherwise
+         """
+-        uri = str(href) 
++        uri = str(href)
+         if self.principalURL() == uri:
+             return True
+         else:

Deleted: CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.auth
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.auth	2006-08-24 20:23:40 UTC (rev 61)
+++ CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.auth	2006-08-24 20:37:57 UTC (rev 62)
@@ -1,23 +0,0 @@
-Index: twisted/web2/dav/auth.py
-===================================================================
---- twisted/web2/dav/auth.py	(revision 17935)
-+++ twisted/web2/dav/auth.py	(working copy)
-@@ -6,6 +6,8 @@
- from twisted.web2.dav import davxml
- from twisted.web2.dav.acl import TwistedPasswordProperty
- 
-+__all__ = ["PrincipalCredentials"]
-+
- class AuthenticationWrapper(WrapperResource):
-     def __init__(self, resource, portal, credentialFactories, loginInterfaces):
-         super(AuthenticationWrapper, self).__init__(resource)
-@@ -11,7 +13,8 @@
-         super(AuthenticationWrapper, self).__init__(resource)
- 
-         self.portal = portal
--        self.credentialFactories = credentialFactories
-+        self.credentialFactories = dict([(factory.scheme, factory) 
-+                                         for factory in credentialFactories])
-         self.loginInterfaces = loginInterfaces
- 
-     def hook(self, req):

Copied: CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.auth.patch (from rev 57, CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.auth)
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.auth.patch	                        (rev 0)
+++ CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.auth.patch	2006-08-24 20:37:57 UTC (rev 62)
@@ -0,0 +1,23 @@
+Index: twisted/web2/dav/auth.py
+===================================================================
+--- twisted/web2/dav/auth.py	(revision 17935)
++++ twisted/web2/dav/auth.py	(working copy)
+@@ -6,6 +6,8 @@
+ from twisted.web2.dav import davxml
+ from twisted.web2.dav.acl import TwistedPasswordProperty
+ 
++__all__ = ["PrincipalCredentials"]
++
+ class AuthenticationWrapper(WrapperResource):
+     def __init__(self, resource, portal, credentialFactories, loginInterfaces):
+         super(AuthenticationWrapper, self).__init__(resource)
+@@ -11,7 +13,8 @@
+         super(AuthenticationWrapper, self).__init__(resource)
+ 
+         self.portal = portal
+-        self.credentialFactories = credentialFactories
++        self.credentialFactories = dict([(factory.scheme, factory) 
++                                         for factory in credentialFactories])
+         self.loginInterfaces = loginInterfaces
+ 
+     def hook(self, req):

Deleted: CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.http
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.http	2006-08-24 20:23:40 UTC (rev 61)
+++ CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.http	2006-08-24 20:37:57 UTC (rev 62)
@@ -1,24 +0,0 @@
-Index: twisted/web2/dav/http.py
-===================================================================
---- twisted/web2/dav/http.py	(revision 17935)
-+++ twisted/web2/dav/http.py	(working copy)
-@@ -102,7 +102,8 @@
-             else:
-                 uri = joinURL(base_uri, subpath)
- 
--            denials.append(davxml.Resource(davxml.HRef(uri), *[davxml.Privilege(p) for p in privileges]))
-+            for p in privileges:
-+                denials.append(davxml.Resource(davxml.HRef(uri), davxml.Privilege(p)))
- 
-         super(NeedPrivilegesResponse, self).__init__(responsecode.FORBIDDEN, davxml.NeedPrivileges(*denials))
- 
-@@ -115,9 +116,6 @@
-         """
-         @param xml_responses: an interable of davxml.Response objects.
-         """
--        multistatus = davxml.MultiStatus(*xml_responses)
--        output = multistatus.toxml()
--
-         Response.__init__(self, code=responsecode.MULTI_STATUS,
-                           stream=davxml.MultiStatus(*xml_responses).toxml())
- 

Copied: CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.http.patch (from rev 57, CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.http)
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.http.patch	                        (rev 0)
+++ CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.http.patch	2006-08-24 20:37:57 UTC (rev 62)
@@ -0,0 +1,24 @@
+Index: twisted/web2/dav/http.py
+===================================================================
+--- twisted/web2/dav/http.py	(revision 17935)
++++ twisted/web2/dav/http.py	(working copy)
+@@ -102,7 +102,8 @@
+             else:
+                 uri = joinURL(base_uri, subpath)
+ 
+-            denials.append(davxml.Resource(davxml.HRef(uri), *[davxml.Privilege(p) for p in privileges]))
++            for p in privileges:
++                denials.append(davxml.Resource(davxml.HRef(uri), davxml.Privilege(p)))
+ 
+         super(NeedPrivilegesResponse, self).__init__(responsecode.FORBIDDEN, davxml.NeedPrivileges(*denials))
+ 
+@@ -115,9 +116,6 @@
+         """
+         @param xml_responses: an interable of davxml.Response objects.
+         """
+-        multistatus = davxml.MultiStatus(*xml_responses)
+-        output = multistatus.toxml()
+-
+         Response.__init__(self, code=responsecode.MULTI_STATUS,
+                           stream=davxml.MultiStatus(*xml_responses).toxml())
+ 

Deleted: CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.method.report_acl_principal_prop_set
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.method.report_acl_principal_prop_set	2006-08-24 20:23:40 UTC (rev 61)
+++ CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.method.report_acl_principal_prop_set	2006-08-24 20:37:57 UTC (rev 62)
@@ -1,13 +0,0 @@
-Index: twisted/web2/dav/method/report_acl_principal_prop_set.py
-===================================================================
---- twisted/web2/dav/method/report_acl_principal_prop_set.py	(revision 17951)
-+++ twisted/web2/dav/method/report_acl_principal_prop_set.py	(working copy)
-@@ -90,7 +90,7 @@
-     acl = acl.getResult()
- 
-     for ace in acl.children:
--        resolved = self.resolvePrincipal(ace.principal, request)
-+        resolved = self.resolvePrincipal(ace.principal.children[0], request)
-         if resolved is not None and resolved not in principals:
-             principals.append(resolved)
- 

Copied: CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.method.report_acl_principal_prop_set.patch (from rev 57, CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.method.report_acl_principal_prop_set)
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.method.report_acl_principal_prop_set.patch	                        (rev 0)
+++ CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.method.report_acl_principal_prop_set.patch	2006-08-24 20:37:57 UTC (rev 62)
@@ -0,0 +1,13 @@
+Index: twisted/web2/dav/method/report_acl_principal_prop_set.py
+===================================================================
+--- twisted/web2/dav/method/report_acl_principal_prop_set.py	(revision 17951)
++++ twisted/web2/dav/method/report_acl_principal_prop_set.py	(working copy)
+@@ -90,7 +90,7 @@
+     acl = acl.getResult()
+ 
+     for ace in acl.children:
+-        resolved = self.resolvePrincipal(ace.principal, request)
++        resolved = self.resolvePrincipal(ace.principal.children[0], request)
+         if resolved is not None and resolved not in principals:
+             principals.append(resolved)
+ 

Deleted: CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.resource
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.resource	2006-08-24 20:23:40 UTC (rev 61)
+++ CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.resource	2006-08-24 20:37:57 UTC (rev 62)
@@ -1,391 +0,0 @@
-Index: twisted/web2/dav/resource.py
-===================================================================
---- twisted/web2/dav/resource.py	(revision 17940)
-+++ twisted/web2/dav/resource.py	(working copy)
-@@ -262,7 +262,8 @@
-                 if name == "acl":
-                     return ifAllowed(
-                         (davxml.ReadACL(),),
--                        lambda: self.accessControlList(request)
-+                        # TODO: Merge change from original patch
-+                        lambda: self.safeAccessControlList(request)
-                     )
- 
-             if namespace == twisted_dav_namespace:
-@@ -582,17 +583,28 @@
- 
-         authHeader = request.headers.getHeader('authorization')
-         if authHeader is not None:
--            if authHeader[0] in request.credentialFactories:
-+            if authHeader[0] not in request.credentialFactories:
-                 log.err("Client authentication scheme %s is not provided by server %s"
-                         % (authHeader[0], request.credentialFactories.keys()))
--                return succeed((True, False))
-+                raise HTTPError(responsecode.FORBIDDEN)
-             else:
-                 factory = request.credentialFactories[authHeader[0]]
- 
--                # FIXME: response, req are not defined
--                creds = factory.decode(response, req.method)
-+                creds = factory.decode(authHeader[1], request.method)
-+
-+                # Try to match principals in each principal collection on the resource
-+                pdetails = self.findPrincipalForAuthID(request, creds.username)
-+                assert pdetails.called
-+                pdetails = pdetails.result
-+                if pdetails:
-+                    principal = IDAVPrincipalResource(pdetails[0])
-+                    principalURI = pdetails[1]
-+                else:
-+                   raise HTTPError(responsecode.FORBIDDEN) 
-+                from twisted.web2.dav.auth import PrincipalCredentials
-+                pcreds = PrincipalCredentials(principal, principalURI, creds)
- 
--                d = request.portal.login(creds, None, *request.loginInterfaces)
-+                d = request.portal.login(pcreds, None, *request.loginInterfaces)
-                 d.addCallback(loginSuccess)
-                 return d
-         else:
-@@ -609,7 +621,7 @@
-         @return: the current principal, as derived from the given request.
-         """
-         if hasattr(request, "user"):
--            return request.user
-+            return request.user.element
-         else:
-             return unauthenticatedPrincipal
- 
-@@ -716,6 +728,10 @@
-         yield oldacl
-         oldacl = oldacl.getResult()
- 
-+        # Check disabled
-+        if oldacl is None:
-+            yield None
-+
-         # Need to get list of supported privileges
-         supported = []
-         def addSupportedPrivilege(sp):
-@@ -747,10 +763,18 @@
-                         yield (davxml.dav_namespace, "no-protected-ace-conflict")
-                         return
-                     # Step 2
--                    elif oldace.inherited:
--                        log.err("Attempt to overwrite inherited ace %r on resource %r" % (oldace, self))
--                        yield (davxml.dav_namespace, "no-inherited-ace-conflict")
--                        return
-+                    """
-+                    RFC3744 says that we either enforce the inherited ace conflict or we ignore it
-+                    # but use access control evaluation to determine whether there us any impact. Given that we
-+                    # have the 'inheritable' behavior it does not make sense to disallow overrides of inherited ACEs
-+                    # since 'inheritable' cannot itself be controlled via protocol.
-+                    
-+                    So the following lines have been commented out for now.
-+                    """
-+                    #elif oldace.inherited:
-+                    #    log.err("Attempt to overwrite inherited ace %r on resource %r" % (oldace, self))
-+                    #    yield (davxml.dav_namespace, "no-inherited-ace-conflict")
-+                    #    return
- 
-             # Step 3
-             if ace.allow and got_deny:
-@@ -806,7 +830,7 @@
-         # FIXME: verify acl is self-consistent
- 
-         # Step 11
--        self.writeDeadProperty(TwistedACLProperty(davxml.ACL(*newset)))
-+        self.writeNewACEs(newset)
-         yield None
- 
-     mergeAccessControlList = deferredGenerator(mergeAccessControlList)
-@@ -811,7 +835,24 @@
- 
-     mergeAccessControlList = deferredGenerator(mergeAccessControlList)
-         
--    def checkAccess(self, request, privileges, recurse=False, principal=None):
-+    def writeNewACEs(self, newaces):
-+        """
-+        Write a new ACL to the resource's property store.
-+        NB We have this as a separate method so that it can be overridden by resources that need to do extra
-+        processing of ACLs being set via the ACL command.
-+        
-+        @param newaces: C{list} of L{ACE} for ACL being set.
-+        """
-+        self.writeDeadProperty(TwistedACLProperty(davxml.ACL(*newaces)))
-+
-+    def matchPrivilege(self, privilege, ace_privileges, supportedPrivileges):
-+        for ace_privilege in ace_privileges:
-+            if privilege == ace_privilege or ace_privilege.isAggregateOf(privilege, supportedPrivileges):
-+                return True
-+
-+        return False
-+
-+    def checkAccess(self, request, privileges, recurse=False, principal=None, inheritedaces=None):
-         """
-         Check whether the given principal has the given privileges.
-         (RFC 3744, section 5.5)
-@@ -821,6 +862,8 @@
-         @param recurse: a boolean.  C{True} if a recursive check on all child
-             resources should be performed as well, C{False} otherwise.  (Has
-             no effect if this resource is not a collection resource.)
-+        @param inheritedaces: a list of L{Aces} corresponding to the precomputed
-+            inheritable aces from the parent resource hierarchy.
-         @return: A L{Deferred} that callbacks with C{None} or errbacks with an
-             L{twisted.web2.dav.acl.AccessDeniedError}
-         """
-@@ -918,7 +961,13 @@
-         current = self.currentPrincipal(request)
-         return self.privilegesForPrincipal(current, request)
- 
--    def accessControlList(self, request, inheritance=True, expanding=False):
-+    def safeAccessControlList(self, request):
-+        acl = self.accessControlList(request)
-+        if acl is None:
-+            acl = davxml.ACL()
-+        return acl
-+
-+    def accessControlList(self, request, inheritance=True, expanding=False, inheritedaces=None):
-         """
-         See L{IDAVResource.accessControlList}.
- 
-@@ -926,6 +975,7 @@
-         C{(L{twisted_private_namespace}, "acl")}.
-         If no ACL has been stored for this resource, it returns the value
-         returned by C{defaultAccessControlList}.
-+        If access is disabled it will return C{None}.
-         """
-         #
-         # Inheritance is problematic. Here is what we do:
-@@ -941,6 +991,12 @@
-         # If those are defined, the relevant ace is applied to the ACL on the
-         # current resource.
-         #
-+
-+        # Check disabled
-+        disabled = self.hasDeadProperty(TwistedAccessDisabledProperty)
-+        if disabled:
-+            yield None
-+
-         myURL = None
- 
-         def getMyURL():
-@@ -976,29 +1032,36 @@
-             if myURL is None:
-                 myURL = getMyURL()
- 
--            if myURL != "/":
--                parentURL = parentForURL(myURL)
--
--                parent = waitForDeferred(request.locateResource(parentURL))
--                yield parent
--                parent = parent.getResult()
--
--                if parent:
--                    parent_acl = waitForDeferred(
--                        parent.accessControlList(request, inheritance=True, expanding=True)
--                    )
--                    yield parent_acl
--                    parent_acl = parent_acl.getResult()
--
--                    for ace in parent_acl.children:
--                        if ace.inherited:
--                            aces.append(ace)
--                        elif TwistedACLInheritable() in ace.children:
--                            # Adjust ACE for inherit on this resource
--                            children = list(ace.children)
--                            children.remove(TwistedACLInheritable())
--                            children.append(davxml.Inherited(davxml.HRef.fromString(parentURL)))
--                            aces.append(davxml.ACE(*children))
-+            if inheritedaces is None:
-+                if myURL != "/":
-+                    parentURL = parentForURL(myURL)
-+    
-+                    parent = waitForDeferred(request.locateResource(parentURL))
-+                    yield parent
-+                    parent = parent.getResult()
-+    
-+                    if parent:
-+                        parent_acl = waitForDeferred(
-+                            parent.accessControlList(request, inheritance=True, expanding=True)
-+                        )
-+                        yield parent_acl
-+                        parent_acl = parent_acl.getResult()
-+    
-+                        # Check disabled
-+                        if parent_acl is None:
-+                            yield None
-+    
-+                        for ace in parent_acl.children:
-+                            if ace.inherited:
-+                                aces.append(ace)
-+                            elif TwistedACLInheritable() in ace.children:
-+                                # Adjust ACE for inherit on this resource
-+                                children = list(ace.children)
-+                                children.remove(TwistedACLInheritable())
-+                                children.append(davxml.Inherited(davxml.HRef.fromString(parentURL)))
-+                                aces.append(davxml.ACE(*children))
-+            else:
-+                aces.extend(inheritedaces)
- 
-             # Always filter out any remaining private properties when we are
-             # returning the ACL for the final resource after doing parent
-@@ -1018,6 +1081,49 @@
- 
-     accessControlList = deferredGenerator(accessControlList)
- 
-+    # TODO: Convert to deferredGenerator
-+    def inheritedACEsforChildren(self, request):
-+        """
-+        Do some optimisation of access control calculation by determining any inherited ACLs outside of
-+        the child resource loop and supply those to the checkAccess on each child.
-+
-+        @param request: the L{IRequest} for the request in progress.
-+        @return:        a C{list} of L{Ace}s that child resources of this one will
-+            inherit and which will match the currently authenticated principal.
-+        """
-+        
-+        # Get the parent ACLs with inheritance and preserve the <inheritable> element.
-+        parent_acl = self.accessControlList(request, inheritance=True, expanding=True)
-+        
-+        # Check disabled
-+        if parent_acl is None:
-+            return None
-+
-+        # Filter out those that are not inheritable (and remove the inheritable element from those that are)
-+        aces = []
-+        for ace in parent_acl.children:
-+            if ace.inherited:
-+                aces.append(ace)
-+            elif TwistedACLInheritable() in ace.children:
-+                # Adjust ACE for inherit on this resource
-+                children = list(ace.children)
-+                children.remove(TwistedACLInheritable())
-+                children.append(davxml.Inherited(davxml.HRef.fromString(self.getURI(request))))
-+                aces.append(davxml.ACE(*children))
-+                
-+        # Filter out those that do not have a principal match with the current principal
-+        principal = self.currentPrincipal(request)
-+        filteredaces = []
-+        for ace in aces:
-+            if self.matchPrincipal(principal, ace.principal, request):
-+                if ace.invert:
-+                    continue
-+            else:
-+                if not ace.invert:
-+                    continue
-+            filteredaces.append(ace)
-+        return filteredaces
-+
-     def inheritedACLSet(self):
-         """
-         @return: a sequence of L{davxml.HRef}s from which ACLs are inherited.
-@@ -1054,6 +1160,10 @@
-                 yield (principal, principalURI)
-                 return
-         else:
-+            if len(self.principalCollections(request)) == 0:
-+                log.msg("<DAV:principal-collection-set> property cannot be found on the resource being authorized: %s" % self)
-+            else:
-+                log.msg("Could not find principal matching user id: %s" % authid)
-             yield None
- 
-     findPrincipalForAuthID = deferredGenerator(findPrincipalForAuthID)
-@@ -1135,13 +1245,12 @@
- 
-         # Now principal2 is an HRef
- 
--        if principal1 == principal2:
-+        # Compare two HRefs and do group membership test as well
-+        if ((principal1 == principal2) or
-+            self.principalIsGroupMember(str(principal1), str(principal2), request)):
-             yield True
-             return
- 
--        # FIXME: We still need to handle the case where principal2 is a group
--        # containing principal1.
--
-         yield False
- 
-     matchPrincipal = deferredGenerator(matchPrincipal)
-@@ -1146,6 +1255,29 @@
- 
-     matchPrincipal = deferredGenerator(matchPrincipal)
- 
-+    def principalIsGroupMember(self, principal1, principal2, request):
-+        """
-+        Check whether one principal is a group member of another.
-+        
-+        @param principal1: C{str} principalURL for principal to test.
-+        @param principal2: C{str} principalURL for possible group principal to test against.
-+        @param request: the request being processed.
-+        @return: C{True} if principal1 is a member of principal2, C{False} otherwise
-+        """
-+        
-+        def defer():
-+            # Get principal resource for principal2
-+            group = self.locateSiblingResource(request, principal2)
-+            from twisted.web2.dav.acl import DAVPrincipalResource
-+            if group and isinstance(group, DAVPrincipalResource):
-+                members = group.groupMembers()
-+                if principal1 in members:
-+                    return True
-+                
-+            return False
-+
-+        return maybeDeferred(defer)
-+        
-     def validPrincipal(self, ace_principal, request):
-         """
-         Check whether the supplied principal is valid for this resource.
-@@ -1207,11 +1339,10 @@
-         All other principals, including meta-principals (eg. L{davxml.All}),
-         resolve to C{None}.
- 
--        @param principal: the L{davxml.Principal} element to resolve.
-+        @param principal: the L{davxml.Principal} child element to resolve.
-         @param request: the request being processed.
-         @return: a deferred L{davxml.HRef} element or C{None}.
-         """
--        principal = principal.children[0]
- 
-         if isinstance(principal, davxml.Property):
-             # raise NotImplementedError("Property principals are not implemented.")
-@@ -1291,6 +1422,10 @@
-         yield acl
-         acl = acl.getResult()
- 
-+        # Check disabled
-+        if acl is None:
-+            yield []
-+
-         granted = []
-         denied = []
-         for ace in acl.children:
-@@ -1430,6 +1565,10 @@
- davxml.registerElement(TwistedPrincipalCollectionSetProperty)
- 
- class TwistedACLInheritable (davxml.WebDAVEmptyElement):
-+    """
-+    When set on an ACE, this indicates that the ACE privileges should be inherited by
-+    all child resources within the resource with this ACE.
-+    """
-     namespace = twisted_dav_namespace
-     name = "inheritable"
- 
-@@ -1436,6 +1575,16 @@
- davxml.registerElement(TwistedACLInheritable)
- davxml.ACE.allowed_children[(twisted_dav_namespace, "inheritable")] = (0, 1)
- 
-+"""
-+When set on a resource, this property indicates that all access to the resource and any of its children
-+is completely disabled - irrespective of any other privileges directly set or inherited.
-+"""
-+class TwistedAccessDisabledProperty (davxml.WebDAVEmptyElement):
-+    namespace = twisted_private_namespace
-+    name = "access-disabled"
-+
-+davxml.registerElement(TwistedAccessDisabledProperty)
-+
- allACL = davxml.ACL(
-     davxml.ACE(
-         davxml.Principal(davxml.All()),

Copied: CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.resource.patch (from rev 57, CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.resource)
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.resource.patch	                        (rev 0)
+++ CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.resource.patch	2006-08-24 20:37:57 UTC (rev 62)
@@ -0,0 +1,391 @@
+Index: twisted/web2/dav/resource.py
+===================================================================
+--- twisted/web2/dav/resource.py	(revision 17940)
++++ twisted/web2/dav/resource.py	(working copy)
+@@ -262,7 +262,8 @@
+                 if name == "acl":
+                     return ifAllowed(
+                         (davxml.ReadACL(),),
+-                        lambda: self.accessControlList(request)
++                        # TODO: Merge change from original patch
++                        lambda: self.safeAccessControlList(request)
+                     )
+ 
+             if namespace == twisted_dav_namespace:
+@@ -582,17 +583,28 @@
+ 
+         authHeader = request.headers.getHeader('authorization')
+         if authHeader is not None:
+-            if authHeader[0] in request.credentialFactories:
++            if authHeader[0] not in request.credentialFactories:
+                 log.err("Client authentication scheme %s is not provided by server %s"
+                         % (authHeader[0], request.credentialFactories.keys()))
+-                return succeed((True, False))
++                raise HTTPError(responsecode.FORBIDDEN)
+             else:
+                 factory = request.credentialFactories[authHeader[0]]
+ 
+-                # FIXME: response, req are not defined
+-                creds = factory.decode(response, req.method)
++                creds = factory.decode(authHeader[1], request.method)
++
++                # Try to match principals in each principal collection on the resource
++                pdetails = self.findPrincipalForAuthID(request, creds.username)
++                assert pdetails.called
++                pdetails = pdetails.result
++                if pdetails:
++                    principal = IDAVPrincipalResource(pdetails[0])
++                    principalURI = pdetails[1]
++                else:
++                   raise HTTPError(responsecode.FORBIDDEN) 
++                from twisted.web2.dav.auth import PrincipalCredentials
++                pcreds = PrincipalCredentials(principal, principalURI, creds)
+ 
+-                d = request.portal.login(creds, None, *request.loginInterfaces)
++                d = request.portal.login(pcreds, None, *request.loginInterfaces)
+                 d.addCallback(loginSuccess)
+                 return d
+         else:
+@@ -609,7 +621,7 @@
+         @return: the current principal, as derived from the given request.
+         """
+         if hasattr(request, "user"):
+-            return request.user
++            return request.user.element
+         else:
+             return unauthenticatedPrincipal
+ 
+@@ -716,6 +728,10 @@
+         yield oldacl
+         oldacl = oldacl.getResult()
+ 
++        # Check disabled
++        if oldacl is None:
++            yield None
++
+         # Need to get list of supported privileges
+         supported = []
+         def addSupportedPrivilege(sp):
+@@ -747,10 +763,18 @@
+                         yield (davxml.dav_namespace, "no-protected-ace-conflict")
+                         return
+                     # Step 2
+-                    elif oldace.inherited:
+-                        log.err("Attempt to overwrite inherited ace %r on resource %r" % (oldace, self))
+-                        yield (davxml.dav_namespace, "no-inherited-ace-conflict")
+-                        return
++                    """
++                    RFC3744 says that we either enforce the inherited ace conflict or we ignore it
++                    # but use access control evaluation to determine whether there us any impact. Given that we
++                    # have the 'inheritable' behavior it does not make sense to disallow overrides of inherited ACEs
++                    # since 'inheritable' cannot itself be controlled via protocol.
++                    
++                    So the following lines have been commented out for now.
++                    """
++                    #elif oldace.inherited:
++                    #    log.err("Attempt to overwrite inherited ace %r on resource %r" % (oldace, self))
++                    #    yield (davxml.dav_namespace, "no-inherited-ace-conflict")
++                    #    return
+ 
+             # Step 3
+             if ace.allow and got_deny:
+@@ -806,7 +830,7 @@
+         # FIXME: verify acl is self-consistent
+ 
+         # Step 11
+-        self.writeDeadProperty(TwistedACLProperty(davxml.ACL(*newset)))
++        self.writeNewACEs(newset)
+         yield None
+ 
+     mergeAccessControlList = deferredGenerator(mergeAccessControlList)
+@@ -811,7 +835,24 @@
+ 
+     mergeAccessControlList = deferredGenerator(mergeAccessControlList)
+         
+-    def checkAccess(self, request, privileges, recurse=False, principal=None):
++    def writeNewACEs(self, newaces):
++        """
++        Write a new ACL to the resource's property store.
++        NB We have this as a separate method so that it can be overridden by resources that need to do extra
++        processing of ACLs being set via the ACL command.
++        
++        @param newaces: C{list} of L{ACE} for ACL being set.
++        """
++        self.writeDeadProperty(TwistedACLProperty(davxml.ACL(*newaces)))
++
++    def matchPrivilege(self, privilege, ace_privileges, supportedPrivileges):
++        for ace_privilege in ace_privileges:
++            if privilege == ace_privilege or ace_privilege.isAggregateOf(privilege, supportedPrivileges):
++                return True
++
++        return False
++
++    def checkAccess(self, request, privileges, recurse=False, principal=None, inheritedaces=None):
+         """
+         Check whether the given principal has the given privileges.
+         (RFC 3744, section 5.5)
+@@ -821,6 +862,8 @@
+         @param recurse: a boolean.  C{True} if a recursive check on all child
+             resources should be performed as well, C{False} otherwise.  (Has
+             no effect if this resource is not a collection resource.)
++        @param inheritedaces: a list of L{Aces} corresponding to the precomputed
++            inheritable aces from the parent resource hierarchy.
+         @return: A L{Deferred} that callbacks with C{None} or errbacks with an
+             L{twisted.web2.dav.acl.AccessDeniedError}
+         """
+@@ -918,7 +961,13 @@
+         current = self.currentPrincipal(request)
+         return self.privilegesForPrincipal(current, request)
+ 
+-    def accessControlList(self, request, inheritance=True, expanding=False):
++    def safeAccessControlList(self, request):
++        acl = self.accessControlList(request)
++        if acl is None:
++            acl = davxml.ACL()
++        return acl
++
++    def accessControlList(self, request, inheritance=True, expanding=False, inheritedaces=None):
+         """
+         See L{IDAVResource.accessControlList}.
+ 
+@@ -926,6 +975,7 @@
+         C{(L{twisted_private_namespace}, "acl")}.
+         If no ACL has been stored for this resource, it returns the value
+         returned by C{defaultAccessControlList}.
++        If access is disabled it will return C{None}.
+         """
+         #
+         # Inheritance is problematic. Here is what we do:
+@@ -941,6 +991,12 @@
+         # If those are defined, the relevant ace is applied to the ACL on the
+         # current resource.
+         #
++
++        # Check disabled
++        disabled = self.hasDeadProperty(TwistedAccessDisabledProperty)
++        if disabled:
++            yield None
++
+         myURL = None
+ 
+         def getMyURL():
+@@ -976,29 +1032,36 @@
+             if myURL is None:
+                 myURL = getMyURL()
+ 
+-            if myURL != "/":
+-                parentURL = parentForURL(myURL)
+-
+-                parent = waitForDeferred(request.locateResource(parentURL))
+-                yield parent
+-                parent = parent.getResult()
+-
+-                if parent:
+-                    parent_acl = waitForDeferred(
+-                        parent.accessControlList(request, inheritance=True, expanding=True)
+-                    )
+-                    yield parent_acl
+-                    parent_acl = parent_acl.getResult()
+-
+-                    for ace in parent_acl.children:
+-                        if ace.inherited:
+-                            aces.append(ace)
+-                        elif TwistedACLInheritable() in ace.children:
+-                            # Adjust ACE for inherit on this resource
+-                            children = list(ace.children)
+-                            children.remove(TwistedACLInheritable())
+-                            children.append(davxml.Inherited(davxml.HRef.fromString(parentURL)))
+-                            aces.append(davxml.ACE(*children))
++            if inheritedaces is None:
++                if myURL != "/":
++                    parentURL = parentForURL(myURL)
++    
++                    parent = waitForDeferred(request.locateResource(parentURL))
++                    yield parent
++                    parent = parent.getResult()
++    
++                    if parent:
++                        parent_acl = waitForDeferred(
++                            parent.accessControlList(request, inheritance=True, expanding=True)
++                        )
++                        yield parent_acl
++                        parent_acl = parent_acl.getResult()
++    
++                        # Check disabled
++                        if parent_acl is None:
++                            yield None
++    
++                        for ace in parent_acl.children:
++                            if ace.inherited:
++                                aces.append(ace)
++                            elif TwistedACLInheritable() in ace.children:
++                                # Adjust ACE for inherit on this resource
++                                children = list(ace.children)
++                                children.remove(TwistedACLInheritable())
++                                children.append(davxml.Inherited(davxml.HRef.fromString(parentURL)))
++                                aces.append(davxml.ACE(*children))
++            else:
++                aces.extend(inheritedaces)
+ 
+             # Always filter out any remaining private properties when we are
+             # returning the ACL for the final resource after doing parent
+@@ -1018,6 +1081,49 @@
+ 
+     accessControlList = deferredGenerator(accessControlList)
+ 
++    # TODO: Convert to deferredGenerator
++    def inheritedACEsforChildren(self, request):
++        """
++        Do some optimisation of access control calculation by determining any inherited ACLs outside of
++        the child resource loop and supply those to the checkAccess on each child.
++
++        @param request: the L{IRequest} for the request in progress.
++        @return:        a C{list} of L{Ace}s that child resources of this one will
++            inherit and which will match the currently authenticated principal.
++        """
++        
++        # Get the parent ACLs with inheritance and preserve the <inheritable> element.
++        parent_acl = self.accessControlList(request, inheritance=True, expanding=True)
++        
++        # Check disabled
++        if parent_acl is None:
++            return None
++
++        # Filter out those that are not inheritable (and remove the inheritable element from those that are)
++        aces = []
++        for ace in parent_acl.children:
++            if ace.inherited:
++                aces.append(ace)
++            elif TwistedACLInheritable() in ace.children:
++                # Adjust ACE for inherit on this resource
++                children = list(ace.children)
++                children.remove(TwistedACLInheritable())
++                children.append(davxml.Inherited(davxml.HRef.fromString(self.getURI(request))))
++                aces.append(davxml.ACE(*children))
++                
++        # Filter out those that do not have a principal match with the current principal
++        principal = self.currentPrincipal(request)
++        filteredaces = []
++        for ace in aces:
++            if self.matchPrincipal(principal, ace.principal, request):
++                if ace.invert:
++                    continue
++            else:
++                if not ace.invert:
++                    continue
++            filteredaces.append(ace)
++        return filteredaces
++
+     def inheritedACLSet(self):
+         """
+         @return: a sequence of L{davxml.HRef}s from which ACLs are inherited.
+@@ -1054,6 +1160,10 @@
+                 yield (principal, principalURI)
+                 return
+         else:
++            if len(self.principalCollections(request)) == 0:
++                log.msg("<DAV:principal-collection-set> property cannot be found on the resource being authorized: %s" % self)
++            else:
++                log.msg("Could not find principal matching user id: %s" % authid)
+             yield None
+ 
+     findPrincipalForAuthID = deferredGenerator(findPrincipalForAuthID)
+@@ -1135,13 +1245,12 @@
+ 
+         # Now principal2 is an HRef
+ 
+-        if principal1 == principal2:
++        # Compare two HRefs and do group membership test as well
++        if ((principal1 == principal2) or
++            self.principalIsGroupMember(str(principal1), str(principal2), request)):
+             yield True
+             return
+ 
+-        # FIXME: We still need to handle the case where principal2 is a group
+-        # containing principal1.
+-
+         yield False
+ 
+     matchPrincipal = deferredGenerator(matchPrincipal)
+@@ -1146,6 +1255,29 @@
+ 
+     matchPrincipal = deferredGenerator(matchPrincipal)
+ 
++    def principalIsGroupMember(self, principal1, principal2, request):
++        """
++        Check whether one principal is a group member of another.
++        
++        @param principal1: C{str} principalURL for principal to test.
++        @param principal2: C{str} principalURL for possible group principal to test against.
++        @param request: the request being processed.
++        @return: C{True} if principal1 is a member of principal2, C{False} otherwise
++        """
++        
++        def defer():
++            # Get principal resource for principal2
++            group = self.locateSiblingResource(request, principal2)
++            from twisted.web2.dav.acl import DAVPrincipalResource
++            if group and isinstance(group, DAVPrincipalResource):
++                members = group.groupMembers()
++                if principal1 in members:
++                    return True
++                
++            return False
++
++        return maybeDeferred(defer)
++        
+     def validPrincipal(self, ace_principal, request):
+         """
+         Check whether the supplied principal is valid for this resource.
+@@ -1207,11 +1339,10 @@
+         All other principals, including meta-principals (eg. L{davxml.All}),
+         resolve to C{None}.
+ 
+-        @param principal: the L{davxml.Principal} element to resolve.
++        @param principal: the L{davxml.Principal} child element to resolve.
+         @param request: the request being processed.
+         @return: a deferred L{davxml.HRef} element or C{None}.
+         """
+-        principal = principal.children[0]
+ 
+         if isinstance(principal, davxml.Property):
+             # raise NotImplementedError("Property principals are not implemented.")
+@@ -1291,6 +1422,10 @@
+         yield acl
+         acl = acl.getResult()
+ 
++        # Check disabled
++        if acl is None:
++            yield []
++
+         granted = []
+         denied = []
+         for ace in acl.children:
+@@ -1430,6 +1565,10 @@
+ davxml.registerElement(TwistedPrincipalCollectionSetProperty)
+ 
+ class TwistedACLInheritable (davxml.WebDAVEmptyElement):
++    """
++    When set on an ACE, this indicates that the ACE privileges should be inherited by
++    all child resources within the resource with this ACE.
++    """
+     namespace = twisted_dav_namespace
+     name = "inheritable"
+ 
+@@ -1436,6 +1575,16 @@
+ davxml.registerElement(TwistedACLInheritable)
+ davxml.ACE.allowed_children[(twisted_dav_namespace, "inheritable")] = (0, 1)
+ 
++"""
++When set on a resource, this property indicates that all access to the resource and any of its children
++is completely disabled - irrespective of any other privileges directly set or inherited.
++"""
++class TwistedAccessDisabledProperty (davxml.WebDAVEmptyElement):
++    namespace = twisted_private_namespace
++    name = "access-disabled"
++
++davxml.registerElement(TwistedAccessDisabledProperty)
++
+ allACL = davxml.ACL(
+     davxml.ACE(
+         davxml.Principal(davxml.All()),

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20060824/a7fc46f7/attachment.html


More information about the calendarserver-changes mailing list