Merge pull request #2189 from pbiering/issue-2187
Sharing-by-map: add support for collection requests missing a trailing /
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
## 3.7.8.dev
|
## 3.7.8.dev
|
||||||
* Fix: sharing/proppatch: reject in case of write-access but 'p' is in permissions
|
* Fix: sharing/proppatch: reject in case of write-access but 'p' is in permissions
|
||||||
|
* Fix: sharing/by-map: catch collection path without trailing / (supporting "pimsync")
|
||||||
|
|
||||||
## 3.7.7
|
## 3.7.7
|
||||||
* Fix: web plugin helpers httputils.serve_resource/serve_folder ignored their mimetypes and fallback_mimetype parameters and always used the built-in mapping, so custom web plugins could not serve additional file types with a correct Content-Type
|
* Fix: web plugin helpers httputils.serve_resource/serve_folder ignored their mimetypes and fallback_mimetype parameters and always used the built-in mapping, so custom web plugins could not serve additional file types with a correct Content-Type
|
||||||
|
|||||||
@@ -628,6 +628,7 @@ class BaseSharing:
|
|||||||
""" returning dict with PathMapped, Owner, Permissions or None if invalid"""
|
""" returning dict with PathMapped, Owner, Permissions or None if invalid"""
|
||||||
if self.sharing_collection_by_map:
|
if self.sharing_collection_by_map:
|
||||||
logger.trace("sharing/map/resolver: check path: %r", path)
|
logger.trace("sharing/map/resolver: check path: %r", path)
|
||||||
|
# check collection path
|
||||||
result = self.database_get_sharing(
|
result = self.database_get_sharing(
|
||||||
ShareType="map",
|
ShareType="map",
|
||||||
PathOrToken=path,
|
PathOrToken=path,
|
||||||
@@ -635,7 +636,7 @@ class BaseSharing:
|
|||||||
User=user)
|
User=user)
|
||||||
|
|
||||||
if not result:
|
if not result:
|
||||||
# fallback to parent path
|
# assume item path, fallback to parent path
|
||||||
parent_path = pathutils.parent_path(path)
|
parent_path = pathutils.parent_path(path)
|
||||||
logger.trace("sharing/map/resolver: check parent path: %r", parent_path)
|
logger.trace("sharing/map/resolver: check parent path: %r", parent_path)
|
||||||
result = self.database_get_sharing(
|
result = self.database_get_sharing(
|
||||||
@@ -646,9 +647,19 @@ class BaseSharing:
|
|||||||
if result:
|
if result:
|
||||||
result['PathMapped'] = path.replace(parent_path, result['PathMapped'])
|
result['PathMapped'] = path.replace(parent_path, result['PathMapped'])
|
||||||
logger.trace("sharing/map/resolver: PathMapped=%r Permissions=%r by parent_path=%r", result['PathMapped'], result['Permissions'], parent_path)
|
logger.trace("sharing/map/resolver: PathMapped=%r Permissions=%r by parent_path=%r", result['PathMapped'], result['Permissions'], parent_path)
|
||||||
else:
|
|
||||||
logger.trace("sharing/map/resolver: not found")
|
if not result and not path.endswith("/"):
|
||||||
return None
|
# assume collection path with missing trailing /
|
||||||
|
path_with_trailing_slash = path + "/"
|
||||||
|
logger.trace("sharing/map/resolver: check path having '/' appended: %r", path_with_trailing_slash)
|
||||||
|
result = self.database_get_sharing(
|
||||||
|
ShareType="map",
|
||||||
|
PathOrToken=path_with_trailing_slash,
|
||||||
|
OnlyEnabled=False,
|
||||||
|
User=user)
|
||||||
|
if result:
|
||||||
|
path = path_with_trailing_slash
|
||||||
|
logger.trace("sharing/map/resolver: PathMapped=%r Permissions=%r by path_with_trailing_slash=%r", result['PathMapped'], result['Permissions'], path_with_trailing_slash)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
if result['EnabledByOwner'] is not True:
|
if result['EnabledByOwner'] is not True:
|
||||||
@@ -666,6 +677,7 @@ class BaseSharing:
|
|||||||
logger.info("sharing/%s: resolved path %r->%r, user %r->%r, Permissions=%r Conversion=%r", "map", result['PathOrToken'], result['PathMapped'], user, result['Owner'], result['Permissions'], result['Conversion'])
|
logger.info("sharing/%s: resolved path %r->%r, user %r->%r, Permissions=%r Conversion=%r", "map", result['PathOrToken'], result['PathMapped'], user, result['Owner'], result['Permissions'], result['Conversion'])
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
logger.trace("sharing/map/resolver: not found")
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
logger.trace("sharing/map: not active")
|
logger.trace("sharing/map: not active")
|
||||||
|
|||||||
@@ -1988,10 +1988,34 @@ class TestSharingApiSanity(BaseTest):
|
|||||||
json_dict['PathOrToken'] = path_shared
|
json_dict['PathOrToken'] = path_shared
|
||||||
_, headers, answer = self._sharing_api_json("map", "enable", check=200, login="user:userpw", json_dict=json_dict)
|
_, headers, answer = self._sharing_api_json("map", "enable", check=200, login="user:userpw", json_dict=json_dict)
|
||||||
|
|
||||||
|
# check GET as user
|
||||||
|
logging.info("\n*** GET collection user -> ok")
|
||||||
|
_, headers, answer = self.request("GET", path_shared, check=200, login="user:userpw")
|
||||||
|
|
||||||
# check REPORT as user
|
# check REPORT as user
|
||||||
logging.info("\n*** REPORT collection user -> ok")
|
logging.info("\n*** REPORT collection user -> ok")
|
||||||
_, responses = self.report(path_shared, """\
|
_, responses = self.report(path_shared, """\
|
||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<C:calendar-query xmlns:C="urn:ietf:params:xml:ns:caldav">
|
||||||
|
<D:prop xmlns:D="DAV:">
|
||||||
|
<D:getetag />
|
||||||
|
</D:prop>
|
||||||
|
</C:calendar-query>""", login="user:userpw")
|
||||||
|
assert len(responses) == 1
|
||||||
|
logging.info("response: %r", responses)
|
||||||
|
response = responses[path_shared_item]
|
||||||
|
assert isinstance(response, dict)
|
||||||
|
status, prop = response["D:getetag"]
|
||||||
|
assert status == 200 and prop.text
|
||||||
|
|
||||||
|
# check GET as user without trailing /
|
||||||
|
logging.info("\n*** GET collection user (without trailing /) -> ok")
|
||||||
|
_, headers, answer = self.request("GET", path_shared.removesuffix("/"), check=200, login="user:userpw")
|
||||||
|
|
||||||
|
# check REPORT as user without trailing /
|
||||||
|
logging.info("\n*** REPORT collection user (without trailing /) -> ok")
|
||||||
|
_, responses = self.report(path_shared.removesuffix("/"), """\
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<C:calendar-query xmlns:C="urn:ietf:params:xml:ns:caldav">
|
<C:calendar-query xmlns:C="urn:ietf:params:xml:ns:caldav">
|
||||||
<D:prop xmlns:D="DAV:">
|
<D:prop xmlns:D="DAV:">
|
||||||
<D:getetag />
|
<D:getetag />
|
||||||
|
|||||||
Reference in New Issue
Block a user