aboutsummaryrefslogtreecommitdiff
path: root/gn_auth/auth/authentication/oauth2/server.py
diff options
context:
space:
mode:
Diffstat (limited to 'gn_auth/auth/authentication/oauth2/server.py')
-rw-r--r--gn_auth/auth/authentication/oauth2/server.py72
1 files changed, 72 insertions, 0 deletions
diff --git a/gn_auth/auth/authentication/oauth2/server.py b/gn_auth/auth/authentication/oauth2/server.py
new file mode 100644
index 0000000..7d7113a
--- /dev/null
+++ b/gn_auth/auth/authentication/oauth2/server.py
@@ -0,0 +1,72 @@
+"""Initialise the OAuth2 Server"""
+import uuid
+import datetime
+from typing import Callable
+
+from flask import Flask, current_app
+from authlib.oauth2.rfc6749.errors import InvalidClientError
+from authlib.integrations.flask_oauth2 import AuthorizationServer
+# from authlib.oauth2.rfc7636 import CodeChallenge
+
+from gn3.auth import db
+
+from .models.oauth2client import client
+from .models.oauth2token import OAuth2Token, save_token
+
+from .grants.password_grant import PasswordGrant
+from .grants.authorisation_code_grant import AuthorisationCodeGrant
+
+from .endpoints.revocation import RevocationEndpoint
+from .endpoints.introspection import IntrospectionEndpoint
+
+def create_query_client_func() -> Callable:
+ """Create the function that loads the client."""
+ def __query_client__(client_id: uuid.UUID):
+ # use current_app rather than passing the db_uri to avoid issues
+ # when config changes, e.g. while testing.
+ with db.connection(current_app.config["AUTH_DB"]) as conn:
+ the_client = client(conn, client_id).maybe(
+ None, lambda clt: clt) # type: ignore[misc]
+ if bool(the_client):
+ return the_client
+ raise InvalidClientError(
+ "No client found for the given CLIENT_ID and CLIENT_SECRET.")
+
+ return __query_client__
+
+def create_save_token_func(token_model: type) -> Callable:
+ """Create the function that saves the token."""
+ def __save_token__(token, request):
+ with db.connection(current_app.config["AUTH_DB"]) as conn:
+ save_token(
+ conn, token_model(
+ token_id=uuid.uuid4(), client=request.client,
+ user=request.user,
+ **{
+ "refresh_token": None, "revoked": False,
+ "issued_at": datetime.datetime.now(),
+ **token
+ }))
+
+ return __save_token__
+
+def setup_oauth2_server(app: Flask) -> None:
+ """Set's up the oauth2 server for the flask application."""
+ server = AuthorizationServer()
+ server.register_grant(PasswordGrant)
+
+ # Figure out a common `code_verifier` for GN2 and GN3 and set
+ # server.register_grant(AuthorisationCodeGrant, [CodeChallenge(required=False)])
+ # below
+ server.register_grant(AuthorisationCodeGrant)
+
+ # register endpoints
+ server.register_endpoint(RevocationEndpoint)
+ server.register_endpoint(IntrospectionEndpoint)
+
+ # init server
+ server.init_app(
+ app,
+ query_client=create_query_client_func(),
+ save_token=create_save_token_func(OAuth2Token))
+ app.config["OAUTH2_SERVER"] = server