From 09725bca7cf65c8e0cb421e48f920f4eb02ed79e Mon Sep 17 00:00:00 2001 From: Marc Scholten Date: Wed, 29 Dec 2021 09:32:51 +0100 Subject: [PATCH] Added withRowLevelSecurityDisabled Executes the given block with the main database role and temporarly sidesteps the row level security policies --- IHP/ModelSupport.hs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/IHP/ModelSupport.hs b/IHP/ModelSupport.hs index e66681fc5..030099db9 100644 --- a/IHP/ModelSupport.hs +++ b/IHP/ModelSupport.hs @@ -450,6 +450,29 @@ withTransaction block = withTransactionConnection do Nothing -> PG.withTransaction connection block {-# INLINABLE withTransaction #-} +-- | Executes the given block with the main database role and temporarly sidesteps the row level security policies. +-- +-- This is used e.g. by IHP AutoRefresh to be able to set up it's database triggers. When trying to set up a database +-- trigger from the ihp_authenticated role, it typically fails because it's missing permissions. Using 'withRowLevelSecurityDisabled' +-- we switch to the main role which is allowed to set up database triggers. +-- +-- SQL queries run from within the passed block are executed in their own transaction. +-- +-- __Example:__ +-- +-- > -- SQL code executed here might be run from the ihp_authenticated role +-- > withRowLevelSecurityDisabled do +-- > -- SQL code executed here is run as the main IHP db role +-- > sqlExec "CREATE OR REPLACE FUNCTION .." () +-- +withRowLevelSecurityDisabled :: (?modelContext :: ModelContext) => ((?modelContext :: ModelContext) => IO a) -> IO a +withRowLevelSecurityDisabled block = do + let currentModelContext = ?modelContext + case get #rowLevelSecurity currentModelContext of + Just _ -> let ?modelContext = currentModelContext { rowLevelSecurity = Nothing, transactionConnection = Nothing } in block + Nothing -> block +{-# INLINABLE withRowLevelSecurityDisabled #-} + -- | Returns the postgres connection when called within a 'withTransaction' block -- -- Throws an error if called from outside a 'withTransaction'