(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)}))}}))))