module IHP.IDE.SchemaDesigner.Controller.Policies where import IHP.ControllerPrelude import IHP.IDE.ToolServer.Types import IHP.IDE.SchemaDesigner.View.Policies.New import IHP.IDE.SchemaDesigner.View.Policies.Edit import IHP.IDE.SchemaDesigner.Types import IHP.IDE.SchemaDesigner.View.Layout (schemaDesignerLayout, findStatementByName) import IHP.IDE.SchemaDesigner.Controller.Helper import qualified IHP.IDE.SchemaDesigner.SchemaOperations as SchemaOperations instance Controller PoliciesController where beforeAction :: (?context::ControllerContext, ?modelContext::ModelContext, ?theAction::PoliciesController) => IO () beforeAction = (?context::ControllerContext) => ((?context::ControllerContext) => Layout) -> IO () ((?context::ControllerContext) => Layout) -> IO () setLayout (?context::ControllerContext) => Layout Layout Html -> Html schemaDesignerLayout action :: (?context::ControllerContext, ?modelContext::ModelContext, ?theAction::PoliciesController) => PoliciesController -> IO () action NewPolicyAction { Text tableName :: Text $sel:tableName:NewPolicyAction :: PoliciesController -> Text tableName } = do [Statement] statements <- IO [Statement] forall controller. (?context::ControllerContext, ?modelContext::ModelContext, ?theAction::controller) => IO [Statement] readSchema let (Just Statement table) = Text -> [Statement] -> Maybe Statement forall {t :: * -> *}. Foldable t => Text -> t Statement -> Maybe Statement findStatementByName Text tableName [Statement] statements let policy :: Statement policy = [Statement] -> Statement -> Statement SchemaOperations.suggestPolicy [Statement] statements Statement table let columns :: [Column] columns = (Statement -> CreateTable unsafeGetCreateTable Statement table).columns NewPolicyView -> IO () forall view. (View view, ?context::ControllerContext) => view -> IO () render NewPolicyView { [Column] [Statement] Text Statement tableName :: Text statements :: [Statement] policy :: Statement columns :: [Column] $sel:statements:NewPolicyView :: [Statement] $sel:tableName:NewPolicyView :: Text $sel:columns:NewPolicyView :: [Column] $sel:policy:NewPolicyView :: Statement .. } action EditPolicyAction { Text $sel:tableName:NewPolicyAction :: PoliciesController -> Text tableName :: Text tableName, Text policyName :: Text $sel:policyName:NewPolicyAction :: PoliciesController -> Text policyName } = do [Statement] statements <- IO [Statement] forall controller. (?context::ControllerContext, ?modelContext::ModelContext, ?theAction::controller) => IO [Statement] readSchema let (Just Statement policy) = [Statement] statements [Statement] -> ([Statement] -> Maybe Statement) -> Maybe Statement forall {t1} {t2}. t1 -> (t1 -> t2) -> t2 |> (Statement -> Bool) -> [Statement] -> Maybe Statement forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a find \case CreatePolicy { $sel:name:StatementCreateTable :: Statement -> Text name = Text policyName', $sel:tableName:StatementCreateTable :: Statement -> Text tableName = Text tableName' } -> Text policyName' Text -> Text -> Bool forall a. Eq a => a -> a -> Bool == Text policyName Bool -> Bool -> Bool && Text tableName' Text -> Text -> Bool forall a. Eq a => a -> a -> Bool == Text tableName Statement otherwise -> Bool False let table :: Maybe Statement table = Text -> [Statement] -> Maybe Statement forall {t :: * -> *}. Foldable t => Text -> t Statement -> Maybe Statement findStatementByName Text tableName [Statement] statements let columns :: [Column] columns = [Column] -> (Statement -> [Column]) -> Maybe Statement -> [Column] forall b a. b -> (a -> b) -> Maybe a -> b maybe [] ((.columns) (CreateTable -> [Column]) -> (Statement -> CreateTable) -> Statement -> [Column] forall b c a. (b -> c) -> (a -> b) -> a -> c forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c . Statement -> CreateTable unsafeGetCreateTable) Maybe Statement table EditPolicyView -> IO () forall view. (View view, ?context::ControllerContext) => view -> IO () render EditPolicyView { [Column] [Statement] Text Statement tableName :: Text statements :: [Statement] policy :: Statement columns :: [Column] $sel:statements:EditPolicyView :: [Statement] $sel:tableName:EditPolicyView :: Text $sel:columns:EditPolicyView :: [Column] $sel:policy:EditPolicyView :: Statement .. } action PoliciesController UpdatePolicyAction = do [Statement] statements <- IO [Statement] forall controller. (?context::ControllerContext, ?modelContext::ModelContext, ?theAction::controller) => IO [Statement] readSchema let tableName :: Text tableName = ByteString -> Text forall valueType. (?context::ControllerContext, ParamReader valueType) => ByteString -> valueType param ByteString "tableName" let name :: Text name = ByteString -> Text forall valueType. (?context::ControllerContext, ParamReader valueType) => ByteString -> valueType param ByteString "name" ([Statement] -> [Statement]) -> IO () forall controller. (?context::ControllerContext, ?modelContext::ModelContext, ?theAction::controller) => ([Statement] -> [Statement]) -> IO () updateSchema (([Statement] -> [Statement]) -> IO ()) -> ([Statement] -> [Statement]) -> IO () forall a b. (a -> b) -> a -> b $ UpdatePolicyOptions -> [Statement] -> [Statement] SchemaOperations.updatePolicy SchemaOperations.UpdatePolicyOptions { $sel:currentName:UpdatePolicyOptions :: Text currentName = Text name , $sel:tableName:UpdatePolicyOptions :: Text tableName = Text tableName , $sel:name:UpdatePolicyOptions :: Text name = ByteString -> Text forall valueType. (?context::ControllerContext, ParamReader valueType) => ByteString -> valueType param ByteString "policyName" , $sel:using:UpdatePolicyOptions :: Maybe Expression using = ByteString -> Maybe Expression forall valueType. (?context::ControllerContext, ParamReader valueType) => ByteString -> valueType param ByteString "using" , $sel:check:UpdatePolicyOptions :: Maybe Expression check = ByteString -> Maybe Expression forall valueType. (?context::ControllerContext, ParamReader valueType) => ByteString -> valueType param ByteString "check" } TablesController -> IO () forall action. (?context::ControllerContext, HasPath action) => action -> IO () redirectTo ShowTableAction { Text tableName :: Text $sel:tableName:TablesAction :: Text .. } action PoliciesController CreatePolicyAction = do [Statement] statements <- IO [Statement] forall controller. (?context::ControllerContext, ?modelContext::ModelContext, ?theAction::controller) => IO [Statement] readSchema let tableName :: Text tableName = ByteString -> Text forall valueType. (?context::ControllerContext, ParamReader valueType) => ByteString -> valueType param ByteString "tableName" let addPolicy :: [Statement] -> [Statement] addPolicy = AddPolicyOptions -> [Statement] -> [Statement] SchemaOperations.addPolicy SchemaOperations.AddPolicyOptions { $sel:tableName:AddPolicyOptions :: Text tableName = Text tableName , $sel:name:AddPolicyOptions :: Text name = ByteString -> Text forall valueType. (?context::ControllerContext, ParamReader valueType) => ByteString -> valueType param ByteString "policyName" , $sel:using:AddPolicyOptions :: Maybe Expression using = ByteString -> Maybe Expression forall valueType. (?context::ControllerContext, ParamReader valueType) => ByteString -> valueType param ByteString "using" , $sel:check:AddPolicyOptions :: Maybe Expression check = ByteString -> Maybe Expression forall valueType. (?context::ControllerContext, ParamReader valueType) => ByteString -> valueType param ByteString "check" } let enableRLS :: [Statement] -> [Statement] enableRLS = Text -> [Statement] -> [Statement] SchemaOperations.enableRowLevelSecurity Text tableName ([Statement] -> [Statement]) -> IO () forall controller. (?context::ControllerContext, ?modelContext::ModelContext, ?theAction::controller) => ([Statement] -> [Statement]) -> IO () updateSchema ([Statement] -> [Statement] enableRLS ([Statement] -> [Statement]) -> ([Statement] -> [Statement]) -> [Statement] -> [Statement] forall b c a. (b -> c) -> (a -> b) -> a -> c forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c . [Statement] -> [Statement] addPolicy) TablesController -> IO () forall action. (?context::ControllerContext, HasPath action) => action -> IO () redirectTo ShowTableAction { Text $sel:tableName:TablesAction :: Text tableName :: Text .. } action DeletePolicyAction { Text $sel:tableName:NewPolicyAction :: PoliciesController -> Text tableName :: Text tableName, Text $sel:policyName:NewPolicyAction :: PoliciesController -> Text policyName :: Text policyName } = do let deletePolicy :: [Statement] -> [Statement] deletePolicy = DeletePolicyOptions -> [Statement] -> [Statement] SchemaOperations.deletePolicy SchemaOperations.DeletePolicyOptions { Text tableName :: Text $sel:tableName:DeletePolicyOptions :: Text tableName, Text policyName :: Text $sel:policyName:DeletePolicyOptions :: Text policyName } let disableRLSIfNoPolicies :: [Statement] -> [Statement] disableRLSIfNoPolicies = Text -> [Statement] -> [Statement] SchemaOperations.disableRowLevelSecurityIfNoPolicies Text tableName ([Statement] -> [Statement]) -> IO () forall controller. (?context::ControllerContext, ?modelContext::ModelContext, ?theAction::controller) => ([Statement] -> [Statement]) -> IO () updateSchema ([Statement] -> [Statement] disableRLSIfNoPolicies ([Statement] -> [Statement]) -> ([Statement] -> [Statement]) -> [Statement] -> [Statement] forall b c a. (b -> c) -> (a -> b) -> a -> c forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c . [Statement] -> [Statement] deletePolicy) TablesController -> IO () forall action. (?context::ControllerContext, HasPath action) => action -> IO () redirectTo ShowTableAction { Text $sel:tableName:TablesAction :: Text tableName :: Text .. }