This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-01-06
Channels
- # announcements (4)
- # aws (2)
- # beginners (48)
- # calva (39)
- # cljsrn (12)
- # clojure (98)
- # clojure-dusseldorf (1)
- # clojure-serbia (2)
- # clojure-spec (13)
- # clojure-uk (13)
- # clojurescript (97)
- # code-reviews (1)
- # datomic (14)
- # fulcro (24)
- # jobs-discuss (160)
- # juxt (1)
- # luminus (2)
- # nrepl (1)
- # off-topic (1)
- # other-languages (1)
- # overtone (1)
- # perun (6)
- # protorepl (16)
- # re-frame (20)
- # reagent (1)
- # reitit (6)
- # rum (8)
- # shadow-cljs (96)
- # spacemacs (8)
- # specter (4)
- # tools-deps (18)
- # uncomplicate (1)
- # vim (1)
I'm about to try to implement authentication and authorization in fulcro. If you were to do this today, would you implement it using a pathom plugin?
In particular, I have this as a potential guide: https://github.com/walkable-server/realworld-fulcro/blob/master/src/conduit/handler/walkable.clj
@pauld, @tony.kay and I are working on a project, we use a combination of java libraries, macros, and parser plugin i’ll make a quick gist
@currentoor wow, thanks!
no worries
the user file shows how we encrypt/store the authentication data
the parser file shows how we inject user info into each parser action (every client request comes with an JWT token)
the mutation file shows how we specify authentication policies for different mutations
the policy file shows a simple example policy, but it can be anything, like checking permissions or access
for example here’s another policy
(defn wash? [db org-id wash-id]
(let [wash (d/entity db [:wash/id wash-id])]
(= org-id
(-> wash
:entity/firm
:db/id))))
(defn wash-ownership [{:keys [env params] :as args}]
(let [{:keys [db current/firm]} env
{:keys [wash/id]} params
org-id (:db/id firm)]
(and (existence args)
(wash? db org-id id))))
every one of our models has a reference to a firm and we can check for ownership based on whether a given model’s firm is the same firm as the user from the token
@currentoor This is wonderful thanks! This is so helpful.
no worries, like i said it was a joint effort with @tony.kay
but this has been asked about a few times before
maintaining an example application is too much work, including it in fulcro is too specific
maybe i should write an article at some point with this example code
then we should share that
since this is something that comes up all the time
oh and we have a similar macro for resolvers
(s/def ::value (s/cat
:value-name (fn [sym] (= sym 'value))
:value-args (fn [a] (and (vector? a) (= 2 (count a))))
:value-body (s/+ (constantly true))))
(s/def ::resolver-args (s/cat
:sym symbol?
:doc (s/? string?)
:output vector?
:policy (s/? (s/spec ::policy))
:value (s/? (s/spec ::value))))
(defmacro ^{:doc "Defines a pathom resolver but with authorization. See pathom docs."
:arglists '([sym docstring? output policy value])} defresolver
[& args]
(let [{:keys [sym output policy value]} (util/conform! ::resolver-args args)
output (first output)
fqsym (if (namespace sym)
sym
(symbol (name (ns-name *ns*)) (name sym)))
policy (:policy-fn policy)
{:keys [value-args value-body]} value
ex-msg (str "Resolver " fqsym " unauthorized, " policy " violated")
ex-body {:status 401}]
`(ucv.server.parser/defresolver '~fqsym ~output
(fn [env# params#]
(if (~policy {:env env# :k '~fqsym :params params#})
(let [~(first value-args) env#
~(second value-args) params#]
~@value-body)
(throw (ex-info ~ex-msg ~ex-body)))))))