Skip to content

Commit

Permalink
Add support for MeB.org OAuth provider
Browse files Browse the repository at this point in the history
Use the newly developed MeB.org OAuth provider for handling login. Also, add support
for writing reviews, voting and retrieving profile if the appropriate scopes are
granted to tokens issued by the MeB.org provider. To distinguish the origin of the
tokens, the fact that MeB.org issued tokens start with `meba_` can be used.
  • Loading branch information
amCap1712 committed Apr 26, 2024
1 parent 28b3bdc commit 1ecc1ae
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 12 deletions.
4 changes: 3 additions & 1 deletion Dockerfile.webpack
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ FROM node:20
RUN mkdir /code
WORKDIR /code

COPY package.json package-lock.json webpack.config.js /code/
COPY package.json package-lock.json /code/
RUN npm install

COPY webpack.config.js .babelrc /code/
6 changes: 3 additions & 3 deletions critiquebrainz/frontend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ def create_app(debug=None, config_path=None):
name='musicbrainz',
client_id=app.config['MUSICBRAINZ_CLIENT_ID'],
client_secret=app.config['MUSICBRAINZ_CLIENT_SECRET'],
authorize_url="https://musicbrainz.org/oauth2/authorize",
access_token_url="https://musicbrainz.org/oauth2/token",
base_url="https://musicbrainz.org/",
authorize_url="https://test.musicbrainz.org/new-oauth2/authorize",
access_token_url="https://test.musicbrainz.org/new-oauth2/token",
base_url="https://test.musicbrainz.org/",
)

# APIs
Expand Down
2 changes: 1 addition & 1 deletion critiquebrainz/frontend/login/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def get_user(self):
data=data,
decoder=musicbrainz_auth_session_decoder,
)
data = s.get('oauth2/userinfo').json()
data = s.get('new-oauth2/userinfo').json()
musicbrainz_id = data.get('sub')
musicbrainz_row_id = data.get('metabrainz_user_id')
user = db_users.get_or_create(musicbrainz_row_id, musicbrainz_id, new_user_data={
Expand Down
2 changes: 1 addition & 1 deletion critiquebrainz/frontend/views/oauth.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ def authorize_prompt():
code = oauth.generate_grant(client_id, current_user.id, redirect_uri, scope)
return redirect(build_url(redirect_uri, dict(code=code, state=state)))
except OAuthError as e:
raise BadRequest(e.desc)
raise BadRequest(e.desc)
29 changes: 28 additions & 1 deletion critiquebrainz/ws/oauth/provider.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from datetime import datetime, timedelta
from functools import wraps

from flask import request
import requests
from flask import request, current_app

import critiquebrainz.db.exceptions as db_exceptions
import critiquebrainz.db.oauth_client as db_oauth_client
Expand Down Expand Up @@ -184,12 +185,38 @@ def generate_token(self, client_id, refresh_token, user_id, scope=None):

return access_token, 'Bearer', self.token_expire, refresh_token

def get_authorized_user_meb(self, access_token, scopes):
""" Query MeB OAuth provider to check validity of the access token """
response = requests.post(
f"https://{current_app.config['MUSICBRAINZ_HOSTNAME']}/new-oauth2/introspect",
data={
"client_id": current_app.config['MUSICBRAINZ_CLIENT_ID'],
"client_secret": current_app.config['MUSICBRAINZ_CLIENT_SECRET'],
"token": access_token,
}
)
if response.status_code != 200:
raise exceptions.InvalidToken
data = response.json()
if data["active"] is False:
raise exceptions.InvalidToken
for scope in scopes:
if scope not in data["scope"]:
raise exceptions.InvalidToken
user = User(db_users.get_by_mb_row_id(data["metabrainz_user_id"]))
return user

def get_authorized_user(self, scopes):
authorization = request.headers.get('Authorization')
if self.validate_authorization_header(authorization) is False:
raise NotAuthorized

access_token = authorization.split()[1]

# tokens that start with meba_ are issued by MeB OAuth provider
if access_token.startswith("meba_"):
return self.get_authorized_user_meb(access_token, scopes)

token = self.fetch_access_token(access_token)
if token is None:
raise exceptions.InvalidToken
Expand Down
7 changes: 2 additions & 5 deletions docker/docker-compose.dev.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# Docker Compose file for development
version: "3.4"

volumes:
cb_home:
cb_postgres:
Expand Down Expand Up @@ -44,7 +41,7 @@ services:
image: redis:4.0-alpine

musicbrainz_db:
image: metabrainz/musicbrainz-test-database:beta
image: metabrainz/musicbrainz-test-database:production
volumes:
- ../data/mbdata:/var/lib/postgresql/data/pgdata:z
environment:
Expand All @@ -60,4 +57,4 @@ services:
dockerfile: Dockerfile.webpack
command: npm run dev
volumes:
- ..:/code:z
- ../critiquebrainz:/code/critiquebrainz:z

0 comments on commit 1ecc1ae

Please sign in to comment.