From 41cabfcdcb409dc93cef1a68633a8ffe8290bb70 Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Tue, 6 Jul 2021 16:05:08 +0200 Subject: [PATCH 01/17] add routes adr --- docs/ocis/adr/0009-routes.md | 95 ++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 docs/ocis/adr/0009-routes.md diff --git a/docs/ocis/adr/0009-routes.md b/docs/ocis/adr/0009-routes.md new file mode 100644 index 000000000..6fc6313ad --- /dev/null +++ b/docs/ocis/adr/0009-routes.md @@ -0,0 +1,95 @@ +## Problem Statement + +When we speak about routes we have to make a difference between browser routes and internal API calls. Browser routes are interpreted by the web client (owncloud/web) to construct API calls1. With this in mind, this is the mapping on ownCloud Web: + +| | Browser URL | Internal Resolution | +|------|---------------------------------------------------------------|-------------------------------------------------| +| OCIS | `https://host/#/files/list/all/TEST` | `https://host/remote.php/webdav/TEST` | +| OC10 | `https://host/index.php/apps/files/?dir=/TEST&fileid=5472225` | `https://host/remote.php/dav/files/aunger/TEST` | + +Note that with an OC10 backend ownCloud's Web format remains unchanged: `https://host/index.html#/files/list/all/TEST` -- still resolves to --> `https://host/remote.php/webdav/TEST`. So here we have to make a distinction and limit the scope of this ADR to "how will a web client deal with browser urls?"2 + +Worth mentioning that on an OC10 backend it seems that `fileid` query parameter takes precedence over the `dir`. In fact if `dir` is invalid but `fileid` isn't, the resolution will succeed, as opposed to if the `fileid` is wrong and `dir` correct, resolution will fail altogether. + +## Proposals + +### Use private links as routes + +First of, let's define what a private link is. A private link is: + +> Another way to access a file or folder is via a private link. It’s a handy way of creating a permanent link for yourself or to point others to a file or folder, within a share, more efficiently. To access the private link, in the Sharing Panel for a file or folder, next to its name you’ll see a small link icon (1), as in the screenshot below. + +_[source](https://doc.owncloud.com/server/user_manual/files/webgui/sharing.html#using-private-links)_ + +Private links are preceded by `/f/` to distinguish from `/s/` shares; this is convention. + +### How MUST a bookmarked private link work with OCIS + +The following flow chart provides an overview on how this should work. + +![img](https://i.imgur.com/bE4xymv.png) + +Regardless of the user being logged in or the private link being "public", ownCloud web receives the following URL: + +`https://host/f/2748872` part of a more general format: `https://host/f/` + +With an OC10 backend the resolution happens on OC10, and the response is a `3XX` with `Location` set to the actual URL, in this case: + +`Location /index.php/apps/files/?dir=/TEST` + +The proposed solution on `WEB-551` relies on the URL being of the format: + +`https://xmpl.com/f//?id=` + +or more blunt: + +`https://host/f/space/relative/path?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` + +Let us breakdown each section (except the obvious): + +`/f/` = private link prefix. This is a convention. +`/space/` = space name. In which storage space does the target file / folder exist. +`/relative/path/` = path of the target file / folder relative to the storage space. +`?id=[...]` = combination of `storage_id` + `:` + `resource_id` + +With the following information we can uniquely identify any resource within any known storages. This path is conditionally displayed. + +`https://host/f/fileid` MUST therefore be expanded to the format: `https://host/f/space/relative/path?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607`, as seen in the previous image. + +This is achieved in ocis because: + +- Admins will use the reva sql storage +- when OC10 + Web receives `https://host/index.php/f/5472225` -- which the internal resolution is -> `https://host/remote.php/dav/files/aunger/TEST` under an OC10 backend. +- when OCIS + Web receives `https://host/index.php/f/5472225` -- OCIS MUST + +Now we have to do more hops. We have gaps to fill up here, so let us delegate the responsibility to OCIS. Parting from the assumption that there is a sql storage provider (this means we can query the resource by its old OC10 id) we could: + +1. fetch the resource by its old ID = `/id=<>:/` +2. find out in which storage space the reference exists = `/space/` +3. find out the storage provider that contains the reference = `/id=:<>/` +4. find out the relative path to the root of the storage space of the reference = `/relative/path/` + +Here we have essentially reconstructed all the info that we need that was defined in WEB-551, this can then be added to the resolution response for `GET https://host/index.php/f/5472225` + +### How would an existing "general purpose" URL bookmark work with an OCIS backend? (WEB requirement) + +A "general purpose bookmark" are just common paths we encounter by browsing on the web-ui. + +`https://host/index.php/apps/files/?dir=/TEST&fileid=5472225` + +Then at some point in the future the admin migrates to OCIS. What would happen to that bookmark? What would OCIS do if a request comes with such format? Well then OCIS has to transform the encoded information within that URL into something its API understand. As we can see here this is NOT a private link, but a simple URL I got just by opening the browser and navigating through my files. + +As we mentioned we want OCIS to be backwards compatible with existing bookmarks, but we're now in a broken state. What must be done by OCIS in order to resolve this? As we saw in the "Browser URL - Internal Resolution" table this URL (received by the web client) needs to be adapted to the OCIS format, and we already have all the information we need. The result is: + +`https://host/index.php/apps/files/?dir=/TEST&fileid=5472225` -> `https://host/remote.php/webdav/TEST` + +## Sources + +1. [Concepting: Use private link as route?](https://jira.owncloud.com/browse/WEB-551) +2. [Translate OC 10 paths to OCIS](https://jira.owncloud.com/browse/OCIS-1765) - fastlane ticket, blocked by (1) + +## Assumptions + +- 1 please provide input. +- 2 assumption. please provide input on this topic. +- From adc21d8f0b8878dec200f5ae593f76c13dc3f2f8 Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Tue, 6 Jul 2021 17:50:03 +0200 Subject: [PATCH 02/17] update ADR --- docs/ocis/adr/0009-routes.md | 75 +++++++++++------------------------- 1 file changed, 22 insertions(+), 53 deletions(-) diff --git a/docs/ocis/adr/0009-routes.md b/docs/ocis/adr/0009-routes.md index 6fc6313ad..88bd2adaf 100644 --- a/docs/ocis/adr/0009-routes.md +++ b/docs/ocis/adr/0009-routes.md @@ -11,9 +11,7 @@ Note that with an OC10 backend ownCloud's Web format remains unchanged: `https:/ Worth mentioning that on an OC10 backend it seems that `fileid` query parameter takes precedence over the `dir`. In fact if `dir` is invalid but `fileid` isn't, the resolution will succeed, as opposed to if the `fileid` is wrong and `dir` correct, resolution will fail altogether. -## Proposals - -### Use private links as routes +## Use private links as routes First of, let's define what a private link is. A private link is: @@ -23,27 +21,34 @@ _[source](https://doc.owncloud.com/server/user_manual/files/webgui/sharing.html# Private links are preceded by `/f/` to distinguish from `/s/` shares; this is convention. -### How MUST a bookmarked private link work with OCIS +## Private link path resolution -The following flow chart provides an overview on how this should work. +Let's have a look at the following scenario: -![img](https://i.imgur.com/bE4xymv.png) +![img](https://i.imgur.com/hy0gSpB.jpeg) -Regardless of the user being logged in or the private link being "public", ownCloud web receives the following URL: +_fig. 1_ -`https://host/f/2748872` part of a more general format: `https://host/f/` +We can observe that the private link can still remain the unchanged, this should provide functionality with existing bookmarks. In order for bookmarked private links to work, the migration from OC10 to OCIS should have taken effect, and the recommended SQL storage provider should be in use, this will allow the OCIS backend to resolve the ID's pre-migration. -With an OC10 backend the resolution happens on OC10, and the response is a `3XX` with `Location` set to the actual URL, in this case: +Let us break down every step of figure 1. -`Location /index.php/apps/files/?dir=/TEST` +1. `GET https://cloud.ocis.com/index.php/f/5472225` + - all the web client has to "remember" is the id of the resource +2. `[303] Location=/marketing/path/to/file?id=storageid:resourceid` + - the server will resolve the file by ID and provide with a URL for the webUI to render of the format: `/space/relative/path?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` +3. `PROPFIND https://host/remote.php/webdav/TEST` + - To adjust to the new format, this WebDAV URL `MUST` change. If we don't have a namespace we can easily encounter naming collisions with different storage spaces1. A proposed WebDAV url format is recommended at this step of the following format: `https://host/remote.php/webdav/space/path/to/file?id=storageid:resourceid` which is provided by the server's original resolution. -The proposed solution on `WEB-551` relies on the URL being of the format: +When it comes to display the path, in order to avoid leaking parent information because the resource is shared, the rules in the following diagram `MUST` be followed: -`https://xmpl.com/f//?id=` + ![img](https://i.imgur.com/bE4xymv.png) -or more blunt: +## On the server side -`https://host/f/space/relative/path?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` +Receiving a GET request to the following resource `GET https://cloud.ocis.com/index.php/f/5472225` will trigger a few hops that `MUST` be cached in order to prevent slow response times. The nature of these requests can be cached because the resources ID are not subject to changes. + +The server `MUST` have a way to resolve the `ID=5472225`. The easiest approach that comes to mind is using the SQL storage driver, that provides compatibility when it comes to migrating files from an OC10 to an OCIS backend. The queried ID already exists in the DB, and the storage driver will just pull all the info it needs to construct the URL to set in the `Location` header of the response. Let us breakdown each section (except the obvious): @@ -52,44 +57,8 @@ Let us breakdown each section (except the obvious): `/relative/path/` = path of the target file / folder relative to the storage space. `?id=[...]` = combination of `storage_id` + `:` + `resource_id` -With the following information we can uniquely identify any resource within any known storages. This path is conditionally displayed. +With all the above data we can start building the Location response header. -`https://host/f/fileid` MUST therefore be expanded to the format: `https://host/f/space/relative/path?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607`, as seen in the previous image. +## Footnotes -This is achieved in ocis because: - -- Admins will use the reva sql storage -- when OC10 + Web receives `https://host/index.php/f/5472225` -- which the internal resolution is -> `https://host/remote.php/dav/files/aunger/TEST` under an OC10 backend. -- when OCIS + Web receives `https://host/index.php/f/5472225` -- OCIS MUST - -Now we have to do more hops. We have gaps to fill up here, so let us delegate the responsibility to OCIS. Parting from the assumption that there is a sql storage provider (this means we can query the resource by its old OC10 id) we could: - -1. fetch the resource by its old ID = `/id=<>:/` -2. find out in which storage space the reference exists = `/space/` -3. find out the storage provider that contains the reference = `/id=:<>/` -4. find out the relative path to the root of the storage space of the reference = `/relative/path/` - -Here we have essentially reconstructed all the info that we need that was defined in WEB-551, this can then be added to the resolution response for `GET https://host/index.php/f/5472225` - -### How would an existing "general purpose" URL bookmark work with an OCIS backend? (WEB requirement) - -A "general purpose bookmark" are just common paths we encounter by browsing on the web-ui. - -`https://host/index.php/apps/files/?dir=/TEST&fileid=5472225` - -Then at some point in the future the admin migrates to OCIS. What would happen to that bookmark? What would OCIS do if a request comes with such format? Well then OCIS has to transform the encoded information within that URL into something its API understand. As we can see here this is NOT a private link, but a simple URL I got just by opening the browser and navigating through my files. - -As we mentioned we want OCIS to be backwards compatible with existing bookmarks, but we're now in a broken state. What must be done by OCIS in order to resolve this? As we saw in the "Browser URL - Internal Resolution" table this URL (received by the web client) needs to be adapted to the OCIS format, and we already have all the information we need. The result is: - -`https://host/index.php/apps/files/?dir=/TEST&fileid=5472225` -> `https://host/remote.php/webdav/TEST` - -## Sources - -1. [Concepting: Use private link as route?](https://jira.owncloud.com/browse/WEB-551) -2. [Translate OC 10 paths to OCIS](https://jira.owncloud.com/browse/OCIS-1765) - fastlane ticket, blocked by (1) - -## Assumptions - -- 1 please provide input. -- 2 assumption. please provide input on this topic. -- +- 1 is this a real concern? Need read proof. From 1a8e00b19eac88d3104bf7494a0c38dc3def0e14 Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Tue, 6 Jul 2021 18:23:26 +0200 Subject: [PATCH 03/17] update ADR with manual get through webUI --- docs/ocis/adr/0009-routes.md | 49 ++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/docs/ocis/adr/0009-routes.md b/docs/ocis/adr/0009-routes.md index 88bd2adaf..fe494c67d 100644 --- a/docs/ocis/adr/0009-routes.md +++ b/docs/ocis/adr/0009-routes.md @@ -1,15 +1,16 @@ ## Problem Statement -When we speak about routes we have to make a difference between browser routes and internal API calls. Browser routes are interpreted by the web client (owncloud/web) to construct API calls1. With this in mind, this is the mapping on ownCloud Web: +When we speak about routes we have to make a difference between browser routes and internal API calls. Browser routes are interpreted by the web client (owncloud/web) to construct API calls. With this in mind, this is the mapping on ownCloud Web with OC10 and OCIS backend: -| | Browser URL | Internal Resolution | -|------|---------------------------------------------------------------|-------------------------------------------------| -| OCIS | `https://host/#/files/list/all/TEST` | `https://host/remote.php/webdav/TEST` | -| OC10 | `https://host/index.php/apps/files/?dir=/TEST&fileid=5472225` | `https://host/remote.php/dav/files/aunger/TEST` | +| | Browser URL | Internal Resolution | +|------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------| +| OC10 | `https://host/index.php/apps/files/?dir=/TEST&fileid=5472225` | `https://host/remote.php/dav/files/aunger/TEST` | +| OCIS | `https://host/#/files/list/all/TEST` | `https://host/remote.php/webdav/TEST` | +| OCIS (after this ADR is implemented) | `https://host/#/space/relative/path?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` | `https://host/remote.php/webdav/space/relative/path?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` | -Note that with an OC10 backend ownCloud's Web format remains unchanged: `https://host/index.html#/files/list/all/TEST` -- still resolves to --> `https://host/remote.php/webdav/TEST`. So here we have to make a distinction and limit the scope of this ADR to "how will a web client deal with browser urls?"2 +Note that with an OC10 backend ownCloud's Web format remains unchanged: `https://host/index.html#/files/list/all/TEST` -- still resolves to --> `https://host/remote.php/webdav/TEST`. So here we have to make a distinction and limit the scope of this ADR to "how will a web client deal with the browser url?" -Worth mentioning that on an OC10 backend it seems that `fileid` query parameter takes precedence over the `dir`. In fact if `dir` is invalid but `fileid` isn't, the resolution will succeed, as opposed to if the `fileid` is wrong and `dir` correct, resolution will fail altogether. +Worth mentioning that on an OC10 backend it seems that `fileid` query parameter takes precedence over the `dir`. In fact if `dir` is invalid but `fileid` isn't, the resolution will succeed, as opposed to if the `fileid` is wrong (doesn't exist) and `dir` correct, resolution will fail altogether. ## Use private links as routes @@ -29,16 +30,15 @@ Let's have a look at the following scenario: _fig. 1_ -We can observe that the private link can still remain the unchanged, this should provide functionality with existing bookmarks. In order for bookmarked private links to work, the migration from OC10 to OCIS should have taken effect, and the recommended SQL storage provider should be in use, this will allow the OCIS backend to resolve the ID's pre-migration. +We observe that the private link can still remain the unchanged, this should provide functionality with existing bookmarks. In order for bookmarked private links to work, the migration from OC10 to OCIS should have taken effect, and the recommended SQL storage provider should be in use, this will allow the OCIS backend to resolve the IDs pre-migration. -Let us break down every step of figure 1. +Let us break down every step of _fig. 1_. 1. `GET https://cloud.ocis.com/index.php/f/5472225` - - all the web client has to "remember" is the id of the resource -2. `[303] Location=/marketing/path/to/file?id=storageid:resourceid` + - all the web client has to "remember" is the ID of the resource +2. Server's response: `Status=303 Location=/marketing/path/to/file?id=storageid:resourceid` - the server will resolve the file by ID and provide with a URL for the webUI to render of the format: `/space/relative/path?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` -3. `PROPFIND https://host/remote.php/webdav/TEST` - - To adjust to the new format, this WebDAV URL `MUST` change. If we don't have a namespace we can easily encounter naming collisions with different storage spaces1. A proposed WebDAV url format is recommended at this step of the following format: `https://host/remote.php/webdav/space/path/to/file?id=storageid:resourceid` which is provided by the server's original resolution. +3. `PROPFIND https://host/remote.php/webdav/space/path/to/file?id=storageid:resourceid` When it comes to display the path, in order to avoid leaking parent information because the resource is shared, the rules in the following diagram `MUST` be followed: @@ -48,17 +48,34 @@ When it comes to display the path, in order to avoid leaking parent information Receiving a GET request to the following resource `GET https://cloud.ocis.com/index.php/f/5472225` will trigger a few hops that `MUST` be cached in order to prevent slow response times. The nature of these requests can be cached because the resources ID are not subject to changes. -The server `MUST` have a way to resolve the `ID=5472225`. The easiest approach that comes to mind is using the SQL storage driver, that provides compatibility when it comes to migrating files from an OC10 to an OCIS backend. The queried ID already exists in the DB, and the storage driver will just pull all the info it needs to construct the URL to set in the `Location` header of the response. +The server `MUST` have a way to resolve the `ID=5472225` (step 2 of the previous paragraph). The easiest approach that comes to mind is using the SQL storage driver, that provides compatibility when it comes to migrating files from an OC10 to an OCIS backend. The queried ID already exists in the DB, and the storage driver will just pull all the info it needs to construct the URL to set in the `Location` header of the response. -Let us breakdown each section (except the obvious): +Let us breakdown each section: `/f/` = private link prefix. This is a convention. `/space/` = space name. In which storage space does the target file / folder exist. `/relative/path/` = path of the target file / folder relative to the storage space. -`?id=[...]` = combination of `storage_id` + `:` + `resource_id` +`?id=[...]` = combination of `storage_id` + `:` + `resource_id` that are gathered by the driver. With all the above data we can start building the Location response header. +Support for the following paths `MUST` occur in order to provide power uses path-base navigation using the webUI: `` + +## Manipulating the path in the URL + +Suppose a power user knows where their resources are and wants to navigate only by modifying the request in the webUI. The user goes to the browser and changes: + +`https://host/space/relative/path?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` + +to + +`https://host/space/relative/path/deeper/file/inside?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` + +Notice that the ID has not changed. Path based resolution should take precedence over ID resolution2. Now we have a `GET` request that the webUI has to adapt to the server's format: + + + ## Footnotes - 1 is this a real concern? Need read proof. +- 2 really? this needs to be discussed, but it makes sense in this context, as the IDs are not human readable. From 273ea197e8f313dd8b4c6f290d74ad8a85b17757 Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Wed, 7 Jul 2021 14:52:43 +0200 Subject: [PATCH 04/17] change ADR scope to global URL instead of private links only --- docs/ocis/adr/0009-routes.md | 86 ++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/docs/ocis/adr/0009-routes.md b/docs/ocis/adr/0009-routes.md index fe494c67d..8ae7a9a77 100644 --- a/docs/ocis/adr/0009-routes.md +++ b/docs/ocis/adr/0009-routes.md @@ -6,60 +6,62 @@ When we speak about routes we have to make a difference between browser routes a |------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------| | OC10 | `https://host/index.php/apps/files/?dir=/TEST&fileid=5472225` | `https://host/remote.php/dav/files/aunger/TEST` | | OCIS | `https://host/#/files/list/all/TEST` | `https://host/remote.php/webdav/TEST` | -| OCIS (after this ADR is implemented) | `https://host/#/space/relative/path?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` | `https://host/remote.php/webdav/space/relative/path?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` | +| OCIS (after this ADR is implemented) | `https://host/#/s//path/to/file?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` | `https://host/remote.php/webdav/space/relative/path?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` | Note that with an OC10 backend ownCloud's Web format remains unchanged: `https://host/index.html#/files/list/all/TEST` -- still resolves to --> `https://host/remote.php/webdav/TEST`. So here we have to make a distinction and limit the scope of this ADR to "how will a web client deal with the browser url?" Worth mentioning that on an OC10 backend it seems that `fileid` query parameter takes precedence over the `dir`. In fact if `dir` is invalid but `fileid` isn't, the resolution will succeed, as opposed to if the `fileid` is wrong (doesn't exist) and `dir` correct, resolution will fail altogether. -## Use private links as routes + is composed of `:` -First of, let's define what a private link is. A private link is: +## Proposed Global URL Format -> Another way to access a file or folder is via a private link. It’s a handy way of creating a permanent link for yourself or to point others to a file or folder, within a share, more efficiently. To access the private link, in the Sharing Panel for a file or folder, next to its name you’ll see a small link icon (1), as in the screenshot below. +`https:///#/s//?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` -_[source](https://doc.owncloud.com/server/user_manual/files/webgui/sharing.html#using-private-links)_ +`/s` denotes that this is a space url. -Private links are preceded by `/f/` to distinguish from `/s/` shares; this is convention. +### URL Semantics -## Private link path resolution +- The relative path and ID are optional. This URL is valid and points to the root of the space with ID = `b78c2044-5b51-446f-82f6-907a664d089`: `https://example.com/#/s/b78c2044-5b51-446f-82f6-907a664d089` +- The following case is valid and will resolve the correct folder ONLY IF the path exists within the space `https://example.com/#/s/b78c2044-5b51-446f-82f6-907a664d089/path/to/file` +- To improve in the previous example and ensure a more resilient link, adding the query string `id` of the target resource (folder or file) is encouraged to prevent always resolving even if the resource is renamed: `https://example.com/#/s/b78c2044-5b51-446f-82f6-907a664d089/path/to/file?id=ba4c1820-df12-11eb-8dcd-ff21f12c1264:beb78dd6-df12-11eb-a05c-a395505126f6` -Let's have a look at the following scenario: +With the above explained, let's see some use cases: -![img](https://i.imgur.com/hy0gSpB.jpeg) +#### Example 1: UserA shares something from her Home folder with UserB -_fig. 1_ +- open the browser and go to `ocis.com` +- the browser's url changes to: `https://ocis.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607`. You're now in YOUR home folder / personal space. +- you create a new folder `TEST` and navigate into it + - the URL now changes to: `https://ocis.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607/TEST` +- You share `TEST` with some else +- YOU navigate into `TEST` + - now the URL would look like: `https://ocis.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:3a9305da-df17-11eb-ab99-abe09d93e08a` -We observe that the private link can still remain the unchanged, this should provide functionality with existing bookmarks. In order for bookmarked private links to work, the migration from OC10 to OCIS should have taken effect, and the recommended SQL storage provider should be in use, this will allow the OCIS backend to resolve the IDs pre-migration. +As you can see, even if you're the owner of `TEST` and navigate into it, the URL changed due to a new space was created. This ensures that while working in your home folder, copying URL and giving them to the person you share the resource with the receiver can still navigate within the new space. -Let us break down every step of _fig. 1_. +In short terms, while navigating using the WebUI, the URL has to constantly change whenever we change spaces. -1. `GET https://cloud.ocis.com/index.php/f/5472225` - - all the web client has to "remember" is the ID of the resource -2. Server's response: `Status=303 Location=/marketing/path/to/file?id=storageid:resourceid` - - the server will resolve the file by ID and provide with a URL for the webUI to render of the format: `/space/relative/path?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` -3. `PROPFIND https://host/remote.php/webdav/space/path/to/file?id=storageid:resourceid` +#### Example 2: UserA shares something from a Workspace -When it comes to display the path, in order to avoid leaking parent information because the resource is shared, the rules in the following diagram `MUST` be followed: +Assuming we only have one storage provider; a consequence of this, all storage spaces will start with the same storage_id. - ![img](https://i.imgur.com/bE4xymv.png) +- open the browser and go to `ocis.com` +- the browser's url changes to: `https://ocis.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607`. You're now in YOUR home folder / personal space. +- you have access to a workspace called `foo` (created by an admin) +- navigate into workspace `foo` + - the URL now changes to: `https://ocis.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:d342f9ce-df18-11eb-b319-1b6d9df4bc74`. You are now at the root of the workspace `foo`. + - because we only have one storage provider, the `space_id` section of the URL only updates the `node_id` part of it. + - had we had more than one storage provider, the `space_id` would depend on which storage provider contains the storage space. +- you create a folder `TEST` +- you navigate into `TEST` + - now the URL would look like: `https://ocis.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:d342f9ce-df18-11eb-b319-1b6d9df4bc74/TEST` + - or a more robust url: `https://ocis.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:d342f9ce-df18-11eb-b319-1b6d9df4bc74/TEST?id=b78c2044-5b51-446f-82f6-907a664d089c:04f1991c-df19-11eb-9cc7-3b09f04f9ca3` -## On the server side +## Rules for reference resolution -Receiving a GET request to the following resource `GET https://cloud.ocis.com/index.php/f/5472225` will trigger a few hops that `MUST` be cached in order to prevent slow response times. The nature of these requests can be cached because the resources ID are not subject to changes. - -The server `MUST` have a way to resolve the `ID=5472225` (step 2 of the previous paragraph). The easiest approach that comes to mind is using the SQL storage driver, that provides compatibility when it comes to migrating files from an OC10 to an OCIS backend. The queried ID already exists in the DB, and the storage driver will just pull all the info it needs to construct the URL to set in the `Location` header of the response. - -Let us breakdown each section: - -`/f/` = private link prefix. This is a convention. -`/space/` = space name. In which storage space does the target file / folder exist. -`/relative/path/` = path of the target file / folder relative to the storage space. -`?id=[...]` = combination of `storage_id` + `:` + `resource_id` that are gathered by the driver. - -With all the above data we can start building the Location response header. - -Support for the following paths `MUST` occur in order to provide power uses path-base navigation using the webUI: `` +- if path can be resolved, then the path is used as the "locator" (instead of the id) +- if path cannot be resolved (eg. because of misspelling, folder moved, renamed etc.) then the id is used as a "locator" ## Manipulating the path in the URL @@ -71,11 +73,19 @@ to `https://host/space/relative/path/deeper/file/inside?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` -Notice that the ID has not changed. Path based resolution should take precedence over ID resolution2. Now we have a `GET` request that the webUI has to adapt to the server's format: +Notice that the ID has not changed. Path based resolution should take precedence over ID resolution. Now we have a `GET` request that the webUI has to adapt to the server's format: +## Considerations +Navigating into a folder that is the root of a space changes the url to reflect that we are now in the root of a space. -## Footnotes +## Improvements -- 1 is this a real concern? Need read proof. -- 2 really? this needs to be discussed, but it makes sense in this context, as the IDs are not human readable. +### Spaces Registry + +A big drawback against this idea is that the length of the URL is increased by a lot, rendering them almost unreadable. Introducing a Spaces Registry (SR) would shorten them. Let's see how. + +A URL without a SR would look like: `https://ocis.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:d342f9ce-df18-11eb-b319-1b6d9df4bc74/TEST?id=b78c2044-5b51-446f-82f6-907a664d089c:04f1991c-df19-11eb-9cc7-3b09f04f9ca3` +The same URL with a SR `https://ocis.com/#/s/workspaceFoo/TEST?id=b78c2044-5b51-446f-82f6-907a664d089c:04f1991c-df19-11eb-9cc7-3b09f04f9ca3` + +Space Registry resolution can happen at the client side (i.e: the client keeps a list of space name -> space id [where space id = storageid + nodeid]; the client queries a SR) or server side. Server side is more resilient due to clients can have limited networking; for instance if they are running on a tight intranet. From 83ba6ad5ba5253fbb8331ea1e0772663d36ee6fe Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Wed, 7 Jul 2021 15:03:05 +0200 Subject: [PATCH 05/17] adapt to the ADR format --- docs/ocis/adr/0009-routes.md | 40 +++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/docs/ocis/adr/0009-routes.md b/docs/ocis/adr/0009-routes.md index 8ae7a9a77..8337277c9 100644 --- a/docs/ocis/adr/0009-routes.md +++ b/docs/ocis/adr/0009-routes.md @@ -1,4 +1,16 @@ -## Problem Statement +--- +title: "9. Global URL" +date: 2021-07-07T14:55:00+01:00 +geekdocRepo: https://github.com/owncloud/ocis +geekdocEditPath: edit/master/docs/ocis/adr +geekdocFilePath: 0009-routes.md +--- + +* Status: proposed +* Deciders: @refs, @butonic, @micbar, @dragotin, @pmaier1 +* Date: 2021-07-07 + +## Context and Problem Statement When we speak about routes we have to make a difference between browser routes and internal API calls. Browser routes are interpreted by the web client (owncloud/web) to construct API calls. With this in mind, this is the mapping on ownCloud Web with OC10 and OCIS backend: @@ -14,13 +26,31 @@ Worth mentioning that on an OC10 backend it seems that `fileid` query parameter is composed of `:` +## Decision Drivers + +* Construct a URL that is not only readable by the user, but it contains all the necessary information to build a query to the backend. + +## Considered Options + +* Consistent Global URL Format + +## Decision Outcome + +Chosen option: "Consistent Global URL Format". + +### Positive Consequences + +* Backwards compatibility with existing bookmarks +* Complete visibility of the tree in the URL +* Unify user facing URL + ## Proposed Global URL Format `https:///#/s//?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` `/s` denotes that this is a space url. -### URL Semantics +## URL Semantics - The relative path and ID are optional. This URL is valid and points to the root of the space with ID = `b78c2044-5b51-446f-82f6-907a664d089`: `https://example.com/#/s/b78c2044-5b51-446f-82f6-907a664d089` - The following case is valid and will resolve the correct folder ONLY IF the path exists within the space `https://example.com/#/s/b78c2044-5b51-446f-82f6-907a664d089/path/to/file` @@ -28,7 +58,7 @@ Worth mentioning that on an OC10 backend it seems that `fileid` query parameter With the above explained, let's see some use cases: -#### Example 1: UserA shares something from her Home folder with UserB +### Example 1: UserA shares something from her Home folder with UserB - open the browser and go to `ocis.com` - the browser's url changes to: `https://ocis.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607`. You're now in YOUR home folder / personal space. @@ -42,7 +72,7 @@ As you can see, even if you're the owner of `TEST` and navigate into it, the URL In short terms, while navigating using the WebUI, the URL has to constantly change whenever we change spaces. -#### Example 2: UserA shares something from a Workspace +### Example 2: UserA shares something from a Workspace Assuming we only have one storage provider; a consequence of this, all storage spaces will start with the same storage_id. @@ -79,7 +109,7 @@ Notice that the ID has not changed. Path based resolution should take precedence Navigating into a folder that is the root of a space changes the url to reflect that we are now in the root of a space. -## Improvements +## Future Improvements ### Spaces Registry From 68d7080facb51b01bac4d043b571b5a2010a3c97 Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Wed, 7 Jul 2021 15:04:45 +0200 Subject: [PATCH 06/17] remove open tag --- docs/ocis/adr/0009-routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ocis/adr/0009-routes.md b/docs/ocis/adr/0009-routes.md index 8337277c9..ce2ac89c3 100644 --- a/docs/ocis/adr/0009-routes.md +++ b/docs/ocis/adr/0009-routes.md @@ -24,7 +24,7 @@ Note that with an OC10 backend ownCloud's Web format remains unchanged: `https:/ Worth mentioning that on an OC10 backend it seems that `fileid` query parameter takes precedence over the `dir`. In fact if `dir` is invalid but `fileid` isn't, the resolution will succeed, as opposed to if the `fileid` is wrong (doesn't exist) and `dir` correct, resolution will fail altogether. - is composed of `:` +`space_id` = `:` ## Decision Drivers From b1ab887004a844f148e911a7ddb661c7ef530531 Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Wed, 7 Jul 2021 15:06:07 +0200 Subject: [PATCH 07/17] expand positive consequences --- docs/ocis/adr/0009-routes.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/ocis/adr/0009-routes.md b/docs/ocis/adr/0009-routes.md index ce2ac89c3..9658f7bff 100644 --- a/docs/ocis/adr/0009-routes.md +++ b/docs/ocis/adr/0009-routes.md @@ -40,9 +40,10 @@ Chosen option: "Consistent Global URL Format". ### Positive Consequences -* Backwards compatibility with existing bookmarks * Complete visibility of the tree in the URL * Unify user facing URL +* Build robust URLs with IDs +* Path visible in the URL ## Proposed Global URL Format From 0a486b2a88e4857d7e2c323aab0ea1a599d7f2cb Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Wed, 7 Jul 2021 15:09:45 +0200 Subject: [PATCH 08/17] fix docs/adr --- ...008-policy-enforcement.md => 0009-policy-enforcement.md} | 4 ++-- docs/ocis/adr/{0009-routes.md => 0010-routes.md} | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) rename docs/ocis/adr/{0008-policy-enforcement.md => 0009-policy-enforcement.md} (97%) rename docs/ocis/adr/{0009-routes.md => 0010-routes.md} (98%) diff --git a/docs/ocis/adr/0008-policy-enforcement.md b/docs/ocis/adr/0009-policy-enforcement.md similarity index 97% rename from docs/ocis/adr/0008-policy-enforcement.md rename to docs/ocis/adr/0009-policy-enforcement.md index 6d14f2b14..98915102a 100644 --- a/docs/ocis/adr/0008-policy-enforcement.md +++ b/docs/ocis/adr/0009-policy-enforcement.md @@ -1,9 +1,9 @@ --- -title: "8. Extensions Policies" +title: "9. Extensions Policies" date: 2021-06-30T14:00:00+01:00 geekdocRepo: https://github.com/owncloud/ocis geekdocEditPath: edit/master/docs/ocis/adr -geekdocFilePath: 0008-policy-enforcement +geekdocFilePath: 0009-policy-enforcement.md --- * Status: proposed diff --git a/docs/ocis/adr/0009-routes.md b/docs/ocis/adr/0010-routes.md similarity index 98% rename from docs/ocis/adr/0009-routes.md rename to docs/ocis/adr/0010-routes.md index 9658f7bff..6bb0ffeb5 100644 --- a/docs/ocis/adr/0009-routes.md +++ b/docs/ocis/adr/0010-routes.md @@ -1,13 +1,13 @@ --- -title: "9. Global URL" +title: "10. Global URL" date: 2021-07-07T14:55:00+01:00 geekdocRepo: https://github.com/owncloud/ocis geekdocEditPath: edit/master/docs/ocis/adr -geekdocFilePath: 0009-routes.md +geekdocFilePath: 0010-routes.md --- * Status: proposed -* Deciders: @refs, @butonic, @micbar, @dragotin, @pmaier1 +* Deciders: @refs, @butonic, @micbar, @dragotin, @hodyroff, @pmaier1, @fschade * Date: 2021-07-07 ## Context and Problem Statement From f1f9583cb5a355c143be3125293597614aac4985 Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Wed, 7 Jul 2021 15:28:58 +0200 Subject: [PATCH 09/17] update space_id grammar --- docs/ocis/adr/0010-routes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ocis/adr/0010-routes.md b/docs/ocis/adr/0010-routes.md index 6bb0ffeb5..035607ae6 100644 --- a/docs/ocis/adr/0010-routes.md +++ b/docs/ocis/adr/0010-routes.md @@ -24,7 +24,7 @@ Note that with an OC10 backend ownCloud's Web format remains unchanged: `https:/ Worth mentioning that on an OC10 backend it seems that `fileid` query parameter takes precedence over the `dir`. In fact if `dir` is invalid but `fileid` isn't, the resolution will succeed, as opposed to if the `fileid` is wrong (doesn't exist) and `dir` correct, resolution will fail altogether. -`space_id` = `:` +`space_id` = `!` ## Decision Drivers @@ -47,7 +47,7 @@ Chosen option: "Consistent Global URL Format". ## Proposed Global URL Format -`https:///#/s//?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` +`https:///#/s//?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` `/s` denotes that this is a space url. From ffca30cc4e97ab33b128ae05417a8820e4b850ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Fri, 16 Jul 2021 20:26:35 +0000 Subject: [PATCH 10/17] fix adr numbering, add alternatives to global url format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- ...template.md => 0009-extension-template.md} | 6 +- ...orcement.md => 0010-policy-enforcement.md} | 4 +- docs/ocis/adr/0010-routes.md | 122 ---------- docs/ocis/adr/0011-global-url-format.md | 210 ++++++++++++++++++ 4 files changed, 217 insertions(+), 125 deletions(-) rename docs/ocis/adr/{0008-extension-template.md => 0009-extension-template.md} (92%) rename docs/ocis/adr/{0009-policy-enforcement.md => 0010-policy-enforcement.md} (97%) delete mode 100644 docs/ocis/adr/0010-routes.md create mode 100644 docs/ocis/adr/0011-global-url-format.md diff --git a/docs/ocis/adr/0008-extension-template.md b/docs/ocis/adr/0009-extension-template.md similarity index 92% rename from docs/ocis/adr/0008-extension-template.md rename to docs/ocis/adr/0009-extension-template.md index c783ee3a8..5dc585ef4 100644 --- a/docs/ocis/adr/0008-extension-template.md +++ b/docs/ocis/adr/0009-extension-template.md @@ -1,5 +1,9 @@ --- -title: "8. Extension Template" +title: "9. Extension Template" +date: 2021-05-03T15:00:00+01:00 +geekdocRepo: https://github.com/owncloud/ocis +geekdocEditPath: edit/master/docs/ocis/adr +geekdocFilePath: 0009-extension-template.md --- * Status: proposed diff --git a/docs/ocis/adr/0009-policy-enforcement.md b/docs/ocis/adr/0010-policy-enforcement.md similarity index 97% rename from docs/ocis/adr/0009-policy-enforcement.md rename to docs/ocis/adr/0010-policy-enforcement.md index 98915102a..35cf1c182 100644 --- a/docs/ocis/adr/0009-policy-enforcement.md +++ b/docs/ocis/adr/0010-policy-enforcement.md @@ -1,9 +1,9 @@ --- -title: "9. Extensions Policies" +title: "10. Extension Policies" date: 2021-06-30T14:00:00+01:00 geekdocRepo: https://github.com/owncloud/ocis geekdocEditPath: edit/master/docs/ocis/adr -geekdocFilePath: 0009-policy-enforcement.md +geekdocFilePath: 0010-policy-enforcement.md --- * Status: proposed diff --git a/docs/ocis/adr/0010-routes.md b/docs/ocis/adr/0010-routes.md deleted file mode 100644 index 035607ae6..000000000 --- a/docs/ocis/adr/0010-routes.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: "10. Global URL" -date: 2021-07-07T14:55:00+01:00 -geekdocRepo: https://github.com/owncloud/ocis -geekdocEditPath: edit/master/docs/ocis/adr -geekdocFilePath: 0010-routes.md ---- - -* Status: proposed -* Deciders: @refs, @butonic, @micbar, @dragotin, @hodyroff, @pmaier1, @fschade -* Date: 2021-07-07 - -## Context and Problem Statement - -When we speak about routes we have to make a difference between browser routes and internal API calls. Browser routes are interpreted by the web client (owncloud/web) to construct API calls. With this in mind, this is the mapping on ownCloud Web with OC10 and OCIS backend: - -| | Browser URL | Internal Resolution | -|------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------| -| OC10 | `https://host/index.php/apps/files/?dir=/TEST&fileid=5472225` | `https://host/remote.php/dav/files/aunger/TEST` | -| OCIS | `https://host/#/files/list/all/TEST` | `https://host/remote.php/webdav/TEST` | -| OCIS (after this ADR is implemented) | `https://host/#/s//path/to/file?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` | `https://host/remote.php/webdav/space/relative/path?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` | - -Note that with an OC10 backend ownCloud's Web format remains unchanged: `https://host/index.html#/files/list/all/TEST` -- still resolves to --> `https://host/remote.php/webdav/TEST`. So here we have to make a distinction and limit the scope of this ADR to "how will a web client deal with the browser url?" - -Worth mentioning that on an OC10 backend it seems that `fileid` query parameter takes precedence over the `dir`. In fact if `dir` is invalid but `fileid` isn't, the resolution will succeed, as opposed to if the `fileid` is wrong (doesn't exist) and `dir` correct, resolution will fail altogether. - -`space_id` = `!` - -## Decision Drivers - -* Construct a URL that is not only readable by the user, but it contains all the necessary information to build a query to the backend. - -## Considered Options - -* Consistent Global URL Format - -## Decision Outcome - -Chosen option: "Consistent Global URL Format". - -### Positive Consequences - -* Complete visibility of the tree in the URL -* Unify user facing URL -* Build robust URLs with IDs -* Path visible in the URL - -## Proposed Global URL Format - -`https:///#/s//?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` - -`/s` denotes that this is a space url. - -## URL Semantics - -- The relative path and ID are optional. This URL is valid and points to the root of the space with ID = `b78c2044-5b51-446f-82f6-907a664d089`: `https://example.com/#/s/b78c2044-5b51-446f-82f6-907a664d089` -- The following case is valid and will resolve the correct folder ONLY IF the path exists within the space `https://example.com/#/s/b78c2044-5b51-446f-82f6-907a664d089/path/to/file` -- To improve in the previous example and ensure a more resilient link, adding the query string `id` of the target resource (folder or file) is encouraged to prevent always resolving even if the resource is renamed: `https://example.com/#/s/b78c2044-5b51-446f-82f6-907a664d089/path/to/file?id=ba4c1820-df12-11eb-8dcd-ff21f12c1264:beb78dd6-df12-11eb-a05c-a395505126f6` - -With the above explained, let's see some use cases: - -### Example 1: UserA shares something from her Home folder with UserB - -- open the browser and go to `ocis.com` -- the browser's url changes to: `https://ocis.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607`. You're now in YOUR home folder / personal space. -- you create a new folder `TEST` and navigate into it - - the URL now changes to: `https://ocis.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607/TEST` -- You share `TEST` with some else -- YOU navigate into `TEST` - - now the URL would look like: `https://ocis.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:3a9305da-df17-11eb-ab99-abe09d93e08a` - -As you can see, even if you're the owner of `TEST` and navigate into it, the URL changed due to a new space was created. This ensures that while working in your home folder, copying URL and giving them to the person you share the resource with the receiver can still navigate within the new space. - -In short terms, while navigating using the WebUI, the URL has to constantly change whenever we change spaces. - -### Example 2: UserA shares something from a Workspace - -Assuming we only have one storage provider; a consequence of this, all storage spaces will start with the same storage_id. - -- open the browser and go to `ocis.com` -- the browser's url changes to: `https://ocis.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607`. You're now in YOUR home folder / personal space. -- you have access to a workspace called `foo` (created by an admin) -- navigate into workspace `foo` - - the URL now changes to: `https://ocis.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:d342f9ce-df18-11eb-b319-1b6d9df4bc74`. You are now at the root of the workspace `foo`. - - because we only have one storage provider, the `space_id` section of the URL only updates the `node_id` part of it. - - had we had more than one storage provider, the `space_id` would depend on which storage provider contains the storage space. -- you create a folder `TEST` -- you navigate into `TEST` - - now the URL would look like: `https://ocis.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:d342f9ce-df18-11eb-b319-1b6d9df4bc74/TEST` - - or a more robust url: `https://ocis.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:d342f9ce-df18-11eb-b319-1b6d9df4bc74/TEST?id=b78c2044-5b51-446f-82f6-907a664d089c:04f1991c-df19-11eb-9cc7-3b09f04f9ca3` - -## Rules for reference resolution - -- if path can be resolved, then the path is used as the "locator" (instead of the id) -- if path cannot be resolved (eg. because of misspelling, folder moved, renamed etc.) then the id is used as a "locator" - -## Manipulating the path in the URL - -Suppose a power user knows where their resources are and wants to navigate only by modifying the request in the webUI. The user goes to the browser and changes: - -`https://host/space/relative/path?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` - -to - -`https://host/space/relative/path/deeper/file/inside?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` - -Notice that the ID has not changed. Path based resolution should take precedence over ID resolution. Now we have a `GET` request that the webUI has to adapt to the server's format: - -## Considerations - -Navigating into a folder that is the root of a space changes the url to reflect that we are now in the root of a space. - -## Future Improvements - -### Spaces Registry - -A big drawback against this idea is that the length of the URL is increased by a lot, rendering them almost unreadable. Introducing a Spaces Registry (SR) would shorten them. Let's see how. - -A URL without a SR would look like: `https://ocis.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:d342f9ce-df18-11eb-b319-1b6d9df4bc74/TEST?id=b78c2044-5b51-446f-82f6-907a664d089c:04f1991c-df19-11eb-9cc7-3b09f04f9ca3` -The same URL with a SR `https://ocis.com/#/s/workspaceFoo/TEST?id=b78c2044-5b51-446f-82f6-907a664d089c:04f1991c-df19-11eb-9cc7-3b09f04f9ca3` - -Space Registry resolution can happen at the client side (i.e: the client keeps a list of space name -> space id [where space id = storageid + nodeid]; the client queries a SR) or server side. Server side is more resilient due to clients can have limited networking; for instance if they are running on a tight intranet. diff --git a/docs/ocis/adr/0011-global-url-format.md b/docs/ocis/adr/0011-global-url-format.md new file mode 100644 index 000000000..9d51b29d8 --- /dev/null +++ b/docs/ocis/adr/0011-global-url-format.md @@ -0,0 +1,210 @@ +--- +title: "11. WebUI URL format" +date: 2021-07-07T14:55:00+01:00 +geekdocRepo: https://github.com/owncloud/ocis +geekdocEditPath: edit/master/docs/ocis/adr +geekdocFilePath: 0011-global-url-format.md +--- + +* Status: proposed +* Deciders: @refs, @butonic, @micbar, @dragotin, @hodyroff, @pmaier1, @fschade +* Date: 2021-07-07 + +## Context and Problem Statement + +When we speak about routes we have to make a difference between browser routes and internal API calls. Browser routes are interpreted by the web client (owncloud/web) to construct API calls. With this in mind, this is the mapping on ownCloud Web with OC10 and OCIS backend: + +| | Browser URL | Internal Resolution | +|------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------| +| OC10 | `https://host/index.php/apps/files/?dir=/TEST&fileid=5472225` | `https://host/remote.php/dav/files/aunger/TEST` | +| OCIS | `https://host/#/files/list/all/TEST` | `https://host/remote.php/webdav/TEST` | +| OCIS (after this ADR is implemented) | `https://host/#/s//path/to/file?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` | `https://host/remote.php/webdav/space/relative/path?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` | + +Note that with an OC10 backend ownCloud's Web format remains unchanged: `https://host/index.html#/files/list/all/TEST` -- still resolves to --> `https://host/remote.php/webdav/TEST`. So here we have to make a distinction and limit the scope of this ADR to "how will a web client deal with the browser url?" + +Worth mentioning that on an OC10 backend it seems that `fileid` query parameter takes precedence over the `dir`. In fact if `dir` is invalid but `fileid` isn't, the resolution will succeed, as opposed to if the `fileid` is wrong (doesn't exist) and `dir` correct, resolution will fail altogether. + +`space_id` = `!` + +## Decision Drivers + +* To reveal relevant context to the user URLs should either carry a path component or a meaningful aliases +* To prevent bookmarks from breaking URLs should have in id component that can be used by the system to lookup the resource + +## Considered Options + +* Existing ownCloud 10 URLs +* ID based URLs +* Path based URLs +* Space based URLs +* Mixed Global URLs + +## Decision Outcome + +Chosen option: "[option 1]", because [justification. e.g., only option, which meets k.o. criterion decision driver | which resolves force force | … | comes out best (see below)]. + +### Positive Consequences + +* [e.g., improvement of quality attribute satisfaction, follow-up decisions required, …] +* … + +### Negative Consequences + +* [e.g., compromising quality attribute, follow-up decisions required, …] +* … + +## Pros and Cons of the Options + +### Existing OwnCloud 10 URLs + +The existing ownCloud 10 URLs look like this + +| URL | comment | +|-|-| +| `https:///apps/files/?dir=&fileid=` | pattern | +| `https://demo.owncloud.com/apps/files/?dir=/&fileid=18` | root of the currently logged in user | +| `https://demo.owncloud.com/index.php/apps/files/?dir=/path/to/resource&fileid=192` | sub folder `/path/to/resource` | + +It contains a path and a `fileid` (which takes precedence). + +* Good, because the `fileid` prevents bookmarks from breaking +* Good, because the `dir` reveals context in the form of a path +* Bad, because URLs still contain a long prefix `(/index.php)/apps/files` +* Bad, because the `fileid` needs to be accompanied by a `storageid` to allow efficient routing in ocis +* Bad, because if not configured properly an additional `/index.php` prefixes the route +* Bad, because powerusers cannot navigate by updating only the path in the URL, as the `fileid` takes precedence. They have to delete the `fileid` to navigate + +### ID based URLs + +MS OneDrive has URLs like this: + +| URL | comment | +|-|-| +| `https:///?id=(&cid=)` | pattern, the `cid` is optional but added automatically | +| `https://onedrive.live.com/?id=root&cid=A12345A14B0A7750` | root of a personal drive | +| `https://onedrive.live.com/?id=A12345A14B0A7750%21359&cid=C12644A14B0A7750` | sub folder in a personal drive | + +It contains only IDs but no folder names. The `fileid` is a URL encoded `!`. Very similar to the CS3 `resourceid` which consists of `storageid` and `nodeid`. + +* Good, because bookmarks cannot break +* Good, because URLs do not disclose unshared path segments +* Bad, because URLs reveal no context to users + +### Path based URLs + +There is a customized ownCluod instance that uses path only based URLs: + +| URL | comment | +|-|-| +| `https:///apps/files/?dir=/&` | root of the currently logged in user | +| `https://demo.owncloud.com/apps/files/?dir=/&` | root of the currently logged in user | +| `https://demo.owncloud.com/apps/files/?dir=/path/to/resource&` | sub folder `/path/to/resource` | + +* Good, because the URLs reveal the full path context to users +* Good, because powerusers can navigate by updating the path in the url +* Bad, because the bookmarks break when someone renames a folder in the path +* Bad, because there is no id that can be used as a fallback lookup mechanism +* Bad, because URLs might leak too much context (parent folders of shared files) + +### Space based URLs + +| URL | comment | +|-|-| +| `https:///#/s/(/)(?id=)` | the pattern, relative `path` and `resource_id` are optional | +| `https://demo.owncloud.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` | root of a storage space, might be the currently logged in users home | +| `https://demo.owncloud.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607/relative/path/to/resource` | sub folder `/relative/path/to/resource` in the storage with id `b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607`, works ***only*** if path still exists | +| `https://demo.owncloud.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607/relative/path/to/resource?id=ba4c1820-df12-11eb-8dcd-ff21f12c1264:beb78dd6-df12-11eb-a05c-a395505126f6` | sub folder `/relative/path/to/resource` in the storage with id `b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607`, lookup can fall back to the `id` | + +{{< hint >}} +* `/#` is used by the current vue router. +* `/s` denotes that this is a space url. +* `` and `` both consist of `:`, but the `space_id` can be replaced with a shorter id or an alias. See furthor down below. +* `` takes precedence over the ``, both are optional +{{< /hint >}} + +* Good, because the URLs reveal a relevant path context to users +* Good, because everything after the `#` is not sent to the server, building the webdav request to list the folder is offloaded to the clients +* Good, because powerusers can navigate by updating the path in the url +* Bad, because the current ids are uuid based, leading to very long URLs where tha path component nearly vanishes between two very long strings +* Bad, because the `#` in the URL is just a technical requirement +* Bad, because ocis web requires a `/#/files/s` at the root of the route to distinguish the files app from other apps +* Bad, while navigating using the WebUI, the URL has to be updated whenever we change spaces. + +With the above explained, let's see some use cases: + +#### Example 1: UserA shares something from her Home folder with UserB + +- open the browser and go to `demo.owncloud.com` +- the browser's url changes to: `https://demo.owncloud.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607`. You're now in YOUR home folder / personal space. +- you create a new folder `/relative/path/to/resource` and navigate into `/relative/path/to` + - the URL now changes to: `https://demo.owncloud.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607/relative/path/to` +- You share `resource` with some else +- YOU navigate into `/relative/path/to/resource` + - now the URL would look like: `https://demo.owncloud.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:3a9305da-df17-11eb-ab99-abe09d93e08a` + +As you can see, even if you're the owner of `/relative/path/to/resource` and navigate into it, the URL changes due to a new space being entered. This ensures that while working in your home folder, copying URLs and giving them to the person you share the resource with, the receiver can still navigate within the new space. + +In short terms, while navigating using the WebUI, the URL has to constantly change whenever we change spaces. + +#### Example 2: UserA shares something from a Workspace + +Assuming we only have one storage provider; a consequence of this, all storage spaces will start with the same storage_id. + +- open the browser and go to `demo.owncloud.com` +- the browser's url changes to: `https://demo.owncloud.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607`. You're now in YOUR home folder / personal space. +- you have access to a workspace called `foo` (created by an admin) +- navigate into workspace `foo` + - the URL now changes to: `https://demo.owncloud.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:d342f9ce-df18-11eb-b319-1b6d9df4bc74`. You are now at the root of the workspace `foo`. + - because we only have one storage provider, the `space_id` section of the URL only updates the `node_id` part of it. + - had we had more than one storage provider, the `space_id` would depend on which storage provider contains the storage space. +- you create a folder `/relative/path/to/resource` +- you navigate into `/relative/path/to/resource` + - now the URL would look like: `https://demo.owncloud.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:d342f9ce-df18-11eb-b319-1b6d9df4bc74/relative/path/to/resource` + - or a more robust url: `https://demo.owncloud.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:d342f9ce-df18-11eb-b319-1b6d9df4bc74/relative/path/to/resource?id=b78c2044-5b51-446f-82f6-907a664d089c:04f1991c-df19-11eb-9cc7-3b09f04f9ca3` + +#### Spaces Registry + +A big drawback against this idea is that the length of the URL is increased by a lot, rendering them almost unreadable. Introducing a Spaces Registry (SR) would shorten them. Let's see how. + +A URL without a SR would look like: `https://ocis.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:d342f9ce-df18-11eb-b319-1b6d9df4bc74/TEST?id=b78c2044-5b51-446f-82f6-907a664d089c:04f1991c-df19-11eb-9cc7-3b09f04f9ca3` +The same URL with a SR `https://ocis.com/#/s/workspaceFoo/TEST?id=b78c2044-5b51-446f-82f6-907a664d089c:04f1991c-df19-11eb-9cc7-3b09f04f9ca3` + +Space Registry resolution can happen at the client side (i.e: the client keeps a list of space name -> space id [where space id = storageid + nodeid]; the client queries a SR) or server side. Server side is more resilient due to clients can have limited networking; for instance if they are running on a tight intranet. + +### Mixed Global URLs + +While ID based space URLs can be made more readable by shortening the IDs they only start to reveal context when an alias is used instead of the space id. These aliases however have to be unique identifiers. These aliases shouly live in namespaces like `/workspaces/marketing` and `/personal/marketing` to make phishing attacks harder (in this case a user that registered with the username `marketing`). But namespaced aliases is semantically equivalent to ... a path hierarchy. + +When every space has a namespaced alias and a relative path we can build a global namespace: + +| URL | comment | +|-|-| +| `https:///files?id=` | the pattern, `/files` might become optional | +| `https://demo.owncloud.com/files/personal/einstein/?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` | root of user `einstein` | +| `https://demo.owncloud.com/files/personal/einstein/relative/path/to/resource?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21608` | sub folder `/relative/path/to/resource` | +| `https://demo.owncloud.com/files/public/kcZVYaXr7oZ66bg/relative/path/to/resource` | sub folder `/relative/path/to/resource` in public link with token `kcZVYaXr7oZ66bg` | +| `https://demo.owncloud.com/files/public/kcZVYaXr7oZ66bg/relative/path/to/resource` | sub folder `/relative/path/to/resource` in public link with token `kcZVYaXr7oZ66bg` | + +`` is the global path in the CS3 api. The CS3 Storage Registry is responsible by managing the mount points. + +In order to be able to copy and paste URLs all resources must be uniquely identifyable: + +* Instead of `/home` the URL always has to reflect the user: `/personal/einstein` +* Public links can use `/public/` +* workspaces can use `/workspaces/` or `/workspaces///` where the hierarchy is given by the organization +* experiments can use `/experiments/` +* research institutes could set up `/papers//` +* trash could be accessed by prefixing the namespace alias with `/trash`? or using `/trash/` +* instead of a namespaced alias a storage space id could be used with a generic `/space/` namespace + +The alias namespace hierarchy and depth can be pre determined by the admin. Even if aliases change the `id` parameter prevents bookmarks from breaking. A user can decide to build a different hierarchy by using his own registry. + +What about shares? Similar to `/home` it must reflect the user: `/shares/einstein` would list all shares *by* einstein for the currently logged in user. The ui needs to apply the same URL rewriting as for space based URLs: when navigating into a share the URL has to switch from `/personal/einstein/relative/path/to/shared/resource` to `/shares/einstein/`. When more than one `resource` was shared a name collision would occur. To prevent this we can use ids `/shares/einstein/id/`. As a default we could take the alias at creation time from the filename. That way two shares to a resource with the same name, eg.: `/personal/einstein/project AAA/foo` and `/personal/einstein/project BBB/foo` would lead to `/shares/einstein/foo` (a CS3 internal reference to `/personal/einstein/project AAA/foo`) and `/shares/einstein/foo (2)` (a CS3 internal reference to `/personal/einstein/project BBB/foo`). `foo (2)` would keep its name even when `foo` is deleted or renamed. Well an id as the alias might be better then, because users might rename these aliases, which would break URLs if they have been bookmarked. In any case this would make end user more aware of what they share AND it would allow them to choose an arbitrary context for the links they want to send out: personal internal share URLs. + +With these different namespaces the `/files` part in the URL becomes obsolete, because the files application can be registered for multiple namespaces: `/personal`, `/workspaces`, `/shares`, `/trash` ... + +* Good, because it contains a global path +* Good, because spaces with namespaced aliases can by bookmarked and copied into mails or chat without disclosing unshared path segments, as the space is supposed to be shared +* Good, because the UI can detect broken paths and notify the user to update his bookmark if the resource could be found by `id` +* Good, because the `/files` part might only be required for `id` only based lookup to let the web ui know which app is responsible for the route +* Good, because it turns shares into deliberately named spaces in `/shares//` From 1bb4dcf782a231415cce74309f77483f82ee4933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Mon, 19 Jul 2021 11:04:22 +0000 Subject: [PATCH 11/17] fix ordering, update context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- .../adr/0001-introduce-accounts-service.md | 1 + ...0002-persist-accounts-using-cs3-storage.md | 1 + .../ocis/adr/0003-external-user-management.md | 1 + docs/ocis/adr/0004-support-hot-migration.md | 1 + .../adr/0005-cs3-api-account-management.md | 1 + docs/ocis/adr/0006-service-discovery.md | 1 + docs/ocis/adr/0007-api-for-spaces.md | 1 + docs/ocis/adr/0008-configuration.md | 1 + docs/ocis/adr/0009-extension-template.md | 3 +- docs/ocis/adr/0010-policy-enforcement.md | 1 + docs/ocis/adr/0011-global-url-format.md | 46 ++++++++++++++----- 11 files changed, 46 insertions(+), 12 deletions(-) diff --git a/docs/ocis/adr/0001-introduce-accounts-service.md b/docs/ocis/adr/0001-introduce-accounts-service.md index 9892dbec1..aab625c9a 100644 --- a/docs/ocis/adr/0001-introduce-accounts-service.md +++ b/docs/ocis/adr/0001-introduce-accounts-service.md @@ -1,5 +1,6 @@ --- title: "1. Introduce an accounts service" +weight: 1 date: 2020-06-15T20:21:00+01:00 geekdocRepo: https://github.com/owncloud/ocis geekdocEditPath: edit/master/docs/ocis/adr diff --git a/docs/ocis/adr/0002-persist-accounts-using-cs3-storage.md b/docs/ocis/adr/0002-persist-accounts-using-cs3-storage.md index e67ffb508..7985f83d5 100644 --- a/docs/ocis/adr/0002-persist-accounts-using-cs3-storage.md +++ b/docs/ocis/adr/0002-persist-accounts-using-cs3-storage.md @@ -1,5 +1,6 @@ --- title: "2. Persist accounts in a CS3 storage" +weight: 2 date: 2020-08-21T20:21:00+01:00 geekdocRepo: https://github.com/owncloud/ocis geekdocEditPath: edit/master/docs/ocis/adr diff --git a/docs/ocis/adr/0003-external-user-management.md b/docs/ocis/adr/0003-external-user-management.md index a705b617b..dbb9fc702 100644 --- a/docs/ocis/adr/0003-external-user-management.md +++ b/docs/ocis/adr/0003-external-user-management.md @@ -1,5 +1,6 @@ --- title: "3. Use external User Management" +weight: 3 date: 2020-12-09T20:21:00+01:00 geekdocRepo: https://github.com/owncloud/ocis geekdocEditPath: edit/master/docs/ocis/adr diff --git a/docs/ocis/adr/0004-support-hot-migration.md b/docs/ocis/adr/0004-support-hot-migration.md index 141afb53d..3bb552dc2 100644 --- a/docs/ocis/adr/0004-support-hot-migration.md +++ b/docs/ocis/adr/0004-support-hot-migration.md @@ -1,5 +1,6 @@ --- title: "4. Support Hot Migration" +weight: 4 date: 2020-12-09T20:21:00+01:00 geekdocRepo: https://github.com/owncloud/ocis geekdocEditPath: edit/master/docs/ocis/adr diff --git a/docs/ocis/adr/0005-cs3-api-account-management.md b/docs/ocis/adr/0005-cs3-api-account-management.md index 1f266319d..55c8e4f17 100644 --- a/docs/ocis/adr/0005-cs3-api-account-management.md +++ b/docs/ocis/adr/0005-cs3-api-account-management.md @@ -1,5 +1,6 @@ --- title: "5. Account Management through CS3 API" +weight: 5 date: 2021-04-12T15:00:00+01:00 geekdocRepo: https://github.com/owncloud/ocis geekdocEditPath: edit/master/docs/ocis/adr diff --git a/docs/ocis/adr/0006-service-discovery.md b/docs/ocis/adr/0006-service-discovery.md index b7bf349a6..bfc077a01 100644 --- a/docs/ocis/adr/0006-service-discovery.md +++ b/docs/ocis/adr/0006-service-discovery.md @@ -1,5 +1,6 @@ --- title: "6. Service Discovery within oCIS and Reva" +weight: 6 date: 2021-04-19T13:00:00+01:00 geekdocRepo: https://github.com/owncloud/ocis geekdocEditPath: edit/master/docs/ocis/adr diff --git a/docs/ocis/adr/0007-api-for-spaces.md b/docs/ocis/adr/0007-api-for-spaces.md index 804af6ed4..0058a8bd4 100644 --- a/docs/ocis/adr/0007-api-for-spaces.md +++ b/docs/ocis/adr/0007-api-for-spaces.md @@ -1,5 +1,6 @@ --- title: "7. Open Graph API for oCIS File Spaces" +weight: 7 date: 2021-05-03T09:00:00+01:00 geekdocRepo: https://github.com/owncloud/ocis geekdocEditPath: edit/master/docs/ocis/adr diff --git a/docs/ocis/adr/0008-configuration.md b/docs/ocis/adr/0008-configuration.md index fd1a06744..6a8d748a6 100644 --- a/docs/ocis/adr/0008-configuration.md +++ b/docs/ocis/adr/0008-configuration.md @@ -1,5 +1,6 @@ --- title: "8. Configuration" +weight: 8 date: 2021-05-03T15:00:00+01:00 geekdocRepo: https://github.com/owncloud/ocis geekdocEditPath: edit/master/docs/ocis/adr diff --git a/docs/ocis/adr/0009-extension-template.md b/docs/ocis/adr/0009-extension-template.md index 5dc585ef4..05d1cc922 100644 --- a/docs/ocis/adr/0009-extension-template.md +++ b/docs/ocis/adr/0009-extension-template.md @@ -1,6 +1,7 @@ --- title: "9. Extension Template" -date: 2021-05-03T15:00:00+01:00 +weight: 9 +date: 2021-06-10T15:00:00+01:00 geekdocRepo: https://github.com/owncloud/ocis geekdocEditPath: edit/master/docs/ocis/adr geekdocFilePath: 0009-extension-template.md diff --git a/docs/ocis/adr/0010-policy-enforcement.md b/docs/ocis/adr/0010-policy-enforcement.md index 35cf1c182..ff7c17c8e 100644 --- a/docs/ocis/adr/0010-policy-enforcement.md +++ b/docs/ocis/adr/0010-policy-enforcement.md @@ -1,5 +1,6 @@ --- title: "10. Extension Policies" +weight: 10 date: 2021-06-30T14:00:00+01:00 geekdocRepo: https://github.com/owncloud/ocis geekdocEditPath: edit/master/docs/ocis/adr diff --git a/docs/ocis/adr/0011-global-url-format.md b/docs/ocis/adr/0011-global-url-format.md index 9d51b29d8..bbd1772d9 100644 --- a/docs/ocis/adr/0011-global-url-format.md +++ b/docs/ocis/adr/0011-global-url-format.md @@ -1,5 +1,6 @@ --- title: "11. WebUI URL format" +weight: 11 date: 2021-07-07T14:55:00+01:00 geekdocRepo: https://github.com/owncloud/ocis geekdocEditPath: edit/master/docs/ocis/adr @@ -12,24 +13,40 @@ geekdocFilePath: 0011-global-url-format.md ## Context and Problem Statement -When we speak about routes we have to make a difference between browser routes and internal API calls. Browser routes are interpreted by the web client (owncloud/web) to construct API calls. With this in mind, this is the mapping on ownCloud Web with OC10 and OCIS backend: +When speaking about URLs we have to make a difference between browser URLs and API URLs. Browser URLs are interpreted by the web client (owncloud/web) to make API calls. With this in mind, this is the mapping on ownCloud Web with OC10 and OCIS backend: -| | Browser URL | Internal Resolution | -|------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------| -| OC10 | `https://host/index.php/apps/files/?dir=/TEST&fileid=5472225` | `https://host/remote.php/dav/files/aunger/TEST` | -| OCIS | `https://host/#/files/list/all/TEST` | `https://host/remote.php/webdav/TEST` | -| OCIS (after this ADR is implemented) | `https://host/#/s//path/to/file?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` | `https://host/remote.php/webdav/space/relative/path?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` | +| | Browser URL | API URL | +|------|----------------------------------------------------------------|----------------------------------------------------| +| OC10 + classic WebUI | `https://demo.owncloud.com/apps/files/?dir=/path/to/resource&fileid=5472225` | `https://demo.owncloud.com/remote.php/dav/files/demo/path/to/resource` | +| OC10 + OCIS WebUI| `https://web.owncloud.com/index.html#/files/list/all/path%2Fto%2Fresource` | `https://demo.owncloud.com/remote.php/webdav/path/to/resource` | +| OCIS | `https://demo.owncloud.com/#/files/list/all/path/to/resource` | `https://demo.owncloud.com/remote.php/webdav/path/to/resource` | -Note that with an OC10 backend ownCloud's Web format remains unchanged: `https://host/index.html#/files/list/all/TEST` -- still resolves to --> `https://host/remote.php/webdav/TEST`. So here we have to make a distinction and limit the scope of this ADR to "how will a web client deal with the browser url?" -Worth mentioning that on an OC10 backend it seems that `fileid` query parameter takes precedence over the `dir`. In fact if `dir` is invalid but `fileid` isn't, the resolution will succeed, as opposed to if the `fileid` is wrong (doesn't exist) and `dir` correct, resolution will fail altogether. +On an OC10 backend the `fileid` query parameter takes precedence over the `dir`. In fact if `dir` is invalid but `fileid` isn't, the resolution will succeed, as opposed to if the `fileid` is wrong (doesn't exist) and `dir` correct, resolution will fail altogether with a 404. -`space_id` = `!` +This ADR is limited to the scope of "how will a web client deal with the browser URL?". The API URLs will change with the spaces concept to `https://demo.owncloud.com/dav/spaces//relative/path/to/resource`. The Web UI can look up a space id and the mount path using the `/graph/v1.0/drives` API: +1. TODO for a given resource id as part of the URL the `https://demo.owncloud.com/v1.0/drive/items/123456A14B0A7750!359?$select=parentReference` can be used to retrieve the drive/space: +``` +{ + "parentReference": { + "driveId": "123456a14b0a7750", + "driveType": "personal", + "id": "123456A14B0A7750!357", + "path": "/drive/root:" + } +} +``` +2. TODO to fetch the list of all spaces with their mount points we need an API endpoint that allows clients (not only the web ui) to 'sync' the list of storages a user has access to from the storage registry on the server side. This allows clients to directly talk to a storage provider on another instance, allowing true storage federation. The MS graph api has no notion of mount points, so we will need to add a `mountpath` *(or `mountpoint`? or `alias`?)* to our [`drive` resource properties in the libreGraph spec](https://github.com/owncloud/open-graph-api/blob/dc6da5359eee0345429080b5b59762fd8c57b121/api/openapi-spec/v0.0.yaml#L351-L384). + + +{{< hint >}} +@jfd: The graph api returns a `path` in the `parentReference`, which is part of the `root` in a `drive` resource. But it contains a value in the namespace of the `graph` endpoint, eg.: `/drive/root:/Bilder` for the `/Bilder` folder in the root of the currently logged in users personal drive/space. Which is again relative to the drive. To give the clients a way to determine the mount point we need to add a new `mountpath/point/alias` property. +{{< /hint >}} ## Decision Drivers -* To reveal relevant context to the user URLs should either carry a path component or a meaningful aliases -* To prevent bookmarks from breaking URLs should have in id component that can be used by the system to lookup the resource +* To reveal relevant context to the user URLs should either carry a path component or a meaningful alias +* To prevent bookmarks from breaking URLs should have an id component that can be used by the system to lookup the resource ## Considered Options @@ -69,6 +86,7 @@ It contains a path and a `fileid` (which takes precedence). * Good, because the `fileid` prevents bookmarks from breaking * Good, because the `dir` reveals context in the form of a path +* Bad, because the web UI needs to look up the space alias in a registry to build an API request for the `/dav/space` endpoint * Bad, because URLs still contain a long prefix `(/index.php)/apps/files` * Bad, because the `fileid` needs to be accompanied by a `storageid` to allow efficient routing in ocis * Bad, because if not configured properly an additional `/index.php` prefixes the route @@ -88,6 +106,7 @@ It contains only IDs but no folder names. The `fileid` is a URL encoded `!< * Good, because bookmarks cannot break * Good, because URLs do not disclose unshared path segments +* Bad, because the web UI needs to look up the space id in a registry to build an API request for the `/dav/space` endpoint * Bad, because URLs reveal no context to users ### Path based URLs @@ -102,6 +121,7 @@ There is a customized ownCluod instance that uses path only based URLs: * Good, because the URLs reveal the full path context to users * Good, because powerusers can navigate by updating the path in the url +* Bad, because the web UI needs to look up the space id in a registry to build an API request for the `/dav/space` endpoint * Bad, because the bookmarks break when someone renames a folder in the path * Bad, because there is no id that can be used as a fallback lookup mechanism * Bad, because URLs might leak too much context (parent folders of shared files) @@ -122,6 +142,7 @@ There is a customized ownCluod instance that uses path only based URLs: * `` takes precedence over the ``, both are optional {{< /hint >}} +* Good, because the web UI does not need to look up the space id in a registry to build an API request for the `/dav/space` endpoint * Good, because the URLs reveal a relevant path context to users * Good, because everything after the `#` is not sent to the server, building the webdav request to list the folder is offloaded to the clients * Good, because powerusers can navigate by updating the path in the url @@ -129,6 +150,7 @@ There is a customized ownCluod instance that uses path only based URLs: * Bad, because the `#` in the URL is just a technical requirement * Bad, because ocis web requires a `/#/files/s` at the root of the route to distinguish the files app from other apps * Bad, while navigating using the WebUI, the URL has to be updated whenever we change spaces. +* Bad, because the technical `` is meaningless to end users With the above explained, let's see some use cases: @@ -208,3 +230,5 @@ With these different namespaces the `/files` part in the URL becomes obsolete, b * Good, because the UI can detect broken paths and notify the user to update his bookmark if the resource could be found by `id` * Good, because the `/files` part might only be required for `id` only based lookup to let the web ui know which app is responsible for the route * Good, because it turns shares into deliberately named spaces in `/shares//` +* Bad, because the web UI needs to look up the space alias in a registry to build an API request for the `/dav/space` endpoint + From c0f8b030e442c5e9105c597dcc18e7cff46d40d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Mon, 19 Jul 2021 11:53:54 +0000 Subject: [PATCH 12/17] link open-graph-api issue for drive mount points MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- docs/ocis/adr/0011-global-url-format.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ocis/adr/0011-global-url-format.md b/docs/ocis/adr/0011-global-url-format.md index bbd1772d9..2b9d3f5a9 100644 --- a/docs/ocis/adr/0011-global-url-format.md +++ b/docs/ocis/adr/0011-global-url-format.md @@ -36,7 +36,7 @@ This ADR is limited to the scope of "how will a web client deal with the browser } } ``` -2. TODO to fetch the list of all spaces with their mount points we need an API endpoint that allows clients (not only the web ui) to 'sync' the list of storages a user has access to from the storage registry on the server side. This allows clients to directly talk to a storage provider on another instance, allowing true storage federation. The MS graph api has no notion of mount points, so we will need to add a `mountpath` *(or `mountpoint`? or `alias`?)* to our [`drive` resource properties in the libreGraph spec](https://github.com/owncloud/open-graph-api/blob/dc6da5359eee0345429080b5b59762fd8c57b121/api/openapi-spec/v0.0.yaml#L351-L384). +2. TODO to fetch the list of all spaces with their mount points we need an API endpoint that allows clients (not only the web ui) to 'sync' the list of storages a user has access to from the storage registry on the server side. This allows clients to directly talk to a storage provider on another instance, allowing true storage federation. The MS graph api has no notion of mount points, so we will need to add a `mountpath` *(or `mountpoint`? or `alias`?)* to our [`drive` resource properties in the libreGraph spec](https://github.com/owncloud/open-graph-api/blob/dc6da5359eee0345429080b5b59762fd8c57b121/api/openapi-spec/v0.0.yaml#L351-L384). Tracked in https://github.com/owncloud/open-graph-api/issues/6 {{< hint >}} From 02d8d744660e8ce22d5828809664d5e50b797d25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Mon, 19 Jul 2021 15:51:59 +0000 Subject: [PATCH 13/17] correct id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- docs/ocis/adr/0011-global-url-format.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ocis/adr/0011-global-url-format.md b/docs/ocis/adr/0011-global-url-format.md index 2b9d3f5a9..8931baa14 100644 --- a/docs/ocis/adr/0011-global-url-format.md +++ b/docs/ocis/adr/0011-global-url-format.md @@ -100,7 +100,7 @@ MS OneDrive has URLs like this: |-|-| | `https:///?id=(&cid=)` | pattern, the `cid` is optional but added automatically | | `https://onedrive.live.com/?id=root&cid=A12345A14B0A7750` | root of a personal drive | -| `https://onedrive.live.com/?id=A12345A14B0A7750%21359&cid=C12644A14B0A7750` | sub folder in a personal drive | +| `https://onedrive.live.com/?id=A12345A14B0A7750%21359&cid=A12345A14B0A7750` | sub folder in a personal drive | It contains only IDs but no folder names. The `fileid` is a URL encoded `!`. Very similar to the CS3 `resourceid` which consists of `storageid` and `nodeid`. From c41d9122b4454f0c00e0113879a8cb3a701717da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Mon, 19 Jul 2021 22:53:31 +0200 Subject: [PATCH 14/17] Apply suggestions from code review Co-authored-by: Alex Unger <6905948+refs@users.noreply.github.com> --- docs/ocis/adr/0011-global-url-format.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/ocis/adr/0011-global-url-format.md b/docs/ocis/adr/0011-global-url-format.md index 8931baa14..f2f8ab6de 100644 --- a/docs/ocis/adr/0011-global-url-format.md +++ b/docs/ocis/adr/0011-global-url-format.md @@ -111,7 +111,7 @@ It contains only IDs but no folder names. The `fileid` is a URL encoded `!< ### Path based URLs -There is a customized ownCluod instance that uses path only based URLs: +There is a customized ownCloud instance that uses path only based URLs: | URL | comment | |-|-| @@ -146,7 +146,7 @@ There is a customized ownCluod instance that uses path only based URLs: * Good, because the URLs reveal a relevant path context to users * Good, because everything after the `#` is not sent to the server, building the webdav request to list the folder is offloaded to the clients * Good, because powerusers can navigate by updating the path in the url -* Bad, because the current ids are uuid based, leading to very long URLs where tha path component nearly vanishes between two very long strings +* Bad, because the current ids are uuid based, leading to very long URLs where the path component nearly vanishes between two very long strings * Bad, because the `#` in the URL is just a technical requirement * Bad, because ocis web requires a `/#/files/s` at the root of the route to distinguish the files app from other apps * Bad, while navigating using the WebUI, the URL has to be updated whenever we change spaces. @@ -166,7 +166,7 @@ With the above explained, let's see some use cases: As you can see, even if you're the owner of `/relative/path/to/resource` and navigate into it, the URL changes due to a new space being entered. This ensures that while working in your home folder, copying URLs and giving them to the person you share the resource with, the receiver can still navigate within the new space. -In short terms, while navigating using the WebUI, the URL has to constantly change whenever we change spaces. +In short terms, while navigating using the WebUI, the URL has to constantly change whenever we change spaces to reflect the most explicit one. #### Example 2: UserA shares something from a Workspace @@ -195,7 +195,7 @@ Space Registry resolution can happen at the client side (i.e: the client keeps a ### Mixed Global URLs -While ID based space URLs can be made more readable by shortening the IDs they only start to reveal context when an alias is used instead of the space id. These aliases however have to be unique identifiers. These aliases shouly live in namespaces like `/workspaces/marketing` and `/personal/marketing` to make phishing attacks harder (in this case a user that registered with the username `marketing`). But namespaced aliases is semantically equivalent to ... a path hierarchy. +While ID based space URLs can be made more readable by shortening the IDs they only start to reveal context when an alias is used instead of the space id. These aliases however have to be unique identifiers. These aliases should live in namespaces like `/workspaces/marketing` and `/personal/marketing` to make phishing attacks harder (in this case a user that registered with the username `marketing`). But namespaced aliases is semantically equivalent to ... a path hierarchy. When every space has a namespaced alias and a relative path we can build a global namespace: @@ -209,7 +209,7 @@ When every space has a namespaced alias and a relative path we can build a globa `` is the global path in the CS3 api. The CS3 Storage Registry is responsible by managing the mount points. -In order to be able to copy and paste URLs all resources must be uniquely identifyable: +In order to be able to copy and paste URLs all resources must be uniquely identifiable: * Instead of `/home` the URL always has to reflect the user: `/personal/einstein` * Public links can use `/public/` @@ -231,4 +231,3 @@ With these different namespaces the `/files` part in the URL becomes obsolete, b * Good, because the `/files` part might only be required for `id` only based lookup to let the web ui know which app is responsible for the route * Good, because it turns shares into deliberately named spaces in `/shares//` * Bad, because the web UI needs to look up the space alias in a registry to build an API request for the `/dav/space` endpoint - From 8d78a64070d13badf7663b0fdecef37c3b9477cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Tue, 20 Jul 2021 13:34:09 +0000 Subject: [PATCH 15/17] cleanup configuration.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- docs/ocis/adr/0008-configuration.md | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/docs/ocis/adr/0008-configuration.md b/docs/ocis/adr/0008-configuration.md index 6a8d748a6..f6c894a55 100644 --- a/docs/ocis/adr/0008-configuration.md +++ b/docs/ocis/adr/0008-configuration.md @@ -7,38 +7,10 @@ geekdocEditPath: edit/master/docs/ocis/adr geekdocFilePath: 0008-configuration.md --- -## 5. Configuration Management for oCIS - * Status: proposed * Deciders: @refs, @butonic, @micbar, @dragotin, @pmaier1 * Date: 2021-05-03 -- [5. Configuration Management for oCIS](#5-configuration-management-for-ocis) - * [Context and Problem Statement](#context-and-problem-statement) - * [Decision Drivers](#decision-drivers) - * [Considered Options](#considered-options) - * [Decision Outcome](#decision-outcome) - + [Positive Consequences](#positive-consequences) - * [Pros and Cons of the Options](#pros-and-cons-of-the-options) - + [Extend FlagInputSourceExtension interface](#extend-flaginputsourceextension-interface) - + [Feature request: support for structured configuration (urfave/cli).](#feature-request-support-for-structured-configuration-urfavecli) - + [Clearly defined boundaries of what can and cannot be done.](#clearly-defined-boundaries-of-what-can-and-cannot-be-done) - + [Expose structured field values as CLI flags](#expose-structured-field-values-as-cli-flags) - + [Drop support for structure configuration](#drop-support-for-structure-configuration) - + [Adapt the "structured config files have the highest priority" within oCIS](#adapt-the-structured-config-files-have-the-highest-priority-within-ocis) - * [Notes](#notes) - + [Use Cases and Expected Behaviors](#use-cases-and-expected-behaviors) - - [Supervised (`ocis server` or `ocis run extension`)](#supervised-ocis-server-or-ocis-run-extension) - * [Known Gotchas](#known-gotchas) - - [Unsupervised (`ocis proxy`)](#unsupervised-ocis-proxy) - + [Other known use cases](#other-known-use-cases) - + [Use Cases for Development](#use-cases-for-development) - + [Config Loading](#config-loading) - + [Start an extension multiple times with different configs (in Supervised mode)](#start-an-extension-multiple-times-with-different-configs-in-supervised-mode) - + [Developing Considered Alternatives Further](#developing-considered-alternatives-further) - + [Follow up PR's](#follow-up-prs) - + [State of the Art](#state-of-the-art) - ## Context and Problem Statement As per urfave/cli's doc: From 3ae2875fa9eaf608341f75b4cb8eda99774c964e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Tue, 20 Jul 2021 15:30:26 +0000 Subject: [PATCH 16/17] add configurable path component option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- docs/ocis/adr/0011-global-url-format.md | 88 ++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 3 deletions(-) diff --git a/docs/ocis/adr/0011-global-url-format.md b/docs/ocis/adr/0011-global-url-format.md index f2f8ab6de..d9e540a97 100644 --- a/docs/ocis/adr/0011-global-url-format.md +++ b/docs/ocis/adr/0011-global-url-format.md @@ -8,12 +8,50 @@ geekdocFilePath: 0011-global-url-format.md --- * Status: proposed -* Deciders: @refs, @butonic, @micbar, @dragotin, @hodyroff, @pmaier1, @fschade +* Deciders: @refs, @butonic, @micbar, @dragotin, @hodyroff, @pmaier1, @fschade, @tbsbdr, @kulmann * Date: 2021-07-07 ## Context and Problem Statement -When speaking about URLs we have to make a difference between browser URLs and API URLs. Browser URLs are interpreted by the web client (owncloud/web) to make API calls. With this in mind, this is the mapping on ownCloud Web with OC10 and OCIS backend: +When speaking about URLs we have to make a difference between browser URLs and API URLs. Only browser URLs are visible to end users and will be bookmarked. The currently existing and bookmarked ownCloud 10 URLs look something like this: + +``` +GET https://demo.owncloud.com/apps/files/?dir=/path/to/resource&fileid=5472225 +303 Location: https://demo.owncloud.com/apps/files/?dir=/path/to/resource +``` + +When the URL contains a `fileid` parameter the server will look up the corresponding `dir`, overwriting whatever was set before the redirect. The `fileid` always takes precedence and the server is responsible for the lookup. + +``` +GET https://demo.owncloud.com/apps/files/?dir=/path/to/resource +``` + +The `dir` parameter is then used to make a WebDAV request against the `/dav/files` endpoint of the currently logged in user: + +``` +PROPFIND https://demo.owncloud.com/remote.php/dav/files/demo/path/to/resource +``` + +The resulting PROPFIND response is used to render the file listing. All good so far. + +For the new ocis web UI we want to clean up the user visible Browser URLs. They currently look like this: + +``` +https://demo.owncloud.com/#/files/list/all/path/to/resource +``` + +Currently, there is no `fileid` like parameter in the browser URL, making bookmarks of it fragile (they break when a bookmarked folder is renamed). + +The oCIS web UI just takes the path and uses the `/webdav` endpoint of the currently logged in user: + +``` +PROPFIND https://demo.owncloud.com/remote.php/webdav/path/to/resource +``` + + +With the new ownCloud web client (owncloud/web) + + needs to interpret them to make API calls. With this in mind, this is the current mapping on ownCloud Web with OC10 and OCIS backend: | | Browser URL | API URL | |------|----------------------------------------------------------------|----------------------------------------------------| @@ -55,6 +93,7 @@ This ADR is limited to the scope of "how will a web client deal with the browser * Path based URLs * Space based URLs * Mixed Global URLs +* Configurable path component in URLs ## Decision Outcome @@ -161,7 +200,7 @@ With the above explained, let's see some use cases: - you create a new folder `/relative/path/to/resource` and navigate into `/relative/path/to` - the URL now changes to: `https://demo.owncloud.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607/relative/path/to` - You share `resource` with some else -- YOU navigate into `/relative/path/to/resource` +- You navigate into `/relative/path/to/resource` - now the URL would look like: `https://demo.owncloud.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:3a9305da-df17-11eb-ab99-abe09d93e08a` As you can see, even if you're the owner of `/relative/path/to/resource` and navigate into it, the URL changes due to a new space being entered. This ensures that while working in your home folder, copying URLs and giving them to the person you share the resource with, the receiver can still navigate within the new space. @@ -204,8 +243,12 @@ When every space has a namespaced alias and a relative path we can build a globa | `https:///files?id=` | the pattern, `/files` might become optional | | `https://demo.owncloud.com/files/personal/einstein/?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` | root of user `einstein` | | `https://demo.owncloud.com/files/personal/einstein/relative/path/to/resource?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21608` | sub folder `/relative/path/to/resource` | +| `https://demo.owncloud.com/files/shares/einstein/somesharename?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21608` | shared URL for `/relative/path/to/resource` | | `https://demo.owncloud.com/files/public/kcZVYaXr7oZ66bg/relative/path/to/resource` | sub folder `/relative/path/to/resource` in public link with token `kcZVYaXr7oZ66bg` | | `https://demo.owncloud.com/files/public/kcZVYaXr7oZ66bg/relative/path/to/resource` | sub folder `/relative/path/to/resource` in public link with token `kcZVYaXr7oZ66bg` | +| `https://demo.owncloud.com/files/personal/einstein/marie is stupid/and richard as well/resource?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21608` | sub folder `marie is stupid/and richard as well/resource` ... something einstein might not want to reveal | +| `https://demo.owncloud.com/files/shares/einstein/resource (2)?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21608` | named link URL for `/marie is stupid/and richard as well/resource`, does not disclose the actual hierarchy, has an appended counter to avaid a collision | +| `https://demo.owncloud.com/files/shares/einstein/mybestfriends?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21608` | named link URL for `/marie is stupid/and richard as well/resource`, does not disclose the actual hierarchy, has a custom alias for the share | `` is the global path in the CS3 api. The CS3 Storage Registry is responsible by managing the mount points. @@ -231,3 +274,42 @@ With these different namespaces the `/files` part in the URL becomes obsolete, b * Good, because the `/files` part might only be required for `id` only based lookup to let the web ui know which app is responsible for the route * Good, because it turns shares into deliberately named spaces in `/shares//` * Bad, because the web UI needs to look up the space alias in a registry to build an API request for the `/dav/space` endpoint + + +### Configurable path component in URLs + +Not every deployment may have the requirement to have the path in the URL. We could use id only based URLs, similar to onedrive and make showing paths configurable. + + +| URL | comment | +|-|-| +| `https:///files?id=` | default id based navigation | +| `https:///files?id=` | optional path based navigation with fallback to id | + +In contrast to ownCloud 10 path takes precedence and the user is warned when the fileid in his bookmark no longer matches the id on the server: sth. like "The path of the resource has changed, please verify and update your bookmark!" + +When a file is selected the filename also becomes part of the URL so individual files can be bookmarked. + +If navigation is id based we need to look up the path for the id so we can make a webdav request, or we need to implement the graph drives and driveItem resources. + +The URL `https:///files?id=̀` is sent to the server. It has to look up the correct path and redirect the request, including the the path. But that would make all bookmarks contain tha path again, even if paths were configured to not be part of the URL. + +The `/meta/` webdav endpoint can be used to look up the path with property `meta-path-for-user`. + +For now, we would use path based navigation with URLs like this: + +``` +https:///files?id= +``` + +This means that only the _resource path_ is part of the URL path. Any other parameter, eg. file `id`, `page` or sort order must be given as URL parameters. + +- [ ] To make lookup by id possible we need to implement the `/meta/` endpoint so the sdk can use it to look up the path. We should not implement a redirect on the ocis server side because the same redirect logic would need to be added to oc10. Having it in ocis web is the right place. + +- [ ] The old sharing links and oc10 urls still need to be redirected by ocis/reva as in oc10. + +Public links would have the same format: `https:///files?id=` The web UI has to detect if the user is logged in or not and adjust the ui accordingly. + +{{< hint warning >}} +Since there is no difference between public and private files a logged in user cannot see the public version of a link unless he logs out. +{{< /hint >}} \ No newline at end of file From 2bc7657cd2af2aa2088bc3354aa56a41a9a15c8a Mon Sep 17 00:00:00 2001 From: Michael Barz Date: Tue, 27 Jul 2021 11:42:15 +0200 Subject: [PATCH 17/17] add short urls to the proposal --- docs/ocis/adr/0011-global-url-format.md | 40 ++++++++++++++----------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/docs/ocis/adr/0011-global-url-format.md b/docs/ocis/adr/0011-global-url-format.md index d9e540a97..54b93eb6a 100644 --- a/docs/ocis/adr/0011-global-url-format.md +++ b/docs/ocis/adr/0011-global-url-format.md @@ -116,12 +116,12 @@ Chosen option: "[option 1]", because [justification. e.g., only option, which me The existing ownCloud 10 URLs look like this | URL | comment | -|-|-| +|-----|---------| | `https:///apps/files/?dir=&fileid=` | pattern | | `https://demo.owncloud.com/apps/files/?dir=/&fileid=18` | root of the currently logged in user | | `https://demo.owncloud.com/index.php/apps/files/?dir=/path/to/resource&fileid=192` | sub folder `/path/to/resource` | -It contains a path and a `fileid` (which takes precedence). +It contains a path and a `fileid` (which takes precedence). * Good, because the `fileid` prevents bookmarks from breaking * Good, because the `dir` reveals context in the form of a path @@ -136,7 +136,7 @@ It contains a path and a `fileid` (which takes precedence). MS OneDrive has URLs like this: | URL | comment | -|-|-| +|-----|---------| | `https:///?id=(&cid=)` | pattern, the `cid` is optional but added automatically | | `https://onedrive.live.com/?id=root&cid=A12345A14B0A7750` | root of a personal drive | | `https://onedrive.live.com/?id=A12345A14B0A7750%21359&cid=A12345A14B0A7750` | sub folder in a personal drive | @@ -153,7 +153,7 @@ It contains only IDs but no folder names. The `fileid` is a URL encoded `!< There is a customized ownCloud instance that uses path only based URLs: | URL | comment | -|-|-| +|-----|---------| | `https:///apps/files/?dir=/&` | root of the currently logged in user | | `https://demo.owncloud.com/apps/files/?dir=/&` | root of the currently logged in user | | `https://demo.owncloud.com/apps/files/?dir=/path/to/resource&` | sub folder `/path/to/resource` | @@ -168,7 +168,7 @@ There is a customized ownCloud instance that uses path only based URLs: ### Space based URLs | URL | comment | -|-|-| +|-----|---------| | `https:///#/s/(/)(?id=)` | the pattern, relative `path` and `resource_id` are optional | | `https://demo.owncloud.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` | root of a storage space, might be the currently logged in users home | | `https://demo.owncloud.com/#/s/b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607/relative/path/to/resource` | sub folder `/relative/path/to/resource` in the storage with id `b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607`, works ***only*** if path still exists | @@ -239,32 +239,35 @@ While ID based space URLs can be made more readable by shortening the IDs they o When every space has a namespaced alias and a relative path we can build a global namespace: | URL | comment | -|-|-| +|-----|---------| | `https:///files?id=` | the pattern, `/files` might become optional | | `https://demo.owncloud.com/files/personal/einstein/?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21607` | root of user `einstein` | | `https://demo.owncloud.com/files/personal/einstein/relative/path/to/resource?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21608` | sub folder `/relative/path/to/resource` | | `https://demo.owncloud.com/files/shares/einstein/somesharename?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21608` | shared URL for `/relative/path/to/resource` | -| `https://demo.owncloud.com/files/public/kcZVYaXr7oZ66bg/relative/path/to/resource` | sub folder `/relative/path/to/resource` in public link with token `kcZVYaXr7oZ66bg` | -| `https://demo.owncloud.com/files/public/kcZVYaXr7oZ66bg/relative/path/to/resource` | sub folder `/relative/path/to/resource` in public link with token `kcZVYaXr7oZ66bg` | | `https://demo.owncloud.com/files/personal/einstein/marie is stupid/and richard as well/resource?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21608` | sub folder `marie is stupid/and richard as well/resource` ... something einstein might not want to reveal | | `https://demo.owncloud.com/files/shares/einstein/resource (2)?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21608` | named link URL for `/marie is stupid/and richard as well/resource`, does not disclose the actual hierarchy, has an appended counter to avaid a collision | | `https://demo.owncloud.com/files/shares/einstein/mybestfriends?id=b78c2044-5b51-446f-82f6-907a664d089c:194b4a97-597c-4461-ab56-afd4f5a21608` | named link URL for `/marie is stupid/and richard as well/resource`, does not disclose the actual hierarchy, has a custom alias for the share | +| `https://demo.owncloud.com/files/public/kcZVYaXr7oZ66bg/relative/path/to/resource` | sub folder `/relative/path/to/resource` in public link with token `kcZVYaXr7oZ66bg` | +| `https://demo.owncloud.com/files/public/kcZVYaXr7oZ66bg/relative/path/to/resource` | sub folder `/relative/path/to/resource` in public link with token `kcZVYaXr7oZ66bg` | +| `https://demo.owncloud.com/s/kcZVYaXr7oZ66bg/` | shortened link to a resource. This is needed to be able to copy a link to a resource whithout leaking any metadata. | + `` is the global path in the CS3 api. The CS3 Storage Registry is responsible by managing the mount points. In order to be able to copy and paste URLs all resources must be uniquely identifiable: * Instead of `/home` the URL always has to reflect the user: `/personal/einstein` -* Public links can use `/public/` -* workspaces can use `/workspaces/` or `/workspaces///` where the hierarchy is given by the organization -* experiments can use `/experiments/` -* research institutes could set up `/papers//` -* trash could be accessed by prefixing the namespace alias with `/trash`? or using `/trash/` -* instead of a namespaced alias a storage space id could be used with a generic `/space/` namespace +* Workspaces can use `/workspaces/` or `/workspaces///` where the hierarchy is given by the organization +* Experiments can use `/experiments/` +* Research institutes could set up `/papers//` +* Trash could be accessed by prefixing the namespace alias with `/trash`? or using `/trash/` +* Instead of a namespaced alias a storage space id could be used with a generic `/space/` namespace +* An url shortener can create urls like `/s/` which could be used as a stable link to a resource. +* Links for anonymous users will resolve to `/public/` -The alias namespace hierarchy and depth can be pre determined by the admin. Even if aliases change the `id` parameter prevents bookmarks from breaking. A user can decide to build a different hierarchy by using his own registry. +The alias namespace hierarchy and depth can be pre determined by the admin. Even if aliases change the `id` parameter prevents bookmarks from breaking. A user can decide to build a different hierarchy by using his own registry. -What about shares? Similar to `/home` it must reflect the user: `/shares/einstein` would list all shares *by* einstein for the currently logged in user. The ui needs to apply the same URL rewriting as for space based URLs: when navigating into a share the URL has to switch from `/personal/einstein/relative/path/to/shared/resource` to `/shares/einstein/`. When more than one `resource` was shared a name collision would occur. To prevent this we can use ids `/shares/einstein/id/`. As a default we could take the alias at creation time from the filename. That way two shares to a resource with the same name, eg.: `/personal/einstein/project AAA/foo` and `/personal/einstein/project BBB/foo` would lead to `/shares/einstein/foo` (a CS3 internal reference to `/personal/einstein/project AAA/foo`) and `/shares/einstein/foo (2)` (a CS3 internal reference to `/personal/einstein/project BBB/foo`). `foo (2)` would keep its name even when `foo` is deleted or renamed. Well an id as the alias might be better then, because users might rename these aliases, which would break URLs if they have been bookmarked. In any case this would make end user more aware of what they share AND it would allow them to choose an arbitrary context for the links they want to send out: personal internal share URLs. +What about shares? Similar to `/home` it must reflect the user: `/shares/einstein` would list all shares *by* einstein for the currently logged in user. The ui needs to apply the same URL rewriting as for space based URLs: when navigating into a share the URL has to switch from `/personal/einstein/relative/path/to/shared/resource` to `/shares/einstein/`. When more than one `resource` was shared a name collision would occur. To prevent this we can use ids `/shares/einstein/id/`. As a default we could take the alias at creation time from the filename. That way two shares to a resource with the same name, eg.: `/personal/einstein/project AAA/foo` and `/personal/einstein/project BBB/foo` would lead to `/shares/einstein/foo` (a CS3 internal reference to `/personal/einstein/project AAA/foo`) and `/shares/einstein/foo (2)` (a CS3 internal reference to `/personal/einstein/project BBB/foo`). `foo (2)` would keep its name even when `foo` is deleted or renamed. Well an id as the alias might be better then, because users might rename these aliases, which would break URLs if they have been bookmarked. In any case this would make end user more aware of what they share AND it would allow them to choose an arbitrary context for the links they want to send out: personal internal share URLs. With these different namespaces the `/files` part in the URL becomes obsolete, because the files application can be registered for multiple namespaces: `/personal`, `/workspaces`, `/shares`, `/trash` ... @@ -273,6 +276,7 @@ With these different namespaces the `/files` part in the URL becomes obsolete, b * Good, because the UI can detect broken paths and notify the user to update his bookmark if the resource could be found by `id` * Good, because the `/files` part might only be required for `id` only based lookup to let the web ui know which app is responsible for the route * Good, because it turns shares into deliberately named spaces in `/shares//` +* Good, because all urls can be shortened to hide any metadata like path, resource name and query parameters * Bad, because the web UI needs to look up the space alias in a registry to build an API request for the `/dav/space` endpoint @@ -282,7 +286,7 @@ Not every deployment may have the requirement to have the path in the URL. We co | URL | comment | -|-|-| +|-----|---------| | `https:///files?id=` | default id based navigation | | `https:///files?id=` | optional path based navigation with fallback to id | @@ -312,4 +316,4 @@ Public links would have the same format: `https:///files?id=` {{< hint warning >}} Since there is no difference between public and private files a logged in user cannot see the public version of a link unless he logs out. -{{< /hint >}} \ No newline at end of file +{{< /hint >}}