import flask from webargs.flaskparser import use_kwargs from atlas_um.api.decorators import doc_details_view from atlas_um import pgdb from atlas_um.audit import user_audit from atlas_um.consts import SystemEvents from atlas_um.logs import logger from atlas_um.helpers.tokens import get_safe_repr from atlas_um.tokens.bearer_tokens import M2MBearerToken from atlas_um.extensions import csrf from atlas_um.api.schemas import ValidationErrorSchema from . import oauth from .schemas import AccessTokenSchema, TokenSchema @oauth.route("/token", methods=["POST"]) @use_kwargs( TokenSchema, location="json_or_form", ) @doc_details_view( summary="Issue M2M bearer token", description="Issue M2M bearer token for the " "client_id/secret/audience combination.", tags=["Auth"], requestBody={ "content": { "application/json": { "schema": TokenSchema, }, "application/x-www-form-urlencoded": { "schema": TokenSchema, }, }, }, responses={ 200: { "description": "Access token", "schema": AccessTokenSchema, }, 422: { "description": "Invalid input params", "schema": ValidationErrorSchema, }, }, ) @csrf.exempt def token(client_id, client_secret, audience, grant_type): application = ( pgdb.Application.query.active() .by_identities(client_id, client_secret, audience) .first() ) if not application: logger.bind(client_id=client_id, audience=audience).warning( "No corresponding application" ) flask.abort(401, "Unauthorized") access_token = M2MBearerToken(application) access_token_string = access_token.encode() access_token_ttl = access_token.ttl user_audit.log( SystemEvents.creating_m2m_token, client_id=client_id, audience=audience, access_token=get_safe_repr(access_token_string), ttl=access_token_ttl, ) logger.bind( application=application, client_id=client_id, audience=audience, access_token=get_safe_repr(access_token_string), ttl=access_token_ttl, ).info("Created access token for application") return flask.jsonify( { "access_token": access_token_string, "token_type": "Bearer", "expires_in": access_token_ttl, } )