Revision: 3593 http://trac.macosforge.org/projects/calendarserver/changeset/3593 Author: cdaboo@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")))
participants (1)
-
source_changes@macosforge.org