From 01016dade67c91879311716fa6753f8ad2ee2dda Mon Sep 17 00:00:00 2001 From: Marc Date: Thu, 21 Mar 2024 10:34:30 +0100 Subject: [PATCH] use string preprocessor and remove functions (#17) * use string preprocessor and remove functions * add deprecation notification to start function --- README.md | 29 -- backend/mariadb_backend.ml | 631 ++++++++++++++++++------------------- lib/persistence.ml | 2 +- test/main.ml | 1 - 4 files changed, 314 insertions(+), 349 deletions(-) diff --git a/README.md b/README.md index 805c1fe..4b05b40 100644 --- a/README.md +++ b/README.md @@ -68,35 +68,6 @@ Example usage: let update_title = Article.update_title ?ctx mike thomas_article "Updated Title" ``` -### Integrate within a query (MariaDB) - -Requirement: Run `MariaDb.start` when the executable is started. - -The `start` function defines needed MariaDB functions for guardian. They can be integrated within your queries as well. -It creates a `guardianValidateUuid(...)` function for all roles, it takes care of all registered Relations within guardian. - -The following example shows how to check for a specific Post: - -```ocaml -(** [guardianValidatePostUuid] - - Input arguments: - - actor_uuid (binary 16) - - action (enum: 'create','read','update','delete','manage') - - target_uuid (binary 16, usually within the query) - - Outputs a boolean -*) -let find_accessible kind = - {sql| - SELECT * - FROM posts - GROUP BY posts.uuid - HAVING guardianValidatePostUuid(guardianEncodeUuid(?), ?, posts.uuid) - |sql} - |> Caqti_type.(t2 UuidActor.t Action.t ->* Post.t) -``` - ## Development A guide how to setup the project with devcontainers can be found [here](./.devcontainer/README.md). diff --git a/backend/mariadb_backend.ml b/backend/mariadb_backend.ml index 118ea2d..6292ac8 100644 --- a/backend/mariadb_backend.ml +++ b/backend/mariadb_backend.ml @@ -25,6 +25,23 @@ struct module Entity = struct module Uuid = struct + let sql_select_fragment field = + [%string + {sql| + LOWER(CONCAT( + SUBSTR(HEX(%{field}), 1, 8), '-', + SUBSTR(HEX(%{field}), 9, 4), '-', + SUBSTR(HEX(%{field}), 13, 4), '-', + SUBSTR(HEX(%{field}), 17, 4), '-', + SUBSTR(HEX(%{field}), 21) + )) + |sql}] + ;; + + let sql_value_fragment name = + [%string {sql| UNHEX(REPLACE(%{name}, '-', '')) |sql}] + ;; + module UuidBase (Core : Guard.Uuid.Sig) = struct include Core @@ -290,40 +307,6 @@ struct let role_assignment = Entity.RoleAssignment.t end - let define_encode_uuid = - let function_name = "guardianEncodeUuid" in - ( function_name - , Format.asprintf - {sql| - CREATE FUNCTION %s(uuid VARCHAR(36)) - RETURNS BINARY(16) - BEGIN - RETURN UNHEX(REPLACE(uuid, '-', '')); - END - |sql} - function_name ) - ;; - - let define_decode_uuid = - let function_name = "guardianDecodeUuid" in - ( function_name - , Format.asprintf - {sql| - CREATE FUNCTION %s(uuid BINARY(16)) - RETURNS VARCHAR(36) - BEGIN - RETURN LOWER(CONCAT( - SUBSTR(HEX(uuid), 1, 8), '-', - SUBSTR(HEX(uuid), 9, 4), '-', - SUBSTR(HEX(uuid), 13, 4), '-', - SUBSTR(HEX(uuid), 17, 4), '-', - SUBSTR(HEX(uuid), 21) - )); - END - |sql} - function_name ) - ;; - let combine_sql from_sql std_filter_sql @@ -345,24 +328,31 @@ struct module ActorRole = struct let upsert_uuid_request = - {sql| - INSERT INTO guardian_actor_role_targets (actor_uuid, role, target_uuid) - VALUES (guardianEncodeUuid(?), ?, guardianEncodeUuid(?)) - ON DUPLICATE KEY UPDATE - mark_as_deleted = NULL, - updated_at = NOW() - |sql} + let open Entity.Uuid in + [%string + {sql| + INSERT INTO guardian_actor_role_targets (actor_uuid, role, target_uuid) + VALUES ( + %{sql_value_fragment "?"}, + ?, + %{sql_value_fragment "?"} + ) + ON DUPLICATE KEY UPDATE + mark_as_deleted = NULL, + updated_at = NOW() + |sql}] |> Entity.ActorRole.targets ->. Caqti_type.unit ;; let upsert_model_request = - {sql| - INSERT INTO guardian_actor_roles (actor_uuid, role) - VALUES (guardianEncodeUuid(?), ?) - ON DUPLICATE KEY UPDATE - mark_as_deleted = NULL, - updated_at = NOW() - |sql} + [%string + {sql| + INSERT INTO guardian_actor_roles (actor_uuid, role) + VALUES (%{Entity.Uuid.sql_value_fragment "?"}, ?) + ON DUPLICATE KEY UPDATE + mark_as_deleted = NULL, + updated_at = NOW() + |sql}] |> Entity.ActorRole.role ->. Caqti_type.unit ;; @@ -374,41 +364,45 @@ struct ;; let find_by_actor_request = - {sql| - SELECT - guardianDecodeUuid(role_targets.actor_uuid), - role_targets.role, - guardianDecodeUuid(role_targets.target_uuid) - FROM guardian_actor_role_targets AS role_targets - WHERE role_targets.actor_uuid = guardianEncodeUuid($1) - AND role_targets.mark_as_deleted IS NULL - UNION - SELECT guardianDecodeUuid(roles.actor_uuid), roles.role, NULL - FROM guardian_actor_roles AS roles - WHERE roles.actor_uuid = guardianEncodeUuid($1) - AND roles.mark_as_deleted IS NULL - |sql} + let open Entity.Uuid in + [%string + {sql| + SELECT + %{sql_select_fragment "role_targets.actor_uuid"}, + role_targets.role, + %{sql_select_fragment "role_targets.target_uuid"} + FROM guardian_actor_role_targets AS role_targets + WHERE role_targets.actor_uuid = %{sql_value_fragment "$1"} + AND role_targets.mark_as_deleted IS NULL + UNION + SELECT %{sql_select_fragment "roles.actor_uuid"}, roles.role, NULL + FROM guardian_actor_roles AS roles + WHERE roles.actor_uuid = %{sql_value_fragment "$1"} + AND roles.mark_as_deleted IS NULL + |sql}] |> Entity.(Uuid.Actor.t ->* ActorRole.t) ;; let find_by_actor ?ctx = Database.collect ?ctx find_by_actor_request let find_by_target_request = - {sql| - SELECT - guardianDecodeUuid(role_targets.actor_uuid), - role_targets.role, - guardianDecodeUuid(role_targets.target_uuid) - FROM guardian_actor_role_targets AS role_targets - WHERE role_targets.role = $1 - AND role_targets.target_uuid = guardianEncodeUuid($2) - AND role_targets.mark_as_deleted IS NULL - UNION - SELECT guardianDecodeUuid(roles.actor_uuid), roles.role, NULL - FROM guardian_actor_roles AS roles - WHERE roles.role = $1 - AND roles.mark_as_deleted IS NULL - |sql} + let open Entity.Uuid in + [%string + {sql| + SELECT + %{sql_select_fragment "role_targets.actor_uuid"}, + role_targets.role, + %{sql_select_fragment "role_targets.target_uuid"} + FROM guardian_actor_role_targets AS role_targets + WHERE role_targets.role = $1 + AND role_targets.target_uuid = %{Entity.Uuid.sql_value_fragment "$2"} + AND role_targets.mark_as_deleted IS NULL + UNION + SELECT %{sql_select_fragment "roles.actor_uuid"}, roles.role, NULL + FROM guardian_actor_roles AS roles + WHERE roles.role = $1 + AND roles.mark_as_deleted IS NULL + |sql}] |> Entity.(Caqti_type.t2 Role.t Uuid.Target.t ->* ActorRole.t) ;; @@ -437,8 +431,8 @@ struct :: args , dyn |> add Model.role role ) | Some uuid -> - ( "(exclude.role = ? AND exclude.target_uuid = \ - guardianEncodeUuid(?))" + ( [%string + {sql|(exclude.role = ? AND exclude.target_uuid = %{Entity.Uuid.sql_value_fragment "?"})|sql}] :: args , dyn |> add Model.role role @@ -464,29 +458,27 @@ struct ;; let find_actors_by_role_request ?(exclude_sql = "") params = - Format.asprintf + [%string {sql| - SELECT guardianDecodeUuid(roles.actor_uuid) + SELECT %{Entity.Uuid.sql_select_fragment "roles.actor_uuid"} FROM guardian_actor_roles AS roles WHERE roles.role = ? AND roles.mark_as_deleted IS NULL - %s - |sql} - exclude_sql + %{exclude_sql} + |sql}] |> params ->* Entity.Uuid.Actor.t ;; let find_actors_by_target_request ?(exclude_sql = "") params = - Format.asprintf + [%string {sql| - SELECT guardianDecodeUuid(role_targets.actor_uuid) + SELECT %{Entity.Uuid.sql_select_fragment "role_targets.actor_uuid"} FROM guardian_actor_role_targets AS role_targets - WHERE role_targets.target_uuid = guardianEncodeUuid(?) + WHERE role_targets.target_uuid = %{Entity.Uuid.sql_value_fragment "?"} AND role_targets.mark_as_deleted IS NULL AND role_targets.role = ? - %s - |sql} - exclude_sql + %{exclude_sql} + |sql}] |> params ->* Entity.Uuid.Actor.t ;; @@ -519,49 +511,50 @@ struct let permissions_of_actor_request = let open Entity in - {sql| - SELECT - role_permissions.permission, - role_permissions.target_model, - guardianDecodeUuid(roles.target_uuid) - FROM - guardian_actor_role_targets AS roles - LEFT JOIN guardian_role_permissions AS role_permissions - ON role_permissions.role = roles.role - AND role_permissions.mark_as_deleted IS NULL - WHERE - roles.mark_as_deleted IS NULL - AND roles.actor_uuid = guardianEncodeUuid($1) - AND `permission` IS NOT null - UNION - SELECT - role_permissions.permission, - role_permissions.target_model, - NULL - FROM - guardian_actor_roles AS roles - LEFT JOIN guardian_role_permissions AS role_permissions - ON role_permissions.role = roles.role - AND role_permissions.mark_as_deleted IS NULL - WHERE - roles.mark_as_deleted IS NULL - AND roles.actor_uuid = guardianEncodeUuid($1) - AND `permission` IS NOT null - UNION - SELECT - actor_permissions.permission, - COALESCE (actor_permissions.target_model, targets.model), - guardianDecodeUuid(actor_permissions.target_uuid) - FROM - guardian_actor_permissions AS actor_permissions - LEFT JOIN guardian_targets AS targets - ON targets.uuid = actor_permissions.target_uuid - AND targets.mark_as_deleted IS NULL - WHERE - actor_permissions.actor_uuid = guardianEncodeUuid($1) - AND actor_permissions.mark_as_deleted IS NULL - AND `permission` IS NOT null - |sql} + [%string + {sql| + SELECT + role_permissions.permission, + role_permissions.target_model, + %{Uuid.sql_select_fragment "roles.target_uuid"} + FROM + guardian_actor_role_targets AS roles + LEFT JOIN guardian_role_permissions AS role_permissions + ON role_permissions.role = roles.role + AND role_permissions.mark_as_deleted IS NULL + WHERE + roles.mark_as_deleted IS NULL + AND roles.actor_uuid = %{Uuid.sql_value_fragment "$1"} + AND `permission` IS NOT null + UNION + SELECT + role_permissions.permission, + role_permissions.target_model, + NULL + FROM + guardian_actor_roles AS roles + LEFT JOIN guardian_role_permissions AS role_permissions + ON role_permissions.role = roles.role + AND role_permissions.mark_as_deleted IS NULL + WHERE + roles.mark_as_deleted IS NULL + AND roles.actor_uuid = %{Uuid.sql_value_fragment "$1"} + AND `permission` IS NOT null + UNION + SELECT + actor_permissions.permission, + COALESCE (actor_permissions.target_model, targets.model), + %{Uuid.sql_select_fragment "actor_permissions.target_uuid"} + FROM + guardian_actor_permissions AS actor_permissions + LEFT JOIN guardian_targets AS targets + ON targets.uuid = actor_permissions.target_uuid + AND targets.mark_as_deleted IS NULL + WHERE + actor_permissions.actor_uuid = %{Uuid.sql_value_fragment "$1"} + AND actor_permissions.mark_as_deleted IS NULL + AND `permission` IS NOT null + |sql}] |> Uuid.Actor.t ->* PermissionOnTarget.t ;; @@ -574,25 +567,26 @@ struct ;; let delete_role_uuid_request = - Format.asprintf + [%string {sql| UPDATE guardian_actor_role_targets SET mark_as_deleted = NOW() - WHERE actor_uuid = guardianEncodeUuid($1) + WHERE actor_uuid = %{Entity.Uuid.sql_value_fragment "$1"} AND role = $2 - AND target_uuid = guardianEncodeUuid($3) - |sql} + AND target_uuid = %{Entity.Uuid.sql_value_fragment "$3"} + |sql}] |> Entity.ActorRole.targets ->. Caqti_type.unit ;; let delete_role_model_request = let open Entity in - {sql| - UPDATE guardian_actor_roles - SET mark_as_deleted = NOW() - WHERE actor_uuid = guardianEncodeUuid($1) - AND role = $2 - |sql} + [%string + {sql| + UPDATE guardian_actor_roles + SET mark_as_deleted = NOW() + WHERE actor_uuid = %{Uuid.sql_value_fragment "$1"} + AND role = $2 + |sql}] |> Caqti_type.(t2 Uuid.Actor.t Model.role ->. unit) ;; @@ -692,12 +686,13 @@ struct ;; let select_sql = - {sql| - guardianDecodeUuid(actor_permissions.actor_uuid), - actor_permissions.permission, - actor_permissions.target_model, - guardianDecodeUuid(actor_permissions.target_uuid) - |sql} + Entity.Uuid. + [ sql_select_fragment "actor_permissions.actor_uuid" + ; "actor_permissions.permission" + ; "actor_permissions.target_model" + ; sql_select_fragment "actor_permissions.target_uuid" + ] + |> CCString.concat ",\n" ;; let combine_sql = combine_sql from_sql std_filter_sql @@ -714,9 +709,10 @@ struct {sql|JOIN guardian_targets AS targets ON targets.uuid = actor_permissions.target_uuid|sql} in let where_additions = - {sql|actor_permissions.target_uuid = $1 - OR actor_permissions.target_model = (SELECT targets.model FROM guardian_targets AS targets WHERE targets.uuid = guardianEncodeUuid($1)) - |sql} + [%string + {sql|actor_permissions.target_uuid = %{Entity.Uuid.sql_value_fragment "$1"} + OR actor_permissions.target_model = (SELECT targets.model FROM guardian_targets AS targets WHERE targets.uuid = %{Entity.Uuid.sql_value_fragment "$1"}) + |sql}] in combine_sql ~joins ~where_additions select_sql |> Entity.(Uuid.Target.t ->* ActorPermission.t) @@ -728,8 +724,8 @@ struct in let where_additions = {sql|actor_permissions.target_model = $1 - OR (actor_permissions.target_model IS NULL AND targets.model = $1) - |sql} + OR (actor_permissions.target_model IS NULL AND targets.model = $1) + |sql} in combine_sql ~joins ~where_additions select_sql |> Entity.(TargetModel.t ->* ActorPermission.t) @@ -744,13 +740,14 @@ struct ;; let insert_request = - {sql| - INSERT INTO guardian_actor_permissions (actor_uuid, permission, target_model, target_uuid) - VALUES (guardianEncodeUuid(?), ?, ?, guardianEncodeUuid(?)) - ON DUPLICATE KEY UPDATE - mark_as_deleted = NULL, - updated_at = NOW() - |sql} + [%string + {sql| + INSERT INTO guardian_actor_permissions (actor_uuid, permission, target_model, target_uuid) + VALUES (%{Entity.Uuid.sql_value_fragment "?"}, ?, ?, %{Entity.Uuid.sql_value_fragment "?"}) + ON DUPLICATE KEY UPDATE + mark_as_deleted = NULL, + updated_at = NOW() + |sql}] |> Entity.ActorPermission.t ->. Caqti_type.unit ;; @@ -760,14 +757,16 @@ struct ;; let delete_request = - {sql| - UPDATE guardian_actor_permissions - SET mark_as_deleted = NOW() - WHERE actor_uuid = guardianEncodeUuid($1) - AND permission = $2 - AND (($3 IS NULL AND target_model IS NULL) OR target_model = $3) - AND (($4 IS NULL AND target_uuid IS NULL) OR target_uuid = guardianEncodeUuid($4)) - |sql} + let open Entity.Uuid in + [%string + {sql| + UPDATE guardian_actor_permissions + SET mark_as_deleted = NOW() + WHERE actor_uuid = %{sql_value_fragment "$1"} + AND permission = $2 + AND (($3 IS NULL AND target_model IS NULL) OR target_model = $3) + AND (($4 IS NULL AND target_uuid IS NULL) OR target_uuid = %{sql_value_fragment "$4"}) + |sql}] |> Entity.ActorPermission.t ->. Caqti_type.unit ;; @@ -787,22 +786,21 @@ struct let std_filter_sql = {sql| actors.mark_as_deleted IS NULL |sql} let select_sql = - {sql| - guardianDecodeUuid(actors.uuid), - actors.model - |sql} + [ Entity.Uuid.sql_select_fragment "actors.uuid"; "actors.model" ] + |> CCString.concat ",\n" ;; let combine_sql = combine_sql from_sql std_filter_sql let insert_request = - {sql| - INSERT INTO guardian_actors (uuid, model) - VALUES (guardianEncodeUuid(?), ?) - ON DUPLICATE KEY UPDATE - mark_as_deleted = NULL, - updated_at = NOW() - |sql} + [%string + {sql| + INSERT INTO guardian_actors (uuid, model) + VALUES (%{Entity.Uuid.sql_value_fragment "?"}, ?) + ON DUPLICATE KEY UPDATE + mark_as_deleted = NULL, + updated_at = NOW() + |sql}] |> Entity.Actor.t ->. Caqti_type.unit ;; @@ -810,7 +808,9 @@ struct let memorize_request = combine_sql - ~where_additions:{sql|actors.uuid = guardianEncodeUuid(?)|sql} + ~where_additions: + [%string + {sql|actors.uuid = %{Entity.Uuid.sql_value_fragment "?"}|sql}] {sql|TRUE|sql} |> Entity.Uuid.Actor.t ->? Caqti_type.bool ;; @@ -823,7 +823,9 @@ struct let find_request = combine_sql - ~where_additions:{sql|actors.uuid = guardianEncodeUuid(?)|sql} + ~where_additions: + [%string + {sql|actors.uuid = %{Entity.Uuid.sql_value_fragment "?"}|sql}] select_sql |> Entity.(Uuid.Actor.t ->? Actor.t) ;; @@ -844,22 +846,21 @@ struct let std_filter_sql = {sql| targets.mark_as_deleted IS NULL |sql} let select_sql = - {sql| - guardianDecodeUuid(targets.uuid), - targets.model - |sql} + [ Entity.Uuid.sql_select_fragment "targets.uuid"; "targets.model" ] + |> CCString.concat ",\n" ;; let combine_sql = combine_sql from_sql std_filter_sql let insert_request = - {sql| - INSERT INTO guardian_targets (uuid, model) - VALUES (guardianEncodeUuid(?), ?) - ON DUPLICATE KEY UPDATE - mark_as_deleted = NULL, - updated_at = NOW() - |sql} + [%string + {sql| + INSERT INTO guardian_targets (uuid, model) + VALUES (%{Entity.Uuid.sql_value_fragment "?"}, ?) + ON DUPLICATE KEY UPDATE + mark_as_deleted = NULL, + updated_at = NOW() + |sql}] |> Caqti_type.(Entity.Target.t ->. unit) ;; @@ -867,7 +868,9 @@ struct let memorize_request = combine_sql - ~where_additions:{sql|targets.uuid = guardianEncodeUuid(?)|sql} + ~where_additions: + [%string + {sql|targets.uuid = %{Entity.Uuid.sql_value_fragment "?"}|sql}] {sql|TRUE|sql} |> Entity.Uuid.Target.t ->? Caqti_type.bool ;; @@ -880,7 +883,9 @@ struct let find_request = combine_sql - ~where_additions:{sql|targets.uuid = guardianEncodeUuid(?)|sql} + ~where_additions: + [%string + {sql|targets.uuid = %{Entity.Uuid.sql_value_fragment "?"}|sql}] select_sql |> Entity.(Uuid.Target.t ->? Target.t) ;; @@ -893,7 +898,9 @@ struct let find_model_request = combine_sql - ~where_additions:{sql|targets.uuid = guardianEncodeUuid(?)|sql} + ~where_additions: + [%string + {sql|targets.uuid = %{Entity.Uuid.sql_value_fragment "?"}|sql}] {sql|targets.model|sql} |> Entity.(Uuid.Target.t ->? TargetModel.t) ;; @@ -906,11 +913,12 @@ struct let promote_request = let open Entity in - {sql| - UPDATE guardian_targets - SET model = $2, mark_as_deleted = NULL - WHERE uuid = guardianEncodeUuid($1) - |sql} + [%string + {sql| + UPDATE guardian_targets + SET model = $2, mark_as_deleted = NULL + WHERE uuid = %{Uuid.sql_value_fragment "$1"} + |sql}] |> Caqti_type.(t2 Uuid.Target.t TargetModel.t ->. unit) ;; @@ -988,28 +996,29 @@ struct let open Lwt.Infix in let validate_request = let open Entity in - {sql| - SELECT ( - SELECT TRUE - FROM guardian_actor_roles AS roles - LEFT JOIN guardian_role_permissions AS role_permissions - ON roles.role = role_permissions.role - AND role_permissions.mark_as_deleted IS NULL - WHERE roles.mark_as_deleted IS NULL - AND roles.actor_uuid = guardianEncodeUuid($1) - AND role_permissions.target_model = $3 - AND (role_permissions.permission = $2 OR role_permissions.permission = 'manage') - LIMIT 1 - ) OR ( - SELECT TRUE - FROM guardian_actor_permissions AS actor_permissions - WHERE actor_permissions.mark_as_deleted IS NULL - AND actor_permissions.actor_uuid = guardianEncodeUuid($1) - AND actor_permissions.target_model = $3 - AND (actor_permissions.permission = $2 OR actor_permissions.permission = 'manage') - LIMIT 1 - ) - |sql} + [%string + {sql| + SELECT ( + SELECT TRUE + FROM guardian_actor_roles AS roles + LEFT JOIN guardian_role_permissions AS role_permissions + ON roles.role = role_permissions.role + AND role_permissions.mark_as_deleted IS NULL + WHERE roles.mark_as_deleted IS NULL + AND roles.actor_uuid = %{Uuid.sql_value_fragment "$1"} + AND role_permissions.target_model = $3 + AND (role_permissions.permission = $2 OR role_permissions.permission = 'manage') + LIMIT 1 + ) OR ( + SELECT TRUE + FROM guardian_actor_permissions AS actor_permissions + WHERE actor_permissions.mark_as_deleted IS NULL + AND actor_permissions.actor_uuid = %{Uuid.sql_value_fragment "$1"} + AND actor_permissions.target_model = $3 + AND (actor_permissions.permission = $2 OR actor_permissions.permission = 'manage') + LIMIT 1 + ) + |sql}] |> Caqti_type.( t3 Uuid.Actor.t Permission.t TargetModel.t ->? option bool) in @@ -1036,44 +1045,45 @@ struct in let validate_request = let open Entity in - {sql| - SELECT ( - SELECT TRUE - FROM guardian_actor_roles AS roles - JOIN guardian_role_permissions AS role_permissions - ON roles.role = role_permissions.role - AND role_permissions.mark_as_deleted IS NULL - WHERE roles.mark_as_deleted IS NULL - AND roles.actor_uuid = guardianEncodeUuid($1) - AND role_permissions.target_model = $3 - AND (role_permissions.permission = $2 OR role_permissions.permission = 'manage') - LIMIT 1 - ) OR ( - SELECT TRUE - FROM guardian_actor_role_targets AS role_targets - LEFT JOIN guardian_role_permissions AS role_permissions - ON role_targets.role = role_permissions.role - AND role_permissions.mark_as_deleted IS NULL - WHERE role_targets.mark_as_deleted IS NULL - AND role_targets.actor_uuid = guardianEncodeUuid($1) - AND role_targets.target_uuid = guardianEncodeUuid($4) - AND role_permissions.target_model = $3 - AND (role_permissions.permission = $2 OR role_permissions.permission = 'manage') - LIMIT 1 - ) OR ( - SELECT TRUE - FROM guardian_actor_permissions AS actor_permissions - WHERE actor_permissions.mark_as_deleted IS NULL - AND actor_permissions.actor_uuid = guardianEncodeUuid($1) - AND ( - (actor_permissions.target_model = $3 AND actor_permissions.target_uuid IS NULL) - OR - (actor_permissions.target_model IS NULL AND actor_permissions.target_uuid = guardianEncodeUuid($4)) - ) - AND (actor_permissions.permission = $2 OR actor_permissions.permission = 'manage') + [%string + {sql| + SELECT ( + SELECT TRUE + FROM guardian_actor_roles AS roles + JOIN guardian_role_permissions AS role_permissions + ON roles.role = role_permissions.role + AND role_permissions.mark_as_deleted IS NULL + WHERE roles.mark_as_deleted IS NULL + AND roles.actor_uuid = %{Uuid.sql_value_fragment "$1"} + AND role_permissions.target_model = $3 + AND (role_permissions.permission = $2 OR role_permissions.permission = 'manage') LIMIT 1 - ) - |sql} + ) OR ( + SELECT TRUE + FROM guardian_actor_role_targets AS role_targets + LEFT JOIN guardian_role_permissions AS role_permissions + ON role_targets.role = role_permissions.role + AND role_permissions.mark_as_deleted IS NULL + WHERE role_targets.mark_as_deleted IS NULL + AND role_targets.actor_uuid = %{Uuid.sql_value_fragment "$1"} + AND role_targets.target_uuid = %{Uuid.sql_value_fragment "$4"} + AND role_permissions.target_model = $3 + AND (role_permissions.permission = $2 OR role_permissions.permission = 'manage') + LIMIT 1 + ) OR ( + SELECT TRUE + FROM guardian_actor_permissions AS actor_permissions + WHERE actor_permissions.mark_as_deleted IS NULL + AND actor_permissions.actor_uuid = %{Uuid.sql_value_fragment "$1"} + AND ( + (actor_permissions.target_model = $3 AND actor_permissions.target_uuid IS NULL) + OR + (actor_permissions.target_model IS NULL AND actor_permissions.target_uuid = %{Uuid.sql_value_fragment "$4"}) + ) + AND (actor_permissions.permission = $2 OR actor_permissions.permission = 'manage') + LIMIT 1 + ) + |sql}] |> Caqti_type.( t2 Uuid.Actor.t @@ -1111,48 +1121,51 @@ struct | false -> fcn in let role_permission_request = - {sql| - SELECT TRUE - FROM guardian_actor_roles AS roles - LEFT JOIN guardian_role_permissions AS role_permissions - ON roles.role = role_permissions.role - AND role_permissions.mark_as_deleted IS NULL - WHERE roles.mark_as_deleted IS NULL - AND roles.actor_uuid = guardianEncodeUuid($1) - AND role_permissions.target_model = $3 - AND (role_permissions.permission = $2 OR role_permissions.permission = 'manage') - LIMIT 1 - |sql} + [%string + {sql| + SELECT TRUE + FROM guardian_actor_roles AS roles + LEFT JOIN guardian_role_permissions AS role_permissions + ON roles.role = role_permissions.role + AND role_permissions.mark_as_deleted IS NULL + WHERE roles.mark_as_deleted IS NULL + AND roles.actor_uuid = %{Entity.Uuid.sql_value_fragment "$1"} + AND role_permissions.target_model = $3 + AND (role_permissions.permission = $2 OR role_permissions.permission = 'manage') + LIMIT 1 + |sql}] |> to_req in let role_permission_target_request = - {sql| - SELECT TRUE - FROM guardian_actor_role_targets AS role_targets - LEFT JOIN guardian_role_permissions AS role_permissions - ON role_targets.role = role_permissions.role - AND role_permissions.mark_as_deleted IS NULL - WHERE role_targets.mark_as_deleted IS NULL - AND role_targets.actor_uuid = guardianEncodeUuid($1) - AND role_permissions.target_model = $3 - AND (role_permissions.permission = $2 OR role_permissions.permission = 'manage') - LIMIT 1 - |sql} + [%string + {sql| + SELECT TRUE + FROM guardian_actor_role_targets AS role_targets + LEFT JOIN guardian_role_permissions AS role_permissions + ON role_targets.role = role_permissions.role + AND role_permissions.mark_as_deleted IS NULL + WHERE role_targets.mark_as_deleted IS NULL + AND role_targets.actor_uuid = %{Entity.Uuid.sql_value_fragment "$1"} + AND role_permissions.target_model = $3 + AND (role_permissions.permission = $2 OR role_permissions.permission = 'manage') + LIMIT 1 + |sql}] |> to_req in let actor_permission_request = - {sql| - SELECT TRUE - FROM guardian_actor_permissions AS actor_permissions - LEFT JOIN guardian_targets AS targets - ON actor_permissions.target_uuid = targets.uuid - AND targets.mark_as_deleted IS NULL - WHERE actor_permissions.mark_as_deleted IS NULL - AND actor_permissions.actor_uuid = guardianEncodeUuid($1) - AND (actor_permissions.permission = $2 OR actor_permissions.permission = 'manage') - AND (targets.model = $3 OR actor_permissions.target_model = $3) - LIMIT 1 - |sql} + [%string + {sql| + SELECT TRUE + FROM guardian_actor_permissions AS actor_permissions + LEFT JOIN guardian_targets AS targets + ON actor_permissions.target_uuid = targets.uuid + AND targets.mark_as_deleted IS NULL + WHERE actor_permissions.mark_as_deleted IS NULL + AND actor_permissions.actor_uuid = %{Entity.Uuid.sql_value_fragment "$1"} + AND (actor_permissions.permission = $2 OR actor_permissions.permission = 'manage') + AND (targets.model = $3 OR actor_permissions.target_model = $3) + LIMIT 1 + |sql}] |> to_req in find_bool role_permission_request @@ -1196,32 +1209,14 @@ struct | Ok () -> true | Error _ -> false ;; - - let define_functions ?ctx () = - let open Caqti_type in - let queries = - [ define_encode_uuid; define_decode_uuid ] - |> CCList.flat_map (fun (fcn_name, fcn) -> - [ Format.asprintf {sql|DROP FUNCTION IF EXISTS %s|sql} fcn_name - ; fcn - ]) - in - let%lwt run = - Database.transaction ?ctx (fun connection -> - let module Connection = (val connection : Caqti_lwt.CONNECTION) in - Lwt_list.iter_s - (fun query -> - Connection.exec (query |> unit ->. unit) () - |> Lwt.map (Database_pools.get_or_raise ?ctx ())) - queries) - in - run - ;; end (** [start ?ctx ()] runs needed actions to start the backend, e.g. redefines needed functions **) - let start = Repo.define_functions + let start ?ctx () = + let (_ : (string * string) list option) = ctx in + Lwt.return_unit + ;; (** [find_migrations ()] returns a list of all migrations as a tuple with key, datetime and sql query **) diff --git a/lib/persistence.ml b/lib/persistence.ml index bed03c6..e071329 100644 --- a/lib/persistence.ml +++ b/lib/persistence.ml @@ -143,7 +143,7 @@ module type Backend = sig val clear_cache : unit -> unit end - val start : ?ctx:context -> unit -> unit Lwt.t + val start : ?ctx:context -> unit -> unit Lwt.t [@@deprecated] val find_migrations : unit -> (string * string * string) list val find_clean : unit -> context val migrate : ?ctx:context -> unit -> unit Lwt.t diff --git a/test/main.ml b/test/main.ml index d346209..c91e87e 100644 --- a/test/main.ml +++ b/test/main.ml @@ -838,7 +838,6 @@ let () = let%lwt () = Maria.delete ~ctx () in let%lwt () = Maria.migrate ~ctx () in let%lwt () = Maria.clean ~ctx () in - let%lwt () = Maria.start ~ctx () in make_test_cases ~ctx (module Maria) "MariadDB Backend" |> Alcotest_lwt.run "Authorization" ;;