zenstackhq / zenstack

Fullstack TypeScript toolkit that enhances Prisma ORM with flexible Authorization layer for RBAC/ABAC/PBAC/ReBAC, offering auto-generated type-safe APIs and frontend hooks.
https://zenstack.dev
MIT License
2.01k stars 85 forks source link

[ZModel] Insufficient type checking for "in" operator #1236

Open ymc9 opened 5 months ago

ymc9 commented 5 months ago
model User {
  id Int @id @default(autoincrement())
  email String @unique
  name String?
  posts Post[]
  teamMemberships TeamMembership[]

  @@allow('all', true)
}

model TeamMembership {
  id Int @id @default(autoincrement())
  teamId Int
  user User @relation(fields: [userId], references: [id])
  userId Int

  @@allow('all', true)
}

model Post {
  id Int @id @default(autoincrement())
  title String

  owner User? @relation(fields: [ownerId], references: [id])
  ownerId Int?
  teamId Int

  @@allow('all', true)
  @@deny('all', teamId in auth().teamMemberships)
}

Inside the @@deny rule, the "in" expression should result in a type-checker error.

jasonmacdonald commented 1 month ago

I hit this same bug, assuming I understand it correctly. When you say "type-checker error," do you mean it should fail, or are you not allowed to use the "in" operator?

I have a case where using the in operator does not add the proper check to the generated policy for using the check function, but it blocks it properly on actual calls.

 // this still passes even if role is STANDARD or Null when called using enhancedClient.model.check('create');
 @@allow('all', auth().role in ['SYSTEM', 'ADMIN']) 

 // But using the following works properly
 @@allow('all', auth().role == 'SYSTEM' || auth().role == 'ADMIN'])