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

Use OAuth for MusicBrainz authentication #216

Open
sampsyo opened this issue Mar 11, 2013 · 23 comments
Open

Use OAuth for MusicBrainz authentication #216

sampsyo opened this issue Mar 11, 2013 · 23 comments
Labels
feature features we would like to implement

Comments

@sampsyo
Copy link
Member

sampsyo commented Mar 11, 2013

MusicBrainz has added an option for OAuth (rather than username/password) authentication. This is way more secure, so we should move over posthaste.

@nogweii
Copy link

nogweii commented Mar 13, 2013

My concern here is normal OAuth flow - where will you store the secrets? Generating a global set for Beets means thta you're at risk for abuse. However, there really isn't anything much better than copying the same workflow from the acoustid plugin. Ah well.

@sampsyo
Copy link
Member Author

sampsyo commented Mar 13, 2013

Yes, such is the problem with token-based authentication in open-source desktop software.

@adamcik
Copy link

adamcik commented Jan 21, 2016

In the case of supporting Spotify's web APIs over auth in mopidy-spotify-web I ended creating https://github.com/adamcik/oauthclientbridge which we host under mopidy.com This allows us to register once and have a stable redirect end point for Spotify's OAuth. Saving end users from having to register, and the secrets stays safe on our server. What we give the client instead is a "Client Credentials Grant" in OAuth speak, basically a user/pw which can be used to get/refresh the OAuth token.

This might also be applicable for the use case you had in mind here.

@sampsyo
Copy link
Member Author

sampsyo commented Jan 21, 2016

Cool! This is a nifty idea; thanks.

@adamcik
Copy link

adamcik commented Jan 21, 2016

An other alternative would just be to ask musicbrainz to support Client Credentials Grants directly (or whatever OAuth grant type best fits) and avoid having any bridge like we have to with Spotify :-)

@opatel99
Copy link
Contributor

Since consumption of the MusicBrainz API is done through https://github.com/alastair/python-musicbrainzngs, OAuth implementation would need to be implemented there first.

Corresponding Issue: alastair/python-musicbrainzngs#89

@tigranl
Copy link
Contributor

tigranl commented Nov 28, 2016

I would like to get this task

@sampsyo
Copy link
Member Author

sampsyo commented Nov 28, 2016

Hi, @tigranl! That's great! Welcome to the beets project and to GCI.

I think the first step here is to get a proof of concept working using a Python library for OAuth. I recommend the library called rauth: https://rauth.readthedocs.io/en/latest/

Can you start by setting up a simple example script that uses rauth to authenticate with the MusicBrainz API? It would be helpful to go through that module's documentation. It might also be helpful to glean some parameters from other clients for the MusicBrainz OAuth2 API, like this one: https://github.com/LordSputnik/passport-musicbrainz-oauth2/blob/master/lib/passport-musicbrainz-oauth2/strategy.js

Once that's working, we can try integrating this strategy into the mbcollection plugin that currently uses password authentication. We'll need to look into implementing the strategy in the python-musicbrainzngs library or in our own code.

@tigranl
Copy link
Contributor

tigranl commented Nov 28, 2016

Hi, @sampsyo. I have sent you an example script.

@sampsyo
Copy link
Member Author

sampsyo commented Nov 28, 2016

Great! This is a good start.

Next, I think we'll need to set up a way to get the "OOB" code that MusicBrainz produces. According to this documentation, that works by setting the redirect URI to urn:ietf:wg:oauth:2.0:oob. We'll then need to ask the user for input to get the code and send it back to the server to verify. You can see a similar workflow going on in the Beatport plugin, which uses OAuth1:

data = beets.ui.input_(u"Enter the string displayed in your browser:")

In the future, could you please paste code here? Either in a Markdown code block or in a linked Gist will do nicely. That way, everyone in the beets community can see and help out.

@tigranl
Copy link
Contributor

tigranl commented Nov 29, 2016

Why do I get "Mismatched redirect URI" when I use urn:ietf:wg:oauth:2.0:oob? I set up installed application type tokens.

@sampsyo
Copy link
Member Author

sampsyo commented Nov 29, 2016

It's hard to say! Can you please include the full error output and the code that produced it? Is there a traceback?

@tigranl
Copy link
Contributor

tigranl commented Nov 29, 2016

Error: invalid_request Mismatched redirect URI
And that's all.

@sampsyo
Copy link
Member Author

sampsyo commented Nov 29, 2016

OK, and can you please include the code that produced the error? What's the Python program you're running, and how did you invoke it?

FWIW, I think the error you're seeing is coming from here in the MusicBrainz server code: https://github.com/metabrainz/musicbrainz-server/blob/60ece227912132de3da59d6cf7132dcf3dbdfc89/lib/MusicBrainz/Server/Controller/OAuth2.pm#L51

Here's the point in that code that the server checks for the OOB parameter: https://github.com/metabrainz/musicbrainz-server/blob/60ece227912132de3da59d6cf7132dcf3dbdfc89/lib/MusicBrainz/Server/Controller/OAuth2.pm#L263

@tigranl
Copy link
Contributor

tigranl commented Nov 29, 2016

I forgot to delete slash from redirect_uri string, can you imagine? Sorry to bother you.
So final script is https://gist.github.com/tigranl/edcdb8b9f7770d0d918ab14273724fa6

@sampsyo
Copy link
Member Author

sampsyo commented Nov 29, 2016

Awesome; thank you! I ran python3 test.py and it worked great—when I complete the authentication, it prints my profile info. ✨

To finish up this task, the last step is to integrate this into the mbcollection plugin. Using the beatport plugin as a guide, can you try adding this authentication code to the setup stage of mbcollection? You can open a pull request with even some initial, non-working code and we'll go from there.

Also, there's no need to preserve any backwards compatibility with password-based authentication. We'll sort that out after you're done.

Thanks again for working on this!

@tigranl
Copy link
Contributor

tigranl commented Nov 30, 2016

According to https://github.com/beetbox/beets/blob/db782a2404fa8a6827c10a6536b4a960d19af135/docs/plugins/mbcollection.rst user needs to add password and login to configuration file. In our case we must get user's token from console input. Am I right?

@sampsyo
Copy link
Member Author

sampsyo commented Nov 30, 2016

Yes! Just like in the beatport plugin, we'll need to call the beets.ui.input_ function to get the token from the user interactively.

@tigranl
Copy link
Contributor

tigranl commented Dec 1, 2016

@sampsyo I have been struggling with rauth error for 2 hours. It throws AttributeError: 'str' object has no attribute 'get'. Code: https://gist.github.com/tigranl/f6725c2d6e76dab891f3447bd34f3ed6
And without a decoder lambda it returns KeyError: 'Decoder failed to handle access_token with data as returned by provider. A different decoder may be needed.

@sampsyo
Copy link
Member Author

sampsyo commented Dec 1, 2016

Hi, @tigranl! When reporting exceptions, it's really important to include the full traceback. That way, we can see where errors are coming from. In other words… http://i.imgur.com/jacoj.jpg 😃

Here, it's probably coming from the session.get call. Can you try printing out the value of session to see if it matches what you expect?

@tigranl
Copy link
Contributor

tigranl commented Dec 2, 2016

@sampsyo My pull request #2298

@tigranl
Copy link
Contributor

tigranl commented Dec 3, 2016

Please, review it. I have 4 hours left to submit my work.

@Louson
Copy link

Louson commented Jan 15, 2023

Hello, based on what I saw here and in #2298, I have suggested a PR to musicbrainzngs

I have not chosen the same oauth library because it does not support revokation but the usage is quite the same.

If this is accepted, it should be easy to include OAuth2 support in beets

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature features we would like to implement
Projects
None yet
Development

No branches or pull requests

6 participants