sharing: change token format to absolut URL
This commit is contained in:
@@ -323,14 +323,14 @@ Create a share by mapping a collection of an `Owner` to a token.
|
|||||||
curl -u user:$userpw -d "PathMapped=/user/testcalendar1/" -d "Enabled=True" -d "Hidden=False" http://localhost:5232/.sharing/v1/token/create
|
curl -u user:$userpw -d "PathMapped=/user/testcalendar1/" -d "Enabled=True" -d "Hidden=False" http://localhost:5232/.sharing/v1/token/create
|
||||||
ApiVersion=1
|
ApiVersion=1
|
||||||
Status='success'
|
Status='success'
|
||||||
PathOrToken='v1/VQR7AmsVRi2ZlFj_JwGpFx-ES5Goyku-gP_YkLh1zUw='
|
PathOrToken='/.token/v1/VQR7AmsVRi2ZlFj_JwGpFx-ES5Goyku-gP_YkLh1zUw0/'
|
||||||
```
|
```
|
||||||
|
|
||||||
* json->json
|
* json->json
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -u user:$userpw -H "Content-Type: application/json" -d '{ "PathMapped": "/user/testcalendar1/", "Enabled": true, "Hidden": false}' http://localhost:5232/.sharing/v1/token/create
|
curl -u user:$userpw -H "Content-Type: application/json" -d '{ "PathMapped": "/user/testcalendar1/", "Enabled": true, "Hidden": false}' http://localhost:5232/.sharing/v1/token/create
|
||||||
{"ApiVersion": 1, "Status": "success", "PathOrToken": "v1/aMsmGqOsRwSH-2-6tEa8EMr4RMYzMU7WvPmjnp5qDnw="}
|
{"ApiVersion": 1, "Status": "success", "PathOrToken": "/.token/v1/aMsmGqOsRwSH-2-6tEa8EMr4RMYzMU7WvPmjnp5qDnw0/"}
|
||||||
```
|
```
|
||||||
|
|
||||||
###### API Hook "(map|bday)/create"
|
###### API Hook "(map|bday)/create"
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ API_TYPES_V1: dict[str, type] = {
|
|||||||
"Hidden": bool,
|
"Hidden": bool,
|
||||||
"Properties": dict}
|
"Properties": dict}
|
||||||
|
|
||||||
TOKEN_PATTERN_V1: str = "(v1/[a-zA-Z0-9_=\\-]{44})"
|
TOKEN_PATTERN_V1: str = "v1/[a-zA-Z0-9_\\-]{44}"
|
||||||
|
|
||||||
PATH_PATTERN: str = "([a-zA-Z0-9/.\\-]+)" # TODO: extend or find better source
|
PATH_PATTERN: str = "([a-zA-Z0-9/.\\-]+)" # TODO: extend or find better source
|
||||||
|
|
||||||
@@ -432,7 +432,7 @@ class BaseSharing:
|
|||||||
if logger.isEnabledFor(logging.DEBUG):
|
if logger.isEnabledFor(logging.DEBUG):
|
||||||
logger.debug("TRACE/sharing/token: check path: %r", path)
|
logger.debug("TRACE/sharing/token: check path: %r", path)
|
||||||
if path.startswith("/.token/"):
|
if path.startswith("/.token/"):
|
||||||
pattern = re.compile('^/\\.token/' + TOKEN_PATTERN_V1 + '$')
|
pattern = re.compile('^(/\\.token/' + TOKEN_PATTERN_V1 + '/)$')
|
||||||
match = pattern.match(path)
|
match = pattern.match(path)
|
||||||
if not match:
|
if not match:
|
||||||
if logger.isEnabledFor(logging.DEBUG):
|
if logger.isEnabledFor(logging.DEBUG):
|
||||||
@@ -753,7 +753,7 @@ class BaseSharing:
|
|||||||
return httputils.bad_request("Invalid value for Permissions")
|
return httputils.bad_request("Invalid value for Permissions")
|
||||||
elif key == "PathOrToken":
|
elif key == "PathOrToken":
|
||||||
if ShareType == "token":
|
if ShareType == "token":
|
||||||
if not re.search('^' + TOKEN_PATTERN_V1 + '$', request_data[key]):
|
if not re.search('^/.token/' + TOKEN_PATTERN_V1 + '/$', request_data[key]):
|
||||||
logger.warning(api_info + ": unsupported " + key)
|
logger.warning(api_info + ": unsupported " + key)
|
||||||
return httputils.bad_request("Invalid value for PathOrToken")
|
return httputils.bad_request("Invalid value for PathOrToken")
|
||||||
else:
|
else:
|
||||||
@@ -928,8 +928,8 @@ class BaseSharing:
|
|||||||
else:
|
else:
|
||||||
User = user
|
User = user
|
||||||
|
|
||||||
# v1: create uuid token with 2x 32 bytes = 256 bit
|
# v1: create uuid token with 2x 32 bytes = 256 bit with base64 encoding but replace '=' with '0' to avoid any additional encoding issues issues
|
||||||
token = "v1/" + str(base64.urlsafe_b64encode(uuid.uuid4().bytes + uuid.uuid4().bytes), 'utf-8')
|
token = "/.token/v1/" + str(base64.urlsafe_b64encode(uuid.uuid4().bytes + uuid.uuid4().bytes), 'utf-8').replace('=', '0') + "/"
|
||||||
|
|
||||||
if logger.isEnabledFor(logging.DEBUG):
|
if logger.isEnabledFor(logging.DEBUG):
|
||||||
logger.debug("TRACE/" + api_info + ": %r (Permissions=%r token=%r)", PathMapped, Permissions, token)
|
logger.debug("TRACE/" + api_info + ": %r (Permissions=%r token=%r)", PathMapped, Permissions, token)
|
||||||
|
|||||||
@@ -703,7 +703,6 @@ class TestSharingApiSanity(BaseTest):
|
|||||||
form_array: Sequence[str]
|
form_array: Sequence[str]
|
||||||
json_dict: dict
|
json_dict: dict
|
||||||
|
|
||||||
path_token = "/.token/"
|
|
||||||
path_base = "/owner/calendar.ics/"
|
path_base = "/owner/calendar.ics/"
|
||||||
path_base2 = "/owner/calendar2.ics/"
|
path_base2 = "/owner/calendar2.ics/"
|
||||||
|
|
||||||
@@ -761,10 +760,10 @@ class TestSharingApiSanity(BaseTest):
|
|||||||
assert "Status='success'" in answer
|
assert "Status='success'" in answer
|
||||||
|
|
||||||
logging.info("\n*** fetch collection using invalid token (without credentials)")
|
logging.info("\n*** fetch collection using invalid token (without credentials)")
|
||||||
_, headers, answer = self.request("GET", path_token + "v1/invalidtoken", check=401)
|
_, headers, answer = self.request("GET", "/.token/v1/invalidtoken/", check=401)
|
||||||
|
|
||||||
logging.info("\n*** fetch collection using token (without credentials)")
|
logging.info("\n*** fetch collection using token (without credentials)")
|
||||||
_, headers, answer = self.request("GET", path_token + token, check=200)
|
_, headers, answer = self.request("GET", token, check=200)
|
||||||
assert "UID:event" in answer
|
assert "UID:event" in answer
|
||||||
|
|
||||||
logging.info("\n*** disable token (form->text)")
|
logging.info("\n*** disable token (form->text)")
|
||||||
@@ -773,7 +772,7 @@ class TestSharingApiSanity(BaseTest):
|
|||||||
assert "Status='success'" in answer
|
assert "Status='success'" in answer
|
||||||
|
|
||||||
logging.info("\n*** fetch collection using disabled token (without credentials)")
|
logging.info("\n*** fetch collection using disabled token (without credentials)")
|
||||||
_, headers, answer = self.request("GET", path_token + token, check=401)
|
_, headers, answer = self.request("GET", token, check=401)
|
||||||
|
|
||||||
logging.info("\n*** enable token (form->text)")
|
logging.info("\n*** enable token (form->text)")
|
||||||
form_array = ["PathOrToken=" + token]
|
form_array = ["PathOrToken=" + token]
|
||||||
@@ -781,7 +780,7 @@ class TestSharingApiSanity(BaseTest):
|
|||||||
assert "Status='success'" in answer
|
assert "Status='success'" in answer
|
||||||
|
|
||||||
logging.info("\n*** fetch collection using token (without credentials)")
|
logging.info("\n*** fetch collection using token (without credentials)")
|
||||||
_, headers, answer = self.request("GET", path_token + token, check=200)
|
_, headers, answer = self.request("GET", token, check=200)
|
||||||
assert "UID:event" in answer
|
assert "UID:event" in answer
|
||||||
|
|
||||||
logging.info("\n*** delete token#2 (json->json)")
|
logging.info("\n*** delete token#2 (json->json)")
|
||||||
@@ -804,7 +803,7 @@ class TestSharingApiSanity(BaseTest):
|
|||||||
_, headers, answer = self._sharing_api_form("token", "delete", check=404, login="owner:ownerpw", form_array=form_array)
|
_, headers, answer = self._sharing_api_form("token", "delete", check=404, login="owner:ownerpw", form_array=form_array)
|
||||||
|
|
||||||
logging.info("\n*** fetch collection using deleted token (without credentials)")
|
logging.info("\n*** fetch collection using deleted token (without credentials)")
|
||||||
_, headers, answer = self.request("GET", path_token + token, check=401)
|
_, headers, answer = self.request("GET", token, check=401)
|
||||||
|
|
||||||
def test_sharing_api_map_basic(self) -> None:
|
def test_sharing_api_map_basic(self) -> None:
|
||||||
"""share-by-map API basic tests."""
|
"""share-by-map API basic tests."""
|
||||||
|
|||||||
Reference in New Issue
Block a user