[CalendarServer-changes] [2097]
CalendarServer/branches/users/cdaboo/private_events-2081/
twistedcaldav
source_changes at macosforge.org
source_changes at macosforge.org
Thu Jan 10 12:23:28 PST 2008
Revision: 2097
http://trac.macosforge.org/projects/calendarserver/changeset/2097
Author: cdaboo at apple.com
Date: 2008-01-10 12:23:26 -0800 (Thu, 10 Jan 2008)
Log Message:
-----------
Query match access restrictions.
Modified Paths:
--------------
CalendarServer/branches/users/cdaboo/private_events-2081/twistedcaldav/caldavxml.py
CalendarServer/branches/users/cdaboo/private_events-2081/twistedcaldav/ical.py
CalendarServer/branches/users/cdaboo/private_events-2081/twistedcaldav/method/report_calquery.py
Modified: CalendarServer/branches/users/cdaboo/private_events-2081/twistedcaldav/caldavxml.py
===================================================================
--- CalendarServer/branches/users/cdaboo/private_events-2081/twistedcaldav/caldavxml.py 2008-01-08 21:32:58 UTC (rev 2096)
+++ CalendarServer/branches/users/cdaboo/private_events-2081/twistedcaldav/caldavxml.py 2008-01-10 20:23:26 UTC (rev 2097)
@@ -191,7 +191,7 @@
self.filter_name = self.filter_name.encode("utf-8")
self.defined = not self.qualifier or (self.qualifier.qname() != (caldav_namespace, "is-not-defined"))
- def match(self, item):
+ def match(self, item, access=None):
"""
Returns True if the given calendar item (either a component, property or parameter value)
matches this filter, False otherwise.
@@ -201,11 +201,11 @@
# be negated by the caller
if not self.defined: return True
- if self.qualifier and not self.qualifier.match(item): return False
+ if self.qualifier and not self.qualifier.match(item, access): return False
if len(self.filters) > 0:
for filter in self.filters:
- if filter._match(item):
+ if filter._match(item, access):
return True
return False
else:
@@ -893,12 +893,16 @@
allowed_children = { (caldav_namespace, "comp-filter"): (1, 1) }
- def match(self, component):
+ def match(self, component, access):
"""
Returns True if the given calendar component matches this filter, False
otherwise.
"""
+ # We only care about certain access restrictions.
+ if access not in (iComponent.ACCESS_CONFIDENTIAL, iComponent.ACCESS_RESTRICTED):
+ access = None
+
# We need to prepare ourselves for a time-range query by pre-calculating
# the set of instances up to the latest time-range limit. That way we can
# avoid having to do some form of recurrence expansion for each query sub-part.
@@ -910,7 +914,7 @@
self.children[0].setInstances(instances)
# <filter> contains exactly one <comp-filter>
- return self.children[0].match(component)
+ return self.children[0].match(component, access)
def valid(self):
"""
@@ -962,7 +966,7 @@
}
allowed_attributes = { "name": True }
- def match(self, item):
+ def match(self, item, access):
"""
Returns True if the given calendar item (which is a component)
matches this filter, False otherwise.
@@ -978,20 +982,26 @@
if len(self.filters) > 0:
for filter in self.filters:
- if filter._match(item):
+ if filter._match(item, access):
return True
return False
else:
return True
- def _match(self, component):
+ def _match(self, component, access):
# At least one subcomponent must match (or is-not-defined is set)
for subcomponent in component.subcomponents():
+ # If access restrictions are in force, restrict matching to specific components only.
+ # In particular do not match VALARM.
+ if access and subcomponent.name() not in ("VEVENT", "VTODO", "VJOURNAL", "VFREEBUSY", "VTIMEZONE",):
+ continue
+
+ # Try to match the component name
if isinstance(self.filter_name, str):
if subcomponent.name() != self.filter_name: continue
else:
if subcomponent.name() not in self.filter_name: continue
- if self.match(subcomponent): break
+ if self.match(subcomponent, access): break
else:
return not self.defined
return self.defined
@@ -1117,10 +1127,22 @@
}
allowed_attributes = { "name": True }
- def _match(self, component):
+ def _match(self, component, access):
+ # When access restriction is in force, we need to only allow matches against the properties
+ # allowed by the access restriction level.
+ if access:
+ allowedProperties = iComponent.confidentialPropertiesMap.get(component.name(), None)
+ if allowedProperties and access == iComponent.ACCESS_RESTRICTED:
+ allowedProperties += iComponent.extraRestrictedProperties
+ else:
+ allowedProperties = None
+
# At least one property must match (or is-not-defined is set)
for property in component.properties():
- if property.name() == self.filter_name and self.match(property): break
+ # Apply access restrictions, if any.
+ if allowedProperties is not None and property.name() not in allowedProperties:
+ continue
+ if property.name() == self.filter_name and self.match(property, access): break
else:
return not self.defined
return self.defined
@@ -1173,7 +1195,7 @@
}
allowed_attributes = { "name": True }
- def _match(self, property):
+ def _match(self, property, access):
# We have to deal with the problem that the 'Native' form of a property
# will be missing the TZID parameter due to the conversion performed. Converting
# to non-native for the entire calendar object causes problems elsewhere, so its
@@ -1186,7 +1208,7 @@
# At least one property must match (or is-not-defined is set)
result = not self.defined
for parameterName in property.params().keys():
- if parameterName == self.filter_name and self.match(property.params()[parameterName]):
+ if parameterName == self.filter_name and self.match(property.params()[parameterName], access):
result = self.defined
break
@@ -1200,7 +1222,7 @@
"""
name = "is-defined"
- def match(self, component):
+ def match(self, component, access):
return component is not None
class IsNotDefined (CalDAVEmptyElement):
@@ -1210,7 +1232,7 @@
"""
name = "is-not-defined"
- def match(self, component):
+ def match(self, component, access):
# Oddly, this needs always to return True so that it appears there is
# a match - but we then "negate" the result if is-not-defined is set.
# Actually this method should never be called as we special case the
@@ -1265,7 +1287,7 @@
else:
self.negate = False
- def match(self, item):
+ def match(self, item, access):
"""
Match the text for the item.
If the item is a property, then match the property value,
@@ -1356,7 +1378,7 @@
# No other tests
return True
- def match(self, property):
+ def match(self, property, access):
"""
NB This is only called when doing a time-range match on a property.
"""
Modified: CalendarServer/branches/users/cdaboo/private_events-2081/twistedcaldav/ical.py
===================================================================
--- CalendarServer/branches/users/cdaboo/private_events-2081/twistedcaldav/ical.py 2008-01-08 21:32:58 UTC (rev 2096)
+++ CalendarServer/branches/users/cdaboo/private_events-2081/twistedcaldav/ical.py 2008-01-10 20:23:26 UTC (rev 2097)
@@ -175,6 +175,16 @@
"RESTRICTED" : ACCESS_RESTRICTED,
}
+ confidentialPropertiesMap = {
+ "VCALENDAR": ("PRODID", "VERSION", "CALSCALE", ACCESS_PROPERTY),
+ "VEVENT": ("UID", "RECURRENCE-ID", "SEQUENCE", "DTSTAMP", "STATUS", "TRANSP", "DTSTART", "DTEND", "DURATION", "RRULE", "RDATE", "EXRULE", "EXDATE", ),
+ "VTODO": ("UID", "RECURRENCE-ID", "SEQUENCE", "DTSTAMP", "STATUS", "DTSTART", "COMPLETED", "DUE", "DURATION", "RRULE", "RDATE", "EXRULE", "EXDATE", ),
+ "VJOURNAL": ("UID", "RECURRENCE-ID", "SEQUENCE", "DTSTAMP", "STATUS", "DTSTART", "RRULE", "RDATE", "EXRULE", "EXDATE", ),
+ "VFREEBUSY": ("UID", "DTSTAMP", "DTSTART", "DTEND", "DURATION", "FREEBUSY", ),
+ "VTIMEZONE": None,
+ }
+ extraRestrictedProperties = ("SUMMARY", "LOCATION",)
+
@classmethod
def fromString(clazz, string):
"""
Modified: CalendarServer/branches/users/cdaboo/private_events-2081/twistedcaldav/method/report_calquery.py
===================================================================
--- CalendarServer/branches/users/cdaboo/private_events-2081/twistedcaldav/method/report_calquery.py 2008-01-08 21:32:58 UTC (rev 2096)
+++ CalendarServer/branches/users/cdaboo/private_events-2081/twistedcaldav/method/report_calquery.py 2008-01-10 20:23:26 UTC (rev 2097)
@@ -31,6 +31,7 @@
from twisted.web2.http import HTTPError, StatusResponse
from twistedcaldav.caldavxml import caldav_namespace
+from twistedcaldav.customxml import TwistedCalendarAccessProperty
from twistedcaldav.method import report_common
import urllib
@@ -113,7 +114,16 @@
@param calendar: the L{Component} calendar read from the resource.
"""
- if query_ok or filter.match(calendar):
+ # Handle private events access restrictions
+ if not isowner:
+ try:
+ access = resource.readDeadProperty(TwistedCalendarAccessProperty)
+ except HTTPError:
+ access = None
+ else:
+ access = None
+
+ if query_ok or filter.match(calendar, access):
# Check size of results is within limit
matchcount[0] += 1
if matchcount[0] > max_number_of_results:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20080110/9c4a64e8/attachment-0001.html
More information about the calendarserver-changes
mailing list