From cfb6ac8e5fb4413c0743ca30ce24dd921804497f Mon Sep 17 00:00:00 2001 From: Johan Carlberg Date: Sun, 25 Jan 2026 11:51:21 +0100 Subject: [PATCH] Optionally set a user's full name in a PostgreSQL session variable for connections. --- .../Authentication/UserAuthenticator.swift | 4 ++-- .../UserSessionAuthenticator.swift | 4 ++-- .../Controllers/AdminController.swift | 2 +- .../Utilities/Request+SQLDatabase.swift | 17 ++++++++++++++--- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/Sources/ManageableUsers/Authentication/UserAuthenticator.swift b/Sources/ManageableUsers/Authentication/UserAuthenticator.swift index 124cb7c..7781eeb 100644 --- a/Sources/ManageableUsers/Authentication/UserAuthenticator.swift +++ b/Sources/ManageableUsers/Authentication/UserAuthenticator.swift @@ -3,9 +3,9 @@ import Vapor struct UserAuthenticator: AsyncBasicAuthenticator where User.SessionID == ExpiringUserId { func authenticate (basic: BasicAuthorization, for request: Request) async throws { - if let user = try await request.db.withSQLConnection { connection in + if let user = try await request.db.withSQLConnection ({ connection in return try await User.find (email: basic.username, password: basic.password, on: connection) - } { + }) { request.auth.login (user) } } diff --git a/Sources/ManageableUsers/Authentication/UserSessionAuthenticator.swift b/Sources/ManageableUsers/Authentication/UserSessionAuthenticator.swift index 3b17359..51bed38 100644 --- a/Sources/ManageableUsers/Authentication/UserSessionAuthenticator.swift +++ b/Sources/ManageableUsers/Authentication/UserSessionAuthenticator.swift @@ -4,9 +4,9 @@ public struct UserSessionAuthenticator: AsyncSessionAu public typealias User = SessionUser public func authenticate (sessionID: SessionUser.SessionID, for request: Request) async throws { - if let user = try await request.db.withSQLConnection { connection in + if let user = try await request.db.withSQLConnection ({ connection in return try await SessionUser.authenticate (sessionID: sessionID, on: connection) - } { + }) { request.logger.info ("Seeing user \(user)") request.auth.login (user) request.logger.info ("Saw user \(user)") diff --git a/Sources/ManageableUsers/Controllers/AdminController.swift b/Sources/ManageableUsers/Controllers/AdminController.swift index cd5f3c9..afac3d0 100644 --- a/Sources/ManageableUsers/Controllers/AdminController.swift +++ b/Sources/ManageableUsers/Controllers/AdminController.swift @@ -116,7 +116,7 @@ public struct AdminController: Sendable where User.SessionID } let save = try request.content.decode(Save.self) - return try await request.db.withSQLConnection { connection in + return try await request.db.withSQLConnection (user: try request.auth.require (BasicUser.self)) { connection in guard (try await User.find (userId, on: connection)) != nil else { throw Abort (.notFound) } diff --git a/Sources/ManageableUsers/Utilities/Request+SQLDatabase.swift b/Sources/ManageableUsers/Utilities/Request+SQLDatabase.swift index 4e8f752..40f475f 100644 --- a/Sources/ManageableUsers/Utilities/Request+SQLDatabase.swift +++ b/Sources/ManageableUsers/Utilities/Request+SQLDatabase.swift @@ -2,13 +2,24 @@ import Fluent import SQLKit extension Database { - public func withSQLConnection(_ closure: @escaping @Sendable (SQLDatabase) async throws -> T) async throws -> T { + public func withSQLConnection(user: BasicUser? = nil, _ closure: @escaping @Sendable (any SQLDatabase) async throws -> T) async throws -> T { return try await self.withConnection { database in - guard let connection = database as? SQLDatabase else { + guard let connection = database as? (any SQLDatabase) else { throw NoSQLDatabaseError (database: database) } + try await connection.raw (""" + SELECT pg_catalog.set_config ('manageable_users.active_user', \(bind: user?.fullName), FALSE) + """) + .run() - return try await closure (connection) + let result = try await closure (connection) + + try await connection.raw (""" + SELECT pg_catalog.set_config ('manageable_users.active_user', NULL, FALSE) + """) + .run() + + return result } } }