Fork me on GitHub
#datomic
<
2018-08-31
>
Oliver George11:08:01

Can someone link me to an example of restricting/filtering query pull based on the users access. Eg “users shouldn’t be able to see comments on jobs unless they wrote them”. Using a pull query I can find jobs and pull the related comments but then need to check access for each comment.

Oliver George02:09:01

Perhaps I can wrap the pull function and do the additional access checks

Oliver George05:09:18

Vague idea would be

(defn pull
  "Like d/pull but checks has-read-access? on relations before including them"
  [db uid eid selector]
  (let [props (remove map? selector)
        joins (apply merge (filter map? selector))
        result (d/pull db eid props)]
    (reduce-kv (fn [result k v]
                 (let [attr-name (attr-name k)
                       eids (d/q '[:find ?eid
                                   :from $ ?eid ?uid
                                   :where
                                   [?eid ?attr-name ?fid]
                                   [(app.perms/has-read-access? $ ?uid ?fid) true]]
                                 db eid uid)
                       attr-data (map #(pull db uid % [{k v}]) eids)]
                   (assoc result attr-name attr-data)))
               result
               joins)))

dominicm14:08:15

A filtered db can be handy at times like this 🙂

Oliver George02:09:55

Can you point me at something related to this please. Sounds interesting.

Oliver George05:09:09

Thanks. That's pretty wild.

Oliver George05:09:20

Possibly not part of the cloud / client api just yet. Interesting idea for user access control though. Would need to get familiar with practicalities and assess performance considerations too. Food for thought though.

dominicm05:09:15

I was something about cloud

dominicm05:09:20

Only pre expected ones, disappointing

henrik19:08:22

@olivergeorge isn't that just another vector in the where clause? :job/author ?user-id or something. Then pull in the find clause.

Oliver George21:08:40

Its the relations in the pull data I can’t filter via a :where clause

henrik06:09:32

It sounds like it would be easiest to handle in a separate query then.