[CalendarServer-changes] [3593] CalendarServer/trunk/twistedcaldav

source_changes at macosforge.org source_changes at macosforge.org
Fri Jan 16 09:44:35 PST 2009


Revision: 3593
          http://trac.macosforge.org/projects/calendarserver/changeset/3593
Author:   cdaboo at apple.com
Date:     2009-01-16 09:44:35 -0800 (Fri, 16 Jan 2009)
Log Message:
-----------
Make sure entirely cancelled event written by ATTENDEE is ignored rather than generating a 403.

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/ical.py
    CalendarServer/trunk/twistedcaldav/method/put_common.py
    CalendarServer/trunk/twistedcaldav/scheduling/addressmapping.py
    CalendarServer/trunk/twistedcaldav/scheduling/implicit.py

Modified: CalendarServer/trunk/twistedcaldav/ical.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/ical.py	2009-01-13 20:09:17 UTC (rev 3592)
+++ CalendarServer/trunk/twistedcaldav/ical.py	2009-01-16 17:44:35 UTC (rev 3593)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2005-2008 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -1417,6 +1417,23 @@
 
         return False
 
+    def hasPropertyValueInAllComponents(self, property):
+        """
+        Test for the existence of a property with a specific value in any sub-component.
+        
+        @param property: property to test for
+        @type property: L{Property}
+        """
+
+        for component in self.subcomponents():
+            if component.name() == "VTIMEZONE":
+                continue
+            found = component.getProperty(property.name())
+            if not found or found.value() != property.value():
+                return False
+
+        return True
+
     def addPropertyToAllComponents(self, property):
         """
         Add a property to all top-level components except VTIMEZONE.

Modified: CalendarServer/trunk/twistedcaldav/method/put_common.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/put_common.py	2009-01-13 20:09:17 UTC (rev 3592)
+++ CalendarServer/trunk/twistedcaldav/method/put_common.py	2009-01-16 17:44:35 UTC (rev 3593)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2005-2007 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -726,9 +726,12 @@
             if do_implicit_action and self.allowImplicitSchedule:
                 new_calendar = (yield scheduler.doImplicitScheduling(self.schedule_tag_match))
                 if new_calendar:
-                    self.calendar = new_calendar
-                    self.calendardata = str(self.calendar)
-                    data_changed = True
+                    if isinstance(new_calendar, int):
+                        returnValue(new_calendar)
+                    else:
+                        self.calendar = new_calendar
+                        self.calendardata = str(self.calendar)
+                        data_changed = True
                 did_implicit_action = True
         else:
             is_scheduling_resource = False
@@ -915,7 +918,18 @@
             new_has_private_comments = self.preservePrivateComments()
     
             # Do scheduling
-            is_scheduling_resource, data_changed, did_implicit_action = (yield self.doImplicitScheduling())
+            implicit_result = (yield self.doImplicitScheduling())
+            if isinstance(implicit_result, int):
+                if implicit_result == ImplicitScheduler.STATUS_ORPHANED_CANCELLED_EVENT:
+                    if reservation:
+                        yield reservation.unreserve()
+            
+                    returnValue(StatusResponse(responsecode.CREATED, "Resource created but immediately deleted by the server."))
+                else:
+                    log.err("Invalid return status code from ImplicitScheduler: %s" % (implicit_result,))
+                    raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "valid-calendar-data")))
+            else:
+                is_scheduling_resource, data_changed, did_implicit_action = implicit_result
 
             # Initialize the rollback system
             self.setupRollback()

Modified: CalendarServer/trunk/twistedcaldav/scheduling/addressmapping.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/addressmapping.py	2009-01-13 20:09:17 UTC (rev 3592)
+++ CalendarServer/trunk/twistedcaldav/scheduling/addressmapping.py	2009-01-16 17:44:35 UTC (rev 3593)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2005-2007 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -49,6 +49,10 @@
     @inlineCallbacks
     def getCalendarUser(self, cuaddr, principal):
         
+        # If we have a principal always treat the user as local
+        if principal:
+            returnValue(LocalCalendarUser(cuaddr, principal))
+
         # Get the type
         cuaddr_type = (yield self.getCalendarUserServiceType(cuaddr))
         if cuaddr_type == DeliveryService.serviceType_caldav:

Modified: CalendarServer/trunk/twistedcaldav/scheduling/implicit.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/implicit.py	2009-01-13 20:09:17 UTC (rev 3592)
+++ CalendarServer/trunk/twistedcaldav/scheduling/implicit.py	2009-01-16 17:44:35 UTC (rev 3593)
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005-2008 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2009 Apple Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -16,23 +16,24 @@
 
 from twisted.internet.defer import inlineCallbacks, returnValue, succeed
 from twisted.web2 import responsecode
+from twisted.web2.dav import davxml
 from twisted.web2.dav.http import ErrorResponse
 from twisted.web2.dav.util import joinURL
 from twisted.web2.dav.util import parentForURL
 from twisted.web2.http import HTTPError
 
+from twistedcaldav import caldavxml
 from twistedcaldav.caldavxml import caldav_namespace
-from twistedcaldav.scheduling.itip import iTipGenerator
+from twistedcaldav.customxml import TwistedSchedulingObjectResource
+from twistedcaldav.ical import Property
 from twistedcaldav.log import Logger
-from twistedcaldav.scheduling.scheduler import CalDAVScheduler
 from twistedcaldav.method import report_common
-from twistedcaldav.scheduling.icaldiff import iCalDiff
-from twistedcaldav import caldavxml
-from twisted.web2.dav import davxml
 from twistedcaldav.scheduling import addressmapping
 from twistedcaldav.scheduling.cuaddress import InvalidCalendarUser,\
     LocalCalendarUser
-from twistedcaldav.customxml import TwistedSchedulingObjectResource
+from twistedcaldav.scheduling.icaldiff import iCalDiff
+from twistedcaldav.scheduling.itip import iTipGenerator
+from twistedcaldav.scheduling.scheduler import CalDAVScheduler
 
 __all__ = [
     "ImplicitScheduler",
@@ -45,14 +46,18 @@
 # Handle the case where a PUT removes the ORGANIZER property. That should be equivalent to cancelling the entire meeting.
 # Support SCHEDULE-AGENT property
 # Support SCHEDULE-STATUS property
-# Support live calendars
 # Support Schedule-Reply header
 #
 
 class ImplicitScheduler(object):
     
+    # Return Status codes
+    STATUS_OK                       = 0
+    STATUS_ORPHANED_CANCELLED_EVENT = 1
+
     def __init__(self):
-        pass
+        
+        self.return_status = ImplicitScheduler.STATUS_OK
 
     @inlineCallbacks
     def testImplicitSchedulingPUT(self, request, resource, resource_uri, calendar, internal_request=False):
@@ -190,7 +195,7 @@
         @param do_smart_merge: if True, merge attendee data on disk with new data being stored,
             else overwrite data on disk.
         @return: a new calendar object modified with scheduling information,
-            or C{None} if nothing happened
+            or C{None} if nothing happened or C{int} if some other state occurs
         """
         
         # Setup some parameters
@@ -205,7 +210,10 @@
         else:
             returnValue(None)
 
-        returnValue(self.return_calendar if hasattr(self, "return_calendar") else self.calendar)
+        if self.return_status:
+            returnValue(self.return_status)
+        else:
+            returnValue(self.return_calendar if hasattr(self, "return_calendar") else self.calendar)
 
     @inlineCallbacks
     def refreshAllAttendeesExceptSome(self, request, resource, calendar, attendees):
@@ -658,8 +666,14 @@
                     log.debug("Implicit - attendee '%s' is updating UID: '%s' but change is not significant" % (self.attendee, self.uid))
                     returnValue(None)
             elif isinstance(self.organizerAddress, LocalCalendarUser):
-                log.debug("Attendee '%s' is not allowed to update UID: '%s' - missing organizer copy" % (self.attendee, self.uid,))
-                assert self.organizer_calendar, "Must have the organizer's copy of an invite"
+                # Check to see whether all instances are CANCELLED
+                if self.calendar.hasPropertyValueInAllComponents(Property("STATUS", "CANCELLED")):
+                    log.debug("Attendee '%s' is creating CANCELLED event for UID: '%s' - missing organizer copy" % (self.attendee, self.uid,))
+                    self.return_status = ImplicitScheduler.STATUS_ORPHANED_CANCELLED_EVENT
+                    returnValue(None)
+                else:
+                    log.debug("Attendee '%s' is not allowed to update UID: '%s' - missing organizer copy" % (self.attendee, self.uid,))
+                    raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "valid-attendee-change")))
             elif isinstance(self.organizerAddress, InvalidCalendarUser):
                 log.debug("Attendee '%s' is not allowed to update UID: '%s' with invalid organizer '%s'" % (self.attendee, self.uid, self.organizer))
                 raise HTTPError(ErrorResponse(responsecode.FORBIDDEN, (caldav_namespace, "valid-attendee-change")))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090116/bc480c22/attachment-0001.html>


More information about the calendarserver-changes mailing list