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] Permission control for Users with polymorphic roles #1745

Closed
aladinelkhalil opened this issue Sep 26, 2024 · 0 comments
Closed
Milestone

Comments

@aladinelkhalil
Copy link

aladinelkhalil commented Sep 26, 2024

Is your feature request related to a problem? Please describe.
So if you look at the Ad model below, I would like to replace the hardcoded value 'STORE' with the buyerType variable. This value currently exists only for Companies with companyType 'Buyer', in the Buyer model it is the type field.

What I'm wishing for is, that I can either replace the hardcoded value 'STORE' here in the Ad model (this one 👇)

@@allow('all', auth().company.companyType == 'Buyer' && 'STORE' in buyerTypes)

with

auth().company.buyer.type / auth().buyer.type

OR I can duplicate the type field in the Company model, make it optional and call it buyerType BuyerType? and then be able to do this

@@allow('all', auth().company.companyType == 'Buyer' && auth().company.buyerType in buyerTypes)

Currently this gives the following error when I try it.
comparison between fields of different models is not supported in model-level "read" rules (zmodel)

Describe the solution you'd like
See above.

Describe alternatives you've considered
Currently, my only solution is

@@allow("all", auth().company.buyerType == "RESTAURANT" && "RESTAURANT" in buyerTypes)
@@allow("all", auth().company.buyerType == "STORE" && "STORE" in buyerTypes)
@@allow("all", auth().company.buyerType == "WHOLESALER" && "WHOLESALER" in buyerTypes)

which is hard to scale and maintain.

Additional context

schema.zmodel

enum BuyerType {
    STORE
    RESTAURANT
    WHOLESALER
}

enum ChainStore {
    ALL
    CHAINSTORE_1
    CHAINSTORE_2
    CHAINSTORE_3
}

abstract model Id {
    id String @id @default(cuid())
}

abstract model Base extends Id {
    createdAt DateTime @default(now())
    updatedAt DateTime @updatedAt
}

model Ad extends Base {
    serial       Int          @unique @default(autoincrement())
    description  String
    batchNumber  String
    deliveryDate DateTime?
    expiryDate   DateTime
    buyerTypes   BuyerType[]
    chainStores  ChainStore[]
    listPrice    Float
    isSold       Boolean      @default(false)

    supplier     Supplier     @relation(fields: [supplierId], references: [id])
    supplierId   String       @default(auth().companyId)

    @@allow('all', auth().company.companyType == 'Buyer' && 'STORE' in buyerTypes)
    @@allow('all', auth().company.companyType == 'Supplier' && auth().companyId == supplierId)
    @@allow('all', auth().isAdmin)
}

model Company extends Base {
    name               String @unique
    organizationNumber String @unique
    users              User[]

    companyType        String
    @@delegate(companyType)

    @@allow('read, update', auth().companyId == id)
    @@allow('all', auth().isAdmin)
}

model Buyer extends Company {
    storeName  String
    type       BuyerType
    chainStore ChainStore @default(ALL)

    @@allow('read, update', auth().company.companyType == 'Buyer' && auth().companyId == id)
    @@allow('all', auth().isAdmin)
}

model Supplier extends Company {
    ads Ad[]

    @@allow('all', auth().company.companyType == 'Supplier' && auth().companyId == id)
    @@allow('all', auth().isAdmin)
}

model User extends Base {
    firstName String
    lastName  String
    email     String   @unique
    username  String   @unique
    password  String   @password @omit
    isAdmin   Boolean  @default(false)

    company   Company? @relation(fields: [companyId], references: [id])
    companyId String?

    @@allow('read', auth().id == id)
    @@allow('read', auth().companyId == companyId)
    @@allow('all', auth().isAdmin)
}
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

2 participants