diff options
Diffstat (limited to 'gn_auth')
42 files changed, 436 insertions, 55 deletions
diff --git a/gn_auth/auth/authentication/oauth2/endpoints/revocation.py b/gn_auth/auth/authentication/oauth2/endpoints/revocation.py index ad9e67c..240ca30 100644 --- a/gn_auth/auth/authentication/oauth2/endpoints/revocation.py +++ b/gn_auth/auth/authentication/oauth2/endpoints/revocation.py @@ -3,7 +3,7 @@ from flask import current_app from authlib.oauth2.rfc7009 import RevocationEndpoint as _RevocationEndpoint -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from gn_auth.auth.authentication.oauth2.models.oauth2token import ( save_token, OAuth2Token, revoke_token) diff --git a/gn_auth/auth/authentication/oauth2/endpoints/utilities.py b/gn_auth/auth/authentication/oauth2/endpoints/utilities.py index d32f9b3..29ace7c 100644 --- a/gn_auth/auth/authentication/oauth2/endpoints/utilities.py +++ b/gn_auth/auth/authentication/oauth2/endpoints/utilities.py @@ -4,7 +4,7 @@ from typing import Any, Optional from flask import current_app from pymonad.maybe import Nothing -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from gn_auth.auth.authentication.oauth2.models.oauth2token import ( OAuth2Token, token_by_access_token, token_by_refresh_token) diff --git a/gn_auth/auth/authentication/oauth2/grants/authorisation_code_grant.py b/gn_auth/auth/authentication/oauth2/grants/authorisation_code_grant.py index 6d8112e..e866c41 100644 --- a/gn_auth/auth/authentication/oauth2/grants/authorisation_code_grant.py +++ b/gn_auth/auth/authentication/oauth2/grants/authorisation_code_grant.py @@ -9,8 +9,8 @@ from flask import current_app as app from authlib.oauth2.rfc6749 import grants from authlib.oauth2.rfc7636 import create_s256_code_challenge -from gn_auth.auth import db -from gn_auth.auth.db_utils import with_db_connection +from gn_auth.auth.db import sqlite3 as db +from gn_auth.auth.db.sqlite3 import with_db_connection from gn_auth.auth.authentication.users import User from ..models.oauth2client import OAuth2Client diff --git a/gn_auth/auth/authentication/oauth2/grants/password_grant.py b/gn_auth/auth/authentication/oauth2/grants/password_grant.py index 75fc122..79382fd 100644 --- a/gn_auth/auth/authentication/oauth2/grants/password_grant.py +++ b/gn_auth/auth/authentication/oauth2/grants/password_grant.py @@ -3,7 +3,7 @@ from flask import current_app as app from authlib.oauth2.rfc6749 import grants -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from gn_auth.auth.authentication.users import valid_login, user_by_email from gn_auth.auth.authorisation.errors import NotFoundError diff --git a/gn_auth/auth/authentication/oauth2/models/authorization_code.py b/gn_auth/auth/authentication/oauth2/models/authorization_code.py index 98b5d0f..6c586f3 100644 --- a/gn_auth/auth/authentication/oauth2/models/authorization_code.py +++ b/gn_auth/auth/authentication/oauth2/models/authorization_code.py @@ -5,7 +5,7 @@ from typing import NamedTuple from pymonad.maybe import Just, Maybe, Nothing -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from .oauth2client import OAuth2Client diff --git a/gn_auth/auth/authentication/oauth2/models/oauth2client.py b/gn_auth/auth/authentication/oauth2/models/oauth2client.py index 07618dd..ea86772 100644 --- a/gn_auth/auth/authentication/oauth2/models/oauth2client.py +++ b/gn_auth/auth/authentication/oauth2/models/oauth2client.py @@ -6,7 +6,7 @@ from typing import Sequence, Optional, NamedTuple from pymonad.maybe import Just, Maybe, Nothing -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from gn_auth.auth.authentication.users import User, users, user_by_id, same_password from gn_auth.auth.authorisation.errors import NotFoundError diff --git a/gn_auth/auth/authentication/oauth2/models/oauth2token.py b/gn_auth/auth/authentication/oauth2/models/oauth2token.py index 725c096..6f9dc12 100644 --- a/gn_auth/auth/authentication/oauth2/models/oauth2token.py +++ b/gn_auth/auth/authentication/oauth2/models/oauth2token.py @@ -5,7 +5,7 @@ from typing import NamedTuple, Optional from pymonad.maybe import Just, Maybe, Nothing -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from gn_auth.auth.authentication.users import User, user_by_id from gn_auth.auth.authorisation.errors import NotFoundError diff --git a/gn_auth/auth/authentication/oauth2/resource_server.py b/gn_auth/auth/authentication/oauth2/resource_server.py index 32c463f..c062b28 100644 --- a/gn_auth/auth/authentication/oauth2/resource_server.py +++ b/gn_auth/auth/authentication/oauth2/resource_server.py @@ -4,7 +4,7 @@ from flask import current_app as app from authlib.oauth2.rfc6750 import BearerTokenValidator as _BearerTokenValidator from authlib.integrations.flask_oauth2 import ResourceProtector -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from gn_auth.auth.authentication.oauth2.models.oauth2token import token_by_access_token class BearerTokenValidator(_BearerTokenValidator): diff --git a/gn_auth/auth/authentication/oauth2/server.py b/gn_auth/auth/authentication/oauth2/server.py index b085219..12366a6 100644 --- a/gn_auth/auth/authentication/oauth2/server.py +++ b/gn_auth/auth/authentication/oauth2/server.py @@ -8,7 +8,7 @@ from authlib.oauth2.rfc6749.errors import InvalidClientError from authlib.integrations.flask_oauth2 import AuthorizationServer # from authlib.oauth2.rfc7636 import CodeChallenge -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from .models.oauth2client import client from .models.oauth2token import OAuth2Token, save_token diff --git a/gn_auth/auth/authentication/oauth2/views.py b/gn_auth/auth/authentication/oauth2/views.py index 43d9e49..ac74739 100644 --- a/gn_auth/auth/authentication/oauth2/views.py +++ b/gn_auth/auth/authentication/oauth2/views.py @@ -14,8 +14,8 @@ from flask import ( render_template, current_app as app) -from gn_auth.auth import db -from gn_auth.auth.db_utils import with_db_connection +from gn_auth.auth.db import sqlite3 as db +from gn_auth.auth.db.sqlite3 import with_db_connection from gn_auth.auth.authorisation.errors import ForbiddenAccess from .resource_server import require_oauth diff --git a/gn_auth/auth/authentication/users.py b/gn_auth/auth/authentication/users.py index 327820e..46cd838 100644 --- a/gn_auth/auth/authentication/users.py +++ b/gn_auth/auth/authentication/users.py @@ -5,7 +5,7 @@ from typing import Any, Tuple, NamedTuple from argon2 import PasswordHasher from argon2.exceptions import VerifyMismatchError -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from gn_auth.auth.authorisation.errors import NotFoundError class User(NamedTuple): diff --git a/gn_auth/auth/authorisation/checks.py b/gn_auth/auth/authorisation/checks.py index 02c6810..46a51fe 100644 --- a/gn_auth/auth/authorisation/checks.py +++ b/gn_auth/auth/authorisation/checks.py @@ -4,7 +4,7 @@ from typing import Callable from flask import request, current_app as app -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from . import privileges as auth_privs from .errors import InvalidData, AuthorisationError diff --git a/gn_auth/auth/authorisation/data/genotypes.py b/gn_auth/auth/authorisation/data/genotypes.py index 41822a1..61963a6 100644 --- a/gn_auth/auth/authorisation/data/genotypes.py +++ b/gn_auth/auth/authorisation/data/genotypes.py @@ -5,7 +5,7 @@ from typing import Iterable from MySQLdb.cursors import DictCursor import gn_auth.auth.db as authdb -import gn_auth.db_utils as gn3db +import gn_auth.auth.db.mariadb as gn3db from gn_auth.auth.dictify import dictify from gn_auth.auth.authorisation.checks import authorised_p from gn_auth.auth.authorisation.groups.models import Group @@ -22,7 +22,7 @@ def linked_genotype_data(conn: authdb.DbConnection) -> Iterable[dict]: "group(s)."), oauth2_scope="profile group resource") def ungrouped_genotype_data(# pylint: disable=[too-many-arguments] - authconn: authdb.DbConnection, gn3conn: gn3db.Connection, + authconn: authdb.DbConnection, gn3conn: gn3db.DbConnection, search_query: str, selected: tuple[dict, ...] = tuple(), limit: int = 10000, offset: int = 0) -> tuple[ dict, ...]: diff --git a/gn_auth/auth/authorisation/data/mrna.py b/gn_auth/auth/authorisation/data/mrna.py index 0b08571..79ea7c0 100644 --- a/gn_auth/auth/authorisation/data/mrna.py +++ b/gn_auth/auth/authorisation/data/mrna.py @@ -4,7 +4,7 @@ from typing import Iterable from MySQLdb.cursors import DictCursor import gn_auth.auth.db as authdb -import gn_auth.db_utils as gn3db +import gn_auth.auth.db.mariadb as gn3db from gn_auth.auth.dictify import dictify from gn_auth.auth.authorisation.checks import authorised_p from gn_auth.auth.authorisation.groups.models import Group @@ -21,7 +21,7 @@ def linked_mrna_data(conn: authdb.DbConnection) -> Iterable[dict]: "group(s)."), oauth2_scope="profile group resource") def ungrouped_mrna_data(# pylint: disable=[too-many-arguments] - authconn: authdb.DbConnection, gn3conn: gn3db.Connection, + authconn: authdb.DbConnection, gn3conn: gn3db.DbConnection, search_query: str, selected: tuple[dict, ...] = tuple(), limit: int = 10000, offset: int = 0) -> tuple[ dict, ...]: diff --git a/gn_auth/auth/authorisation/data/phenotypes.py b/gn_auth/auth/authorisation/data/phenotypes.py index 2f4c564..d3cc33a 100644 --- a/gn_auth/auth/authorisation/data/phenotypes.py +++ b/gn_auth/auth/authorisation/data/phenotypes.py @@ -5,13 +5,13 @@ from typing import Any, Iterable from MySQLdb.cursors import DictCursor import gn_auth.auth.db as authdb -import gn_auth.db_utils as gn3db +import gn_auth.auth.db.mariadb as gn3db from gn_auth.auth.dictify import dictify from gn_auth.auth.authorisation.checks import authorised_p from gn_auth.auth.authorisation.groups.models import Group def linked_phenotype_data( - authconn: authdb.DbConnection, gn3conn: gn3db.Connection, + authconn: authdb.DbConnection, gn3conn: gn3db.DbConnection, species: str = "") -> Iterable[dict[str, Any]]: """Retrieve phenotype data linked to user groups.""" authkeys = ("SpeciesId", "InbredSetId", "PublishFreezeId", "PublishXRefId") @@ -52,7 +52,7 @@ def linked_phenotype_data( "group(s)."), oauth2_scope="profile group resource") def ungrouped_phenotype_data( - authconn: authdb.DbConnection, gn3conn: gn3db.Connection): + authconn: authdb.DbConnection, gn3conn: gn3db.DbConnection): """Retrieve phenotype data that is not linked to any user group.""" with gn3conn.cursor() as cursor: params = tuple( @@ -82,7 +82,7 @@ def ungrouped_phenotype_data( return tuple() -def __traits__(gn3conn: gn3db.Connection, params: tuple[dict, ...]) -> tuple[dict, ...]: +def __traits__(gn3conn: gn3db.DbConnection, params: tuple[dict, ...]) -> tuple[dict, ...]: """An internal utility function. Don't use outside of this module.""" if len(params) < 1: return tuple() @@ -115,7 +115,7 @@ def __traits__(gn3conn: gn3db.Connection, params: tuple[dict, ...]) -> tuple[dic "group(s)."), oauth2_scope="profile group resource") def link_phenotype_data( - authconn:authdb.DbConnection, gn3conn: gn3db.Connection, group: Group, + authconn:authdb.DbConnection, gn3conn: gn3db.DbConnection, group: Group, traits: tuple[dict, ...]) -> dict: """Link phenotype traits to a user group.""" with authdb.cursor(authconn) as cursor: diff --git a/gn_auth/auth/authorisation/data/views.py b/gn_auth/auth/authorisation/data/views.py index a25e9a2..9e55dd8 100644 --- a/gn_auth/auth/authorisation/data/views.py +++ b/gn_auth/auth/authorisation/data/views.py @@ -10,13 +10,13 @@ from MySQLdb.cursors import DictCursor from authlib.integrations.flask_oauth2.errors import _HTTPException from flask import request, jsonify, Response, Blueprint, current_app as app -import gn_auth.db_utils as gn3db +import gn_auth.auth.db.mariadb as gn3db from gn_auth import jobs from gn_auth.commands import run_async_cmd from gn_auth.db.traits import build_trait_name -from gn_auth.auth import db -from gn_auth.auth.db_utils import with_db_connection +from gn_auth.auth.db import sqlite3 as db +from gn_auth.auth.db.sqlite3 import with_db_connection from gn_auth.auth.authorisation.checks import require_json from gn_auth.auth.authorisation.errors import InvalidData, NotFoundError diff --git a/gn_auth/auth/authorisation/groups/data.py b/gn_auth/auth/authorisation/groups/data.py index d05747b..2d9ddb5 100644 --- a/gn_auth/auth/authorisation/groups/data.py +++ b/gn_auth/auth/authorisation/groups/data.py @@ -1,14 +1,14 @@ """Handles the resource objects' data.""" from MySQLdb.cursors import DictCursor -from gn_auth import db_utils as gn3db -from gn_auth.auth import db as authdb +from gn_auth.auth.db import mariadb as gn3db +from gn_auth.auth.db import sqlite3 as authdb from gn_auth.auth.authorisation.groups import Group from gn_auth.auth.authorisation.checks import authorised_p from gn_auth.auth.authorisation.errors import NotFoundError def __fetch_mrna_data_by_ids__( - conn: gn3db.Connection, dataset_ids: tuple[str, ...]) -> tuple[ + conn: gn3db.DbConnection, dataset_ids: tuple[str, ...]) -> tuple[ dict, ...]: """Fetch mRNA Assay data by ID.""" with conn.cursor(DictCursor) as cursor: @@ -26,7 +26,7 @@ def __fetch_mrna_data_by_ids__( raise NotFoundError("Could not find mRNA Assay data with the given ID.") def __fetch_geno_data_by_ids__( - conn: gn3db.Connection, dataset_ids: tuple[str, ...]) -> tuple[ + conn: gn3db.DbConnection, dataset_ids: tuple[str, ...]) -> tuple[ dict, ...]: """Fetch genotype data by ID.""" with conn.cursor(DictCursor) as cursor: @@ -44,7 +44,7 @@ def __fetch_geno_data_by_ids__( raise NotFoundError("Could not find Genotype data with the given ID.") def __fetch_pheno_data_by_ids__( - conn: gn3db.Connection, dataset_ids: tuple[str, ...]) -> tuple[ + conn: gn3db.DbConnection, dataset_ids: tuple[str, ...]) -> tuple[ dict, ...]: """Fetch phenotype data by ID.""" with conn.cursor(DictCursor) as cursor: @@ -66,7 +66,7 @@ def __fetch_pheno_data_by_ids__( "Could not find Phenotype/Publish data with the given IDs.") def __fetch_data_by_id( - conn: gn3db.Connection, dataset_type: str, + conn: gn3db.DbConnection, dataset_type: str, dataset_ids: tuple[str, ...]) -> tuple[dict, ...]: """Fetch data from MySQL by IDs.""" fetch_fns = { @@ -82,7 +82,7 @@ def __fetch_data_by_id( "group(s)."), oauth2_scope="profile group resource") def link_data_to_group( - authconn: authdb.DbConnection, gn3conn: gn3db.Connection, + authconn: authdb.DbConnection, gn3conn: gn3db.DbConnection, dataset_type: str, dataset_ids: tuple[str, ...], group: Group) -> tuple[ dict, ...]: """Link the given data to the specified group.""" diff --git a/gn_auth/auth/authorisation/groups/models.py b/gn_auth/auth/authorisation/groups/models.py index 9008bef..0ffd3a7 100644 --- a/gn_auth/auth/authorisation/groups/models.py +++ b/gn_auth/auth/authorisation/groups/models.py @@ -7,7 +7,7 @@ from typing import Any, Sequence, Iterable, Optional, NamedTuple from flask import g from pymonad.maybe import Just, Maybe, Nothing -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from gn_auth.auth.dictify import dictify from gn_auth.auth.authentication.users import User, user_by_id diff --git a/gn_auth/auth/authorisation/groups/views.py b/gn_auth/auth/authorisation/groups/views.py index d1724cc..a63e09d 100644 --- a/gn_auth/auth/authorisation/groups/views.py +++ b/gn_auth/auth/authorisation/groups/views.py @@ -7,11 +7,11 @@ from functools import partial from MySQLdb.cursors import DictCursor from flask import request, jsonify, Response, Blueprint, current_app -from gn_auth.auth import db -from gn_auth import db_utils as gn3db +from gn_auth.auth.db import sqlite3 as db +from gn_auth.auth.db import mariadb as gn3db from gn_auth.auth.dictify import dictify -from gn_auth.auth.db_utils import with_db_connection +from gn_auth.auth.db.sqlite3 import with_db_connection from .data import link_data_to_group from .models import ( @@ -169,7 +169,7 @@ def unlinked_genotype_data( return tuple(dict(row) for row in cursor.fetchall()) def unlinked_phenotype_data( - authconn: db.DbConnection, gn3conn: gn3db.Connection, + authconn: db.DbConnection, gn3conn: gn3db.DbConnection, group: Group) -> tuple[dict, ...]: """ Retrieve all phenotype data linked to a group but not linked to any diff --git a/gn_auth/auth/authorisation/privileges.py b/gn_auth/auth/authorisation/privileges.py index 1b0f06c..a348b92 100644 --- a/gn_auth/auth/authorisation/privileges.py +++ b/gn_auth/auth/authorisation/privileges.py @@ -1,7 +1,7 @@ """Handle privileges""" from typing import Any, Iterable, NamedTuple -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from gn_auth.auth.authentication.users import User class Privilege(NamedTuple): diff --git a/gn_auth/auth/authorisation/resources/checks.py b/gn_auth/auth/authorisation/resources/checks.py index a341dbd..0c57b17 100644 --- a/gn_auth/auth/authorisation/resources/checks.py +++ b/gn_auth/auth/authorisation/resources/checks.py @@ -3,7 +3,7 @@ from uuid import UUID from functools import reduce from typing import Sequence -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from gn_auth.auth.authentication.users import User def __organise_privileges_by_resource_id__(rows): diff --git a/gn_auth/auth/authorisation/resources/models.py b/gn_auth/auth/authorisation/resources/models.py index d96979f..8c035c9 100644 --- a/gn_auth/auth/authorisation/resources/models.py +++ b/gn_auth/auth/authorisation/resources/models.py @@ -5,10 +5,10 @@ from uuid import UUID, uuid4 from functools import reduce, partial from typing import Any, Dict, Sequence, Optional, NamedTuple -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from gn_auth.auth.dictify import dictify from gn_auth.auth.authentication.users import User -from gn_auth.auth.db_utils import with_db_connection +from gn_auth.auth.db.sqlite3 import with_db_connection from .checks import authorised_for diff --git a/gn_auth/auth/authorisation/resources/views.py b/gn_auth/auth/authorisation/resources/views.py index 9645303..157d5a3 100644 --- a/gn_auth/auth/authorisation/resources/views.py +++ b/gn_auth/auth/authorisation/resources/views.py @@ -6,7 +6,7 @@ from functools import reduce from flask import request, jsonify, Response, Blueprint, current_app as app -from gn_auth.auth.db_utils import with_db_connection +from gn_auth.auth.db.sqlite3 import with_db_connection from .checks import authorised_for from .models import ( diff --git a/gn_auth/auth/authorisation/roles/models.py b/gn_auth/auth/authorisation/roles/models.py index 742a90e..0fecfc1 100644 --- a/gn_auth/auth/authorisation/roles/models.py +++ b/gn_auth/auth/authorisation/roles/models.py @@ -5,7 +5,7 @@ from typing import Any, Sequence, Iterable, NamedTuple from pymonad.either import Left, Right, Either -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from gn_auth.auth.dictify import dictify from gn_auth.auth.authentication.users import User from gn_auth.auth.authorisation.errors import AuthorisationError diff --git a/gn_auth/auth/authorisation/roles/views.py b/gn_auth/auth/authorisation/roles/views.py index 6510365..4fc51f7 100644 --- a/gn_auth/auth/authorisation/roles/views.py +++ b/gn_auth/auth/authorisation/roles/views.py @@ -3,7 +3,7 @@ import uuid from flask import jsonify, Response, Blueprint, current_app -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from gn_auth.auth.dictify import dictify from .models import user_role diff --git a/gn_auth/auth/authorisation/users/admin/ui.py b/gn_auth/auth/authorisation/users/admin/ui.py index 4351a68..9087412 100644 --- a/gn_auth/auth/authorisation/users/admin/ui.py +++ b/gn_auth/auth/authorisation/users/admin/ui.py @@ -3,7 +3,7 @@ from functools import wraps from flask import flash, url_for, redirect from gn_auth.auth.authentication.users import User -from gn_auth.auth.db_utils import with_db_connection +from gn_auth.auth.db.sqlite3 import with_db_connection from gn_auth.auth.authorisation.roles.models import user_roles from gn_auth.session import logged_in, session_user, clear_session_info diff --git a/gn_auth/auth/authorisation/users/admin/views.py b/gn_auth/auth/authorisation/users/admin/views.py index ab04f91..4a37bc5 100644 --- a/gn_auth/auth/authorisation/users/admin/views.py +++ b/gn_auth/auth/authorisation/users/admin/views.py @@ -18,8 +18,8 @@ from flask import ( from gn_auth import session -from gn_auth.auth import db -from gn_auth.auth.db_utils import with_db_connection +from gn_auth.auth.db import sqlite3 as db +from gn_auth.auth.db.sqlite3 import with_db_connection from gn_auth.auth.authentication.oauth2.models.oauth2client import ( save_client, diff --git a/gn_auth/auth/authorisation/users/collections/views.py b/gn_auth/auth/authorisation/users/collections/views.py index 3dcc10f..9900205 100644 --- a/gn_auth/auth/authorisation/users/collections/views.py +++ b/gn_auth/auth/authorisation/users/collections/views.py @@ -4,8 +4,8 @@ from uuid import UUID from redis import Redis from flask import jsonify, request, Response, Blueprint, current_app -from gn_auth.auth import db -from gn_auth.auth.db_utils import with_db_connection +from gn_auth.auth.db import sqlite3 as db +from gn_auth.auth.db.sqlite3 import with_db_connection from gn_auth.auth.authorisation.checks import require_json from gn_auth.auth.authorisation.errors import NotFoundError diff --git a/gn_auth/auth/authorisation/users/masquerade/models.py b/gn_auth/auth/authorisation/users/masquerade/models.py index c45d761..9779764 100644 --- a/gn_auth/auth/authorisation/users/masquerade/models.py +++ b/gn_auth/auth/authorisation/users/masquerade/models.py @@ -5,7 +5,7 @@ from datetime import datetime from flask import current_app as app -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from gn_auth.auth.authorisation.errors import ForbiddenAccess from gn_auth.auth.authorisation.roles.models import user_roles diff --git a/gn_auth/auth/authorisation/users/masquerade/views.py b/gn_auth/auth/authorisation/users/masquerade/views.py index 9e42945..7bd8ddb 100644 --- a/gn_auth/auth/authorisation/users/masquerade/views.py +++ b/gn_auth/auth/authorisation/users/masquerade/views.py @@ -4,7 +4,7 @@ from functools import partial from flask import request, jsonify, Response, Blueprint -from gn_auth.auth.db_utils import with_db_connection +from gn_auth.auth.db.sqlite3 import with_db_connection from gn_auth.auth.authorisation.errors import InvalidData from gn_auth.auth.authorisation.checks import require_json diff --git a/gn_auth/auth/authorisation/users/models.py b/gn_auth/auth/authorisation/users/models.py index 71fa390..61489cf 100644 --- a/gn_auth/auth/authorisation/users/models.py +++ b/gn_auth/auth/authorisation/users/models.py @@ -2,7 +2,7 @@ import uuid from functools import reduce -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from gn_auth.auth.authorisation.roles.models import Role from gn_auth.auth.authorisation.checks import authorised_p from gn_auth.auth.authorisation.privileges import Privilege diff --git a/gn_auth/auth/authorisation/users/views.py b/gn_auth/auth/authorisation/users/views.py index 7783dca..0646e3a 100644 --- a/gn_auth/auth/authorisation/users/views.py +++ b/gn_auth/auth/authorisation/users/views.py @@ -7,9 +7,9 @@ import sqlite3 from email_validator import validate_email, EmailNotValidError from flask import request, jsonify, Response, Blueprint, current_app -from gn_auth.auth import db +from gn_auth.auth.db import sqlite3 as db from gn_auth.auth.dictify import dictify -from gn_auth.auth.db_utils import with_db_connection +from gn_auth.auth.db.sqlite3 import with_db_connection from .models import list_users from .masquerade.views import masq diff --git a/gn_auth/templates/admin/dashboard.html b/gn_auth/templates/admin/dashboard.html new file mode 100644 index 0000000..7798022 --- /dev/null +++ b/gn_auth/templates/admin/dashboard.html @@ -0,0 +1,24 @@ +{%extends "base.html"%} + +{%block title%}Genenetwork3: Admin Dashboard{%endblock%} + +{%block pagetitle%}Admin Dashboard{%endblock%} + +{%block content%} +{{flash_messages()}} + +<ul class="nav"> + <li> + <a href="{{url_for('oauth2.admin.register_client')}}" + title="Register a new OAuth2 client.">Register OAuth2 Client</a> + </li> + <li> + <a href="{{url_for('oauth2.admin.list_clients')}}" + title="List OAuth2 clients.">List OAuth2 Client</a> + </li> + <li> + <a href="{{url_for('oauth2.admin.logout')}}" + title="Log out of the system.">Logout</a> + </li> +</ul> +{%endblock%} diff --git a/gn_auth/templates/admin/list-oauth2-clients.html b/gn_auth/templates/admin/list-oauth2-clients.html new file mode 100644 index 0000000..0104f0d --- /dev/null +++ b/gn_auth/templates/admin/list-oauth2-clients.html @@ -0,0 +1,56 @@ +{%extends "base.html"%} + +{%block title%}Genenetwork3: OAuth2 Clients{%endblock%} + +{%block pagetitle%}OAuth2 Clients{%endblock%} + +{%block content%} +{{flash_messages()}} + +<table class="table table-hover table-striped cell-border no-footer"> + <caption>List of registered OAuth2 clients</caption> + <thead> + <tr> + <th>Client ID</th> + <th>Client Name</th> + <th>Default Redirect URI</th> + <th>Owner</th> + <th colspan="2">Actions</th> + </tr> + </thead> + + <tbody> + {%for client in clients%} + <tr> + <td>{{client.client_id}}</td> + <td>{{client.client_metadata.client_name}}</td> + <td>{{client.client_metadata.default_redirect_uri}}</td> + <td>{{client.user.name}} ({{client.user.email}})</td> + <td> + <a href="{{url_for('oauth2.admin.view_client', client_id=client.client_id)}}" + title"View/Edit client {{client.client_metadata.client_name}}" + class="btn btn-info"> + View/Edit + </a> + </td> + <td> + <form id="frm:delete:{{client.client_id}}" + action="{{url_for('oauth2.admin.delete_client')}}" + method="POST"> + <input type="hidden" name="client_id" value="{{client.client_id}}" /> + <input type="submit" value="Delete" + title"Delete client {{client.client_metadata.client_name}}" + class="btn btn-danger" /> + </form> + </td> + </tr> + {%else%} + <tr> + <td colspan="4" style="text-align: center;"> + No registered OAuth2 clients! + </td> + </tr> + {%endfor%} + </tbody> +</table> +{%endblock%} diff --git a/gn_auth/templates/admin/login.html b/gn_auth/templates/admin/login.html new file mode 100644 index 0000000..ac217ab --- /dev/null +++ b/gn_auth/templates/admin/login.html @@ -0,0 +1,32 @@ +{%extends "base.html"%} + +{%block title%}Log in to Genenetwork3{%endblock%} + +{%block pagetitle%}Admin Log In{%endblock%} + +{%block content%} +{{flash_messages()}} + +<form method="POST" action="{{url_for('oauth2.admin.login')}}"> + + <fieldset> + <legend>User Credentials</legend> + + <input name="next_uri" type="hidden" value={{next_uri}}> + + <fieldset class="form-group"> + <label for="txt:email" class="form-label">Email Address</label> + <input name="email" type="email" id="txt:email" required="required" + placeholder="your@email.address" class="form-control" /> + </fieldset> + + <fieldset class="form-group"> + <label for="txt:password" class="form-label">Password</label> + <input name="password" type="password" id="txt:password" + required="required" class="form-control" /> + </fieldset> + </fieldset> + + <input type="submit" value="log in" class="btn btn-primary" /> +</form> +{%endblock%} diff --git a/gn_auth/templates/admin/register-client.html b/gn_auth/templates/admin/register-client.html new file mode 100644 index 0000000..daac977 --- /dev/null +++ b/gn_auth/templates/admin/register-client.html @@ -0,0 +1,78 @@ +{%extends "base.html"%} + +{%block title%}Genenetwork3: Register OAuth2 Client{%endblock%} + +{%block pagetitle%}Register OAuth2 Client{%endblock%} + +{%block content%} +{{flash_messages()}} + +<form method="POST" action="{{url_for('oauth2.admin.register_client')}}"> + + <fieldset> + <legend>Select client scope</legend> + + {%for scp in scope%} + <input name="scope[]" id="chk:{{scp}}"type="checkbox" value="{{scp}}" + {%if scp=="profile"%}checked="checked"{%endif%} /> + <label for="chk:{{scp}}">{{scp}}</label><br /> + {%endfor%} + + </fieldset> + + <fieldset> + <legend>Basic OAuth2 client information</legend> + + + <label for="txt:client-name">Client name</label> + <input name="client_name" type="text" id="txt:client-name" + required="required" /> + <br /><br /> + + <label for="txt:redirect-uri">Redirect URI</label> + <input name="redirect_uri" type="text" id="txt:redirect-uri" + required="required" /> + <br /><br /> + + <label for="txt:other-redirect-uris"> + Other redirect URIs (Enter one URI per line)</label> + <br /> + <textarea name="other_redirect_uris" id="txt:other-redirect-uris" + cols="80" rows="10" + title="Enter one URI per line."></textarea> + <br /><br /> + <fieldset> + <legend>Supported grant types</legend> + <input name="grants[]" + type="checkbox" + value="authorization_code" + id="chk:authorization-code" + checked="checked" /> + <label for="chk:authorization-code">Authorization Code</label> + <br /><br /> + + <input name="grants[]" + type="checkbox" + value="refresh_token" + id="chk:refresh-token" /> + <label for="chk:refresh-token">Refresh Token</label> + </fieldset> + </fieldset> + + <fieldset> + <legend>User information</legend> + + <p>The user to register this client for</p> + <select name="user" required="required"> + {%for user in users%} + <option value="{{user.user_id}}" + {%if user.user_id==current_user.user_id%} + selected="selected" + {%endif%}>{{user.name}} ({{user.email}})</option> + {%endfor%} + </select> + </fieldset> + + <input type="submit" value="register client" /> +</form> +{%endblock%} diff --git a/gn_auth/templates/admin/registered-client.html b/gn_auth/templates/admin/registered-client.html new file mode 100644 index 0000000..5c46f4d --- /dev/null +++ b/gn_auth/templates/admin/registered-client.html @@ -0,0 +1,21 @@ +{%extends "base.html"%} + +{%block title%}Genenetwork3: Register OAuth2 Client{%endblock%} + +{%block pagetitle%}Register OAuth2 Client{%endblock%} + +{%block content%} +{{flash_messages()}} + +<p>Client has been registered successfully.</p> + +<p>Please save the following client details somewhere. There is no way to + retrieve the the <strong>CLIENT_SECRET</strong> once you leave this page.</p> + +<dl> + <dt>CLIENT_ID</dt> + <dd>{{client.client_id}}</dd> + <dt>CLIENT_SECRET</dt> + <dd>{{client_secret}}</dd> +</dl> +{%endblock%} diff --git a/gn_auth/templates/admin/view-oauth2-client.html b/gn_auth/templates/admin/view-oauth2-client.html new file mode 100644 index 0000000..b90428d --- /dev/null +++ b/gn_auth/templates/admin/view-oauth2-client.html @@ -0,0 +1,75 @@ +{%extends "base.html"%} + +{%block title%}Genenetwork3: View OAuth2 Client{%endblock%} + +{%block pagetitle%}View OAuth2 Client{%endblock%} + +{%block content%} +{{flash_messages()}} + +{%if client.is_nothing()%} +<p>No such client</p> +{%else%} +{%set client = client.value%} +<form method="POST" action="{{url_for('oauth2.admin.edit_client')}}"> + <legend>View/Edit Oauth2 Client</legend> + <input type="hidden" name="client_id" value="{{client.client_id}}" /> + <div> + <p><strong>Client ID: <strong> {{client.client_id}}</p> + <p><strong>Client Name: <strong> {{client.client_metadata.client_name}}</p> + </div> + <fieldset> + <legend>Scope</legend> + {%for scp in scope%} + <input name="scope[]" id="chk:{{scp}}" type="checkbox" value="{{scp}}" + {%if scp in client.client_metadata.scope%} + checked="checked" + {%endif%} /> + <label for="chk:{{scp}}">{{scp}}</label><br /> + {%endfor%} + </fieldset> + + <fieldset> + <legend>Redirect URIs</legend> + <label for="txt:default-redirect-uri">Default Redirect URI</label> + <br /> + <input type="text" name="default_redirect_uri" id="txt:default-redirect-uri" + value="{{client.client_metadata.default_redirect_uri}}" + required="required"> + <br /><br /> + + <label for="txta:other-redirect-uris">Other Redirect URIs</label> + <br /> + <textarea id="txta:other-redirect-uris" + name="other_redirect_uris" + cols="80" rows="10" + title="Enter one URI per line." + >{{"\r\n".join(client.client_metadata.redirect_uris)}}</textarea> + </fieldset> + + <fieldset> + <legend>Grants</legend> + <input name="grants[]" + type="checkbox" + value="authorization_code" + id="chk:authorization-code" + {%if "authorization_code" in client.client_metadata.grant_types%} + checked="checked" + {%endif%} /> + <label for="chk:authorization-code">Authorization Code</label> + <br /><br /> + + <input name="grants[]" + type="checkbox" + value="refresh_token" + id="chk:refresh-token" + {%if "refresh_token" in client.client_metadata.grant_types%} + checked="checked" + {%endif%} /> + <label for="chk:refresh-token">Refresh Token</label> + </fieldset> + + <input type="submit" value="update client" /> +</form> +{%endif%} +{%endblock%} diff --git a/gn_auth/templates/base.html b/gn_auth/templates/base.html new file mode 100644 index 0000000..db08545 --- /dev/null +++ b/gn_auth/templates/base.html @@ -0,0 +1,24 @@ +{% from "common-macros.html" import flash_messages%} +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + + <title>Genenetwork 3: {%block title%}{%endblock%}</title> + + <link rel="stylesheet" type="text/css" + href="https://genenetwork.org/static/new/css/bootstrap-custom.css" /> + <link rel="stylesheet" type="text/css" href="/static/css/styles.css" /> + {%block css%}{%endblock%} + </head> + + <body> + <h1>Genenetwork3: {%block pagetitle%}{%endblock%}</h1> + + <div class="container"> + {%block content%}{%endblock%} + </div> + {%block js%}{%endblock%} + <body> +</html> diff --git a/gn_auth/templates/common-macros.html b/gn_auth/templates/common-macros.html new file mode 100644 index 0000000..1d9f302 --- /dev/null +++ b/gn_auth/templates/common-macros.html @@ -0,0 +1,7 @@ +{%macro flash_messages()%} +<div class="alert-messages"> + {%for category,message in get_flashed_messages(with_categories=true)%} + <div class="alert {{category}}" role="alert">{{message}}</div> + {%endfor%} +</div> +{%endmacro%} diff --git a/gn_auth/templates/oauth2/authorise-user.html b/gn_auth/templates/oauth2/authorise-user.html new file mode 100644 index 0000000..b9284e5 --- /dev/null +++ b/gn_auth/templates/oauth2/authorise-user.html @@ -0,0 +1,48 @@ +{%extends "base.html"%} + +{%block title%}Authorise User{%endblock%} + +{%block pagetitle%}Authenticate to the API Server{%endblock%} + +{%block content%} +{{flash_messages()}} + +<form method="POST" action="{{url_for('oauth2.auth.authorise')}}"> + <input type="hidden" name="response_type" value="{{response_type}}" /> + <input type="hidden" name="scope" value="{{scope | join(' ')}}" /> + <input type="hidden" name="client_id" value="{{client.client_id}}" /> + <p> + You are authorising "{{client.client_metadata.client_name}}" to access + Genenetwork 3 with the following scope: + </p> + <fieldset> + <legend>Scope</legend> + {%for scp in scope%} + <div class="checkbox disabled"> + <label for="scope:{{scp}}"> + <input id="scope:{{scp}}" type="checkbox" name="scope[]" value="{{scp}}" + checked="checked" disabled="disabled" /> + {{scp}} + </label> + </div> + {%endfor%} + </fieldset> + + <fieldset> + <legend>User Credentials</legend> + <fieldset class="form-group"> + <label for="user:email" class="form-label">Email</label> + <input type="email" name="user:email" id="user:email" required="required" + class="form-control"/> + </fieldset> + + <fieldset class="form-group"> + <label for="user:password" class="form-label">Password</label> + <input type="password" name="user:password" id="user:password" + required="required" class="form-control" /> + </fieldset> + </fieldset> + + <input type="submit" value="authorise" class="btn btn-primary" /> +</form> +{%endblock%} diff --git a/gn_auth/templates/oauth2/oauth2_error.html b/gn_auth/templates/oauth2/oauth2_error.html new file mode 100644 index 0000000..ec9a500 --- /dev/null +++ b/gn_auth/templates/oauth2/oauth2_error.html @@ -0,0 +1,16 @@ +{%extends "base.html"%} + +{%block title%}OAuth2 Error{%endblock%} + +{%block pagetitle%}Error: {{error.status_code}}{%endblock%} + +{%block content%} +{{flash_messages()}} + +There was an error trying to fulfill your request: + +<p> + <strong>{{error.error}}</strong>: + {{error.description}} +</p> +{%endblock%} |