Files
integreat/src/cljc/auto_ap/permissions.cljc
2024-10-18 21:00:50 -07:00

153 lines
3.8 KiB
Clojure

(ns auto-ap.permissions
#?(:clj
(:require [cemerick.url :as url])))
;; TODO after getting rid of cljs, use malli schemas to decode this
(defn get-client-id [client]
(cond (nat-int? client)
client
(:db/id client)
(:db/id client)
:else
nil))
(defn can? [user {:keys [client subject activity]}]
(let [role (or (:user/role user) (:role user) user)
client-id (get-client-id client)]
(cond (#{:user-role/admin "admin"} role)
true
(and client-id (not (get (into #{} (map :db/id (or (:clients user)
(:user/clients user)))) client-id)))
false
(#{:user-role/power-user "power-user"} role)
(cond
(#{:invoice-page :payment-page :my-company-page :transaction-page :ledger-page} subject)
true
(= [:invoice :import] [subject activity])
true
(= [:invoice :create] [subject activity])
true
(= [:invoice :pay] [subject activity])
true
(= [:invoice :edit] [subject activity])
true
(= [:invoice :delete] [subject activity])
true
(= [:sales :read] [subject activity])
true
(= [:vendor :create] [subject activity])
true
(= [:vendor :edit] [subject activity])
true
(= [:ledger :read] [subject activity])
true
(= [:balance-sheet :read] [subject activity])
true
:else false)
(#{:user-role/manager "manager"} role)
(cond
(#{:invoice-page :payment-page :my-company-page :transaction-page} subject)
true
(= [:vendor :create] [subject activity])
true
(= [:vendor :edit] [subject activity])
true
(= [:invoice :create] [subject activity])
true
(= [:invoice :pay] [subject activity])
true
(= [:invoice :edit] [subject activity])
true
(= [:invoice :delete] [subject activity])
true
(= [:ledger :read] [subject activity])
true
(= [:balance-sheet :read] [subject activity])
true
:else false)
(#{:user-role/read-only "read-only"} role)
(cond
(= :ledger-page subject) true
(= [:ledger :read] [subject activity])
true
(= [:balance-sheet :read] [subject activity])
true
:else false)
(#{:user-role/user "user"} role)
(cond
(#{:invoice-page :payment-page :my-company-page :transaction-page :ledger-page} subject)
true
(= [:vendor :create] [subject activity])
true
(= [:vendor :edit] [subject activity])
true
(= [:signature :edit] [subject activity])
true
(= [:invoice :create] [subject activity])
true
(= [:invoice :pay] [subject activity])
true
(= [:invoice :edit] [subject activity])
true
(= [:invoice :delete] [subject activity])
true
(= [:ledger :read] [subject activity])
true
(= [:balance-sheet :read] [subject activity])
true
:else false)
:else
false)))
#? (:clj
(defn wrap-must [handler policy]
(fn [request]
(if (can? (:identity request) policy)
(handler request)
{:status 302
:headers {"Location" (str "/login?"
(url/map->query {"redirect-to" (:uri request)}))}}))))