GithubHelp home page GithubHelp logo

Comments (4)

maticzav avatar maticzav commented on April 27, 2024

Hey @kevrat 👋,

That's an interesting question. Let me think...I think I would do it like this;

  1. Extract the ID of the competition in the request (args)
  2. Check whether such post already exists using Prisma's .exist function.
  3. If there exists a competition with such id and owner, 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.

kevrat avatar kevrat commented on April 27, 2024

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.

maticzav avatar maticzav commented on April 27, 2024

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.

kevrat avatar kevrat commented on April 27, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.