Merge pull request #95 from chripo/easy-connect

Easy connect
This commit is contained in:
Guillaume Ayoub 2014-02-05 12:38:09 +01:00
commit 00674fe8b0
2 changed files with 87 additions and 60 deletions

View File

@ -283,10 +283,14 @@ class Application(object):
read_allowed_items, write_allowed_items = \ read_allowed_items, write_allowed_items = \
self.collect_allowed_items(items, user) self.collect_allowed_items(items, user)
is_authenticated = auth.is_authenticated(user, password)
if ((read_allowed_items or write_allowed_items) if ((read_allowed_items or write_allowed_items)
and (not user or auth.is_authenticated(user, password))) or \ and (not user or is_authenticated)) or \
(is_authenticated and function == self.propfind) or \
function == self.options or not items: function == self.options or not items:
# Collections found, or OPTIONS request, or no items at all # Collections found, or authenticated PROPFIND request,
# or OPTIONS request, or no items at all
status, headers, answer = function( status, headers, answer = function(
environ, read_allowed_items, write_allowed_items, content, environ, read_allowed_items, write_allowed_items, content,
user) user)
@ -294,7 +298,7 @@ class Application(object):
status, headers, answer = NOT_ALLOWED status, headers, answer = NOT_ALLOWED
if ((status, headers, answer) == NOT_ALLOWED and if ((status, headers, answer) == NOT_ALLOWED and
not auth.is_authenticated(user, password) and not is_authenticated and
config.get("auth", "type") != "None"): config.get("auth", "type") != "None"):
# Unknown or unauthorized user # Unknown or unauthorized user
log.LOGGER.info("%s refused" % (user or "Anonymous user")) log.LOGGER.info("%s refused" % (user or "Anonymous user"))

View File

@ -227,14 +227,19 @@ def propfind(path, xml_request, collections, user=None):
_tag("D", "displayname"), _tag("D", "displayname"),
_tag("D", "owner"), _tag("D", "owner"),
_tag("D", "getetag"), _tag("D", "getetag"),
_tag("D", "current-user-principal"),
_tag("A", "calendar-color"), _tag("A", "calendar-color"),
_tag("CS", "getctag")] _tag("CS", "getctag")]
# Writing answer # Writing answer
multistatus = ET.Element(_tag("D", "multistatus")) multistatus = ET.Element(_tag("D", "multistatus"))
for collection in collections: if collections:
response = _propfind_response(path, collection, props, user) for collection in collections:
response = _propfind_response(path, collection, props, user)
multistatus.append(response)
else:
response = _propfind_response(path, None, props, user)
multistatus.append(response) multistatus.append(response)
return _pretty_xml(multistatus) return _pretty_xml(multistatus)
@ -250,8 +255,11 @@ def _propfind_response(path, item, props, user):
response = ET.Element(_tag("D", "response")) response = ET.Element(_tag("D", "response"))
href = ET.Element(_tag("D", "href")) href = ET.Element(_tag("D", "href"))
uri = item.url if is_collection else "%s/%s" % (path, item.name) if item:
href.text = _href(uri.replace("//", "/")) uri = item.url if is_collection else "%s/%s" % (path, item.name)
href.text = _href(uri.replace("//", "/"))
else:
href.text = _href(path)
response.append(href) response.append(href)
propstat404 = ET.Element(_tag("D", "propstat")) propstat404 = ET.Element(_tag("D", "propstat"))
@ -267,16 +275,28 @@ def _propfind_response(path, item, props, user):
for tag in props: for tag in props:
element = ET.Element(tag) element = ET.Element(tag)
is404 = False is404 = False
if tag == _tag("D", "getetag"): if tag in (_tag("D", "principal-URL"),
element.text = item.etag _tag("D", "current-user-principal")):
elif tag == _tag("D", "principal-URL"): if user:
tag = ET.Element(_tag("D", "href")) tag = ET.Element(_tag("D", "href"))
tag.text = _href(path) tag.text = _href("%s/" % user)
else:
is404 = True
tag = ET.Element(_tag("D", "unauthenticated"))
element.append(tag) element.append(tag)
elif tag in (_tag("D", "principal-collection-set"), elif tag == _tag("D", "principal-collection-set"):
_tag("C", "calendar-user-address-set"), tag = ET.Element(_tag("D", "href"))
_tag("CR", "addressbook-home-set"), tag.text = _href("/")
_tag("C", "calendar-home-set")): element.append(tag)
elif tag in (_tag("C", "calendar-home-set"),
_tag("CR", "addressbook-home-set")):
if user and path == "/%s/" % user:
tag = ET.Element(_tag("D", "href"))
tag.text = _href(path)
element.append(tag)
else:
is404 = True
elif tag == _tag("C", "calendar-user-address-set"):
tag = ET.Element(_tag("D", "href")) tag = ET.Element(_tag("D", "href"))
tag.text = _href(path) tag.text = _href(path)
element.append(tag) element.append(tag)
@ -294,13 +314,6 @@ def _propfind_response(path, item, props, user):
comp.set("name", component) comp.set("name", component)
element.append(comp) element.append(comp)
# pylint: enable=W0511 # pylint: enable=W0511
elif tag == _tag("D", "current-user-principal") and user:
tag = ET.Element(_tag("D", "href"))
if item.resource_type == "addressbook":
tag.text = _href("/%s/addressbook.vcf/" % user)
else:
tag.text = _href("/%s/calendar.ics/" % user)
element.append(tag)
elif tag == _tag("D", "current-user-privilege-set"): elif tag == _tag("D", "current-user-privilege-set"):
privilege = ET.Element(_tag("D", "privilege")) privilege = ET.Element(_tag("D", "privilege"))
privilege.append(ET.Element(_tag("D", "all"))) privilege.append(ET.Element(_tag("D", "all")))
@ -318,45 +331,55 @@ def _propfind_response(path, item, props, user):
report_tag.text = report_name report_tag.text = report_name
supported.append(report_tag) supported.append(report_tag)
element.append(supported) element.append(supported)
elif is_collection: # item related properties
if tag == _tag("D", "getcontenttype"): elif item:
element.text = item.mimetype if tag == _tag("D", "getetag"):
elif tag == _tag("D", "resourcetype"):
if item.is_principal:
tag = ET.Element(_tag("D", "principal"))
element.append(tag)
if item.is_leaf(item.path) or (
not item.exists and item.resource_type):
# 2nd case happens when the collection is not stored yet,
# but the resource type is guessed
if item.resource_type == "addressbook":
tag = ET.Element(_tag("CR", item.resource_type))
else:
tag = ET.Element(_tag("C", item.resource_type))
element.append(tag)
tag = ET.Element(_tag("D", "collection"))
element.append(tag)
elif tag == _tag("D", "owner") and item.owner_url:
element.text = item.owner_url
elif tag == _tag("CS", "getctag"):
element.text = item.etag element.text = item.etag
elif tag == _tag("C", "calendar-timezone"): elif is_collection:
element.text = ical.serialize( if tag == _tag("D", "getcontenttype"):
item.tag, item.headers, item.timezones) element.text = item.mimetype
elif tag == _tag("D", "displayname"): elif tag == _tag("D", "resourcetype"):
element.text = item.name if item.is_principal:
elif tag == _tag("A", "calendar-color"): tag = ET.Element(_tag("D", "principal"))
element.text = item.color element.append(tag)
else: if item.is_leaf(item.path) or (
human_tag = _tag_from_clark(tag) not item.exists and item.resource_type):
if human_tag in collection_props: # 2nd case happens when the collection is not stored yet,
element.text = collection_props[human_tag] # but the resource type is guessed
if item.resource_type == "addressbook":
tag = ET.Element(_tag("CR", item.resource_type))
else:
tag = ET.Element(_tag("C", item.resource_type))
element.append(tag)
tag = ET.Element(_tag("D", "collection"))
element.append(tag)
elif tag == _tag("D", "owner") and item.owner_url:
element.text = item.owner_url
elif tag == _tag("CS", "getctag"):
element.text = item.etag
elif tag == _tag("C", "calendar-timezone"):
element.text = ical.serialize(
item.tag, item.headers, item.timezones)
elif tag == _tag("D", "displayname"):
element.text = item.name
elif tag == _tag("A", "calendar-color"):
element.text = item.color
else: else:
is404 = True human_tag = _tag_from_clark(tag)
# Not for collections if human_tag in collection_props:
elif tag == _tag("D", "getcontenttype"): element.text = collection_props[human_tag]
element.text = "%s; component=%s" % ( else:
item.mimetype, item.tag.lower()) is404 = True
# Not for collections
elif tag == _tag("D", "getcontenttype"):
element.text = "%s; component=%s" % (
item.mimetype, item.tag.lower())
elif tag == _tag("D", "resourcetype"):
# resourcetype must be returned empty for non-collection elements
pass
else:
is404 = True
# Not for items
elif tag == _tag("D", "resourcetype"): elif tag == _tag("D", "resourcetype"):
# resourcetype must be returned empty for non-collection elements # resourcetype must be returned empty for non-collection elements
pass pass