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

Added support for Jottacloud cli token #7

Merged
merged 2 commits into from
Jun 12, 2022

Conversation

albertony
Copy link
Contributor

@albertony albertony commented Mar 29, 2022

Jottacloud used to support basic username/password authentication, but this was recently discontinued, while re-enabled for a limited time until June 1st 2022 after request from Duplicati users.

The new authentication in Jottacloud is based on OAuth and OpenID Connect. It does not use regular OAuth workflow, with redirect to login with callback etc. Instead, users have to manually log in to the official web gui and generate what they call a "Personal Login token" ("Generate a personal login token to log in to the Jottacloud Command-Line Tool"). This single-use token contains a username and password that can then be used as basic authentication to request a real OAuth token.

This PR adds Jottacloud as a provider. The login button leads to a new page showing a simple input box for the user to manually enter a "Personal Login Token". This is then used to request a OAuth token. Finally this is hooked into the same logic as the existing providers: Saving the token, generate authid, show the logged-in page.

Some question marks:

  • I have called it "CLI Token" in the code, currently. Not sure if that is the best name for it... OpenID has something called "ID Token", but I can't really get it to match what the Jottacloud token contains. Other services have something called "Personal Access Token". I ended up naming it "CLI Token" to avoid the confusion of using some name from a standard that is not really followed.

  • I was a bit unsure about the fetch token logic; is it correct to do the following in the CliTokenLoginHandler:

    fetchtoken = dbmodel.create_fetch_token(resp)
    
    # If this was part of a polling request, signal completion
    dbmodel.update_fetch_token(fetchtoken, authid)
    
  • What is the significance of the user_id? It is not part of the token returned from Jottacloud, so it will be stored as N/A in oauth service. What is the effect of this? We do have the real username included in the login token, so we could use that if it is beneficial in any way..

  • Developer tested, but more real user/beta-testing would be nice (was asked for in forum, but not sure if anyone actually did the effort). First of all I have done manual testing of the web gui / rest api of the service itself. Then @jthall put a lot of effort into testing it with Duplicati, as discussed in the issue, successfully (after a couple of patches, mentioned in additional comments to this pr) running Duplicati against the oauth service running in a local python environment. Later, also described in comment on the issue, it was deployed to Google App Engine (at a custom/unofficial url) and then tested with Duplicati connecting to it, which also seem to work fine.

See:

@albertony
Copy link
Contributor Author

Pushed some small tweaks after performing some more manual testing:

  • Styling of input field for cli token, and also authid in existing revoke page to make it consistent:
    • Bootstrap style, like the other page elements.
    • Wider (100% of parent by default when using bootstrap style), so that more of the token/authid is visible.
    • Marked as required in the form, i.e. must have non-zero input for the button to trigger.
  • Error handling when processing the cli token:
    • Since this new cli token handling for Jottacloud is a process with several manual steps (users must themselves log in to a separate website, generate the token, copy it, and paste it into the appropriate field in the oauth handler site) there is a chance of user error that would only be reported as "Server error, close window and try again".
    • Now indicating if token was invalid, i.e. not valid base64 or not valid json after decoding base64. E.g. user copy-pasted some text other than the token.
    • Now indicating if HTTP Error 401 (Unauthorized) occured when requesting a oauth token using the cli token. This can easily happen if the user tries to use a cli token that has already been used before.

@albertony albertony force-pushed the jottacloud_clitoken branch from 5d0e5b0 to c4e5ac8 Compare April 15, 2022 22:09
@albertony
Copy link
Contributor Author

Pushed a bugfix reported by @jthall in the related issue: Jottacloud returns the personal login token with base64 encoding in "dialect": raw (as in no padding) and urlsafe (as in "-" used instead of "+", and "_" used instead of "/").

@albertony albertony force-pushed the jottacloud_clitoken branch from c4e5ac8 to cf69fec Compare April 15, 2022 22:37
Use bootstrap styling, with size according to parent to make entire input visible,
and mark input as required.
@albertony albertony force-pushed the jottacloud_clitoken branch from cf69fec to a3f50ea Compare April 16, 2022 11:31
@albertony
Copy link
Contributor Author

Pushed another fix after feedback by @jthall: Using space delimited scope value "openid offline_access" according to standard, instead of plus delimited (which will be encoded into %2B) like rclone did ("offline_access+openid").

@kenkendk
Copy link
Member

Great work @albertony

@kenkendk kenkendk merged commit 9b2be41 into duplicati:master Jun 12, 2022
@kenkendk
Copy link
Member

I have now deployed a version that supports Jottacloud using the CLI token

@albertony albertony deleted the jottacloud_clitoken branch June 12, 2022 20:53
albertony added a commit to albertony/oauth-handler that referenced this pull request Jun 13, 2022
…i leading to HTTP 500 error

This bug was introduced in duplicati#7
@albertony
Copy link
Contributor Author

@kenkendk, I don't know if you considered these two things I was uncertain about, and if you can tell me a bit about them: What is the "fetchtoken", and is it relevant for the Jottacloud/CLIToken logic? And what is the significance of the user_id?

I was a bit unsure about the fetch token logic; is it correct to do the following in the CliTokenLoginHandler:

fetchtoken = dbmodel.create_fetch_token(resp)

# If this was part of a polling request, signal completion
dbmodel.update_fetch_token(fetchtoken, authid)

What is the significance of the user_id? It is not part of the token returned from Jottacloud, so it will be stored as N/A in > oauth service. What is the effect of this? We do have the real username included in the login token, so we could use that if it is beneficial in any way..

@albertony
Copy link
Contributor Author

Regarding the fetch_token, I think I found the answer myself. Included a fix for this PR #10.

Still wondering about the user_id..

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

Successfully merging this pull request may close these issues.

2 participants