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.07k stars 88 forks source link

Error when auth() is null on a nested policy #380

Closed sidharthv96 closed 1 year ago

sidharthv96 commented 1 year ago

Description and expected behavior

The idea is for public Documents to be accessible for everyone.

model User {
  id String @id @unique @default(uuid()) @db.Uuid
  projects Project[]

  // ...
}

model Project {
  id String @id @unique @default(uuid()) @db.Uuid
  documents Document[]
  ownerID String @db.Uuid
  owner User @relation(fields: [ownerID], references: [id])
  // ...
  @@allow('all', owner == auth())
}

model Document {
  id String @id @default(uuid()) @db.Uuid
  projectID String @db.Uuid
  project Project @relation(fields: [projectID], references: [id], onDelete: NoAction, onUpdate: NoAction)
  isPublic Boolean @default(false)
  diagramDocuments DiagramDocument[]
  // ...

  @@allow('read', isPublic)
  @@allow('all', project.owner == auth())
}

model DiagramDocument {
  id String @unique @default(uuid()) @db.Uuid
  documentID String @db.Uuid
  document Document @relation(fields: [documentID], references: [id], onDelete: Cascade, onUpdate: NoAction)
  // ...
  @@allow('read', document.isPublic)
  @@allow('all', document.project.owner == auth())
}

But the query fails with this error when no user is passed.

Invalid `prisma.document.findMany()` invocation:

{
  where: {
    AND: [
      {
        id: '76851c4d-1742-4c6f-b856-48ed37b01301'
      },
      {
        OR: [
          {
            isPublic: true
          },
          {
            project: {
              owner: {
              ~~~~~
                is: null
              }
            }
          }
        ]
      }
    ]
  },
  include: {
    diagramDocuments: {
      where: {
        AND: [
          {
            major: 0,
            minor: 1
          },
          {
            OR: [
              {
                document: {
                  isPublic: true
                }
              },
              {
                document: {
                  project: {
                  ~~~~~~~
                    owner: {
                      is: null
                    }
                  }
                }
              }
            ]
          }
        ]
      }
    }
  }
}

Unknown arg `project` in include.diagramDocuments.where.AND.1.OR.1.document.project for type DocumentRelationFilter. Did you mean `select`? Available args:
type DocumentRelationFilter {
  is?: DocumentWhereInput | Null
  isNot?: DocumentWhereInput | Null
}
Unknown arg `owner` in where.AND.1.OR.1.project.owner for type ProjectRelationFilter. Did you mean `is`? Available args:
type ProjectRelationFilter {
  is?: ProjectWhereInput
  isNot?: ProjectWhereInput
}

Screenshots If applicable, add screenshots to help explain your problem.

Environment (please complete the following information):

Additional context Add any other context about the problem here.

ymc9 commented 1 year ago

Thanks for reporting this @sidharthv96 ! I'm looking into it and will update back soon.

ymc9 commented 1 year ago

Hi, I tried with a Postgres setup but couldn't reproduce the issue. Could you check if all your zenstack dependencies are of the same version? You can run npx zenstack info to get it.

My setup is shared here if it helps: https://github.com/ymc9/zenstack-380

sidharthv96 commented 1 year ago

Thank you for the repro. It runs fine in the repro.

I did a workaround to use the old prisma if user isn't available. But now it works even after removing that. Didn't do any changes to zenstack or prisma versions.

It's really weird.

image

--

I noticed you had used withPresets in the repro, but the docs mention withPolicy https://zenstack.dev/docs/get-started/backend. Is there any difference between the two?

--

Also, prisma is throwing this warning

imports from "@prisma/client/runtime" are deprecated.
Use "@prisma/client/runtime/library",  "@prisma/client/runtime/data-proxy" or  "@prisma/client/runtime/binary"
ymc9 commented 1 year ago

Thanks for trying it out. It is weird. Do you recall installing an older version of ZenStack before? Anonymous user wasn't handled cleanly in previous versions but it has been fixed within the past two weeks or so.

withPresets is simply a shortcut for combining withPolicy, withPassword and withOmit. It's equivalent to withPolicy in terms of validating access policies.

ymc9 commented 1 year ago

The deprecated Prisma dependencies is tracked by an issue here and I think it can be resolved soon.

sidharthv96 commented 1 year ago

I haven't installed an older version before. First time installing in the repo yesterday. Thanks for the prompt response. I'll use the repro to report any new errors I see.