FitTrackee/fittrackee/oauth2/routes.py

78 lines
2.1 KiB
Python

from typing import Dict, Tuple, Union
from flask import Blueprint, Response, request
from fittrackee import db
from fittrackee.oauth2.server import require_auth
from fittrackee.responses import HttpResponse, InvalidPayloadErrorResponse
from fittrackee.users.models import User
from .client import create_oauth_client
from .server import authorization_server
oauth_blueprint = Blueprint('oauth', __name__)
EXPECTED_METADATA_KEYS = [
'client_name',
'client_uri',
'redirect_uris',
'scope',
]
@oauth_blueprint.route('/oauth/apps', methods=['POST'])
@require_auth()
def create_client(auth_user: User) -> Union[HttpResponse, Tuple[Dict, int]]:
client_metadata = request.get_json()
if not client_metadata:
return InvalidPayloadErrorResponse(
message='OAuth client metadata missing'
)
missing_keys = [
key
for key in EXPECTED_METADATA_KEYS
if key not in client_metadata.keys()
]
if missing_keys:
return InvalidPayloadErrorResponse(
message=(
'OAuth client metadata missing keys: '
f'{", ".join(missing_keys)}'
)
)
new_client = create_oauth_client(client_metadata, auth_user)
db.session.add(new_client)
db.session.commit()
return (
{
'status': 'created',
'data': {'client': new_client.serialize()},
},
201,
)
@oauth_blueprint.route('/oauth/authorize', methods=['POST'])
@require_auth()
def authorize(auth_user: User) -> Response:
data = request.form
if not data or 'client_id' not in data or 'response_type' not in data:
return InvalidPayloadErrorResponse()
authorization_server.get_consent_grant(end_user=auth_user)
return authorization_server.create_authorization_response(
grant_user=auth_user
)
@oauth_blueprint.route('/oauth/token', methods=['POST'])
def issue_token() -> Response:
return authorization_server.create_token_response()
@oauth_blueprint.route('/oauth/revoke', methods=['POST'])
def revoke_token() -> Response:
return authorization_server.create_endpoint_response('revocation')