diff options
-rw-r--r-- | gn_auth/__init__.py | 37 | ||||
-rw-r--r-- | gn_auth/auth/authentication/oauth2/grants/jwt_bearer_grant.py | 5 | ||||
-rw-r--r-- | gn_auth/auth/authentication/oauth2/models/oauth2client.py | 5 | ||||
-rw-r--r-- | gn_auth/auth/authorisation/users/admin/views.py | 1 | ||||
-rw-r--r-- | gn_auth/debug.py | 22 | ||||
-rw-r--r-- | gn_auth/wsgi.py | 31 |
6 files changed, 65 insertions, 36 deletions
diff --git a/gn_auth/__init__.py b/gn_auth/__init__.py index b695ebf..658f034 100644 --- a/gn_auth/__init__.py +++ b/gn_auth/__init__.py @@ -1,6 +1,7 @@ """Application initialisation module.""" import os import sys +import logging from pathlib import Path from typing import Optional, Callable @@ -52,10 +53,38 @@ def load_secrets_conf(app: Flask) -> None: app.config.from_pyfile(secretsfile) -def create_app( - config: Optional[dict] = None, - setup_logging: Callable[[Flask], None] = lambda appl: None -) -> Flask: +def dev_loggers(appl: Flask) -> None: + """Setup the logging handlers.""" + stderr_handler = logging.StreamHandler(stream=sys.stderr) + appl.logger.addHandler(stderr_handler) + + root_logger = logging.getLogger() + root_logger.addHandler(stderr_handler) + root_logger.setLevel(appl.config["LOGLEVEL"]) + + +def gunicorn_loggers(appl: Flask) -> None: + """Use gunicorn logging handlers for the application.""" + logger = logging.getLogger("gunicorn.error") + appl.logger.handlers = logger.handlers + appl.logger.setLevel(logger.level) + + +def setup_logging(appl: Flask) -> Callable[[Flask], None]: + """ + Setup the loggers according to the WSGI server used to run the application. + """ + # https://datatracker.ietf.org/doc/html/draft-coar-cgi-v11-03#section-4.1.17 + # https://wsgi.readthedocs.io/en/latest/proposals-2.0.html#making-some-keys-required + # https://peps.python.org/pep-3333/#id4 + software, *_version_and_comments = os.environ.get( + "SERVER_SOFTWARE", "").split('/') + if bool(software): + return gunicorn_loggers(appl) + return dev_loggers(appl) + + +def create_app(config: Optional[dict] = None) -> Flask: """Create and return a new flask application.""" app = Flask(__name__) diff --git a/gn_auth/auth/authentication/oauth2/grants/jwt_bearer_grant.py b/gn_auth/auth/authentication/oauth2/grants/jwt_bearer_grant.py index 975cd68..27783ac 100644 --- a/gn_auth/auth/authentication/oauth2/grants/jwt_bearer_grant.py +++ b/gn_auth/auth/authentication/oauth2/grants/jwt_bearer_grant.py @@ -8,6 +8,7 @@ from authlib.oauth2.rfc7523.jwt_bearer import JWTBearerGrant as _JWTBearerGrant from authlib.oauth2.rfc7523.token import ( JWTBearerTokenGenerator as _JWTBearerTokenGenerator) +from gn_auth.debug import __pk__ from gn_auth.auth.db.sqlite3 import with_db_connection from gn_auth.auth.authentication.users import user_by_id @@ -75,7 +76,9 @@ class JWTBearerGrant(_JWTBearerGrant): def resolve_client_key(self, client, headers, payload): """Resolve client key to decode assertion data.""" - return client.jwks().find_by_kid(headers["kid"]) + keyset = client.jwks() + __pk__("THE KEYSET =======>", keyset.keys) + return keyset.find_by_kid(headers["kid"]) def authenticate_user(self, subject): diff --git a/gn_auth/auth/authentication/oauth2/models/oauth2client.py b/gn_auth/auth/authentication/oauth2/models/oauth2client.py index 2c36f45..df5d564 100644 --- a/gn_auth/auth/authentication/oauth2/models/oauth2client.py +++ b/gn_auth/auth/authentication/oauth2/models/oauth2client.py @@ -292,7 +292,10 @@ def delete_client( def update_client_attribute( - client: OAuth2Client, attribute: str, value: Any) -> OAuth2Client: + client: OAuth2Client,# pylint: disable=[redefined-outer-name] + attribute: str, + value: Any +) -> OAuth2Client: """Return a new OAuth2Client with the given attribute updated/changed.""" attrs = { attr: type(value) diff --git a/gn_auth/auth/authorisation/users/admin/views.py b/gn_auth/auth/authorisation/users/admin/views.py index 5ad9038..9bc1c36 100644 --- a/gn_auth/auth/authorisation/users/admin/views.py +++ b/gn_auth/auth/authorisation/users/admin/views.py @@ -327,6 +327,7 @@ def delete_client(): @admin.route("/clients/<uuid:client_id>/change-secret", methods=["GET", "POST"]) @is_admin def change_client_secret(client_id: uuid.UUID): + """Enable changing of a client's secret.""" def __no_client__(): # Calling the function causes the flash to be evaluated # flash("No such client was found!", "alert-danger") diff --git a/gn_auth/debug.py b/gn_auth/debug.py new file mode 100644 index 0000000..6b7173b --- /dev/null +++ b/gn_auth/debug.py @@ -0,0 +1,22 @@ +"""Debug utilities""" +import logging +from flask import current_app + +__this_module_name__ = __name__ + + +# pylint: disable=invalid-name +def getLogger(name: str): + """Return a logger""" + return ( + logging.getLogger(name) + if not bool(current_app) + else current_app.logger) + +def __pk__(*args): + """Format log entry""" + value = args[-1] + title_vals = " => ".join(args[0:-1]) + logger = getLogger(__this_module_name__) + logger.debug("%s: %s", title_vals, value) + return value diff --git a/gn_auth/wsgi.py b/gn_auth/wsgi.py index bb8abd2..4904da3 100644 --- a/gn_auth/wsgi.py +++ b/gn_auth/wsgi.py @@ -3,7 +3,6 @@ import os import sys import uuid import json -import logging from math import ceil from pathlib import Path from typing import Callable @@ -24,35 +23,7 @@ from gn_auth.auth.authorisation.users.admin.models import make_sys_admin from scripts import register_sys_admin as rsysadm# type: ignore[import] -def dev_loggers(appl: Flask) -> None: - """Setup the logging handlers.""" - stderr_handler = logging.StreamHandler(stream=sys.stderr) - appl.logger.addHandler(stderr_handler) - - root_logger = logging.getLogger() - root_logger.addHandler(stderr_handler) - root_logger.setLevel(appl.config["LOGLEVEL"]) - - -def gunicorn_loggers(appl: Flask) -> None: - """Use gunicorn logging handlers for the application.""" - logger = logging.getLogger("gunicorn.error") - appl.logger.handlers = logger.handlers - appl.logger.setLevel(logger.level) - - -def setup_loggers() -> Callable[[Flask], None]: - """ - Setup the loggers according to the WSGI server used to run the application. - """ - # https://datatracker.ietf.org/doc/html/draft-coar-cgi-v11-03#section-4.1.17 - # https://wsgi.readthedocs.io/en/latest/proposals-2.0.html#making-some-keys-required - # https://peps.python.org/pep-3333/#id4 - software, *_version_and_comments = os.environ.get( - "SERVER_SOFTWARE", "").split('/') - return gunicorn_loggers if bool(software) else dev_loggers - -app = create_app(setup_logging=setup_loggers()) +app = create_app() ##### BEGIN: CLI Commands ##### |