[CalendarServer-changes] [7456] CalendarServer/branches/users/glyph/new-export/twistedcaldav

source_changes at macosforge.org source_changes at macosforge.org
Mon May 16 07:42:19 PDT 2011


Revision: 7456
          http://trac.macosforge.org/projects/calendarserver/changeset/7456
Author:   glyph at apple.com
Date:     2011-05-16 07:42:18 -0700 (Mon, 16 May 2011)
Log Message:
-----------
Simplify (and fix) 'isOwner' function, and remove kwargs from all callers, as they're all always set to True (as they need to be, in order to be correct).

Modified Paths:
--------------
    CalendarServer/branches/users/glyph/new-export/twistedcaldav/method/get.py
    CalendarServer/branches/users/glyph/new-export/twistedcaldav/method/report_calendar_query.py
    CalendarServer/branches/users/glyph/new-export/twistedcaldav/method/report_multiget_common.py
    CalendarServer/branches/users/glyph/new-export/twistedcaldav/resource.py
    CalendarServer/branches/users/glyph/new-export/twistedcaldav/stdconfig.py
    CalendarServer/branches/users/glyph/new-export/twistedcaldav/storebridge.py
    CalendarServer/branches/users/glyph/new-export/twistedcaldav/test/test_resource.py
    CalendarServer/branches/users/glyph/new-export/twistedcaldav/test/util.py

Modified: CalendarServer/branches/users/glyph/new-export/twistedcaldav/method/get.py
===================================================================
--- CalendarServer/branches/users/glyph/new-export/twistedcaldav/method/get.py	2011-05-16 14:42:04 UTC (rev 7455)
+++ CalendarServer/branches/users/glyph/new-export/twistedcaldav/method/get.py	2011-05-16 14:42:18 UTC (rev 7456)
@@ -81,7 +81,7 @@
                 if self.accessMode:
             
                     # Non DAV:owner's have limited access to the data
-                    isowner = (yield self.isOwner(request, adminprincipals=True, readprincipals=True))
+                    isowner = (yield self.isOwner(request))
                     
                     # Now "filter" the resource calendar data
                     caldata = PrivateEventFilter(self.accessMode, isowner).filter(caldata)

Modified: CalendarServer/branches/users/glyph/new-export/twistedcaldav/method/report_calendar_query.py
===================================================================
--- CalendarServer/branches/users/glyph/new-export/twistedcaldav/method/report_calendar_query.py	2011-05-16 14:42:04 UTC (rev 7455)
+++ CalendarServer/branches/users/glyph/new-export/twistedcaldav/method/report_calendar_query.py	2011-05-16 14:42:18 UTC (rev 7456)
@@ -174,7 +174,7 @@
             filteredaces = (yield calresource.inheritedACEsforChildren(request))
 
             # Check private events access status
-            isowner = (yield calresource.isOwner(request, adminprincipals=True, readprincipals=True))
+            isowner = (yield calresource.isOwner(request))
 
             # Check for disabled access
             if filteredaces is not None:
@@ -229,7 +229,7 @@
                     timezone = tuple(tz.calendar().subcomponents())[0]
 
             # Check private events access status
-            isowner = (yield calresource.isOwner(request, adminprincipals=True, readprincipals=True))
+            isowner = (yield calresource.isOwner(request))
 
             calendar = (yield calresource.iCalendarForUser(request))
             yield queryCalendarObjectResource(calresource, uri, None, calendar, timezone)

Modified: CalendarServer/branches/users/glyph/new-export/twistedcaldav/method/report_multiget_common.py
===================================================================
--- CalendarServer/branches/users/glyph/new-export/twistedcaldav/method/report_multiget_common.py	2011-05-16 14:42:04 UTC (rev 7455)
+++ CalendarServer/branches/users/glyph/new-export/twistedcaldav/method/report_multiget_common.py	2011-05-16 14:42:18 UTC (rev 7456)
@@ -139,7 +139,7 @@
             disabled = True
             
         # Check private events access status
-        isowner = (yield self.isOwner(request, adminprincipals=True, readprincipals=True))
+        isowner = (yield self.isOwner(request))
 
     elif self.isAddressBookCollection():
         requestURIis = "addressbook"
@@ -352,7 +352,7 @@
                         filteredaces = (yield parent.inheritedACEsforChildren(request))
 
                         # Check private events access status
-                        isowner = (yield parent.isOwner(request, adminprincipals=True, readprincipals=True))
+                        isowner = (yield parent.isOwner(request))
                 else:
                     name = unquote(resource_uri[resource_uri.rfind("/") + 1:])
                     if (resource_uri != request.uri) or not self.exists():
@@ -376,7 +376,7 @@
                     filteredaces = (yield parent.inheritedACEsforChildren(request))
 
                     # Check private events access status
-                    isowner = (yield parent.isOwner(request, adminprincipals=True, readprincipals=True))
+                    isowner = (yield parent.isOwner(request))
         
                 # Check privileges - must have at least DAV:read
                 try:

Modified: CalendarServer/branches/users/glyph/new-export/twistedcaldav/resource.py
===================================================================
--- CalendarServer/branches/users/glyph/new-export/twistedcaldav/resource.py	2011-05-16 14:42:04 UTC (rev 7455)
+++ CalendarServer/branches/users/glyph/new-export/twistedcaldav/resource.py	2011-05-16 14:42:18 UTC (rev 7456)
@@ -878,7 +878,7 @@
         """
         Return the DAV:owner property value (MUST be a DAV:href or None).
         """
-        
+
         isVirt = self.isVirtualShare()
         if isVirt:
             parent = (yield self.locateParent(request, self._share.hosturl))
@@ -928,33 +928,21 @@
             returnValue(None)
 
 
-    def isOwner(self, request, adminprincipals=False, readprincipals=False):
+    @inlineCallbacks
+    def isOwner(self, request):
         """
-        Determine whether the DAV:owner of this resource matches the currently authorized principal
-        in the request. Optionally test for admin or read principals and allow those.
+        Determine whether the DAV:owner of this resource matches the currently
+        authorized principal in the request, or if the user is a read-only or
+        read-write administrator.
         """
+        current = self.currentPrincipal(request)
+        if current in config.AllAdminPrincipalObjects:
+            returnValue(True)
+        if davxml.Principal((yield self.owner(request))) == current:
+            returnValue(True)
+        returnValue(False)
 
-        def _gotOwner(owner):
-            current = self.currentPrincipal(request)
-            if davxml.Principal(owner) == current:
-                return True
-            
-            if adminprincipals:
-                for principal in config.AdminPrincipals:
-                    if davxml.Principal(davxml.HRef(principal)) == current:
-                        return True
 
-            if readprincipals:
-                for principal in config.AdminPrincipals:
-                    if davxml.Principal(davxml.HRef(principal)) == current:
-                        return True
-                
-            return False
-
-        d = self.owner(request)
-        d.addCallback(_gotOwner)
-        return d
-
     ##
     # DAVResource
     ##

Modified: CalendarServer/branches/users/glyph/new-export/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/branches/users/glyph/new-export/twistedcaldav/stdconfig.py	2011-05-16 14:42:04 UTC (rev 7455)
+++ CalendarServer/branches/users/glyph/new-export/twistedcaldav/stdconfig.py	2011-05-16 14:42:18 UTC (rev 7456)
@@ -1040,6 +1040,19 @@
 
     log.debug("Nav ACL: %s" % (configDict.ProvisioningResourceACL.toxml(),))
 
+    def principalObjects(urls):
+        for principalURL in urls:
+            yield davxml.Principal(davxml.HRef(principalURL))
+
+    # Should be sets, except WebDAVElement isn't hashable.
+    a = configDict.AdminPrincipalObjects = list(
+        principalObjects(configDict.AdminPrincipals))
+    b = configDict.ReadPrincipalObjects = list(
+        principalObjects(configDict.ReadPrincipals))
+    configDict.AllAdminPrincipalObjects = a + b
+
+
+
 def _updateRejectClients(configDict):
     #
     # Compile RejectClients expressions for speed

Modified: CalendarServer/branches/users/glyph/new-export/twistedcaldav/storebridge.py
===================================================================
--- CalendarServer/branches/users/glyph/new-export/twistedcaldav/storebridge.py	2011-05-16 14:42:04 UTC (rev 7455)
+++ CalendarServer/branches/users/glyph/new-export/twistedcaldav/storebridge.py	2011-05-16 14:42:18 UTC (rev 7456)
@@ -938,7 +938,7 @@
         filteredaces = (yield self.inheritedACEsforChildren(request))
 
         tzids = set()
-        isowner = (yield self.isOwner(request, adminprincipals=True, readprincipals=True))
+        isowner = (yield self.isOwner(request))
         accessPrincipal = (yield self.resourceOwnerPrincipal(request))
 
         for name, uid, type in (yield maybeDeferred(self.index().bruteForceSearch)): #@UnusedVariable

Modified: CalendarServer/branches/users/glyph/new-export/twistedcaldav/test/test_resource.py
===================================================================
--- CalendarServer/branches/users/glyph/new-export/twistedcaldav/test/test_resource.py	2011-05-16 14:42:04 UTC (rev 7455)
+++ CalendarServer/branches/users/glyph/new-export/twistedcaldav/test/test_resource.py	2011-05-16 14:42:18 UTC (rev 7456)
@@ -14,13 +14,23 @@
 # limitations under the License.
 ##
 
-from twistedcaldav.resource import CalDAVResource, CommonHomeResource, CalendarHomeResource, AddressBookHomeResource
+from twisted.internet.defer import inlineCallbacks
 
+from twext.web2.test.test_server import SimpleRequest
+
+from twext.web2.dav.davxml import Principal
+from twext.web2.dav.davxml import Unauthenticated
+from twext.web2.dav.element.rfc2518 import HRef
+
+from twistedcaldav.resource import (
+    CalDAVResource, CommonHomeResource, CalendarHomeResource,
+    AddressBookHomeResource)
+
 from twistedcaldav.test.util import InMemoryPropertyStore
 from twistedcaldav.test.util import TestCase
 from twistedcaldav.config import config
 
-from twisted.internet.defer import inlineCallbacks
+from twistedcaldav.test.util import patchConfig
 
 
 class StubProperty(object):
@@ -62,6 +72,7 @@
         self.assertTrue(('http://calendarserver.org/ns/', 'push-transports') in resource.liveProperties())
         self.assertTrue(('http://calendarserver.org/ns/', 'pushkey') in resource.liveProperties())
 
+
     def test_calendarHomeliveProperties(self):
         resource = CalendarHomeResource(None, None, None, StubHome())
         self.assertTrue(('http://calendarserver.org/ns/', 'push-transports') in resource.liveProperties())
@@ -70,6 +81,7 @@
         self.assertTrue(('http://calendarserver.org/ns/', 'xmpp-heartbeat-uri') in resource.liveProperties())
         self.assertTrue(('http://calendarserver.org/ns/', 'xmpp-server') in resource.liveProperties())
 
+
     def test_addressBookHomeliveProperties(self):
         resource = AddressBookHomeResource(None, None, None, StubHome())
         self.assertTrue(('http://calendarserver.org/ns/', 'push-transports') in resource.liveProperties())
@@ -78,6 +90,7 @@
         self.assertTrue(('http://calendarserver.org/ns/', 'xmpp-heartbeat-uri') not in resource.liveProperties())
         self.assertTrue(('http://calendarserver.org/ns/', 'xmpp-server') not in resource.liveProperties())
 
+
     @inlineCallbacks
     def test_push404(self):
         """
@@ -117,3 +130,88 @@
         self.assertEqual((yield resource.readProperty(('http://calendarserver.org/ns/', 'xmpp-uri'), None)), None)
         self.assertEqual((yield resource.readProperty(('http://calendarserver.org/ns/', 'xmpp-heartbeat-uri'), None)), None)
         self.assertEqual((yield resource.readProperty(('http://calendarserver.org/ns/', 'xmpp-server'), None)), None)
+
+
+
+class OwnershipTests(TestCase):
+    """
+    L{CalDAVResource.isOwner} determines if the authenticated principal of the
+    given request is the owner of that resource.
+    """
+
+    @inlineCallbacks
+    def test_isOwnerUnauthenticated(self):
+        """
+        L{CalDAVResource.isOwner} returns C{False} for unauthenticated requests.
+        """
+        site = None
+        request = SimpleRequest(site, "GET", "/not/a/real/url/")
+        request.authzUser = request.authnUser = Principal(Unauthenticated())
+        rsrc = CalDAVResource()
+        rsrc.owner = lambda igreq: HRef("/somebody/")
+        self.assertEquals((yield rsrc.isOwner(request)), False)
+
+
+    @inlineCallbacks
+    def test_isOwnerNo(self):
+        """
+        L{CalDAVResource.isOwner} returns C{True} for authenticated requests
+        with a principal that matches the resource's owner.
+        """
+        site = None
+        request = SimpleRequest(site, "GET", "/not/a/real/url/")
+        theOwner = Principal(HRef("/yes-i-am-the-owner/"))
+        request.authzUser = request.authnUser = theOwner
+        rsrc = CalDAVResource()
+        rsrc.owner = lambda igreq: HRef("/no-i-am-not-the-owner/")
+        self.assertEquals((yield rsrc.isOwner(request)), False)
+
+
+    @inlineCallbacks
+    def test_isOwnerYes(self):
+        """
+        L{CalDAVResource.isOwner} returns C{True} for authenticated requests
+        with a principal that matches the resource's owner.
+        """
+        site = None
+        request = SimpleRequest(site, "GET", "/not/a/real/url/")
+        theOwner = Principal(HRef("/yes-i-am-the-owner/"))
+        request.authzUser = request.authnUser = theOwner
+        rsrc = CalDAVResource()
+        rsrc.owner = lambda igreq: HRef("/yes-i-am-the-owner/")
+        self.assertEquals((yield rsrc.isOwner(request)), True)
+
+
+    @inlineCallbacks
+    def test_isOwnerAdmin(self):
+        """
+        L{CalDAVResource.isOwner} returns C{True} for authenticated requests
+        with a principal that matches any principal configured in the
+        L{AdminPrincipals} list.
+        """
+        theAdmin = "/read-write-admin/"
+        patchConfig(self, AdminPrincipals=[theAdmin])
+        site = None
+        request = SimpleRequest(site, "GET", "/not/a/real/url/")
+        request.authzUser = request.authnUser = Principal(HRef(theAdmin))
+        rsrc = CalDAVResource()
+        rsrc.owner = lambda igreq: HRef("/some-other-user/")
+        self.assertEquals((yield rsrc.isOwner(request)), True)
+
+
+    @inlineCallbacks
+    def test_isOwnerReadPrincipal(self):
+        """
+        L{CalDAVResource.isOwner} returns C{True} for authenticated requests
+        with a principal that matches any principal configured in the
+        L{AdminPrincipals} list.
+        """
+        theAdmin = "/read-only-admin/"
+        patchConfig(self, ReadPrincipals=[theAdmin])
+        site = None
+        request = SimpleRequest(site, "GET", "/not/a/real/url/")
+        request.authzUser = request.authnUser = Principal(HRef(theAdmin))
+        rsrc = CalDAVResource()
+        rsrc.owner = lambda igreq: HRef("/some-other-user/")
+        self.assertEquals((yield rsrc.isOwner(request)), True)
+

Modified: CalendarServer/branches/users/glyph/new-export/twistedcaldav/test/util.py
===================================================================
--- CalendarServer/branches/users/glyph/new-export/twistedcaldav/test/util.py	2011-05-16 14:42:04 UTC (rev 7455)
+++ CalendarServer/branches/users/glyph/new-export/twistedcaldav/test/util.py	2011-05-16 14:42:18 UTC (rev 7456)
@@ -586,8 +586,21 @@
 
 
 
+def patchConfig(testCase, **kw):
+    """
+    Patch the global configuration (including running the appropriate hooks) for
+    the duration of the given test.
+    """
+    preserved = {}
+    for k in kw:
+        preserved[k] = config.get(k, None)
+    def reUpdate():
+        config.update(preserved)
+    testCase.addCleanup(reUpdate)
+    config.update(kw)
 
 
+
 class ErrorOutput(Exception):
     """
     The process produced some error output and exited with a non-zero exit
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110516/7b28841c/attachment-0001.html>


More information about the calendarserver-changes mailing list