diff --git a/radicale/__init__.py b/radicale/__init__.py index 90b0752..39402ba 100644 --- a/radicale/__init__.py +++ b/radicale/__init__.py @@ -302,6 +302,23 @@ class Application: is_authenticated = self.is_authenticated(user, password) is_valid_user = is_authenticated or not user + # Create principal collection + if user and is_authenticated: + principal_path = "/%s/" % user + if self.authorized(user, self.Collection(principal_path, True), + "w"): + with self.Collection.acquire_lock("r"): + principal = next(self.Collection.discover(principal_path), + None) + if not principal or principal.path != principal_path.strip("/"): + with self.Collection.acquire_lock("w"): + # the collection might exist by now + principal = next(self.Collection.discover( + principal_path), None) + if (not principal or + principal.path != principal_path.strip("/")): + self.Collection.create_collection(principal_path) + # Get content content_length = int(environ.get("CONTENT_LENGTH") or 0) if content_length: diff --git a/radicale/storage.py b/radicale/storage.py index dd5290a..e43ebe5 100644 --- a/radicale/storage.py +++ b/radicale/storage.py @@ -364,25 +364,27 @@ class Collection(BaseCollection): # path should already be sanitized sane_path = sanitize_path(path).strip("/") attributes = sane_path.split("/") - if not attributes: - return + if not attributes[0]: + attributes.pop() # Try to guess if the path leads to a collection or an item folder = os.path.expanduser( cls.configuration.get("storage", "filesystem_folder")) if not os.path.isdir(path_to_filesystem(folder, sane_path)): # path is not a collection - if os.path.isfile(path_to_filesystem(folder, sane_path)): + if attributes and os.path.isfile(path_to_filesystem(folder, + sane_path)): # path is an item attributes.pop() - elif os.path.isdir(path_to_filesystem(folder, *attributes[:-1])): + elif attributes and os.path.isdir(path_to_filesystem( + folder, *attributes[:-1])): # path parent is a collection attributes.pop() # TODO: else: return? path = "/".join(attributes) - principal = len(attributes) <= 1 + principal = len(attributes) == 1 collection = cls(path, principal) yield collection if depth != "0": diff --git a/radicale/xmlutils.py b/radicale/xmlutils.py index bf3fff9..57552b9 100644 --- a/radicale/xmlutils.py +++ b/radicale/xmlutils.py @@ -589,16 +589,17 @@ def _propfind_response(path, item, props, user, write=False): is404 = False if tag == _tag("D", "getetag"): element.text = item.etag - elif tag == _tag("D", "principal-URL"): - tag = ET.Element(_tag("D", "href")) - tag.text = _href(collection, path) - element.append(tag) elif tag == _tag("D", "getlastmodified"): element.text = item.last_modified - elif tag in (_tag("D", "principal-collection-set"), - _tag("C", "calendar-user-address-set"), - _tag("CR", "addressbook-home-set"), - _tag("C", "calendar-home-set")): + elif tag == _tag("D", "principal-collection-set"): + tag = ET.Element(_tag("D", "href")) + tag.text = _href(collection, "/") + element.append(tag) + elif (tag in (_tag("C", "calendar-user-address-set"), + _tag("D", "principal-URL"), + _tag("CR", "addressbook-home-set"), + _tag("C", "calendar-home-set")) and + collection.is_principal): tag = ET.Element(_tag("D", "href")) tag.text = _href(collection, path) element.append(tag)