Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 16 additions & 20 deletions src/fluree/db/json_ld/policy/enforce.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -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 [<? go-try]]
[fluree.db.util.parse :as util.parse]))

Expand Down Expand Up @@ -92,26 +93,21 @@
"Once narrowed to a specific set of policies, execute and return
appropriate policy response."
[db tracker sid policies]
(let [tracer (-> 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 (<? (dbproto/-query (root db) tracker query)))
deny-query-result)]
(swap! exec-counter inc)
(if result
(do (swap! allowed-counter inc)
true)
(recur r)))
;; no more policies left to evaluate - all returned false
false)))))
(go-try
(loop [[{:keys [id query] :as policy} & r] policies]
;; return first truthy response, else false
(if policy
(let [query* (when query (policy-query db sid query))
result (if query*
(seq (<? (dbproto/-query (root db) tracker query*)))
deny-query-result)]
(track/policy-exec! tracker id)
(if result
(do (track/policy-allow! tracker id)
true)
(recur r)))
;; no more policies left to evaluate - all returned false
false))))

(defn policies-allow-viewing?
[db tracker sid policies]
Expand Down
33 changes: 15 additions & 18 deletions src/fluree/db/json_ld/policy/rules.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -189,27 +189,24 @@

(defn build-wrapper
[db]
(fn [wrapper {:keys [id] :as policy}]
(let [wrapper* (-> 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]
Expand All @@ -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]
Expand Down
7 changes: 2 additions & 5 deletions src/fluree/db/query/api.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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 (<? (exec-fn))
policy-report (when-not (dataset? ds)
(policy.rules/enforcement-report ds))
tally (track/tally tracker)]
(cond-> (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
Expand Down
34 changes: 27 additions & 7 deletions src/fluree/db/track.cljc
Original file line number Diff line number Diff line change
@@ -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))
Expand Down Expand Up @@ -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)))
33 changes: 33 additions & 0 deletions src/fluree/db/track/policy.cljc
Original file line number Diff line number Diff line change
@@ -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 `<policy-id>->{:executed <count> :allowed <count>}`, 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)
20 changes: 8 additions & 12 deletions src/fluree/db/transact.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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)
(<? (policy/policy-enforce-db db tracker parsed-context parsed-opts))
db)]
(let [tracker (track/init parsed-opts)
policy-db (if (policy/policy-enforced-opts? parsed-opts)
(<? (policy/policy-enforce-db db tracker parsed-context parsed-opts))
db)]
(track/register-policies! tracker policy-db)
(try*
(let [staged-db (<? (stage policy-db tracker identity parsed-txn parsed-opts))
policy-report (policy.rules/enforcement-report staged-db)
tally (track/tally tracker)]
(cond-> (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)
(<? (policy/policy-enforce-db db parsed-context parsed-opts))
Expand Down
12 changes: 6 additions & 6 deletions test/fluree/db/policy/target_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@
(:fuel txn-result)))
(is (= ["a:burt-wish1"]
(:result result)))
(is (= {"http://a.co/wishlistCreatePolicy" {:executed 1, :allowed 1},
"http://a.co/wishlistModifyPolicy" {:executed 2, :allowed 2},
(is (= {"http://a.co/wishlistCreatePolicy" {:executed 0, :allowed 0},
"http://a.co/wishlistModifyPolicy" {:executed 0, :allowed 0},
"http://a.co/wishlistViewPolicy" {:executed 1, :allowed 1},
"http://a.co/wishlistItemCreatePolicy" {:executed 0, :allowed 0},
"http://a.co/wishlistItemModifyPolicy" {:executed 0, :allowed 0},
Expand Down Expand Up @@ -243,10 +243,10 @@
"a:rank" 1}]
(:result result)))
(is (= {"http://a.co/wishlistCreatePolicy" {:executed 0, :allowed 0},
"http://a.co/wishlistModifyPolicy" {:executed 1, :allowed 1},
"http://a.co/wishlistModifyPolicy" {:executed 0, :allowed 0},
"http://a.co/wishlistViewPolicy" {:executed 0, :allowed 0},
"http://a.co/wishlistItemCreatePolicy" {:executed 0, :allowed 0},
"http://a.co/wishlistItemModifyPolicy" {:executed 3, :allowed 3},
"http://a.co/wishlistItemModifyPolicy" {:executed 0, :allowed 0},
"http://a.co/wishlistItemViewPolicy" {:executed 3, :allowed 3},
"http://a.co/availableModifyPolicy" {:executed 0, :allowed 0}}
(:policy result)))
Expand Down Expand Up @@ -306,7 +306,7 @@
"http://a.co/wishlistItemCreatePolicy" {:executed 0, :allowed 0},
"http://a.co/wishlistItemModifyPolicy" {:executed 0, :allowed 0},
"http://a.co/wishlistItemViewPolicy" {:executed 3, :allowed 3},
"http://a.co/availableModifyPolicy" {:executed 2, :allowed 0}}
"http://a.co/availableModifyPolicy" {:executed 1, :allowed 0}}
(:policy result)))
(is (= 6
(:fuel result)))))))
Expand Down Expand Up @@ -334,7 +334,7 @@
"http://a.co/wishlistItemCreatePolicy" {:executed 0, :allowed 0},
"http://a.co/wishlistItemModifyPolicy" {:executed 0, :allowed 0},
"http://a.co/wishlistItemViewPolicy" {:executed 3, :allowed 3},
"http://a.co/availableModifyPolicy" {:executed 2, :allowed 2}}
"http://a.co/availableModifyPolicy" {:executed 1, :allowed 1}}
(:policy result)))
(is (= 6
(:fuel result)))))))))))
Expand Down
2 changes: 1 addition & 1 deletion test/fluree/db/transact/transact_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@
:id :ex/alice
:quux/corge "grault"}]}
committed @(fluree/transact! conn txn {:meta true})]
(is (= #{:address :db :fuel :hash :ledger-id :size :status :t :time}
(is (= #{:address :db :fuel :hash :ledger-id :size :status :t :time :policy}
(set (keys committed))))))

(testing "Throws on invalid txn"
Expand Down