diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 7d2e61de9..6b82a2db0 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 6.5.1 +current_version = 6.6.0 commit = True tag = False parse = (?P\d+)\.(?P\d+)\.(?P[A-z0-9-]+) diff --git a/api/server.py b/api/server.py index 3ad2dc4b5..8e035c97e 100644 --- a/api/server.py +++ b/api/server.py @@ -20,7 +20,7 @@ from api.settings import PROFILE_REQUESTS, SKIP_DATABASE_CONNECTION # This tag is automatically updated by bump2version -_VERSION = '6.5.1' +_VERSION = '6.6.0' logger = get_logger() diff --git a/api/utils/db.py b/api/utils/db.py index 8e23419e8..5d88a2b1b 100644 --- a/api/utils/db.py +++ b/api/utils/db.py @@ -1,14 +1,14 @@ -from os import getenv import logging +from os import getenv from fastapi import Depends, HTTPException, Request -from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials +from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer from google.auth.transport import requests from google.oauth2 import id_token from api.settings import get_default_user from api.utils.gcp import email_from_id_token -from db.python.connect import SMConnections, Connection +from db.python.connect import Connection, SMConnections from db.python.gcp_connect import BqConnection, PubSubConnection from db.python.tables.project import ProjectPermissionsTable @@ -61,22 +61,27 @@ def authenticate( logging.info(f'Using {default_user} as authenticated user') return default_user - raise HTTPException(status_code=401, detail=f'Not authenticated :(') + raise HTTPException(status_code=401, detail='Not authenticated :(') async def dependable_get_write_project_connection( project: str, + request: Request, author: str = Depends(authenticate), ar_guid: str = Depends(get_ar_guid), on_behalf_of: str | None = Depends(get_on_behalf_of), ) -> Connection: """FastAPI handler for getting connection WITH project""" + meta = {'path': request.url.path} + if request.client: + meta['ip'] = request.client.host return await ProjectPermissionsTable.get_project_connection( project_name=project, author=author, readonly=False, ar_guid=ar_guid, on_behalf_of=on_behalf_of, + meta=meta, ) @@ -96,10 +101,18 @@ async def dependable_get_readonly_project_connection( async def dependable_get_connection( - author: str = Depends(authenticate), ar_guid: str = Depends(get_ar_guid) + request: Request, + author: str = Depends(authenticate), + ar_guid: str = Depends(get_ar_guid), ): """FastAPI handler for getting connection withOUT project""" - return await SMConnections.get_connection_no_project(author, ar_guid=ar_guid) + meta = {'path': request.url.path} + if request.client: + meta['ip'] = request.client.host + + return await SMConnections.get_connection_no_project( + author, ar_guid=ar_guid, meta=meta + ) async def dependable_get_bq_connection(author: str = Depends(authenticate)): diff --git a/db/python/connect.py b/db/python/connect.py index a800ac4c9..98df8b323 100644 --- a/db/python/connect.py +++ b/db/python/connect.py @@ -1,4 +1,4 @@ -# pylint: disable=unused-import +# pylint: disable=unused-import,too-many-instance-attributes # flake8: noqa """ Code for connecting to Postgres database @@ -51,6 +51,7 @@ def __init__( on_behalf_of: str | None, readonly: bool, ar_guid: str | None, + meta: dict[str, str] | None = None, ): self.connection: databases.Database = connection self.project: int | None = project @@ -58,6 +59,7 @@ def __init__( self.on_behalf_of: str | None = on_behalf_of self.readonly: bool = readonly self.ar_guid: str | None = ar_guid + self.meta = meta self._audit_log_id: int | None = None @@ -81,6 +83,7 @@ async def audit_log_id(self): ar_guid=self.ar_guid, comment=None, project=self.project, + meta=self.meta, ) return self._audit_log_id @@ -223,7 +226,9 @@ async def get_made_connection(): return conn @staticmethod - async def get_connection_no_project(author: str, ar_guid: str): + async def get_connection_no_project( + author: str, ar_guid: str, meta: dict[str, str] + ): """Get a db connection from a project and user""" # maybe it makes sense to perform permission checks here too logger.debug(f'Authenticate no-project connection with {author!r}') @@ -240,4 +245,5 @@ async def get_connection_no_project(author: str, ar_guid: str): on_behalf_of=None, ar_guid=ar_guid, readonly=False, + meta=meta, ) diff --git a/db/python/tables/project.py b/db/python/tables/project.py index b3f0bec55..d87c28960 100644 --- a/db/python/tables/project.py +++ b/db/python/tables/project.py @@ -61,6 +61,7 @@ async def get_project_connection( readonly: bool, ar_guid: str, on_behalf_of: str | None = None, + meta: dict[str, str] | None = None, ): """Get a db connection from a project and user""" # maybe it makes sense to perform permission checks here too @@ -80,6 +81,7 @@ async def get_project_connection( readonly=readonly, on_behalf_of=on_behalf_of, ar_guid=ar_guid, + meta=meta, ) async def audit_log_id(self): diff --git a/deploy/python/version.txt b/deploy/python/version.txt index a194c18e8..826f5ce03 100644 --- a/deploy/python/version.txt +++ b/deploy/python/version.txt @@ -1 +1 @@ -6.5.1 +6.6.0 diff --git a/setup.py b/setup.py index 7a24996d4..652b5093f 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ setup( name=PKG, # This tag is automatically updated by bump2version - version='6.5.1', + version='6.6.0', description='Python API for interacting with the Sample API system', long_description=readme, long_description_content_type='text/markdown', diff --git a/web/package.json b/web/package.json index 0bb1b828c..afeaa739b 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "metamist", - "version": "6.5.1", + "version": "6.6.0", "private": true, "dependencies": { "@apollo/client": "^3.7.3",