Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes to appregistry and the HTTP appprovider service #1923

Open
ishank011 opened this issue Jul 26, 2021 · 16 comments
Open

Changes to appregistry and the HTTP appprovider service #1923

ishank011 opened this issue Jul 26, 2021 · 16 comments
Assignees

Comments

@ishank011
Copy link
Contributor

To keep track of the changes left from #1785:

  • The token expiration time should not be a configurable parameter. Figure out a way to pass that to the HTTP layer without having to dismantle it
  • Coordinate with the web team to pass the view mode as a parameter to the GET call
  • Add the option to restrict view modes in apps itself
@ishank011 ishank011 self-assigned this Jul 26, 2021
@ishank011
Copy link
Contributor Author

ishank011 commented Aug 3, 2021

The changes to be made after the discussion today:

  1. Need to add a new endpoint to the HTTP service which would return all the supported mime types along with the apps that they can be opened with. This would utilize the newly added ListSupportedMimeTypes CS3APIs call. The response would look like:
{
    "mime-types": [
        "text/markdown": [{app_name: "Codimd"}],
        "application/vnd.oasis.opendocument.text": [{app_name: "Collabora"}, {app_name: "OnlyOffice"}, {app_name: "MS Office"}],
        "application/vnd.oasis.opendocument.spreadsheet": [{app_name: "Collabora"}, {app_name: "OnlyOffice"}, {app_name: "MS Office"}],
        ...
    ]
}

Note that we're returning the mime types here instead of the extension because we can add custom types in reva itself and the clients don't need to know about those. Related owncloud/web#5135

We can also return other stuff such as the link to a static asset representing the icon corresponding to the app. Some apps might want to execute some action (eg, via a JS script) so we need to see how those can be passed, but that can be decided later.

  1. The open HTTP endpoint in reva needs to return app-specific (but agnostic to the app provider service) headers and form parameters which would be utilized by web to call the app URL. The main motive is to avoid passing these in the URL which can otherwise expose access tokens following the WOPI specs. After doing a requirement analysis of which apps we're planning on supporting, this payload seems to handle almost all such cases. @wkloucek can you add here your notes about what parameters each app expects?
    The open request would have the following parameters
    • file_id
    • app_name (optional; if missing, the default app is used; if default is not set, the first app in the list is used)
    • view_mode (optional; if missing, we'll use the max permissions the user has on the resource)

To help web identify how the call has to be made to the app, an extra parameter method will be added. For example, two responses can look like:

{
    "app-url": "collabora.owncloud.com/loleaflet/u-u-i-d/loleaflet.html?src=...",
    "method": "POST",
    "form-parameters": {
        "access-token": "reva-token",
        "access-token-ttl": "when-reva-token-expires"
    }
}

{
    "app-url": "jupyterlabs.owncloud.com/src=...",
    "method": "GET",
    "headers": {
        "user-language": "en",
        "user-session-id": 1234
    }
}
  1. The response from WOPI would also be in the form of a JSON object instead of the current way of encoding all parameters in the URI. cc @glpatcern

  2. Based on the permissions and mime-type obtained from the PROPFIND response, web will display the possible actions for each file. Currently, we don't have user-specific or group-specific information or user-defaults so all users and all storages have access to all allowed apps, but this will be the next step to be added. cc @wkloucek

  3. We need to come up with a design to display all the specific actions in web. For example, for a word file, we have 3 apps x 3 view modes. Displaying 9 actions in the drop-down menu doesn't really make up a good UX. @kulmann @pascalwengerter @fschade

Please add any other points that I might have missed @labkode @wkloucek @glpatcern

@glpatcern
Copy link
Member

glpatcern commented Aug 3, 2021

Thanks Ishank for the nice summary. Following your list:

  1. I'll create a PR in the wopiserver, I expect we could provide a response to /wopi/iop/openinapp that fully matches the GRPC or HTTP AppProviderResponse, such as:
{
  "app-url" : "collabora.owncloud.com/...?WOPISrc=...",
  "form-parameters" : { "access_token" : "xyz", "access_token_ttl": 123 }
}

(Side-note: who decides the method? shall we rather assume that if form-parameters are empty then method = GET, else POST?)

  1. Just to report my comment: to simplify the UI, in first approximation for the Word case (3x3 actions) one could show a single View action (opens in the default app with READ_ONLY as viewMode) plus the 3 Open with <appname> actions (all in edit mode).

@ishank011
Copy link
Contributor Author

@glpatcern I think the token dismantling should happen in the driver, since the TTL would be decided by the reva token. Maybe wopiserver can just return the token itself.

(Side-note: who decides the method? shall we rather assume that if form-parameters are empty then method = GET, else POST?)

I think this should also be passed from the driver. That way we have a complete URL object being returned as part of the CS3APIs call (URL, form, headers, method). What do you think?

Just to report my comment: to simplify the UI, in first approximation for the Word case (3x3 actions) one could show a single View action (opens in the default app with READ_ONLY as viewMode) plus the 3 Open with actions (all in edit mode).

+1

@ishank011
Copy link
Contributor Author

ishank011 commented Aug 3, 2021

For the listing endpoint at /app/list/, we have

$ curl -v -k -X GET 'http://localhost:19001/app/list' | jq
{
  "mime_types": {
    "application/msword": {
      "app_provider_names": [
        "Collabora",
        "Microsoft Office 365"
      ]
    },
    "application/octet-stream": {
      "app_provider_names": [
        "Collabora",
        "Microsoft Office 365"
      ]
    },
    "application/pdf": {
      "app_provider_names": [
        "Microsoft Office 365"
      ]
    },
    "application/rtf": {
      "app_provider_names": [
        "Collabora",
        "Microsoft Office 365"
      ]
    },
    ...
  }
}

We can expand this so instead of just the names, we return the whole provider struct which could have the icon URI, description and so on.

@glpatcern
Copy link
Member

@glpatcern I think the token dismantling should happen in the driver, since the TTL would be decided by the reva token. Maybe wopiserver can just return the token itself.

You're absolutely right, my mistake. The wopiserver will definitely not dismantle the Reva token and will only return { "access_token" : "xyz"} - which is on its own not to be dismantled by Reva, so responsibilities stay separated.

I think this should also be passed from the driver. That way we have a complete URL object being returned as part of the CS3APIs call (URL, form, headers, method). What do you think?

Why not, but then if we want the driver to decide the method it could do so based on a config parameter, or on some kind of defaults. E.g. the wopi driver could default to POST (assuming all WOPI apps support it), the swan driver could default to GET, etc.

@wkloucek
Copy link
Contributor

wkloucek commented Aug 4, 2021

After doing a requirement analysis of which apps we're planning on supporting, this payload seems to handle almost all such cases. @wkloucek can you add here your notes about what parameters each app expects?

  • Collabora / MS Office Online (WOPI)
    • WOPIsrc
    • access_token
    • access_token_ttl (valid until -> unix timestamp milliseconds)
    • there are more parameters which could be used in the future and are already used by oC10: language, revisionhistory, title, closebutton
  • CodiMD ( (WOPI Bridge)
    • docid
    • userName
    • metadata
    • t (access token)
  • Etherpad (WOPI Bridge)
    • docid
    • metadata
    • t (access token)
    • apiKey
    • displayName
  • Only Office
    • filetype
    • key
    • title
    • url
    • document type
  • Jupyter / SWAN
    • ?

@wkloucek
Copy link
Contributor

wkloucek commented Aug 4, 2021

I also had a discussion with my colleagues and they added following feedback:

  • we could introduce some scope for the ListSupportedMimeTypes dependent on which client is requesting the list. Usecase: oC Desktop client / iOS app / Android app should also use this endpoint and display the file actions like oC Web will be doing it. Except that you may to omit some actions on some clients, eg. do not offer to open a document in Collabora on the Android app.
  • we are missing a view-only grant in the ResourcePermissions which allows the user to view a file (eg. in Collabora with a watermark) but not to download the file, which is already cared of in the OpenInAppRequest

@labkode
Copy link
Member

labkode commented Aug 5, 2021

@wkloucek I'll be discussing with @butonic today about a way to have finer controls for sharing permissions and I can fold in this requirement for view-only mode.

@glpatcern
Copy link
Member

I concur we need a view-only "value" in the set of permissions, and I started to do some some work in this direction in the context of the deny permission implementation. Let's review what we have.

@ishank011
Copy link
Contributor Author

we could introduce some scope for the ListSupportedMimeTypes dependent on which client is requesting the list.

I think we can add this filtering to the HTTP service instead of CS3APIs as it doesn't really fit there.

@ishank011
Copy link
Contributor Author

HTTP response for Collabora, which supports POST

» curl -v -k -X POST 'http://localhost:19001/app/open?file_id=MTIzZTQ1NjctZTg5Yi0xMmQzLWE0NTYtNDI2NjU1NDQwMDAwOmZpbGVpZC1laW5zdGVpbiUyRnNhbXBsZS5kb2M=&view_mode=write&app_name=Collabora' -u einstein:relativity | jq

* Server auth using Basic with user 'einstein'
> POST /app/open?file_id=MTIzZTQ1NjctZTg5Yi0xMmQzLWE0NTYtNDI2NjU1NDQwMDAwOmZpbGVpZC1laW5zdGVpbiUyRnNhbXBsZS5kb2M=&view_mode=write&app_name=Collabora HTTP/1.1
> Authorization: Basic ZWluc3RlaW46cmVsYXRpdml0eQ==
> User-Agent: curl/7.29.0
> Host: localhost:19001
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Vary: Origin
< Date: Tue, 10 Aug 2021 14:43:19 GMT
< Content-Length: 1842
<
{
  "app_url": "https://collabora-online.cern.ch/byoa/collabora/loleaflet/78239aa/loleaflet.html?&WOPISrc=https%3A%2F%2Fcbox-wopiocis-01.cern.ch%3A8443%2Fwopi%2Ffiles%2F123e4567-e89b-12d3-a456-426655440000-ZmlsZWlkLWVpbnN0ZWluJTJGc2FtcGxlLmRvYw%3D%3D",
  "method": "POST",
  "form_parameters": {
    "access_token": "eyJ0eXAiOiJKV1QiLC...",
    "access_token_ttl": "1628693306"
  }
}

Response for CodiMD, which doesn't

» curl -v -k -X POST 'http://localhost:19001/app/open?file_id=MTIzZTQ1NjctZTg5Yi0xMmQzLWE0NTYtNDI2NjU1NDQwMDAwOmZpbGVpZC1laW5zdGVpbiUyRmEubWQ=&view_mode=write&app_name=CodiMD' -u einstein:relativity | jq

* Server auth using Basic with user 'einstein'
> POST /app/open?file_id=MTIzZTQ1NjctZTg5Yi0xMmQzLWE0NTYtNDI2NjU1NDQwMDAwOmZpbGVpZC1laW5zdGVpbiUyRmEubWQ=&view_mode=write&app_name=CodiMD HTTP/1.1
> Authorization: Basic ZWluc3RlaW46cmVsYXRpdml0eQ==
> User-Agent: curl/7.29.0
> Host: localhost:19001
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Vary: Origin
< Date: Tue, 10 Aug 2021 14:41:28 GMT
< Content-Length: 1824
<
{
  "app_url": "https://qa.cernbox.cern.ch/byoa/codimd/GkG6Q6WLEd4GeGc7fm7EQlQ31H8?metadata=https%3A%2F%2Fcbox-wopiocis-01.cern.ch%3A8443%2Fwopi%2Ffiles%2F123e4567-e89b-12d3-a456-426655440000-ZmlsZWlkLWVpbnN0ZWluJTJGYS5tZA%3D%3D%3Ft%3DeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2Vya...&apiKey=testsecret&displayName=einstein",
  "method": "GET"
}

@ishank011
Copy link
Contributor Author

Wopiserver changes by @glpatcern: cs3org/wopiserver#43

@wkloucek
Copy link
Contributor

wkloucek commented Aug 13, 2021

One thing we didn't talk about is what we should display in the New file dialog:
image

Technically we just have the mimetypes (see #1923 (comment)) available, but these are not really user friendly (eg. create new application/vnd.oasis.opendocument.text doesn't come in handy for non technical people).

Do you have any ideas? Maybe add a human friendly file name to the mimetype? (I see L10N challenges incoming....)

cc @kulmann @fschade

@labkode
Copy link
Member

labkode commented Aug 16, 2021

@wkloucek maybe we can expand the mapping of mimetypes with a new field "display name" that is more user friendly?

@wkloucek
Copy link
Contributor

@wkloucek maybe we can expand the mapping of mimetypes with a new field "display name" that is more user friendly?

there is PR on that in the CSapis: https://github.com/cs3org/cs3apis/pull/145/files. Will have a look next week

@glpatcern
Copy link
Member

Yep, I just created that PR for this use case indeed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants