[CalendarServer-changes] [3313] CalendarServer/branches/users/cdaboo/implicit-if-match-3306/ twistedcaldav
source_changes at macosforge.org
source_changes at macosforge.org
Mon Nov 3 19:10:04 PST 2008
Revision: 3313
http://trac.macosforge.org/projects/calendarserver/changeset/3313
Author: cdaboo at apple.com
Date: 2008-11-03 19:10:03 -0800 (Mon, 03 Nov 2008)
Log Message:
-----------
Schedule-Tag/If-Schedule-Tag-Match header behavior. Attendee logic for when tag changes is not quite
right.
Modified Paths:
--------------
CalendarServer/branches/users/cdaboo/implicit-if-match-3306/twistedcaldav/__init__.py
CalendarServer/branches/users/cdaboo/implicit-if-match-3306/twistedcaldav/caldavxml.py
CalendarServer/branches/users/cdaboo/implicit-if-match-3306/twistedcaldav/method/get.py
CalendarServer/branches/users/cdaboo/implicit-if-match-3306/twistedcaldav/method/put_common.py
Modified: CalendarServer/branches/users/cdaboo/implicit-if-match-3306/twistedcaldav/__init__.py
===================================================================
--- CalendarServer/branches/users/cdaboo/implicit-if-match-3306/twistedcaldav/__init__.py 2008-11-04 00:33:58 UTC (rev 3312)
+++ CalendarServer/branches/users/cdaboo/implicit-if-match-3306/twistedcaldav/__init__.py 2008-11-04 03:10:03 UTC (rev 3313)
@@ -65,8 +65,17 @@
File.contentTypes = loadMimeTypes(("/etc/apache2/mime.types", "/etc/httpd/mime.types",))
import twisted.web2.dav.davxml
+from twisted.web2.http_headers import DefaultHTTPHandler, last, singleHeader, tokenize
import twistedcaldav.caldavxml
import twistedcaldav.customxml
twisted.web2.dav.davxml.registerElements(twistedcaldav.caldavxml)
twisted.web2.dav.davxml.registerElements(twistedcaldav.customxml)
+
+DefaultHTTPHandler.updateParsers({
+ 'If-Schedule-Tag-Match':(last, str),
+})
+DefaultHTTPHandler.updateGenerators({
+ 'Schedule-Tag':(str, singleHeader),
+})
+
Modified: CalendarServer/branches/users/cdaboo/implicit-if-match-3306/twistedcaldav/caldavxml.py
===================================================================
--- CalendarServer/branches/users/cdaboo/implicit-if-match-3306/twistedcaldav/caldavxml.py 2008-11-04 00:33:58 UTC (rev 3312)
+++ CalendarServer/branches/users/cdaboo/implicit-if-match-3306/twistedcaldav/caldavxml.py 2008-11-04 03:10:03 UTC (rev 3313)
@@ -1664,6 +1664,15 @@
allowed_children = { (davxml.dav_namespace, "href"): (0, None) } # NB Minimum is zero because this is a property name
+class ScheduleTag (CalDAVTextElement):
+ """
+ Property on scheduling resources.
+ (CalDAV-schedule, section x.x.x)
+ """
+ name = "schedule-tag"
+ hidden = True
+ protected = True
+
class ScheduleInbox (CalDAVEmptyElement):
"""
Denotes the resource type of a calendar schedule Inbox.
Modified: CalendarServer/branches/users/cdaboo/implicit-if-match-3306/twistedcaldav/method/get.py
===================================================================
--- CalendarServer/branches/users/cdaboo/implicit-if-match-3306/twistedcaldav/method/get.py 2008-11-04 00:33:58 UTC (rev 3312)
+++ CalendarServer/branches/users/cdaboo/implicit-if-match-3306/twistedcaldav/method/get.py 2008-11-04 03:10:03 UTC (rev 3313)
@@ -28,6 +28,7 @@
from twisted.web2.stream import MemoryStream
from twistedcaldav import caldavxml
+from twistedcaldav.caldavxml import ScheduleTag
from twistedcaldav.customxml import TwistedCalendarAccessProperty
from twistedcaldav.ical import Component
@@ -59,6 +60,14 @@
response.headers.setHeader("content-type", MimeType.fromString("text/calendar; charset=utf-8"))
returnValue(response)
+
# Do normal GET behavior
response = (yield super(CalDAVFile, self).http_GET(request))
+
+ # Add Schedule-Tag header if property is present
+ if self.exists() and self.hasDeadProperty(ScheduleTag):
+ scheduletag = self.readDeadProperty(ScheduleTag)
+ if scheduletag:
+ response.headers.setHeader("Schedule-Tag", str(scheduletag))
+
returnValue(response)
Modified: CalendarServer/branches/users/cdaboo/implicit-if-match-3306/twistedcaldav/method/put_common.py
===================================================================
--- CalendarServer/branches/users/cdaboo/implicit-if-match-3306/twistedcaldav/method/put_common.py 2008-11-04 00:33:58 UTC (rev 3312)
+++ CalendarServer/branches/users/cdaboo/implicit-if-match-3306/twistedcaldav/method/put_common.py 2008-11-04 03:10:03 UTC (rev 3313)
@@ -22,6 +22,7 @@
import os
import types
+import uuid
from twisted.internet import reactor
from twisted.internet.defer import Deferred, inlineCallbacks, succeed
@@ -44,7 +45,7 @@
from twisted.web2.stream import MemoryStream
from twistedcaldav.config import config
-from twistedcaldav.caldavxml import NoUIDConflict
+from twistedcaldav.caldavxml import NoUIDConflict, ScheduleTag
from twistedcaldav.caldavxml import NumberOfRecurrencesWithinLimits
from twistedcaldav.caldavxml import caldav_namespace
from twistedcaldav.customxml import calendarserver_namespace ,\
@@ -273,6 +274,7 @@
# Basic validation
yield self.validCopyMoveOperation()
+ self.validIfScheduleMatch()
if self.destinationcal:
# Valid resource name check
@@ -366,6 +368,24 @@
log.debug(msg)
raise HTTPError(StatusResponse(responsecode.FORBIDDEN, msg))
+ def validIfScheduleMatch(self):
+ """
+ Check for If-ScheduleTag-Match header behavior.
+ """
+
+ # Only when a direct request
+ if not self.isiTIP and not self.internal_request:
+ header = self.request.headers.getHeader("If-Schedule-Tag-Match")
+ if header:
+ # Do "precondition" test
+ matched = False
+ if self.destination.exists() and self.destination.hasDeadProperty(ScheduleTag):
+ scheduletag = self.destination.readDeadProperty(ScheduleTag)
+ matched = (scheduletag == header)
+ if not matched:
+ log.debug("If-Schedule-Tag-Match: header value '%s' does not match resource value '%s'" % (header, scheduletag,))
+ raise HTTPError(responsecode.PRECONDITION_FAILED)
+
def validResourceName(self):
"""
Make sure that the resource name for the new resource is valid.
@@ -606,6 +626,15 @@
@inlineCallbacks
def doImplicitScheduling(self):
+
+ # Get any existing scheduletag property on the resource
+ if self.destination.exists() and self.destination.hasDeadProperty(ScheduleTag):
+ self.scheduletag = self.destination.readDeadProperty(ScheduleTag)
+ if self.scheduletag:
+ self.scheduletag = str(self.scheduletag)
+ else:
+ self.scheduletag = None
+
data_changed = False
# Do scheduling
@@ -862,8 +891,29 @@
# Check for scheduling object resource and write property
if is_scheduling_resource:
self.destination.writeDeadProperty(TwistedSchedulingObjectResource())
- elif not self.destinationcal:
+
+ # Need to figure out when to change the schedule tag:
+ #
+ # 1. If this is not an internal request then the resource is being explicitly changed
+ # 2. If it is an internal request for the Organizer, schedule tag never changes
+ # 3. If it is an internal request for an Attendee and the message being processed came
+ # from the Organizer then the schedule tag changes.
+
+ change_scheduletag = True
+ if self.internal_request:
+ # TODO: Organizer vs Attendee logic
+ change_scheduletag = False
+
+ if change_scheduletag or self.scheduletag is None:
+ self.scheduletag = str(uuid.uuid4())
+ self.destination.writeDeadProperty(ScheduleTag.fromString(self.scheduletag))
+
+ # Add a response header
+ response.headers.setHeader("Schedule-Tag", self.scheduletag)
+
+ else:
self.destination.removeDeadProperty(TwistedSchedulingObjectResource)
+ self.destination.removeDeadProperty(ScheduleTag)
# Check for existence of private comments and write property
if config.Scheduling["CalDAV"].get("EnablePrivateComments", True):
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20081103/ff5715e8/attachment.html>
More information about the calendarserver-changes
mailing list