Fork me on GitHub
#pathom
<
2023-01-30
>
Eric Dvorsak10:01:39

Is there an easy way to make the parser behave the same as in lenient mode except for a certain kind of exception (in my case authorization exception). Basically I'd like to use the lenient mode for the API but in case a resolver throws an authorization exception it should interrupt and return minimal infos

Eric Dvorsak10:01:45

What imostly want is to avoid spewing the :com.wsscode.pathom3.entity-tree/entity-tree in the response when the exception is Unauthorized

caleb.macdonaldblack15:01:25

This is interesting. It would be useful to wire many graphs together with their own configurations. For example running in parallel seems to be all of nothing.

Eric Dvorsak16:01:40

yes the idea is to drop the query entirely in case of unauthorized access to an attribute for now if there's a way to just drop the subquery I'd probably go for it, but one step at a time, and it might not be easy because the authorization attributes are siblings of the others

Eric Dvorsak16:01:25

I was initially going for a solution that rewrites resolvers to include authorization attributes in the inputs (and a pending-authorization / authorized resolver for circular dependencies eg child must have parent authorized but you only know the parent after resolving the child) but it turned out to be too slow when dealing with 1000s of attributes whose authorization requires deep recursion. I am now following the path of changing the query which drastically improved the perf in my case https://github.com/yenda/pathauth It would be very close to no-auth perfs once I let parent authorization flow to children

wilkerlucio17:01:42

this goes a bit against the processing model of Pathom, because pathom intentionally doesn't have anything to deal with entities per-see, because for Pathom entities are just generic bags, so from an authorization perspective, just because you can't access attribute :a, that doesn't mean you wont be able to access :b at the same entity, in this thinking, each attribute has potently its own authorization behavior

Eric Dvorsak18:01:59

yes that's a trade-off I'm fine with here. I expect access to unauthorized attributes to be an adversarial use case. No user (UI) would do that

Eric Dvorsak18:01:34

in return I get the advantage that pathom can resolve my authorizations and fail early when its not granted

Eric Dvorsak18:01:57

@U066U8JQJ > this goes a bit against the processing model of Pathom, because pathom intentionally doesn't have anything to deal with entities per-see, because for Pathom entities are just generic bags, so from an authorization perspective, just because you can't access attribute :a, that doesn't mean you wont be able to access :b at the same entity, in this thinking, each attribute has potently its own authorization behavior I agree with this, that's why ideally the behavior I'd be looking for is that when an authorization resolver throws, I have the list of siblings that need to be blocked. But it also means I need to be able to interrupt the subqueries if those siblings are joins. For now it's not too much of a big deal because I'm fine with throwing away the whole query

Eric Dvorsak18:01:43

but it's too good right now to be able to define authorization like this:

(defattr id :question/id :int
  {...
   pa/auth [:course/authorized?]})
then pathom just adds :course/authorized as a sibling when :question/id shows up in a query and figures out the inputs required to resolve it (currently I do a little more, when an id attribute requires auth, any attribute linked to it does as well)

Tommy19:01:31

how do you guys typically structure your crud mutations (more accurately CUD, as read is with resolvers not mutations). I am considering doing just

(org.myproject/crud {:action :{create,delete,update} :type :{user,post,comment} :id 342 :resource {:user/name "tommy" :user/bio "new bio.."}) 

Tommy19:01:51

i.e. having a single mutation for entire project.

Tommy19:01:49

other option is (org.myproject.user/crud ...) in the same ns as all the other user code. This way I can put code in specific to the user...

Tommy19:01:49

third option is (org.myproject.user/delete ...), (org.myproject.user/create )...

Tommy19:01:05

I like first one, because I can make a lot of use of multimethods and specifically keyword https://clojuredocs.org/clojure.core/derive (which seem cool, but I havent used them before). Any thoughts?

wilkerlucio20:01:54

in general I rather have one mutation per operation, not a rule though, but you can also make some helpers that generate resolvers (to avoid the repetition)

👍 2