FitTrackee/fittrackee/oauth2/routes.py
2022-05-29 14:23:30 +02:00

78 lines
2.1 KiB
Python

from typing import Dict, Tuple, Union
from flask import Blueprint, Response, request
from fittrackee import db
from fittrackee.responses import HttpResponse, InvalidPayloadErrorResponse
from fittrackee.users.decorators import authenticate
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'])
@authenticate
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'])
@authenticate
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')