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

@uppy/companion-client,@uppy/provider-views: make authentication optional #4556

Merged
merged 6 commits into from
Aug 6, 2023

Conversation

dschmidt
Copy link
Contributor

@dschmidt dschmidt commented Jul 6, 2023

… in ProviderView

see #4551 for context

This allows provider plugins to circumvent the authentication flow and roundtrip to companion.
A different approach would be to move the actual authentication handling in handleAuth into the provider class and make it possible to override it.

What do you think, what do you prefer?

The use case for this is the following: my WebDAV provider allows browsing public links (basically unprotected webdav endpoints) without triggering an authentication flow.

I would still like to use the AuthView and render a custom form (see #4555) but immediately switch towards the file browser without the authentication flow.

Screenshot_20230706_173835
Screenshot_20230706_173858

@dschmidt
Copy link
Contributor Author

A different approach would be to move the actual authentication handling in handleAuth into the provider class and make it possible to override it.

I thought I'd give this approach a spin and pushed a second commit.
It's a slightly more invasive change and I'm not sure how much of a breaking change this could be for anyone, but apart from that I think it's the more elegant and flexible approach. It allows plugin authors to override the login method with custom logic (instead of just shortcutting the authentication).

This is what I do now in my WebDAV provider:

    this.provider = new Provider(uppy, {
      companionUrl: this.opts.companionUrl,
      companionHeaders: this.opts.companionHeaders,
      companionKeysParams: this.opts.companionKeysParams,
      companionCookiesRule: this.opts.companionCookiesRule,
      provider: 'webdavPublicLink',
      pluginId: this.id,
    })
    this.provider.login = async () => {
      // do some async checks for whatever ... or just do nothing
    }
    this.provider.logout = async () => {
      return { ok: true, revoked: true }
    }

Also I think it really makes sense to put the login logic into the companion client as it's completely agnostic of the provider view and this way can be used when just using the companion client without the dashboard.
It's not a mandatory change to anyone using just the companion client, but only an additional helper - only real change being authUrl() now adding the state on its own

Let me know, what works better for you. I'm fine with either version I pushed...

@arturi
Copy link
Contributor

arturi commented Jul 12, 2023

Thanks for your contributions, much appreciated. Public WebDav providers, and potentially more non-oauth like FTP is something we do want to support. We’ve discussed this in a call and need some more time to think about the best approach.

We have a separate login-less flow for Unsplash plugin already, the SearchProviderView, so we were discussing if we could re-use that, with a url instead of search.

@dschmidt
Copy link
Contributor Author

Okay, great - it's not time critical for me, as we've created a fork that we're going to use for the time being.
It's just important to me that I can get rid of it in the long run - and it doesn't take so long that I have forgotten what I've actually done here 😇
What time frame are we talking about and what would be a good time to ping you if this goes stale? I don't want to be annoying but I know how easy it is to lose track of issues and that a friendly ping often helps me ;-)

I'm not attached at all to my code, so I'm happy to throw it away with you come up with any better approaches to enable my use cases - I just tried to get things working :)
As external contributor it's hard to contribute refactorings with an even bigger scope, but I'm happy to adapt my code or contribute feedback.

@mifi
Copy link
Contributor

mifi commented Jul 31, 2023

I think this change makes a lot of sense. It's basically just moving code around a bit to make it easier to override/disable the auth method. more flexibility is good! But like you say, it could be considered a breaking change, and i'm not super into Uppy code's architecture so i'm not sure if it's the "correct" way. How do we want developers creating their own Uppy providers to "extend" Provider? this.provider.login = () => {} doesn't seem like a very oop way of doing it. maybe if we're going to make a breaking change, we should also make an architectural overhaul of the ProviderView/Provider architecture eto make it easier for devs to make their own providers

Copy link
Member

@Murderlon Murderlon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this makes sense too. It's a breaking change when people upgrade Uppy but do not upgrade Companion to latest at the same time. I think we've made changes like this before without a major, such as the new endpoints in Companion for S3 multipart, which would fail similarly.

It might be okay to do in a minor release, if we write a clear warning in the docs.

@mifi
Copy link
Contributor

mifi commented Jul 31, 2023

I think this makes sense too. It's a breaking change when people upgrade Uppy but do not upgrade Companion to latest at the same time. I think we've made changes like this before without a major, such as the new endpoints in Companion for S3 multipart, which would fail similarly.

I don't think this change has anything to do with Companion, or am I missing something? as far as I can tell it's only an internal refactoring of Uppy's client code

@dschmidt
Copy link
Contributor Author

I think this change makes a lot of sense. It's basically just moving code around a bit to make it easier to override/disable the auth method. more flexibility is good!

Cool!

Regarding:

But like you say, it could be considered a breaking change, and i'm not super into Uppy code's architecture so i'm not sure if it's the "correct" way.

and

I think this makes sense too. It's a breaking change when people upgrade Uppy but do not upgrade Companion to latest at the same time. I think we've made changes like this before without a major, such as the new endpoints in Companion for S3 multipart, which would fail similarly.

It might be okay to do in a minor release, if we write a clear warning in the docs.

Looked at it again, not sure how this would break for anyone in what context. This is completely independent from companion, it's just adding an additional method to companion-client and moves code from ProviderView there.

How do we want developers creating their own Uppy providers to "extend" Provider? this.provider.login = () => {} doesn't seem like a very oop way of doing it. maybe if we're going to make a breaking change, we should also make an architectural overhaul of the ProviderView/Provider architecture eto make it easier for devs to make their own providers

Dunno, you can always properly subclass - but overriding it on the instance is okaaayiish for JS imho.

PS: Rebased.

@Murderlon
Copy link
Member

Sorry I was mistaken, companion-client and provider-views can never be out of sync so this is totally fine 👍

@Murderlon
Copy link
Member

Murderlon commented Aug 1, 2023

CI fails on this though:

Error: Unused locale key "authAborted" in @uppy/core

I think you have to move that entry from @uppy/core/locale to @uppy/provider-views.

@dschmidt
Copy link
Contributor Author

dschmidt commented Aug 1, 2023

Ah, because it was moved from provider-views to companion-client.
I'll check if I can move translations...

@dschmidt
Copy link
Contributor Author

dschmidt commented Aug 1, 2023

Can you possibly help me with this?

The companion-client/Provider is not a "full plugin", but just a (base-) class - so the usual pattern of setting this.defaultLocale does not "just work".
What would be a good way to implement this?
I could provide defaultLocale from the Provider object, but that would need to be merged into translations in all consuming plugins. Something along these lines:


    this.provider = new Provider(uppy, {
      companionUrl: this.opts.companionUrl,
      companionHeaders: this.opts.companionHeaders,
      companionKeysParams: this.opts.companionKeysParams,
      companionCookiesRule: this.opts.companionCookiesRule,
      provider: 'facebook',
      pluginId: this.id,
    })

    this.defaultLocale = merge(this.provider.defaultLocale, locale)

seems cumbersome ... any better ideas?

@dschmidt
Copy link
Contributor Author

dschmidt commented Aug 1, 2023

Maybe not toooo bad after all...

@dschmidt
Copy link
Contributor Author

dschmidt commented Aug 1, 2023

CI is ✅

…correct source, but always return after rejections

While these events should be ignored they might be unrelated and should not reject the whole login
Copy link
Member

@Murderlon Murderlon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I didn't see that this translation string would become an issue.

I don't think the merging of locales is something we want to do. Ideally we avoid this complexity.

It seems it was in fact working but our hacky test was just faulty, it didn't check for core locale strings in companion-client. Reverted your change and updated the test.

@dschmidt
Copy link
Contributor Author

dschmidt commented Aug 3, 2023

Whatever works, thanks for taking care :)

Copy link
Contributor

@mifi mifi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice stuff!

@mifi mifi merged commit 79ff451 into transloadit:main Aug 6, 2023
15 checks passed
github-actions bot added a commit that referenced this pull request Aug 15, 2023
| Package                   | Version | Package                   | Version |
| ------------------------- | ------- | ------------------------- | ------- |
| @uppy/audio               |   1.1.2 | @uppy/locales             |   3.3.0 |
| @uppy/aws-s3              |   3.2.2 | @uppy/onedrive            |   3.1.3 |
| @uppy/aws-s3-multipart    |   3.5.3 | @uppy/progress-bar        |   3.0.3 |
| @uppy/box                 |   2.1.3 | @uppy/provider-views      |   3.5.0 |
| @uppy/companion           |   4.8.0 | @uppy/redux-dev-tools     |   3.0.3 |
| @uppy/companion-client    |   3.3.0 | @uppy/screen-capture      |   3.1.2 |
| @uppy/core                |   3.4.0 | @uppy/status-bar          |   3.2.4 |
| @uppy/dashboard           |   3.5.1 | @uppy/thumbnail-generator |   3.0.4 |
| @uppy/drag-drop           |   3.0.3 | @uppy/transloadit         |   3.2.1 |
| @uppy/dropbox             |   3.1.3 | @uppy/tus                 |   3.1.3 |
| @uppy/facebook            |   3.1.2 | @uppy/unsplash            |   3.2.2 |
| @uppy/file-input          |   3.0.3 | @uppy/url                 |   3.3.3 |
| @uppy/google-drive        |   3.2.1 | @uppy/webcam              |   3.3.2 |
| @uppy/image-editor        |   2.1.3 | @uppy/xhr-upload          |   3.3.2 |
| @uppy/informer            |   3.0.3 | @uppy/zoom                |   2.1.2 |
| @uppy/instagram           |   3.1.2 | uppy                      |  3.14.0 |

- meta: Readme improvements (Artur Paikin / #4622)
- @uppy/companion: Fix typos and add env vars to .env.example (Dominik Schmidt / #4624)
- @uppy/aws-s3-multipart: pass the `uploadURL` back to the caller (Antoine du Hamel / #4614)
- meta: update to node-18.17.0-alpine,  (odselsevier / #4617)
- @uppy/aws-s3,@uppy/aws-s3-multipart: update types (Antoine du Hamel / #4611)
- @uppy/aws-s3-multipart,@uppy/aws-s3,@uppy/companion,@uppy/transloadit,@uppy/xhr-upload: use uppercase HTTP method names (Antoine du Hamel / #4612)
- meta: e2e: fix race condition in transloadit test (Antoine du Hamel / #4616)
- @uppy/aws-s3,@uppy/aws-s3-multipart: update types (bdirito / #4576)
- @uppy/core: allow duplicate files with onBeforeFileAdded (Merlijn Vos / #4594)
- @uppy/companion: make CSRF protection helpers available to providers (Dominik Schmidt / #4554)
- @uppy/companion: fix Redis key default TTL (Subha Sarkar / #4607)
- @uppy/companion: Fix Uploader.js metadata normalisation (Subha Sarkar / #4608)
- @uppy/companion-client,@uppy/provider-views: make authentication optional (Dominik Schmidt / #4556)
- @uppy/provider-views: fix ProviderView error on empty plugin.icon (Dominik Schmidt / #4553)
- @uppy/aws-s3,@uppy/tus,@uppy/xhr-upload:  Invoke headers function for remote uploads (Dominik Schmidt / #4596)
- @uppy/companion: Unify redis initialization (Dominik Schmidt / #4597)
- meta: lock node-js version on ci (Mikael Finstad / #4606)
- @uppy/companion: allow dynamic S3 bucket (rmoura-92 / #4579)
- @uppy/status-bar: e2e: add test for retrying and pausing uploads (Antoine du Hamel / #3599)
- meta: e2e: remove too short timeout (Antoine du Hamel / #4602)
Murderlon added a commit that referenced this pull request Aug 24, 2023
* main: (28 commits)
  Release: [email protected] (#4644)
  @uppy/aws-s3-multipart: fix types when using deprecated option (#4634)
  @uppy/companion: harden lint rules (#4641)
  allow empty objects for `fields` types (#4631)
  meta: upgrade Node.js docker version (#4630)
  Release: [email protected] (#4626)
  Readme improvements (#4622)
  Fix typos and add env vars to .env.example (#4624)
  @uppy/aws-s3-multipart: pass the `uploadURL` back to the caller (#4614)
  update to node-18.17.0-alpine,  (#4617)
  @uppy/aws-s3,@uppy/aws-s3-multipart: update types (#4611)
  use uppercase HTTP method names (#4612)
  e2e: fix race condition in transloadit test (#4616)
  @uppy/aws-s3,@uppy/aws-s3-multipart: update types (#4576)
  @uppy/core: allow duplicate files with onBeforeFileAdded (#4594)
  @uppy/companion: make CSRF protection helpers available to providers (#4554)
  @uppy/companion: fix Redis key default TTL (#4607)
  @uppy/companion: Fix Uploader.js metadata normalisation (#4608)
  @uppy/companion-client,@uppy/provider-views: make authentication optional (#4556)
  @uppy/provider-views: fix ProviderView error on empty plugin.icon (#4553)
  ...
@dschmidt dschmidt deleted the optional-authentication branch June 13, 2024 21:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants