New right "i": Only allowing HTTP method GET
This commit is contained in:
@ -71,21 +71,28 @@ class ApplicationGetMixin:
|
||||
if path == "/.web" or path.startswith("/.web/"):
|
||||
return self._web.get(environ, base_prefix, path, user)
|
||||
access = app.Access(self._rights, user, path)
|
||||
if not access.check("r"):
|
||||
if not access.check("r") and "i" not in access.permissions:
|
||||
return httputils.NOT_ALLOWED
|
||||
with self._storage.acquire_lock("r", user):
|
||||
item = next(self._storage.discover(path), None)
|
||||
if not item:
|
||||
return httputils.NOT_FOUND
|
||||
if not access.check("r", item):
|
||||
if access.check("r", item):
|
||||
limited_access = False
|
||||
elif "i" in access.permissions:
|
||||
limited_access = True
|
||||
else:
|
||||
return httputils.NOT_ALLOWED
|
||||
if isinstance(item, storage.BaseCollection):
|
||||
tag = item.get_meta("tag")
|
||||
if not tag:
|
||||
return httputils.DIRECTORY_LISTING
|
||||
return (httputils.NOT_ALLOWED if limited_access else
|
||||
httputils.DIRECTORY_LISTING)
|
||||
content_type = xmlutils.MIMETYPES[tag]
|
||||
content_disposition = self._content_disposition_attachement(
|
||||
propose_filename(item))
|
||||
elif limited_access:
|
||||
return httputils.NOT_ALLOWED
|
||||
else:
|
||||
content_type = xmlutils.OBJECT_MIMETYPES[item.name]
|
||||
content_disposition = ""
|
||||
|
@ -21,10 +21,12 @@ collections and entries.
|
||||
|
||||
Permissions:
|
||||
|
||||
- R: read a collection (excluding address book or calendar collections)
|
||||
- r: read an address book or calendar collection
|
||||
- W: write a collection (excluding address book or calendar collections)
|
||||
- w: write an address book or calendar collection
|
||||
- R: read collections (excluding address books and calendars)
|
||||
- r: read address book and calendar collections
|
||||
- i: subset of **r** that only allows direct access via HTTP method GET
|
||||
(CalDAV/CardDAV is susceptible to expensive search requests)
|
||||
- W: write collections (excluding address books and calendars)
|
||||
- w: write address book and calendar collections
|
||||
|
||||
Take a look at the class ``BaseRights`` if you want to implement your own.
|
||||
|
||||
|
@ -136,6 +136,30 @@ permissions: Rr""")
|
||||
self._test_rights("from_file", "", "/custom/sub", "w", 401)
|
||||
self._test_rights("from_file", "tmp", "/custom/sub", "w", 403)
|
||||
|
||||
def test_from_file_limited_get(self):
|
||||
rights_file_path = os.path.join(self.colpath, "rights")
|
||||
with open(rights_file_path, "w") as f:
|
||||
f.write("""\
|
||||
[write-all]
|
||||
user: tmp
|
||||
collection: .*
|
||||
permissions: RrWw
|
||||
[limited-public]
|
||||
user: .*
|
||||
collection: public/[^/]*
|
||||
permissions: i""")
|
||||
self.configuration.update(
|
||||
{"rights": {"type": "from_file",
|
||||
"file": rights_file_path}}, "test")
|
||||
self.application = Application(self.configuration)
|
||||
self.mkcalendar("/tmp/calendar", login="tmp:bepo")
|
||||
self.mkcol("/public", login="tmp:bepo")
|
||||
self.mkcalendar("/public/calendar", login="tmp:bepo")
|
||||
self.get("/tmp/calendar", check=401)
|
||||
self.get("/public/", check=401)
|
||||
self.get("/public/calendar")
|
||||
self.get("/public/calendar/1.ics", check=401)
|
||||
|
||||
def test_custom(self):
|
||||
"""Custom rights management."""
|
||||
self._test_rights("radicale.tests.custom.rights", "", "/", "r", 401)
|
||||
|
Reference in New Issue
Block a user