Comments (4)
Hey @kevrat 👋,
That's an interesting question. Let me think...I think I would do it like this;
- Extract the
ID
of thecompetition
in the request (args
) - Check whether such post already exists using Prisma's
.exist
function. - If there exists a competition with such
id
andowner
, allow access otherwise deny it.
const isOwnerOfCompetition = rule({ cache: 'strict' })(
async (parent, { where: { id } }, ctx, info) => {
const userID = getUserID(ctx)
return ctx.db.exists.Competition({
id,
owner: { id: userID }
})
},
)
Hope this helps you out! 🙂
from graphql-shield.
I mean that i can do:
mutation{
updateCompetition(where:{id:"my id and i is owner"},data:{
owner:{
connect:{
id:"Id of any other user, that dont want to be connecting"
}
}
}){
id
}
}
and change owner id of my competition (or post, or comment or any other things what have owner like field).
I can create many competitions and connect it to other users that dont want this. So in this case we need something little smarter than just checking if user is owner and if yes - to allow him modify owner field of him node.
I want to do this in shield - because i think it is simplier set the rule, than create wrapper resolver for every resolver.
Of course, maybe i'm wrong and this not good idea do it in shield. What do you think?
from graphql-shield.
Hey @kevrat 👋,
Thank you for being so patient, I've been super busy lately. I am glad to hear that you like shield
so much; at the moment, I can think of two ways of solving your problem;
Omit connect
option in competition
input type alltogether
You could change the input
type of updateConnection
mutation and remove the connect
option. This way you would solve the problem, but you also couldn't access that functionality anymore, which is a significant tradeoff.
Find the connect
fields in data
and check whether they match user's id
This one is very similar to the approach I mentioned above. Very straightforward, destructure the object and see if it includes the id
field under connection, and decide whether you should allow or deny the action.
Maybe a little add-on; I would say that shield
is a rather young library and I believe many things are going to change and improve in the future. Furthermore, it's only a generalised approach to writing permission logic that many have implemented ground up for their particular use cases - it's a generalisation library of a typical pattern. I think we are all still exploring how to cover different use cases and write as little rules as possible using such permission logic implementation style. I believe issues such as this particular one help us progress a lot faster with the exploration. Therefore, I would love to hear your opinion as well. How do you think this could be solved?
PS.: There's something cooking up in #92, be sure to check it out and leave some comments! Maybe you get an idea of how to solve this problem as well.
from graphql-shield.
Thanks for answers. I'm using the second way.
But by this way the rules grow to monstrous size, if to make them universal for use in a mutation (also "where" field may contain id at different levels of nesting), entity and field of an entity.
I think another way it is create very little, stupid rules and name it like "mutationIsOwnerOfCompetition", "fieldIsOwnerOfCompetition" but there will be a lot of them, so it will be difficult to work with them.
If use something between, then is hard to keep in mind - it is rule for mutation or for field? And this also does not resolve the situation if the id is at different levels of nesting.
Here is my little part of code for isOwnerOfCompetition
rule. I am use this in mutation and field
index.ts
import { shield, and, or, deny, allow, rule } from 'graphql-shield'
import * as rules from './rules'
export const permissions = shield(
{
Mutation: {
updateCompetition: rules.isOwnerOfCompetition,
},
Competition: {
applications: rules.isOwnerOfCompetition
}
}
)
rules.ts
export const isOwnerOfCompetition = rule({ cache: 'strict' })(
async (
{ id = null } = {},
{ where: {
id: competitionId = null, competition: { id: competitionQueryId = null }
} = { competition: {} } },
ctx: Context,
info
) => {
return ctx.db.exists.Competition({
id: competitionId || id || competitionQueryId,
owner: {
id: getUserId(ctx)
}
})
}
)
It is so big, because in mutation we search ids in args object, but in the field resolver we search ids in parent object. I'm just saying this, if suddenly someone has an idea how to make it easier
Also i understand that it is young library and a lot of work is ahead.
Anyway thanks for graphql-shield. It saved me a lot of time 👍
from graphql-shield.
Related Issues (20)
- Execute root fields rules prior graphql execute phase
- Add the ability to use Fragments and post-execution rules with the single server/schema
- Add Typescript typings to rule args
- Add the ability to attach rules using GraphQL Directives
- CI: add codecov reports
- Provide a way to expose authorization metadata through the graphql schema
- GraphQL Shield Roadmap
- 7.6.4 ESM build broken HOT 5
- Documentation website down HOT 1
- How to use `if` condition in GraphQL Shield HOT 2
- Shield rules type generation based on schema HOT 1
- Feature request: wildcard functionality for field names
- Update [email protected] module to avoid @types/lodash and babel runtime in production deps
- fallbackError loses custom error types
- fallbackRule context information HOT 2
- Question: Is there a way to return objects on rules?
- ..
- Typo in the Docs
- Shield permissions only working properly with 'debug: true' HOT 1
- Performance -- every field wrapped is unnecessarily wrapped in a promise HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from graphql-shield.