diff --git a/uffd/oauth2/views.py b/uffd/oauth2/views.py index c3c33af0f537c2f8ef116de82f024eeb2f6071ac..d5f5cd48bbbba04b93f74d49567858ce146aa937 100644 --- a/uffd/oauth2/views.py +++ b/uffd/oauth2/views.py @@ -1,6 +1,7 @@ import datetime import functools import urllib.parse +import secrets from flask import Blueprint, request, jsonify, render_template, session, redirect, url_for, flash from flask_oauthlib.provider import OAuth2Provider @@ -21,7 +22,15 @@ def load_client(client_id): @oauth.grantgetter def load_grant(client_id, code): - return OAuth2Grant.query.filter_by(client_id=client_id, code=code).first() + if '-' not in code: + return None + grant_id, grant_code = code.split('-', 2) + grant = OAuth2Grant.query.get(grant_id) + if not grant or grant.client_id != client_id: + return None + if not secrets.compare_digest(grant.code, grant_code): + return None + return grant @oauth.grantsetter def save_grant(client_id, code, oauthreq, *args, **kwargs): # pylint: disable=unused-argument @@ -30,14 +39,28 @@ def save_grant(client_id, code, oauthreq, *args, **kwargs): # pylint: disable=un code=code['code'], redirect_uri=oauthreq.redirect_uri, expires=expires, _scopes=' '.join(oauthreq.scopes)) db.session.add(grant) db.session.commit() + code['code'] = f"{grant.id}-{code['code']}" return grant @oauth.tokengetter def load_token(access_token=None, refresh_token=None): + # pylint: disable=too-many-return-statements if access_token: - return OAuth2Token.query.filter_by(access_token=access_token).first() + if '-' not in access_token: + return None + tok_id, tok_secret = access_token.split('-', 2) + tok = OAuth2Token.query.get(tok_id) + if not tok or not secrets.compare_digest(tok.access_token, tok_secret): + return None + return tok if refresh_token: - return OAuth2Token.query.filter_by(refresh_token=refresh_token).first() + if '-' not in refresh_token: + return None + tok_id, tok_secret = refresh_token.split('-', 2) + tok = OAuth2Token.query.get(tok_id) + if not tok or not secrets.compare_digest(tok.refresh_token, tok_secret): + return None + return tok return None @oauth.tokensetter @@ -56,6 +79,8 @@ def save_token(token_data, oauthreq, *args, **kwargs): # pylint: disable=unused- ) db.session.add(tok) db.session.commit() + token_data['access_token'] = f"{tok.id}-{token_data['access_token']}" + token_data['refresh_token'] = f"{tok.id}-{token_data['refresh_token']}" return tok bp = Blueprint('oauth2', __name__, url_prefix='/oauth2/', template_folder='templates')