[CalendarServer-changes] [356] CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav

source_changes at macosforge.org source_changes at macosforge.org
Thu Nov 2 14:02:47 PST 2006


Revision: 356
          http://trac.macosforge.org/projects/calendarserver/changeset/356
Author:   cdaboo at apple.com
Date:     2006-11-02 14:02:46 -0800 (Thu, 02 Nov 2006)

Log Message:
-----------
Change to a subscription based mechanism for notifications. This still needs more work for it to be useful and secure.

Modified Paths:
--------------
    CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/customxml.py
    CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/method/delete.py
    CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/method/put.py
    CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/notifications.py
    CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/resource.py

Modified: CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/customxml.py
===================================================================
--- CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/customxml.py	2006-11-02 20:30:09 UTC (rev 355)
+++ CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/customxml.py	2006-11-02 22:02:46 UTC (rev 356)
@@ -284,6 +284,28 @@
 
     allowed_children = { (davxml.dav_namespace, "href"): (0, 1) }
 
+class AutoSubscribed (davxml.WebDAVElement):
+    """
+    A property to indicate which principals will receive notifications.
+    (Apple Extension to CalDAV)
+    """
+    namespace = twisted_dav_namespace
+    name = "auto-subscribed"
+    hidden = True
+
+    allowed_children = { (davxml.dav_namespace, "principal"): (0, None) }
+
+class Unsubscribed (davxml.WebDAVElement):
+    """
+    A property to indicate which auto-subscribed principals will not receive notifications.
+    (Apple Extension to CalDAV)
+    """
+    namespace = twisted_dav_namespace
+    name = "unsubscribed"
+    hidden = True
+
+    allowed_children = { (davxml.dav_namespace, "principal"): (0, None) }
+
 ##
 # Extensions to davxml.ResourceType
 ##

Modified: CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/method/delete.py
===================================================================
--- CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/method/delete.py	2006-11-02 20:30:09 UTC (rev 355)
+++ CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/method/delete.py	2006-11-02 22:02:46 UTC (rev 356)
@@ -66,12 +66,8 @@
             if isinstance(request.authnUser.children[0], davxml.HRef):
                 authid = str(request.authnUser.children[0])
 
-            principals = waitForDeferred(self.principalsWithReadPrivilege(request))
-            yield principals
-            principals = principals.getResult()
-
             notification = Notification(action=Notification.ACTION_DELETED, authid=authid, oldETag=oldETag, oldURI=request.uri)
-            d = waitForDeferred(notification.doNotification(request, principals))
+            d = waitForDeferred(notification.doNotification(request, parent, self))
             yield d
             d.getResult()
 

Modified: CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/method/put.py
===================================================================
--- CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/method/put.py	2006-11-02 20:30:09 UTC (rev 355)
+++ CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/method/put.py	2006-11-02 22:02:46 UTC (rev 356)
@@ -110,16 +110,12 @@
             else:
                 newETag = None
             
-            principals = waitForDeferred(self.principalsWithReadPrivilege(request))
-            yield principals
-            principals = principals.getResult()
-
             notification = Notification(action={
                 responsecode.OK         : Notification.ACTION_MODIFIED,
                 responsecode.CREATED    : Notification.ACTION_CREATED,
                 responsecode.NO_CONTENT : Notification.ACTION_MODIFIED,
             }[response.code], authid=authid, oldETag=oldETag, newETag=newETag, oldURI=request.uri)
-            d = waitForDeferred(notification.doNotification(request, principals))
+            d = waitForDeferred(notification.doNotification(request, parent, self))
             yield d
             d.getResult()
         

Modified: CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/notifications.py
===================================================================
--- CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/notifications.py	2006-11-02 20:30:09 UTC (rev 355)
+++ CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/notifications.py	2006-11-02 22:02:46 UTC (rev 356)
@@ -19,6 +19,7 @@
 from twisted.internet.defer import deferredGenerator
 from twisted.internet.defer import waitForDeferred
 from twisted.web2.dav.method import put_common
+from twisted.web2.dav.resource import DAVPrincipalResource
 from twisted.web2.dav import davxml
 from twistedcaldav import customxml
 from twisted.web2.dav.element.base import twisted_dav_namespace
@@ -63,14 +64,73 @@
         self.oldURI = oldURI
         self.newURI = newURI
 
-    def doNotification(self, request, principals):
+    def doNotification(self, request, parent, resource):
         """
         Put the supplied noitification into the notification collection of the specified principal.
         
         @param request: L{Request} for request in progress.
-        @param principals: C{list} of L{davxml.Principal}'s to send notifications to.
+        @param resource: L{DAVResource}trigerring the notification.
         """
         
+        # First determine which principals should get notified
+        #
+        # Procedure:
+        #
+        # 1. Get the list of auto-subscribed principals from the parent collection property.
+        # 2. Expand any group principals in the list into their user principals.
+        # 3. Get the list of unsubscribed principals from the parent collection property.
+        # 4. Expand any group principals in the list into their user principals.
+        # 5. Generate a set from the difference between the subscribed list and unsubscribed list.
+        
+        def _expandPrincipals(principals):
+            result = []
+            for principal in principals:
+
+                principal = waitForDeferred(parent.resolvePrincipal(principal.children[0], request))
+                yield principal
+                principal = principal.getResult()
+                if principal is None:
+                    continue
+        
+                presource = waitForDeferred(request.locateResource(str(principal)))
+                yield presource
+                presource = presource.getResult()
+        
+                if not isinstance(presource, DAVPrincipalResource):
+                    continue
+                
+                # Step 2. Expand groups.
+                members = presource.groupMembers()
+                
+                if members:
+                    for member in members:
+                        result.append(davxml.Principal(davxml.HRef.fromString(member)))
+                else:
+                    result.append(davxml.Principal(principal))
+            yield result
+
+        _expandPrincipals = deferredGenerator(_expandPrincipals)
+
+        # For drop box we look at the parent collection of the target resource and get the
+        # set of auto-subscribed principals, then subtract the set of unsubscribed principals.
+        if not parent.hasDeadProperty(customxml.AutoSubscribed):
+            yield None
+            return
+
+        principals = set()
+        autosubs = parent.readDeadProperty(customxml.AutoSubscribed).children
+        d = waitForDeferred(_expandPrincipals(autosubs))
+        yield d
+        autosubs = d.getResult()
+        principals.update(autosubs)
+        
+        if parent.hasDeadProperty(customxml.Unsubscribed):
+            unsubs = parent.readDeadProperty(customxml.Unsubscribed).children
+            d = waitForDeferred(_expandPrincipals(unsubs))
+            yield d
+            unsubs = d.getResult()
+            principals.difference_update(unsubs)
+        
         for principal in principals:
             if not isinstance(principal.children[0], davxml.HRef):
                 continue

Modified: CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/resource.py
===================================================================
--- CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/resource.py	2006-11-02 20:30:09 UTC (rev 355)
+++ CalendarServer/branches/users/cdaboo/dropbox/twistedcaldav/resource.py	2006-11-02 22:02:46 UTC (rev 356)
@@ -286,73 +286,6 @@
 
     authorizationPrincipal = deferredGenerator(authorizationPrincipal)
 
-    def principalsWithReadPrivilege(self, request):
-        """
-        Return a list of principals that have read privilege to this resource.
-        
-        """
-        
-        # Procedure:
-        #
-        # 1. Get list of all principals referenced in the ACL for the resource.
-        # 2. Expand groups in the principal list to their user principals.
-        # 3. For each user principal see if it has read privilege and if so add to the list.
-    
-        # Step 1. Get ACL principals.
-        acl = waitForDeferred(self.accessControlList(request))
-        yield acl
-        acl = acl.getResult()
-    
-        # Check disabled
-        if acl is None:
-            yield []
-            return
-    
-        principals = set()
-        
-        for ace in acl.children:
-            # First see if the ace's principal affects the principal being tested.
-            # FIXME: support the DAV:invert operation
-    
-            principal = ace.principal
-            
-            principal = waitForDeferred(self.resolvePrincipal(principal.children[0], request))
-            yield principal
-            principal = principal.getResult()
-            if principal is None:
-                continue
-    
-            presource = waitForDeferred(request.locateResource(str(principal)))
-            yield presource
-            presource = presource.getResult()
-    
-            if not isinstance(presource, DAVPrincipalResource):
-                continue
-            
-            # Step 2. Expand groups.
-            members = presource.groupMembers()
-            
-            if members:
-                for member in members:
-                    principals.add(davxml.Principal(davxml.HRef.fromString(member)))
-            else:
-                principals.add(davxml.Principal(principal))
-                
-        # Step 3. Check privileges
-        result = []
-        for principal in principals:
-            try:
-                d = waitForDeferred(self.checkPrivileges(request, (davxml.Read,), principal=principal))
-                yield d
-                test = d.getResult()
-                if test is not None:
-                    result.append(principal)
-            except:
-                pass
-        yield result
-    
-    principalsWithReadPrivilege = deferredGenerator(principalsWithReadPrivilege)
-    
     ##
     # CalDAV
     ##

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


More information about the calendarserver-changes mailing list