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, replace, findForeignKey, findTableIndex) import IHP.IDE.SchemaDesigner.Controller.Helper import IHP.IDE.SchemaDesigner.Controller.Validation import qualified Data.Text as Text import qualified Data.Maybe as Maybe import qualified Data.List as List import qualified IHP.IDE.SchemaDesigner.SchemaOperations as SchemaOperations instance Controller PoliciesController where beforeAction :: IO () beforeAction = (?context::ControllerContext) => ((?context::ControllerContext) => Layout) -> IO () ((?context::ControllerContext) => Layout) -> IO () setLayout (?context::ControllerContext) => Layout Html -> Html schemaDesignerLayout action :: PoliciesController -> IO () action NewPolicyAction { Text $sel:tableName:NewPolicyAction :: PoliciesController -> Text tableName :: 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 = Proxy "columns" -> CreateTable -> [Column] forall model (name :: Symbol) value. (KnownSymbol name, HasField name model value) => Proxy name -> model -> value get IsLabel "columns" (Proxy "columns") Proxy "columns" #columns (CreateTable -> [Column]) -> CreateTable -> [Column] forall a b. (a -> b) -> a -> b $ Statement -> CreateTable unsafeGetCreateTable Statement table NewPolicyView -> IO () forall view. (View view, ?context::ControllerContext) => view -> IO () render NewPolicyView :: [Statement] -> Text -> [Column] -> Statement -> NewPolicyView NewPolicyView { [Column] [Statement] Text Statement $sel:policy:NewPolicyView :: Statement $sel:columns:NewPolicyView :: [Column] $sel:tableName:NewPolicyView :: Text $sel:statements:NewPolicyView :: [Statement] columns :: [Column] policy :: Statement statements :: [Statement] tableName :: Text .. } action EditPolicyAction { Text tableName :: Text $sel:tableName:NewPolicyAction :: PoliciesController -> Text tableName, Text $sel:policyName:NewPolicyAction :: PoliciesController -> Text policyName :: 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 [] (Proxy "columns" -> CreateTable -> [Column] forall model (name :: Symbol) value. (KnownSymbol name, HasField name model value) => Proxy name -> model -> value get IsLabel "columns" (Proxy "columns") Proxy "columns" #columns (CreateTable -> [Column]) -> (Statement -> CreateTable) -> Statement -> [Column] 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 :: [Statement] -> Text -> [Column] -> Statement -> EditPolicyView EditPolicyView { [Column] [Statement] Text Statement $sel:policy:EditPolicyView :: Statement $sel:columns:EditPolicyView :: [Column] $sel:tableName:EditPolicyView :: Text $sel:statements:EditPolicyView :: [Statement] columns :: [Column] policy :: Statement statements :: [Statement] tableName :: Text .. } 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 UpdatePolicyOptions :: Text -> Text -> Text -> Maybe Expression -> Maybe Expression -> UpdatePolicyOptions 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 -> TablesController ShowTableAction { Text $sel:tableName:TablesAction :: Text tableName :: 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 AddPolicyOptions :: Text -> Text -> Maybe Expression -> Maybe Expression -> AddPolicyOptions 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 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 -> TablesController ShowTableAction { Text tableName :: Text $sel:tableName:TablesAction :: Text .. } action DeletePolicyAction { Text tableName :: Text $sel:tableName:NewPolicyAction :: PoliciesController -> Text tableName, Text policyName :: Text $sel:policyName:NewPolicyAction :: PoliciesController -> Text policyName } = do let deletePolicy :: [Statement] -> [Statement] deletePolicy = DeletePolicyOptions -> [Statement] -> [Statement] SchemaOperations.deletePolicy DeletePolicyOptions :: Text -> Text -> DeletePolicyOptions SchemaOperations.DeletePolicyOptions { Text $sel:tableName:DeletePolicyOptions :: Text tableName :: Text tableName, Text $sel:policyName:DeletePolicyOptions :: Text policyName :: 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 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 -> TablesController ShowTableAction { Text tableName :: Text $sel:tableName:TablesAction :: Text .. }