From 6c6e0e964ad24a64932fd46f3c8eac5db27f14bf Mon Sep 17 00:00:00 2001 From: Lucas Sousa Date: Fri, 6 Oct 2023 17:31:14 +0200 Subject: [PATCH] Create RBAC contexts for new plastic strategies [Re #1611] * We'll need the RBAC contexts as we'll use permissions to control access of users to plastic strategy's API resources. --- backend/src/gpml/db/plastic_strategy.clj | 31 ++++++++++++- backend/src/gpml/db/plastic_strategy.sql | 8 ++++ .../handler/programmatic/plastic_strategy.clj | 10 ++--- backend/src/gpml/service/plastic_strategy.clj | 43 ++++++++++++++++++- 4 files changed, 84 insertions(+), 8 deletions(-) diff --git a/backend/src/gpml/db/plastic_strategy.clj b/backend/src/gpml/db/plastic_strategy.clj index f0538810d..a1258b8f6 100644 --- a/backend/src/gpml/db/plastic_strategy.clj +++ b/backend/src/gpml/db/plastic_strategy.clj @@ -1,10 +1,13 @@ (ns gpml.db.plastic-strategy {:ns-tracker/resource-deps ["plastic_strategy.sql"]} - (:require [hugsql.core :as hugsql])) + (:require [gpml.db.jdbc-util :as jdbc-util] + [hugsql.core :as hugsql])) (declare get-plastic-strategies* update-plastic-strategy* - create-plastic-strategies*) + create-plastic-strategies* + create-plastic-strategy* + delete-plastic-strategy*) (hugsql/def-db-fns "gpml/db/plastic_strategy.sql") @@ -64,3 +67,27 @@ {:success? false :reason :exception :error-details {:msg (ex-message t)}}))) + +(defn create-plastic-strategy + [conn plastic-strategy] + (jdbc-util/with-constraint-violation-check + [{:type :unique + :name "plastic_strategy_country_id_key" + :error-reason :already-exists}] + {:success? true + :id (:id (create-plastic-strategy* conn plastic-strategy))})) + +(defn delete-plastic-strategy + [conn plastic-strategy-id] + (try + (let [affected (delete-plastic-strategy* conn {:id plastic-strategy-id})] + (if (= affected 1) + {:success? true} + {:success? false + :reason :unexpected-number-of-affected-rows + :error-details {:expected-affected-rows 1 + :actual-affected-rows affected}})) + (catch Throwable t + {:success? false + :reason :exception + :error-details {:msg (ex-message t)}}))) diff --git a/backend/src/gpml/db/plastic_strategy.sql b/backend/src/gpml/db/plastic_strategy.sql index b0aef6db1..4b961e472 100644 --- a/backend/src/gpml/db/plastic_strategy.sql +++ b/backend/src/gpml/db/plastic_strategy.sql @@ -27,3 +27,11 @@ WHERE id = :id; -- :name create-plastic-strategies* :execute :affected INSERT INTO plastic_strategy(country_id) VALUES :t*:plastic-strategy; + +-- :name create-plastic-strategy* :returning-execute :one +INSERT INTO plastic_strategy(country_id) +VALUES (:country-id) RETURNING id; + +-- :name delete-plastic-strategy* :execute :affected +DELETE FROM plastic_strategy +WHERE id = :id; diff --git a/backend/src/gpml/handler/programmatic/plastic_strategy.clj b/backend/src/gpml/handler/programmatic/plastic_strategy.clj index 22d549137..6af76919e 100644 --- a/backend/src/gpml/handler/programmatic/plastic_strategy.clj +++ b/backend/src/gpml/handler/programmatic/plastic_strategy.clj @@ -1,6 +1,6 @@ (ns gpml.handler.programmatic.plastic-strategy - (:require [gpml.db.plastic-strategy :as db.ps] - [gpml.handler.responses :as r] + (:require [gpml.handler.responses :as r] + [gpml.service.plastic-strategy :as srv.ps] [integrant.core :as ig])) (def ^:private create-plastic-strategies-params-schema @@ -11,10 +11,10 @@ [:int {:min 1}]]) (defn- create-plastic-strategies - [{:keys [db]} req] + [config req] (let [countries-ids (get-in req [:parameters :body]) - plastic-strategies (map vector countries-ids) - result (db.ps/create-plastic-strategies (:spec db) plastic-strategies)] + plastic-strategies (map #(zipmap [:country-id] [%]) countries-ids) + result (srv.ps/create-plastic-strategies config plastic-strategies)] (if (:success? result) (r/ok {}) (r/server-error (dissoc result :success?))))) diff --git a/backend/src/gpml/service/plastic_strategy.clj b/backend/src/gpml/service/plastic_strategy.clj index 4176fef2e..1cbef09cc 100644 --- a/backend/src/gpml/service/plastic_strategy.clj +++ b/backend/src/gpml/service/plastic_strategy.clj @@ -1,5 +1,7 @@ (ns gpml.service.plastic-strategy - (:require [gpml.db.plastic-strategy :as db.ps])) + (:require [gpml.db.plastic-strategy :as db.ps] + [gpml.service.permissions :as srv.permissions] + [gpml.util.thread-transactions :as tht])) (defn get-plastic-strategies [{:keys [db]} search-opts] @@ -17,3 +19,42 @@ result (db.ps/update-plastic-strategy (:spec db) {:id (-> result :plastic-strategy :id) :updates {:steps steps}})))) + +(defn create-plastic-strategy + [{:keys [db logger]} plastic-strategy] + (let [transactions + [{:txn-fn + (fn tx-create-plastic-strategy + [{:keys [plastic-strategy]}] + (db.ps/create-plastic-strategy (:spec db) plastic-strategy)) + :rollback-fn + (fn rollback-create-plastic-strategy + [{:keys [id] :as context}] + (db.ps/delete-plastic-strategy (:spec db) {:id id}) + context)} + {:txn-fn + (fn tx-create-plastic-strategy-rbac-context + [{:keys [id] :as context}] + (let [result (srv.permissions/create-resource-context {:conn (:spec db) + :logger logger} + {:context-type :plastic-strategy + :resource-id id})] + (if (:success? result) + {:success? true} + (assoc context + :success? false + :reason :failed-to-create-plastic-strategy-rbac-context + :error-details result))))}] + context {:success? true + :plastic-strategy plastic-strategy}] + (tht/thread-transactions logger transactions context))) + +(defn create-plastic-strategies + [config plastic-strategies] + (let [results (map (partial create-plastic-strategy config) plastic-strategies)] + (if (every? :success? results) + {:success? true} + {:success? false + :reason :failed-to-create-all-plastic-strategies + :error-details {:msg "Partial failure" + :failed-results (filter (comp not :success?) results)}})))