-
-
Save eyston/ace33b385f57aabc7807 to your computer and use it in GitHub Desktop.
const hasRole = (role, next) => { | |
return (obj, args, ctx) => { | |
if (ctx.rootValue.user.hasRole(role)) { | |
next(obj, args, ctx); | |
} else { | |
return null; | |
} | |
} | |
} |
const { query, variables } = request.params; // from the request | |
const user = db.getUser(request.session.userId); // from your session -- pretend it has user id or something! | |
graphql(schema, query, {user}, variables); // shove the user in the root value |
const UserType = new GraphQLObjectType({ | |
name: 'User', | |
fields: { | |
email: { | |
type: GraphQLString, | |
resolve: (user, _, {rootValue}) => { | |
// only the current user can see their email | |
// can imagine this checking admin roles and stuff | |
if (user.id === rootValue.user.id) { | |
return user.email; | |
} else { | |
// maybe you can throw to add an error to the response! | |
return null; | |
} | |
} | |
}, | |
socialSecurityNumber: { | |
type: GraphQLString, | |
resolve: hasRole('admin', user => user.socialSecurityNumber) | |
} | |
} | |
}); |
Yah, I've been tracking the om-next
stuff. GraphQL is different in that it in fact is spec to walk the whole tree. This is actually what I wanted to get at in the last comment -- only the leave values matter. Every complex value which gets returned is simply the collection of its leaves.
With om-next
the parser can return complex values meaning you do not necessarily walk the leaves. In this case your parser/read for :project
would want to make sure the value it returns has been pre-filtered to the current user.
I haven't implemented a parser / done much with om-next but maybe the parser can be recursive? The Falcor router essentially does this. One route might handle :project
and then defer to a different handler which handles :file
or something.
@bostonou I can't stop:
https://www.youtube.com/watch?v=7lm3K8zVOdY
This was a talk from clojure/conj 2014 where a bank actually filters a datomic database to only include attributes a user can see. This means any query can be run safely as the only attribute values which can possibly be returned are authorized.
I have _zero_ idea if this is a good / bad idea, but definitely neato. And cognitect has included them in literature so maybe its a great idea, I dunno!
One last thing to remember: only scalar resolves are values that end up in the response.
Take the query:
The resolve for
user(id: 1)
might query a database which returns{id: 1, name: "Erik", email: "[email protected]" }
. This complex doesn't get copied to the response, it just gets handed to the next resolve function ... so your query response is currently:Then the resolve for
name
gets run. This resolve returns a value and since it is a scalar it gets added to the response: