Revision
1580
Author
cdaboo@apple.com
Date
2007-05-30 12:58:59 -0700 (Wed, 30 May 2007)

Log Message

Fix for SACL check causing Kerberos auth to fail. Plus optimize SACL check so it only happens once in any one
request.

Modified Paths

Diff

Modified: CalendarServer/branches/users/cdaboo/sacl-1576/twistedcaldav/extensions.py (1579 => 1580)


--- CalendarServer/branches/users/cdaboo/sacl-1576/twistedcaldav/extensions.py	2007-05-30 17:31:35 UTC (rev 1579)
+++ CalendarServer/branches/users/cdaboo/sacl-1576/twistedcaldav/extensions.py	2007-05-30 19:58:59 UTC (rev 1580)
@@ -24,7 +24,7 @@
     "DAVResource",
     "DAVFile",
     "ReadOnlyResourceMixIn",
-    "SudoAuthIDMixin",
+    "SudoSACLMixin",
 ]
 
 import cPickle as pickle
@@ -49,12 +49,22 @@
 from twistedcaldav.directory.sudo import SudoDirectoryService
 from twistedcaldav.directory.directory import DirectoryService
 
-class SudoAuthIDMixin(object):
+class SudoSACLMixin(object):
     """
     Mixin class to let DAVResource, and DAVFile subclasses below know
     about sudoer principals and how to find their AuthID
     """
 
+    def authenticate(self, request):
+        # Bypass normal authentication if its already been done (by SACL check)
+        if (hasattr(request, "authnUser") and
+            hasattr(request, "authzUser") and
+            request.authnUser is not None and
+            request.authzUser is not None):
+            return (request.authnUser, request.authzUser)
+        else:
+            return super(SudoSACLMixin, self).authenticate(request)
+
     def findPrincipalForAuthID(self, authid):
         """
         Return an authentication and authorization principal identifiers for 
@@ -68,7 +78,7 @@
             if principal is not None:
                 return principal
 
-        return super(SudoAuthIDMixin, self).findPrincipalForAuthID(authid)
+        return super(SudoSACLMixin, self).findPrincipalForAuthID(authid)
 
     def authorizationPrincipal(self, request, authid, authnPrincipal):
         """
@@ -131,7 +141,7 @@
             raise HTTPError(responsecode.FORBIDDEN)
         else:
             # No proxy - do default behavior
-            d = waitForDeferred(super(SudoAuthIDMixin, self).authorizationPrincipal(request, authid, authnPrincipal))
+            d = waitForDeferred(super(SudoSACLMixin, self).authorizationPrincipal(request, authid, authnPrincipal))
             yield d
             yield d.getResult()
             return
@@ -139,8 +149,7 @@
     authorizationPrincipal = deferredGenerator(authorizationPrincipal)
 
 
-
-class DAVResource (SudoAuthIDMixin, SuperDAVResource):
+class DAVResource (SudoSACLMixin, SuperDAVResource):
     """
     Extended L{twisted.web2.dav.resource.DAVResource} implementation.
     """
@@ -335,7 +344,7 @@
             return davxml.ResourceType(davxml.Principal())
 
 
-class DAVFile (SudoAuthIDMixin, SuperDAVFile):
+class DAVFile (SudoSACLMixin, SuperDAVFile):
     """
     Extended L{twisted.web2.dav.static.DAVFile} implementation.
     """

Modified: CalendarServer/branches/users/cdaboo/sacl-1576/twistedcaldav/root.py (1579 => 1580)


--- CalendarServer/branches/users/cdaboo/sacl-1576/twistedcaldav/root.py	2007-05-30 17:31:35 UTC (rev 1579)
+++ CalendarServer/branches/users/cdaboo/sacl-1576/twistedcaldav/root.py	2007-05-30 19:58:59 UTC (rev 1580)
@@ -48,7 +48,7 @@
                 self.useSacls = True
             else:
                 log.msg(("RootResource.CheckSACL is unset but "
-                         "config.EnableSACLs is True, SACLs will not be"
+                         "config.EnableSACLs is True, SACLs will not be "
                          "turned on."))
 
         self.contentFilters = []
@@ -83,6 +83,10 @@
                         request.remoteAddr)))
 
         def _checkSACLCb((authnUser, authzUser)):
+            # Cache the authentication details
+            request.authnUser = authnUser
+            request.authzUser = authzUser
+
             # Figure out the "username" from the davxml.Principal object
             username = authzUser.children[0].children[0].data
             username = username.rstrip('/').split('/')[-1]
@@ -91,6 +95,8 @@
                 log.msg("User '%s' is not enabled with the '%s' SACL" % (username, self.saclService,))
                 return Failure(HTTPError(403))
 
+            # Mark SACL's as having been checked so we can avoid doing it multiple times
+            request.checkedSACL = True
             return True
             
         d = defer.maybeDeferred(self.authenticate, request)
@@ -102,7 +108,7 @@
         for filter in self.contentFilters:
             request.addResponseFilter(filter[0], atEnd=filter[1])
 
-        if self.useSacls:
+        if self.useSacls and not hasattr(request, "checkedSACL"):
             d = self.checkSacl(request)
             d.addCallback(lambda _: super(RootResource, self
                                           ).locateChild(request, segments))