Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prisma how to run other queries as findMany #828

Open
13uraksahin opened this issue Oct 26, 2023 · 4 comments
Open

Prisma how to run other queries as findMany #828

13uraksahin opened this issue Oct 26, 2023 · 4 comments

Comments

@13uraksahin
Copy link

Is your feature request related to a problem? Please describe.
We cannot use accessibleBy with prisma's findUnique, update and delete functions.
When we use accessibleBy(ability).ModelName it gives this result: { OR: [ { uniqueValue: 1 } ] }
However what we need is only bare object: { uniqueValue: 1 }

Describe the solution you'd like
So, what I do is:
I also use params in the conditions... if there is param it adds and if there is not it leaves conditions alone:

To define:
can('read', 'post', { authorId: account.id, ...params }); (if there is any param it will add, and if there is none, there will be only authorId) - (Also ...params part is not the topic but this example shows that if casl solves the problem, how easy the implementation is) - (Also, we can even write conditions with operators like AND / OR)

prisma.post.findMany({ where: accessibleBy(ability).Post['OR'][0] })
prisma.post.findUnique({ where: accessibleBy(ability).Post['OR'][0] })
prisma.post.update({ where: accessibleBy(ability).Post['OR'][0] })
prisma.post.update({ where: accessibleBy(ability).Post['OR'][0] }) // runs if no foreign key constraint exist

(Also need to use // @ts-ignore if using with TypeScript)

We should not be writing ['OR'][0] to the end (also I do not think that anyone writes 😄)... and accessibleBy(ability).Post should be enough.
Are there any reason that casl does not provide bare object rather than default added OR array inside of an object? Because bare object will solve 95% of cases which people can face isn't it?

@stalniy
Copy link
Owner

stalniy commented Oct 26, 2023

Casl wraps everything in OR because in case of multiple rules for the same action/subject type they are OR-ed.

I can optimize it for single OR condition but then your whole app may be broken because at some point in the future you may add additional condition.

So I’d not rely on the shape of the conditions casl returns you back

@13uraksahin
Copy link
Author

Hmm, I got the point. Correct as fundamental.

However, without any extra or (or anything else), we can also add our own AND or OR conditions, and with the proper documentation, this can be understood and used by developers much more easily. Should it really be OR-ed by default while I can write myself? Because we have the @casl/prisma package, but we cannot use with the prisma if we won't use findMany or findFirst, (I mean we really cannot use with prisma). Also, I am not sure, but this can be done with casl because doc only shows how to write findMany and this update won't affect findMany.

What I suggest makes us to be able to:
We can add all types of conditions to the conditions inside can/cannot which will create accessibleBy(ability)
We can add all types of conditions to the prisma where object
We can combine both of above
Won't violate the fundamentals
Won't break the apps written with documentation

I think this is easier while brings much more possibilities to the code. And I think it does not violates the fundamentals. We still create.

@saboorajat
Copy link

saboorajat commented Feb 6, 2024

Hey,
I want to have condition which will check that if last_name is present then it must be Tony but as it's update API we might not send last_name hence the other condition. It would have been nice if $or was available for use. Also, i noticed if i want to have multiple conditions example first_name then ability.relevantRuleFor(inputAction as ACTIONS, subject(String(subjectName), { [key]: value })
will be true always

{
            type: "can",
            action: ACTIONS.UPDATE_INPUT,
            subject,
            fields: ["first_name", "last_name", "id", "email"],
            condition: { last_name: "Tony" },
        },
        {
            type: "can",
            action: ACTIONS.UPDATE_INPUT,
            subject,
            fields: ["first_name", "last_name", "id", "email"],
            condition: { last_name: { $exists: false } },
        },

@jbeckton
Copy link

I am finding that CASL in a typescript app to be nearly unusable. If you are protecting routes as well as Prisma queries there is no way to reuse any code between the two use cases. So, as you add models to your Prisma schema you have to update both sections of code. Then there is the issue of user permissions. If you create a permission array for the route guards, so that you can generate mongo abilities, you cannot also use that permissions array to create the prisma ability. So I have to convert the user permissions data to some other format in order to use it with the prisma integration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants