diff --git a/src/fluree/db/json_ld/policy/enforce.cljc b/src/fluree/db/json_ld/policy/enforce.cljc index 735da41b56..cf83aa4c75 100644 --- a/src/fluree/db/json_ld/policy/enforce.cljc +++ b/src/fluree/db/json_ld/policy/enforce.cljc @@ -3,6 +3,7 @@ [fluree.db.dbproto :as dbproto] [fluree.db.json-ld.iri :as iri] [fluree.db.json-ld.policy :as policy :refer [root]] + [fluree.db.track :as track] [fluree.db.util.async :refer [ db :policy :trace)] - (go-try - (loop [[policy & r] policies] - ;; return first truthy response, else false - (if policy - (let [{exec-counter :executed - allowed-counter :allowed} (get tracer (:id policy)) - - query (when-let [query (:query policy)] - (policy-query db sid query)) - result (if query - (seq ( wrapper - (assoc-in [:trace id :executed] (atom 0)) - (assoc-in [:trace id :allowed] (atom 0)))] - (cond - (seq (:on-property policy)) - (add-property-restriction policy db wrapper*) + (fn [wrapper policy] + (cond + (seq (:on-property policy)) + (add-property-restriction policy db wrapper) - (or (:s-targets policy) - (:p-targets policy) - (:o-targets policy)) - (add-default-restriction policy wrapper*) + (or (:s-targets policy) + (:p-targets policy) + (:o-targets policy)) + (add-default-restriction policy wrapper) - (seq (:on-class policy)) - (add-class-restriction policy db wrapper*) + (seq (:on-class policy)) + (add-class-restriction policy db wrapper) - (:default? policy) - (add-default-restriction policy wrapper*) + (:default? policy) + (add-default-restriction policy wrapper) - :else - wrapper*)))) + :else + wrapper))) (defn parse-policies [db tracker error-ch policy-values policy-docs] @@ -224,7 +221,7 @@ (async/pipe ch))))) ;; build policy wrapper attached to db containing parsed policies - (async/reduce (build-wrapper db) {:trace {}} policy-ch))) + (async/reduce (build-wrapper db) {} policy-ch))) (defn wrap-policy ([db policy-rules policy-values] diff --git a/src/fluree/db/query/api.cljc b/src/fluree/db/query/api.cljc index 56cf6a944d..adb4f703a8 100644 --- a/src/fluree/db/query/api.cljc +++ b/src/fluree/db/query/api.cljc @@ -5,7 +5,6 @@ [fluree.db.connection :as connection] [fluree.db.dataset :as dataset :refer [dataset?]] [fluree.db.json-ld.policy :as perm] - [fluree.db.json-ld.policy.rules :as policy.rules] [fluree.db.ledger :as ledger] [fluree.db.query.fql :as fql] [fluree.db.query.fql.syntax :as syntax] @@ -76,12 +75,10 @@ returns a result or throws an exception." [ds tracker exec-fn] (go-try + (track/register-policies! tracker ds) (try* (let [result ( (assoc tally :status 200, :result result) - policy-report (assoc :policy policy-report))) + (assoc tally :status 200, :result result)) (catch* e (let [data (-> tracker track/tally diff --git a/src/fluree/db/track.cljc b/src/fluree/db/track.cljc index 280c78f285..b9367c5d1c 100644 --- a/src/fluree/db/track.cljc +++ b/src/fluree/db/track.cljc @@ -1,5 +1,6 @@ (ns fluree.db.track (:require [fluree.db.track.fuel :as fuel] + [fluree.db.track.policy :as policy] [fluree.db.track.time :as time])) #?(:clj (set! *warn-on-reflection* true)) @@ -50,22 +51,41 @@ [tracker max-fuel] (assoc tracker :fuel (fuel/init max-fuel))) +(defn init-policy + [tracker] + (assoc tracker :policy (policy/init))) + (defn init "Creates a new fuel tracker w/ optional fuel limit (0 means unlimited)." - ([] - (init {})) - ([{:keys [max-fuel] :as opts}] - (cond-> {} - (track-time? opts) init-time - (track-fuel? opts) (init-fuel max-fuel)))) + [{:keys [max-fuel] :as opts}] + (cond-> {} + (track-time? opts) init-time + (track-fuel? opts) (init-fuel max-fuel) + (track-policy? opts) init-policy)) (defn track-fuel! [tracker error-ch] (when-let [fuel-tracker (:fuel tracker)] (fuel/track! fuel-tracker error-ch))) +(defn register-policies! + [tracker policy-db] + (when-let [policy-tracker (:policy tracker)] + (policy/register-policies! policy-tracker policy-db))) + +(defn policy-exec! + [tracker policy-id] + (when-let [policy-tracker (:policy tracker)] + (policy/track-exec! policy-tracker policy-id))) + +(defn policy-allow! + [tracker policy-id] + (when-let [policy-tracker (:policy tracker)] + (policy/track-allow! policy-tracker policy-id))) + (defn tally [tracker] (cond-> tracker (contains? tracker :time) (update :time time/tally) - (contains? tracker :fuel) (update :fuel fuel/tally))) + (contains? tracker :fuel) (update :fuel fuel/tally) + (contains? tracker :policy) (update :policy policy/tally))) diff --git a/src/fluree/db/track/policy.cljc b/src/fluree/db/track/policy.cljc new file mode 100644 index 0000000000..468d0541ad --- /dev/null +++ b/src/fluree/db/track/policy.cljc @@ -0,0 +1,33 @@ +(ns fluree.db.track.policy) + +(defn register-policies! + [tracker policy-db] + (reset! tracker (reduce (fn [state policy-id] + (assoc state policy-id {:executed 0 :allowed 0})) + {} + (concat (->> policy-db :policy :view :class (vals) (mapv :id)) + (->> policy-db :policy :view :property (vals) (mapv :id)) + (->> policy-db :policy :view :default (mapv :id)) + + (->> policy-db :policy :modify :class (vals) (mapv :id)) + (->> policy-db :policy :modify :property (vals) (mapv :id)) + (->> policy-db :policy :modify :default (mapv :id)))))) + +(defn init + "Map of `->{:executed :allowed }`, where `:executed` is the + number of times a policy is executed on a flake and `:allowed` is the number of times + it grants access to a flake." + [] + (atom {})) + +(defn track-exec! + [tracker policy-id] + (swap! tracker update-in [policy-id :executed] inc)) + +(defn track-allow! + [tracker policy-id] + (swap! tracker update-in [policy-id :allowed] inc)) + +(defn tally + [tracker] + @tracker) diff --git a/src/fluree/db/transact.cljc b/src/fluree/db/transact.cljc index e4034ed1f1..86e574dbb4 100644 --- a/src/fluree/db/transact.cljc +++ b/src/fluree/db/transact.cljc @@ -8,7 +8,6 @@ [fluree.db.json-ld.credential :as credential] [fluree.db.json-ld.iri :as iri] [fluree.db.json-ld.policy :as policy] - [fluree.db.json-ld.policy.rules :as policy.rules] [fluree.db.ledger :as ledger] [fluree.db.nameservice :as nameservice] [fluree.db.storage :as storage] @@ -82,22 +81,19 @@ parsed-context (:context parsed-opts) identity (:identity parsed-opts)] (if (track/track-txn? parsed-opts) - (let [tracker (track/init parsed-opts) - policy-db (if (policy/policy-enforced-opts? parsed-opts) - ( (assoc tally :status 200, :db staged-db) - policy-report (assoc :policy policy-report))) + (assoc tally :status 200, :db staged-db)) (catch* e (throw (ex-info (ex-message e) - (let [policy-report (policy.rules/enforcement-report policy-db) - tally (track/tally tracker)] - (cond-> (merge (ex-data e) tally) - policy-report (assoc :policy policy-report))) + (let [tally (track/tally tracker)] + (merge (ex-data e) tally)) e))))) (let [policy-db (if (policy/policy-enforced-opts? parsed-opts) (