Files
integreat/src/clj/auto_ap/graphql/utils.clj
2022-03-14 10:43:38 -07:00

126 lines
3.3 KiB
Clojure

(ns auto-ap.graphql.utils
(:require [clojure.string :as str]
[auto-ap.datomic :refer [conn]]
[clj-time.coerce :as coerce]
[auto-ap.time :as atime]
[buddy.auth :refer [throw-unauthorized]]
[datomic.api :as d]
[clojure.walk :as walk]
[clojure.tools.logging :as log]))
(defn snake->kebab [s]
(str/replace s #"_" "-"))
(defn kebab [x]
(if (qualified-keyword? x)
(keyword (snake->kebab (namespace x)) (snake->kebab (name x)) )
(keyword (snake->kebab (name x)))))
(defn kebab->snake [s]
(str/replace (str/replace s #"-" "_") #"\?$" "" ))
(defn snake [x]
(keyword (kebab->snake (name x))))
(defn ->graphql [m]
(walk/postwalk
(fn [node]
(cond
(keyword? node)
(snake node)
:else
node))
m))
(defn <-graphql [m]
(walk/postwalk
(fn [node]
(cond
(keyword? node)
(kebab node)
:else
node))
m))
(defn is-admin? [id]
(= "admin" (:user/role id)))
(defn assert-admin [id]
(when-not (= "admin" (:user/role id))
(log/warn "user " id " not an admin!")
(throw-unauthorized)))
(defn assert-present
([args key]
(assert-present args key (name key)))
([args key name]
(if (not (get args key))
(throw (ex-info (str "Missing field '" name "'.")
{:validation-error (str "Missing field '" name "'.")})))))
(defn assert-failure
([message]
(throw (ex-info message
{:validation-error message}))))
(defn assert-power-user [id]
(when-not (#{"power-user" "admin"} (:user/role id))
(log/warn "user " id " not an power-user!")
(throw-unauthorized)))
(defn can-see-client? [identity client]
(when (not client)
(log/warn "WARNING - permission checking for null client"))
(or (= "admin" (:user/role identity))
((set (map :db/id (:user/clients identity))) (:db/id client))
((set (map :db/id (:user/clients identity))) client)))
(defn assert-can-see-client [identity client]
(when-not (can-see-client? identity client)
(log/warn "IDENTITY " identity " can not see company " client)
(throw-unauthorized)))
(defn limited-clients [id]
(cond
(or
(= (:user/role id) "none"))
[]
(= (:user/role id) "admin")
nil
(#{"manager" "user" "power-user"} (:user/role id))
(:user/clients id [])))
(defn result->page [results result-count key args]
{key (map ->graphql results)
:total result-count
:count (count results)
:start (:start args 0)
:end (+ (:start args 0) (count results))})
(defn ident->enum-f [k]
#(update % k
(fn [value] (some-> value :db/ident name keyword))))
(defn enum->keyword [e namespace]
(some->> e name snake->kebab (keyword namespace)))
(defn get-locked-until [client-id]
(:client/locked-until (d/pull (d/db conn) [:client/locked-until] client-id)))
(defn assert-not-locked [client-id date]
(let [locked-until (get-locked-until client-id)]
(when (and locked-until
(>= (compare locked-until (coerce/to-date date)) 0))
(assert-failure (str "Integreat has locked finances prior to " (-> locked-until coerce/to-date-time (atime/unparse-local atime/normal-date)) ".")))))
(defn assert-none-locked [client-id dates]
(doseq [d dates]
(assert-not-locked client-id d)))