[CalendarServer-changes] [5277] CalendarServer/branches/users/cdaboo/shared-calendars-5187/ twistedcaldav

source_changes at macosforge.org source_changes at macosforge.org
Wed Mar 10 07:31:47 PST 2010


Revision: 5277
          http://trac.macosforge.org/projects/calendarserver/changeset/5277
Author:   cdaboo at apple.com
Date:     2010-03-10 07:31:47 -0800 (Wed, 10 Mar 2010)
Log Message:
-----------
Support for invite replies via POST on calendar home.

Modified Paths:
--------------
    CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/sharing.py
    CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/static.py

Modified: CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/sharing.py
===================================================================
--- CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/sharing.py	2010-03-10 15:29:31 UTC (rev 5276)
+++ CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/sharing.py	2010-03-10 15:31:47 UTC (rev 5277)
@@ -104,6 +104,32 @@
 
         return succeed(True)
 
+    @inlineCallbacks
+    def changeUserInviteState(self, request, inviteUID, userid, state, summary=None):
+        
+        shared = (yield self.isShared(request))
+        if not shared:
+            raise HTTPError(ErrorResponse(
+                responsecode.FORBIDDEN,
+                (customxml.calendarserver_namespace, "valid-request"),
+                "invalid share",
+            ))
+            
+        record = self.invitesDB().recordForInviteUID(inviteUID)
+        if record is None or record.userid != userid:
+            raise HTTPError(ErrorResponse(
+                responsecode.FORBIDDEN,
+                (customxml.calendarserver_namespace, "valid-request"),
+                "invalid invitation uid: %s" % (inviteUID,),
+            ))
+        
+        # Only certain states are sharer controlled
+        if record.state in ("NEEDS-ACTION", "ACCEPTED", "DECLINED",):
+            record.state = state
+            if summary is not None:
+                record.summary = summary
+            self.invitesDB().addOrUpdateRecord(record)
+
     def isShared(self, request):
         """ Return True if this is an owner shared calendar collection """
         return succeed(self.isSpecialCollection(customxml.SharedOwner))
@@ -354,19 +380,19 @@
                     if userid is None:
                         raise HTTPError(ErrorResponse(
                             responsecode.FORBIDDEN,
-                            (customxml.calendarserver_namespace, "valid-request-content-type"),
+                            (customxml.calendarserver_namespace, "valid-request"),
                             "missing href: %s" % (inviteset,),
                         ))
                     if access is None:
                         raise HTTPError(ErrorResponse(
                             responsecode.FORBIDDEN,
-                            (customxml.calendarserver_namespace, "valid-request-content-type"),
+                            (customxml.calendarserver_namespace, "valid-request"),
                             "missing access: %s" % (inviteset,),
                         ))
                     if summary is None:
                         raise HTTPError(ErrorResponse(
                             responsecode.FORBIDDEN,
-                            (customxml.calendarserver_namespace, "valid-request-content-type"),
+                            (customxml.calendarserver_namespace, "valid-request"),
                             "missing summary: %s" % (inviteset,),
                         ))
 
@@ -385,7 +411,7 @@
                 if userid is None:
                     raise HTTPError(ErrorResponse(
                         responsecode.FORBIDDEN,
-                        (customxml.calendarserver_namespace, "valid-request-content-type"),
+                        (customxml.calendarserver_namespace, "valid-request"),
                         "missing href: %s" % (inviteremove,),
                     ))
                 if len(access) == 0:
@@ -463,7 +489,7 @@
                 doc = davxml.WebDAVDocument.fromString(data)
             except ValueError, e:
                 self.log_error("Error parsing doc (%s) Doc:\n %s" % (str(e), data,))
-                raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (customxml.calendarserver_namespace, "valid-request-content")))
+                raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (customxml.calendarserver_namespace, "valid-request")))
 
             root = doc.root_element
             xmlDocHanders = {
@@ -473,7 +499,7 @@
                 return xmlDocHanders[type(root)](root).addErrback(_handleErrorResponse)
             else:
                 self.log_error("Unsupported XML (%s)" % (root,))
-                raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (customxml.calendarserver_namespace, "valid-request-content")))
+                raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (customxml.calendarserver_namespace, "valid-request")))
 
         return allDataFromStream(request.stream).addCallback(_getData)
 
@@ -483,7 +509,7 @@
             if mimetype.mediaType in ("application", "text",) and mimetype.mediaSubtype == "xml":
                 encoding = mimetype.params["charset"] if "charset" in mimetype.params else "utf8"
                 return succeed(encoding)
-        raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (customxml.calendarserver_namespace, "valid-request-content-type")))
+        raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (customxml.calendarserver_namespace, "valid-request")))
 
     def xmlPOSTAuth(self, request):
         d = self.authorize(request, (davxml.Read(), davxml.Write()))
@@ -515,20 +541,38 @@
     set of shared calendfars.
     """
     
-    def acceptShare(self, request, hostUrl, displayname=None):
-        """ Accept an invite to a shared calendar """
-        return succeed(True)
+    def acceptShare(self, request, hostUrl, inviteUID, displayname=None):
+        return self._changeShare(request, "ACCEPTED", hostUrl, inviteUID, displayname)
 
     def wouldAcceptShare(self, hostUrl, request):
         return succeed(True)
 
-    def removeShare(self, hostUrl, resourceName, request):
+    def removeShare(self, request, hostUrl, resourceName):
         """ Remove a shared calendar named in resourceName """
         return succeed(True)
 
-    def declineShare(self, hostUrl, request):
-        return succeed(True)
+    def declineShare(self, request, hostUrl, inviteUID):
+        return self._changeShare(request, "DECLINED", hostUrl, inviteUID)
 
+    @inlineCallbacks
+    def _changeShare(self, request, state, hostUrl, inviteUID, displayname=None):
+        """ Accept an invite to a shared calendar """
+        
+        # Change state in sharer invite
+        owner = (yield self.ownerPrincipal(request))
+        owner = owner.principalURL()
+        sharedCalendar = (yield request.locateResource(hostUrl))
+        if sharedCalendar is None:
+            # Original shared calendar is gone - nothing we can do except ignore it
+            raise HTTPError(ErrorResponse(
+                responsecode.FORBIDDEN,
+                (customxml.calendarserver_namespace, "valid-request"),
+                "invalid shared calendar",
+            ))
+            
+        # Change the record
+        yield sharedCalendar.changeUserInviteState(request, inviteUID, owner, state, displayname)
+
     def xmlPOSTNoAuth(self, encoding, request):
         def _handleResponse(result):
             response = Response(code=responsecode.OK)
@@ -544,6 +588,7 @@
             hostUrl = None
             accepted = None
             summary = None
+            inviteUID = None
             for item in inviteupdatedoc.children:
                 if isinstance(item, customxml.InviteStatusAccepted):
                     accepted = True
@@ -559,25 +604,19 @@
                             for hrefItem in hosturlItem.children:
                                 if isinstance(hrefItem, PCDATAElement):
                                     hostUrl = hrefItem.data
+                elif isinstance(item, customxml.UID):
+                    inviteUID = str(item)
             
-            if accepted is not None:
-                if hostUrl:
-                    if accepted:
-                        return self.acceptShare(request, hostUrl, displayname=summary)
-                    else:
-                        return self.declineShare(hostUrl, request)
-                else:
-                    raise HTTPError(ErrorResponse(
-                        responsecode.FORBIDDEN,
-                        (customxml.calendarserver_namespace, "valid-request-content"),
-                        "missing hosturl",
-                    ))
-            else:
+            if accepted is None or hostUrl is None or inviteUID is None:
                 raise HTTPError(ErrorResponse(
                     responsecode.FORBIDDEN,
-                    (customxml.calendarserver_namespace, "valid-request-content"),
-                    "missing invite status",
+                    (customxml.calendarserver_namespace, "valid-request"),
+                    "missing required XML elements",
                 ))
+            if accepted:
+                return self.acceptShare(request, hostUrl, inviteUID, displayname=summary)
+            else:
+                return self.declineShare(request, hostUrl, inviteUID)
 
         def _getData(data):
             try:

Modified: CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/static.py
===================================================================
--- CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/static.py	2010-03-10 15:29:31 UTC (rev 5276)
+++ CalendarServer/branches/users/cdaboo/shared-calendars-5187/twistedcaldav/static.py	2010-03-10 15:31:47 UTC (rev 5277)
@@ -94,6 +94,7 @@
 from twistedcaldav.directory.calendar import DirectoryCalendarHomeUIDProvisioningResource
 from twistedcaldav.directory.calendar import DirectoryCalendarHomeResource
 from twistedcaldav.directory.resource import AutoProvisioningResourceMixIn
+from twistedcaldav.sharing import SharedHomeMixin
 from twistedcaldav.timezoneservice import TimezoneServiceResource
 from twistedcaldav.vcardindex import AddressBookIndex
 from twistedcaldav.cache import DisabledCacheNotifier, PropfindCacheMixin
@@ -912,7 +913,7 @@
     def url(self):
         return joinURL(self.parent.url(), self.record.uid)
 
-class CalendarHomeFile (PropfindCacheMixin, AutoProvisioningFileMixIn, DirectoryCalendarHomeResource, CalDAVFile):
+class CalendarHomeFile (PropfindCacheMixin, AutoProvisioningFileMixIn, SharedHomeMixin, DirectoryCalendarHomeResource, CalDAVFile):
     """
     Calendar home collection resource.
     """
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100310/d70c0661/attachment-0001.html>


More information about the calendarserver-changes mailing list