[CalendarServer-changes] [56]
CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted
source_changes at macosforge.org
source_changes at macosforge.org
Thu Aug 24 12:45:44 PDT 2006
Revision: 56
Author: cdaboo at apple.com
Date: 2006-08-24 12:45:42 -0700 (Thu, 24 Aug 2006)
Log Message:
-----------
These are no longer relevant as some have already been incorporated into twisted branch. Others
have been merged in with the new twisted code and will re-appear shortly...
Removed 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.element.rfc3744.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.resource.patch
CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.static.patch
Deleted: CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.acl.patch
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.acl.patch 2006-08-23 19:14:16 UTC (rev 55)
+++ CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.acl.patch 2006-08-24 19:45:42 UTC (rev 56)
@@ -1,48 +0,0 @@
-Index: twisted/web2/dav/acl.py
-===================================================================
---- twisted/web2/dav/acl.py (revision 17005)
-+++ twisted/web2/dav/acl.py (working copy)
-@@ -50,8 +50,8 @@
- ##
-
- liveProperties = DAVLeafResource.liveProperties + (
-- (dav_namespace, "alternate-uri-set"),
-- (dav_namespace, "principal-url" ),
-+ (dav_namespace, "alternate-URI-set"),
-+ (dav_namespace, "principal-URL" ),
- (dav_namespace, "group-member-set" ),
- (dav_namespace, "group-membership" ),
- )
-@@ -68,10 +68,8 @@
- def readProperty(self, property, request):
- if type(property) is tuple:
- qname = property
-- sname = "{%s}%s" % property
- else:
- qname = property.qname()
-- sname = property.sname()
-
- namespace, name = qname
-
-@@ -76,10 +74,10 @@
- namespace, name = qname
-
- if namespace == dav_namespace:
-- if name == "alternate-uri-set":
-+ if name == "alternate-URI-set":
- return davxml.AlternateURISet(*[davxml.HRef(u) for u in self.alternateURIs()])
-
-- if name == "principal-url":
-+ if name == "principal-URL":
- return davxml.PrincipalURL(davxml.HRef(self.principalURL()))
-
- if name == "group-member-set":
-@@ -86,7 +84,7 @@
- return davxml.GroupMemberSet(*[davxml.HRef(p) for p in self.groupMembers()])
-
- if name == "group-membership":
-- return davxml.GroupMemberSet(*[davxml.HRef(g) for g in self.groupMemberships()])
-+ return davxml.GroupMembership(*[davxml.HRef(g) for g in self.groupMemberships()])
-
- if name == "resourcetype":
- if self.isCollection():
Deleted: CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.auth.patch
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.auth.patch 2006-08-23 19:14:16 UTC (rev 55)
+++ CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.auth.patch 2006-08-24 19:45:42 UTC (rev 56)
@@ -1,20 +0,0 @@
-Index: twisted/web2/dav/auth.py
-===================================================================
---- twisted/web2/dav/auth.py (revision 17005)
-+++ twisted/web2/dav/auth.py (working copy)
-@@ -190,7 +190,6 @@
- log.err("Client authentication password for %s incorrect" % (self.username,))
- return False, None
- else:
-- log.err("Client authentication user id %s does not match a principal on the server" % (self.username,))
- return False, None
-
- class BasicAuthorizer:
-@@ -306,7 +305,6 @@
- log.err("Client authentication password for %s incorrect" % (self.username,))
- return False, None
- else:
-- log.err("Client authentication user id %s does not match a principal on the server" % (self.username,))
- return False, None
-
- def checkPassword(self, password):
Deleted: CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.element.rfc3744.patch
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.element.rfc3744.patch 2006-08-23 19:14:16 UTC (rev 55)
+++ CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.element.rfc3744.patch 2006-08-24 19:45:42 UTC (rev 56)
@@ -1,22 +0,0 @@
-Index: twisted/web2/dav/element/rfc3744.py
-===================================================================
---- twisted/web2/dav/element/rfc3744.py (revision 17005)
-+++ twisted/web2/dav/element/rfc3744.py (working copy)
-@@ -147,7 +147,7 @@
- Property which contains the URIs of network resources with additional
- descriptive information about the principal. (RFC 3744, section 4.1)
- """
-- name = "alternate-uri-set"
-+ name = "alternate-URI-set"
- hidden = True
- protected = True
-
-@@ -158,7 +158,7 @@
- Property which contains the URL that must be used to identify this principal
- in an ACL request. (RFC 3744, section 4.2)
- """
-- name = "principal-url"
-+ name = "principal-URL"
- hidden = True
- protected = True
-
Deleted: CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.http.patch
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.http.patch 2006-08-23 19:14:16 UTC (rev 55)
+++ CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.http.patch 2006-08-24 19:45:42 UTC (rev 56)
@@ -1,24 +0,0 @@
-Index: twisted/web2/dav/http.py
-===================================================================
---- twisted/web2/dav/http.py (revision 17005)
-+++ 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.resource.patch
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.resource.patch 2006-08-23 19:14:16 UTC (rev 55)
+++ CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.resource.patch 2006-08-24 19:45:42 UTC (rev 56)
@@ -1,429 +0,0 @@
-Index: twisted/web2/dav/resource.py
-===================================================================
---- twisted/web2/dav/resource.py (revision 17097)
-+++ twisted/web2/dav/resource.py (working copy)
-@@ -193,7 +193,13 @@
- return davxml.GETContentType(generateContentType(mimeType))
-
- if name == "getcontentlength":
-- return davxml.GETContentLength(str(self.contentLength()))
-+ length = self.contentLength()
-+ if length is None:
-+ # TODO: really we should "render" the resource and determine its size from that,
-+ # but for now we just return an empty element.
-+ return davxml.GETContentLength("")
-+ else:
-+ return davxml.GETContentLength(str(length))
-
- if name == "getlastmodified":
- return davxml.GETLastModified.fromDate(self.lastModified())
-@@ -227,7 +233,10 @@
- # MUST have DAV:read-acl ACL to return this
- if self.checkAccess(request, (davxml.ReadACL(),)):
- raise HTTPError(StatusResponse(responsecode.UNAUTHORIZED, "Access denied while reading property %s." % (sname,)))
-- return self.accessControlList(request)
-+ acl = self.accessControlList(request)
-+ if acl is None:
-+ acl = davxml.ACL()
-+ return acl
-
- if name == "acl-restrictions":
- return davxml.ACLRestrictions()
-@@ -700,6 +709,10 @@
-
- oldacl = self.accessControlList(request)
-
-+ # Check disabled
-+ if oldacl is None:
-+ return None
-+
- # Need to get list of supported privileges
- supported = []
- def addSupportedPrivilege(sp):
-@@ -727,9 +740,17 @@
- log.err("Attempt to overwrite protected ace %r on resource %r" % (oldace, self))
- return (davxml.dav_namespace, "no-protected-ace-conflict")
- # Step 2
-- elif oldace.inherited:
-- log.err("Attempt to overwrite inherited ace %r on resource %r" % (oldace, self))
-- return (davxml.dav_namespace, "no-inherited-ace-conflict")
-+ """
-+ 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 3 lines have been commented out for now.
-+ """
-+ #elif oldace.inherited:
-+ # log.err("Attempt to overwrite inherited ace %r on resource %r" % (oldace, self))
-+ # return (davxml.dav_namespace, "no-inherited-ace-conflict")
-
- # Step 3
- if ace.allow and got_deny:
-@@ -776,10 +797,27 @@
- # FIXME: verify acl is self-consistent
-
- # Step 11
-- self.writeDeadProperty(TwistedACLProperty(davxml.ACL(*newset)))
-+ self.writeNewACEs(newset)
- return None
-
-- 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)
-@@ -789,6 +827,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 sequence of tuples, one for each resource for which one or
- more of the given privileges are not granted, in the form
- C{(uri, privileges)}, where uri is a URL path relative to this
-@@ -800,80 +840,8 @@
- principal = self.currentPrincipal(request)
- supportedPrivileges = self.supportedPrivileges(request)
-
-- # The interesting part of a principal is it's one child
-- principal = principal.children[0]
--
- # Other principals types don't make sense as actors.
-- assert principal.name in ("unauthenticated", "href")
--
-- def match_principal(ace_principal):
-- """
-- Returns True if ace_principal matches principal.
-- """
-- # See RFC 3744, section 5.5.1
--
-- # The interesting part of a principal is it's one child
-- ace_principal = ace_principal.children[0]
--
-- if isinstance(ace_principal, davxml.Property):
-- #FIXME: I think this is wrong - we need to get the ns, name from the first child of DAV:property
-- namespace = ace_principal.attributes.get(["namespace"], dav_namespace)
-- name = ace_principal.attributes["name"]
--
-- try:
-- ace_principal = self.readProperty((namespace, name), request)
-- except HTTPError, e:
-- assert e.response.code == responsecode.NOT_FOUND
-- return False
--
-- if len(ace_principal) != 1:
-- return False
--
-- # The interesting part of a principal is it's one child
-- ace_principal = ace_principal.children[0]
--
-- if not isinstance(ace_principal, davxml.HRef):
-- return False
--
-- raise NotImplementedError("Need to verify that ACE principal URL is valid")
--
-- # Fall through...
--
-- if isinstance(ace_principal, davxml.Self):
-- try:
-- self = IDAVPrincipalResource(self)
-- except TypeError:
-- log.err("DAV:self ACE is set on non-principal resource %r" % (self,))
-- return False
--
-- if isinstance(principal, davxml.Unauthenticated):
-- return False
--
-- if isinstance(principal, davxml.HRef):
-- return str(principal) == self.principalURL()
--
-- raise AssertionError("We shouldn't be here")
--
-- if isinstance(ace_principal, davxml.All):
-- return True
--
-- if isinstance(ace_principal, davxml.Authenticated):
-- if isinstance(principal, davxml.HRef):
-- return True
-- else:
-- return False
--
-- if isinstance(ace_principal, davxml.Unauthenticated) or isinstance(ace_principal, davxml.HRef):
-- return ace_principal == principal
--
-- raise AssertionError("We shouldn't be here")
--
-- def match_privilege(privilege, ace_privileges):
-- for ace_privilege in ace_privileges:
-- if privilege == ace_privilege or ace_privilege.isAggregateOf(privilege, supportedPrivileges):
-- return True
--
-- return False
-+ assert principal.children[0].name in ("unauthenticated", "href")
-
- if recurse:
- depth="infinity"
-@@ -883,7 +851,13 @@
- errors = []
-
- for resource, subpath in itertools.chain(((self, None),), self.findChildren(depth=depth)):
-- acl = resource.accessControlList(request)
-+ acl = resource.accessControlList(request, inheritedaces=inheritedaces)
-+
-+ # Check for disabled
-+ if acl is None:
-+ errors.append((subpath, list(privileges)))
-+ continue
-+
- pending = list(privileges)
- denied = []
-
-@@ -889,10 +863,10 @@
-
- for ace in acl.children:
- for privilege in tuple(pending):
-- if not match_privilege(davxml.Privilege(privilege), ace.privileges):
-+ if not self.matchPrivilege(davxml.Privilege(privilege), ace.privileges, supportedPrivileges):
- continue
-
-- if match_principal(ace.principal):
-+ if self.matchPrincipal(principal, ace.principal, request):
- if ace.invert:
- continue
- else:
-@@ -930,7 +904,7 @@
- current = self.currentPrincipal(request)
- return self.privilegesForPrincipal(current, request)
-
-- def accessControlList(self, request, inheritance=True, expanding=False):
-+ def accessControlList(self, request, inheritance=True, expanding=False, inheritedaces=None):
- """
- See L{IDAVResource.accessControlList}.
-
-@@ -938,6 +912,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}.
- """
-
- """
-@@ -949,6 +924,12 @@
- all parent resources of the current one looking for any <Twisted:inheritable> elements.
- If those are defined, the relevant ace is applied to the ACL on the current resource.
- """
-+
-+ # Check disabled
-+ disabled = self.hasDeadProperty(TwistedAccessDisabledProperty)
-+ if disabled:
-+ return None
-+
- try:
- acl = self.readDeadProperty(TwistedACLProperty).getValue()
- except HTTPError, e:
-@@ -965,22 +946,30 @@
- if inheritance:
- aces = list(acl.children)
-
-- if self.getURI(request) != "/":
-- parentURL = parentForURL(self.getURI(request))
-- parent = self.locateSiblingResource(request, parentURL)
--
-- if parent:
-- parent_acl = parent.accessControlList(request, inheritance=True, expanding=True)
--
-- 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 self.getURI(request) != "/":
-+ parentURL = parentForURL(self.getURI(request))
-+ parent = self.locateSiblingResource(request, parentURL)
-+
-+ if parent:
-+ parent_acl = parent.accessControlList(request, inheritance=True, expanding=True)
-+
-+ # Check disabled
-+ if parent_acl is None:
-+ return 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
-@@ -998,6 +987,48 @@
-
- return acl
-
-+ 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.
-@@ -1023,6 +1054,10 @@
- if isPrincipalResource(principal):
- return (principal, principalURI)
- 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)
- return None
-
- def samePrincipal(self, principal1, principal2):
-@@ -1109,11 +1144,36 @@
- else:
- return False
-
-- if isinstance(principal2, davxml.Unauthenticated) or isinstance(principal2, davxml.HRef):
-+ if isinstance(principal2, davxml.Unauthenticated):
- return principal2 == principal1
-
-+ # Compare two HRefs and do group membership test as well
-+ if isinstance(principal2, davxml.HRef):
-+ return (principal2 == principal1 or
-+ self.principalIsGroupMember(str(principal1), str(principal2), request))
-+
- raise AssertionError("We shouldn't be here")
-
-+ 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
-+ """
-+
-+ # 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
-+
- def validPrincipal(self, ace_principal, request):
- """
- Check whether the supplied principal is valid for this resource.
-@@ -1228,6 +1288,11 @@
- NB Return aggregate privileges expanded.
- """
- acl = self.accessControlList(request)
-+
-+ # Check disabled
-+ if acl is None:
-+ return []
-+
- granted = []
- denied = []
- for ace in acl.children:
-@@ -1374,6 +1439,11 @@
- parser.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"
-
-@@ -1380,6 +1450,17 @@
- parser.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"
-+
-+parser.registerElement(TwistedAccessDisabledProperty)
-+
-+
- allACL = davxml.ACL(
- davxml.ACE(
- davxml.Principal(davxml.All()),
Deleted: CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.static.patch
===================================================================
--- CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.static.patch 2006-08-23 19:14:16 UTC (rev 55)
+++ CalendarServer/branches/users/cdaboo/acl-merge/patches/Twisted/twisted.web2.dav.static.patch 2006-08-24 19:45:42 UTC (rev 56)
@@ -1,164 +0,0 @@
-Index: twisted/web2/dav/static.py
-===================================================================
---- twisted/web2/dav/static.py (revision 17005)
-+++ twisted/web2/dav/static.py (working copy)
-@@ -32,8 +32,10 @@
- import urllib
-
- from twisted.python import log
--from twisted.web2.static import File
--from twisted.web2.server import StopTraversal
-+from twisted.web2 import dirlist
-+from twisted.web2 import http
-+from twisted.web2 import responsecode
-+from twisted.web2 import stream
- from twisted.web2.dav import davxml
- from twisted.web2.dav.idav import IDAVResource
- from twisted.web2.dav.resource import DAVResource
-@@ -38,6 +40,8 @@
- from twisted.web2.dav.idav import IDAVResource
- from twisted.web2.dav.resource import DAVResource
- from twisted.web2.dav.util import bindMethods
-+from twisted.web2.server import StopTraversal
-+from twisted.web2.static import File
-
- try:
- from twisted.web2.dav.xattrprops import xattrPropertyStore as DeadPropertyStore
-@@ -117,7 +121,51 @@
- """
- assert depth in ("0", "1", "infinity"), "Invalid depth: %s" % (depth,)
- if depth != "0" and self.isCollection():
-- for name in self.listChildren():
-+ # 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.
-+ filteredaces = self.inheritedACEsforChildren(request)
-+
-+ # Check for disabled access
-+ if filteredaces is not None:
-+ for name in self.listChildren():
-+ try:
-+ child = IDAVResource(self.getChild(name))
-+ except TypeError:
-+ child = None
-+
-+ if child is not None:
-+ # Check privileges of child - skip if access denied
-+ if child.checkAccess(request, privileges, inheritedaces=filteredaces):
-+ continue
-+
-+ if child.isCollection():
-+ yield (child, name + "/")
-+ if depth == "infinity":
-+ for grandchild in child.findChildrenWithPrivileges(depth, privileges, request):
-+ yield (grandchild[0], name + "/" + grandchild[1])
-+ else:
-+ yield (child, name)
-+
-+ def listChildrenWithPrivileges(self, privileges, request):
-+ """
-+ NB This method looks at the actual objects in the file system.
-+
-+ @return: a sequence of the names of all known children of this resource that have the
-+ associated privileges set.
-+ """
-+ children = self.putChildren.keys()
-+ if self.fp.isdir():
-+ children += [c for c in self.fp.listdir() if c not in children]
-+
-+ result = []
-+
-+ # 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.
-+ filteredaces = self.inheritedACEsforChildren(request)
-+
-+ # Check for disabled access
-+ if filteredaces is not None:
-+ for name in children:
- try:
- child = IDAVResource(self.getChild(name))
- except TypeError:
-@@ -122,19 +170,14 @@
- child = IDAVResource(self.getChild(name))
- except TypeError:
- child = None
--
-+
- if child is not None:
- # Check privileges of child - skip if access denied
-- if child.checkAccess(request, privileges):
-+ if child.checkAccess(request, privileges, inheritedaces=filteredaces):
- continue
--
-- if child.isCollection():
-- yield (child, name + "/")
-- if depth == "infinity":
-- for grandchild in child.findChildrenWithPrivileges(depth, privileges, request):
-- yield (grandchild[0], name + "/" + grandchild[1])
-- else:
-- yield (child, name)
-+ result.append(name)
-+
-+ return result
-
- ##
- # ACL
-@@ -256,6 +299,59 @@
- if len(upath) == 0:
- upath = "/"
- return urllib.quote(upath)
-+
-+ def render(self, req):
-+ """
-+ This is a direct copy of webs.static.render with the listChildren behavior replaced with
-+ findChildrenWithPrivileges to ensure that the current authenticated principal can only list
-+ directory contents that they have read permissions for.
-+ """
-+ if not self.fp.exists():
-+ return responsecode.NOT_FOUND
-+
-+ if self.fp.isdir():
-+ if req.uri[-1] != "/":
-+ # Redirect to include trailing '/' in URI
-+ return http.RedirectResponse(req.unparseURL(path=req.path+'/'))
-+ else:
-+ ifp = self.fp.childSearchPreauth(*self.indexNames)
-+ if ifp:
-+ # Render from the index file
-+ standin = self.createSimilarFile(ifp.path)
-+ else:
-+ # Render from a DirectoryLister
-+ standin = dirlist.DirectoryLister(
-+ self.fp.path,
-+ self.listChildrenWithPrivileges((davxml.Read(),), req),
-+ self.contentTypes,
-+ self.contentEncodings,
-+ self.defaultType
-+ )
-+ return standin.render(req)
-+
-+ try:
-+ f = self.fp.open()
-+ except IOError, e:
-+ import errno
-+ if e[0] == errno.EACCES:
-+ return responsecode.FORBIDDEN
-+ elif e[0] == errno.ENOENT:
-+ return responsecode.NOT_FOUND
-+ else:
-+ raise
-+
-+ response = http.Response()
-+ response.stream = stream.FileStream(f, 0, self.fp.getsize())
-+
-+ for (header, value) in (
-+ ("content-type", self.contentType()),
-+ ("content-encoding", self.contentEncoding()),
-+ ):
-+ if value is not None:
-+ response.headers.setHeader(header, value)
-+
-+ return response
-+
-
- #
- # Attach method handlers to DAVFile
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20060824/26992a61/attachment.html
More information about the calendarserver-changes
mailing list