From 278d8db432378655b76f0ee4cbbc776d50928fdb Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Wed, 28 Dec 2022 14:39:29 +0300 Subject: auth: Add resource server and /user endpoint Add a resource server with the validator for the bearer token to protect the resources endpoints. Add a protected `/user` endpoint that returns the user details for valid tokens. * gn3/auth/authentication/oauth2/resource_server.py: new file * gn3/auth/authentication/oauth2/views.py: add /user endpoint --- gn3/auth/authentication/oauth2/resource_server.py | 19 +++++++++++++++++++ gn3/auth/authentication/oauth2/views.py | 14 +++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 gn3/auth/authentication/oauth2/resource_server.py diff --git a/gn3/auth/authentication/oauth2/resource_server.py b/gn3/auth/authentication/oauth2/resource_server.py new file mode 100644 index 0000000..885cbd8 --- /dev/null +++ b/gn3/auth/authentication/oauth2/resource_server.py @@ -0,0 +1,19 @@ +"""Protect the resources endpoints""" + +from flask import current_app as app +from authlib.oauth2.rfc6750 import BearerTokenValidator as _BearerTokenValidator +from authlib.integrations.flask_oauth2 import ResourceProtector, current_token + +from gn3.auth import db +from gn3.auth.authentication.oauth2.models.oauth2token import token_by_access_token + +class BearerTokenValidator(_BearerTokenValidator): + """Extends `authlib.oauth2.rfc6750.BearerTokenValidator`""" + def authenticate_token(self, token_string: str): + with db.connection(app.config["AUTH_DB"]) as conn: + return token_by_access_token(conn, token_string).maybe( + None, lambda tok: tok) + +require_oauth = ResourceProtector() + +require_oauth.register_token_validator(BearerTokenValidator()) diff --git a/gn3/auth/authentication/oauth2/views.py b/gn3/auth/authentication/oauth2/views.py index 58fa6d4..0947aa2 100644 --- a/gn3/auth/authentication/oauth2/views.py +++ b/gn3/auth/authentication/oauth2/views.py @@ -1,8 +1,9 @@ """Endpoints for the oauth2 server""" import uuid -from flask import Blueprint, current_app as app +from flask import jsonify, Blueprint, current_app as app +from .resource_server import require_oauth from .endpoints.revocation import RevocationEndpoint from .endpoints.introspection import IntrospectionEndpoint @@ -40,3 +41,14 @@ def introspect_token(): """Provide introspection information for the token.""" return app.config["OAUTH2_SERVER"].create_endpoint_response( IntrospectionEndpoint.ENDPOINT_NAME) + +@oauth2.route("/user") +@require_oauth("profile") +def user_details(): + with require_oauth.acquire("profile") as token: + user = token.user + return jsonify({ + "user_id": user.user_id, + "email": user.email, + "name": user.name + }) -- cgit v1.2.3