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

[Feature Request] Stop certain access control rules not to be applied while connecting/disconnecting relationship #1471

Open
Milan-Bhl opened this issue May 28, 2024 · 1 comment

Comments

@Milan-Bhl
Copy link

Is your feature request related to a problem? Please describe.
I have zmodels structured like this:

model User {
    ...
    roles              Role[]

    modifiedById String? @default(auth().id)

    modifiedBy         User?        @relation("modifiedBy", fields: [modifiedById], references: [id])
    modifiedUsers      User[]       @relation("modifiedBy")
    
    @@deny('update', future().modifiedById != auth().id)
}

model Role {
    name String
    description String
    users       User[]
    permissions Permission[]
    modifiedById String? @default(auth().id)
    modifiedBy  User?        @relation("ModifiedRole", fields: [modifiedById], references: [id])
    @@deny('update', future().modifiedById != auth().id)
}

model Permission {
    name String
    description String
    roles       Role[]
    modifiedById String? @default(auth().id)
    modifiedBy  User?   @relation("ModifiedPermission", fields: [modifiedById], references: [id])
    @@deny('update', future().modifiedById != auth().id)
}

This works fine for normal scenarios of editing/updating/creating roles or permissions or users. But this causes us issues when we are just trying to associate Permissions (connect/disconnect) to a Role OR connecting/disconnecting roles from users.

The issue here is that UPDATE is rejected with error of ACCESS_POLICY_VIOLATION for e.g. while trying to assign a role to a user with

const { mutateAsync: addRoles } = useUpdateUser({
    onSuccess: async () => {
      ...
    },
  });

addRoles({
      where: {
        id: '......',
      },
      data: {
        modifiedById: '......',
        roles: {
          connect: newRoles,
        },
      },
    });

will fail with error

{
    "error": {
        "message": "denied by policy: Role entities failed 'postUpdate' check, entity {\"id\":\"......................................\"} failed policy check",
        "reason": "ACCESS_POLICY_VIOLATION",
        "rejectedByPolicy": true,
        "prisma": true,
        "code": "P2004"
    }
}

The problem is being caused by post-update check on modifiedById on both sides of the relationship.

Describe the solution you'd like
Stop the post update checks when the modification is just connecting/disconnecting and not actual update of the model

Describe alternatives you've considered
...

Additional context
...

@Milan-Bhl Milan-Bhl changed the title [Feature Request] Stop certain access control rules not to be applied on many-to-many relationship [Feature Request] Stop certain access control rules not to be applied while connecting/disconnecting relationship May 28, 2024
@ymc9
Copy link
Member

ymc9 commented May 29, 2024

Hi @mbhele-xrdigital , thanks for bringing this up.

The current design of policy behavior is explained here: https://zenstack.dev/docs/the-complete-guide/part1/access-policy/model-level#evaluation-of-model-level-policies.

Basically, for relation connect/disconnect, the side that gets the foreign key field update is required to be "updatable". However, implicit many-to-many is a special case because there's an implied "join table" that connects both sides. Currently, ZenStack is conservative and requires both sides to be updatable.

There was a suggestion for utilizing the field-level policies to fine-tune this behavior: #856

It hasn't been implemented yet.

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

No branches or pull requests

2 participants