[CalendarServer-changes] [2723] CalendarServer/branches/users/cdaboo/implicit-2660/twistedcaldav/ scheduling/scheduler.py

source_changes at macosforge.org source_changes at macosforge.org
Fri Jul 18 08:45:47 PDT 2008


Revision: 2723
          http://trac.macosforge.org/projects/calendarserver/changeset/2723
Author:   cdaboo at apple.com
Date:     2008-07-18 08:45:47 -0700 (Fri, 18 Jul 2008)
Log Message:
-----------
POST on Outbox now restricted by implicit scheduling. We will allow a compatibility mode whereby we return a success
to such POST requests for old client support.

Modified Paths:
--------------
    CalendarServer/branches/users/cdaboo/implicit-2660/twistedcaldav/scheduling/scheduler.py

Modified: CalendarServer/branches/users/cdaboo/implicit-2660/twistedcaldav/scheduling/scheduler.py
===================================================================
--- CalendarServer/branches/users/cdaboo/implicit-2660/twistedcaldav/scheduling/scheduler.py	2008-07-18 14:52:09 UTC (rev 2722)
+++ CalendarServer/branches/users/cdaboo/implicit-2660/twistedcaldav/scheduling/scheduler.py	2008-07-18 15:45:47 UTC (rev 2723)
@@ -21,7 +21,7 @@
 from twisted.web2 import responsecode
 from twisted.web2.dav import davxml
 from twisted.web2.dav.http import ErrorResponse, errorForFailure, messageForFailure, statusForFailure
-from twisted.web2.http import HTTPError, Response
+from twisted.web2.http import HTTPError, Response, StatusResponse
 from twisted.web2.http_headers import MimeType
 
 from twistedcaldav import caldavxml
@@ -37,6 +37,7 @@
 from twistedcaldav.scheduling.imip import ScheduleViaIMip
 from twistedcaldav.scheduling.ischedule import ScheduleViaISchedule
 from twistedcaldav.scheduling.ischeduleservers import IScheduleServers
+from twistedcaldav.config import config
 
 import itertools
 import re
@@ -66,6 +67,7 @@
         self.organizer = None
         self.timeRange = None
         self.excludeUID = None
+        self.fakeTheResult = False
     
     @inlineCallbacks
     def doSchedulingViaPOST(self):
@@ -121,6 +123,9 @@
         # Generate accounting information
         self.doAccounting()
 
+        # Do some final checks after we have gathered all our information
+        self.finalChecks()
+
         # Do scheduling tasks
         response = (yield self.generateSchedulingResponse())
 
@@ -208,30 +213,33 @@
             raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (calendarserver_namespace, "no-access-restrictions")))
     
     def checkForFreeBusy(self):
-        if (self.calendar.propertyValue("METHOD") == "REQUEST") and (self.calendar.mainType() == "VFREEBUSY"):
-            # Extract time range from VFREEBUSY object
-            vfreebusies = [v for v in self.calendar.subcomponents() if v.name() == "VFREEBUSY"]
-            if len(vfreebusies) != 1:
-                log.err("iTIP data is not valid for a VFREEBUSY request: %s" % (self.calendar,))
-                raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "valid-calendar-data")))
-            dtstart = vfreebusies[0].getStartDateUTC()
-            dtend = vfreebusies[0].getEndDateUTC()
-            if dtstart is None or dtend is None:
-                log.err("VFREEBUSY start/end not valid: %s" % (self.calendar,))
-                raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "valid-calendar-data")))
-            self.timeRange = TimeRange(start="20000101T000000Z", end="20070102T000000Z")
-            self.timeRange.start = dtstart
-            self.timeRange.end = dtend
+        if not hasattr(self, "isfreebusy"):
+            if (self.calendar.propertyValue("METHOD") == "REQUEST") and (self.calendar.mainType() == "VFREEBUSY"):
+                # Extract time range from VFREEBUSY object
+                vfreebusies = [v for v in self.calendar.subcomponents() if v.name() == "VFREEBUSY"]
+                if len(vfreebusies) != 1:
+                    log.err("iTIP data is not valid for a VFREEBUSY request: %s" % (self.calendar,))
+                    raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "valid-calendar-data")))
+                dtstart = vfreebusies[0].getStartDateUTC()
+                dtend = vfreebusies[0].getEndDateUTC()
+                if dtstart is None or dtend is None:
+                    log.err("VFREEBUSY start/end not valid: %s" % (self.calendar,))
+                    raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "valid-calendar-data")))
+                self.timeRange = TimeRange(start="20000101T000000Z", end="20070102T000000Z")
+                self.timeRange.start = dtstart
+                self.timeRange.end = dtend
+        
+                # Look for masked UID
+                self.excludeUID = self.calendar.getMaskUID()
+        
+                # Do free busy operation
+                self.isfreebusy = True
+            else:
+                # Do regular invite (fan-out)
+                self.isfreebusy = False
+        
+        return self.isfreebusy
     
-            # Look for masked UID
-            self.excludeUID = self.calendar.getMaskUID()
-    
-            # Do free busy operation
-            return True
-        else:
-            # Do regular invite (fan-out)
-            return False
-    
     def securityChecks(self):
         raise NotImplementedError
 
@@ -256,6 +264,12 @@
                     )
                 )
 
+    def finalChecks(self):
+        """
+        Final checks before doing the actual scheduling.
+        """
+        pass
+
     @inlineCallbacks
     def generateSchedulingResponse(self):
 
@@ -273,7 +287,10 @@
         imip_recipients = []
         for recipient in self.recipients:
     
-            if isinstance(recipient, LocalCalendarUser):
+            if self.fakeTheResult:
+                responses.add(recipient.cuaddr, responsecode.OK, reqstatus="2.0;Success")
+                
+            elif isinstance(recipient, LocalCalendarUser):
                 caldav_recipients.append(recipient)
 
             elif isinstance(recipient, RemoteCalendarUser):
@@ -333,6 +350,19 @@
 
 class CalDAVScheduler(Scheduler):
 
+    def __init__(self, request, resource):
+        super(CalDAVScheduler, self).__init__(request, resource)
+        self.doingPOST = False
+
+    @inlineCallbacks
+    def doSchedulingViaPOST(self):
+        """
+        The Scheduling POST operation on an Outbox.
+        """
+        self.doingPOST = True
+        result = (yield super(CalDAVScheduler, self).doSchedulingViaPOST())
+        returnValue(result)
+
     def checkAuthorization(self):
         # Must have an authenticated user
         if self.resource.currentPrincipal(self.request) == davxml.Principal(davxml.Unauthenticated()):
@@ -483,6 +513,29 @@
             log.err("Unknown iTIP METHOD for security checks: %s" % (self.calendar.propertyValue("METHOD"),))
             raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "valid-calendar-data")))
 
+    def finalChecks(self):
+        """
+        Final checks before doing the actual scheduling.
+        """
+        
+        # With implicit scheduling only certain types of iTIP operations are allowed for POST.
+        
+        if self.doingPOST:
+            # Freebusy requests always processed
+            if self.checkForFreeBusy():
+                return
+            
+            # COUNTER and DECLINE-COUNTER allowed
+            if self.calendar.propertyValue("METHOD") in ("COUNTER", "DECLINECOUNTER"):
+                return
+            
+            # Anything else is not allowed. However, for compatIbility we will optionally 
+            # return a success response for all attendees.
+            if config.Scheduling["CalDAV"]["OldDraftCompatability"]:
+                self.fakeTheResult = True
+            else:
+                raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, "Invalid iTIP message for implicit scheduling"))
+
 class IScheduleScheduler(Scheduler):
 
     def checkAuthorization(self):
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20080718/7f686fc0/attachment-0001.html 


More information about the calendarserver-changes mailing list