[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