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

[Feature Request] Support for Polymorphic Associations #430

Closed jiashengguo closed 5 months ago

jiashengguo commented 1 year ago

Background

This is probably one of the Prisma feature requests that got the most likes 😄. The name "polymorphic association" may sound a bit "obscure". Other terms can be union support, generic foreign key, abstract relation, etc.

It's an extremely useful feature for many applications, and from ZenStack (access control) point of view, it's even more useful, as it'll allow you to more easily consolidate access policies at an abstract level while still being able to make refinements at concrete levels. Here's an example for modeling a CMS (note ZenStack already has the abstract syntax today):

model User {
  id Int
  contents Content[]
}

abstract model Content {
  id Int
  owner User @relation(fields: [ownerId], references: [id])
  ownerId Int
  deleted Boolean @default(false)

  @@deny('read', deleted)
  @@allow('all', auth().role == 'ADMIN')
}

model Post extends Content {
  published Boolean

  @@deny('delete', published)
}

model Video extends Content {
  ...
}

Proposed Solution

To be honest, we haven't thought deeply about the design and implementation, but I think the general approach would be to provide a concise syntax to model it in ZModel and transpile such relations into Prisma Schema using a [relationId, relationType] tuple. The downside is we lose native fk constraint support for integrity and need to compensate for it using transactions.

It's possible that addressing it from ZenStack side is easier than adding such support in Prisma. But there are still many details to consider and feedback to collect, and it'll be quite some work.

Related: #613

leonard-henriquez commented 1 year ago

Oh wow ! Do you plan to implement it in Zenstack ? @jiashengguo It would be a reason on its own to use Zenstack !!! Do you have an ETA ?

jiashengguo commented 1 year ago

@leonard-henriquez Thanks for your upvoting for this so that we could prioritize it. We have just started to investigate the possible ways to implement it, no ETA yet. We will update it here once we got something. Meanwhile, you are welcome to give any suggestions or even contribute to it.

ymc9 commented 10 months ago

Adding a related discord thread: https://discord.com/channels/1035538056146595961/1159604160707170315

ymc9 commented 10 months ago

More context related to the previous discord thread:

image image image
ymc9 commented 9 months ago

A blog post that captured the detailed thoughts about how to implement it.

https://zenstack.dev/blog/polymorphism

michael-cohen-io commented 8 months ago

hey team, curious if this feature is being actively developed or being considered for a release soon? Would love to be able to use zenstack's proposed polymorphic declarations in our project soon if possible

ymc9 commented 7 months ago

hey team, curious if this feature is being actively developed or being considered for a release soon? Would love to be able to use zenstack's proposed polymorphic declarations in our project soon if possible

Hi @michael-cohen-io ,

We've just released the first alpha of V2 containing the implementation: https://zenstack.dev/docs/next/guides/polymorphism. It'd be great if you want to give it a try and provide feedback!

adriangalilea commented 7 months ago

Hey guys, thanks for the great work, I was very hesitant on the concept of adding more magical abstractions on top of magical abstractions, but I was really impressed by the level of thoughtfulness throughout the project so I'm willing to give it a chance since I need polymorphic associations on my project and it's either that or maybe scrapping prisma altogether.

I wanted to know if this implementation is something that I can start using in prod(for an app that has no users yet, and some months from testing) just so it may allow me to focus on the rest of the project if this implementation is planned to eventually become stable without minor changes on my side or if it sounds like a bad idea or is not usable yet.

Thanks.

ymc9 commented 7 months ago

Hey guys, thanks for the great work, I was very hesitant on the concept of adding more magical abstractions on top of magical abstractions, but I was really impressed by the level of thoughtfulness throughout the project so I'm willing to give it a chance since I need polymorphic associations on my project and it's either that or maybe scrapping prisma altogether.

I wanted to know if this implementation is something that I can start using in prod(for an app that has no users yet, and some months from testing) just so it may allow me to focus on the rest of the project if this implementation is planned to eventually become stable without minor changes on my side or if it sounds like a bad idea or is not usable yet.

Thanks.

Hi @adriangalilea , thanks for your interest to this feature!

It's currently in the alpha stage, so it's definitely not a good idea to use in production. We'll try to release a stable V2 version within Q1. The general approach/API is stable enough, I believe.

jiashengguo commented 5 months ago

fixed.