wasp-lang / wasp

The fastest way to develop full-stack web apps with React & Node.js.
https://wasp-lang.dev
MIT License
13.77k stars 1.18k forks source link

Improve CRUD operations default implementations #1253

Open infomiho opened 1 year ago

infomiho commented 1 year ago

We implemented CRUD operations that automatically generate queries and actions based of an entity that user defined.

The default operations are pretty basic:

Downsides of the current default implementations

  1. The data is not validated in any way
  2. There is no authorization mechanism to limit access to certain resources

Users have to override the default implementation to get those behaviours. This makes the CRUD operations less useful and appealing. The goal is to add certain features to Wasp to make the CRUD operations by default powerful enough for most common use cases.

Some thing we can do

Authorization

It would enable the user to define which users are allowed to perform which operations and on which resources.

Input validation

Save only valid data instead of saving everything that comes from the frontend.

Customization through Wasp DSL

We want to give users some knobs to turn in the Wasp DSL to customize the CRUD operations without writing JS code. Things like:

Customization through pre/post hooks

Check things before operation is executed or perform some action after the operation is executed.

Martinsos commented 1 year ago

Ideas for validation:

  1. We introduce a simple language on top of PSL, via custom attributes, so you can define for each entity which fields are modifiable by user, and which are not. Also, which ones are visible by user, and which ones are not. This could be pretty useful. It is a good question how this scales with having roles and more complex authZ mechanisms though, would be great if we can make it work with that somehow, or at least not be in the way. If we pull this off, it can also be used in other parts of Wasp.
  2. We define directly in CRUD which entity fields are allowed, both in input and output. We could do this declaratively, or we could provide hooks for validation / sanitizing the output, ... . This is more straight forward but it not usable outside of CRUD.
ymc9 commented 1 year ago

Hi @infomiho @Martinsos , I just stumbled upon this issue when checking out Wasp (very cool!).

I'm the creator of ZenStack, which is a full-stack toolkit based on Prisma. One of the main things it does is to extend PSL and add a flexible access control layer there - both at the schema level and at runtime. The Prisma's query API is fully preserved and authorization works transparently under the hood.

Do you think it's an interesting idea to integrate ZenStack with Wasp? It'll probably look like:

entity Task {=psl
    id          Int     @id @default(autoincrement())
    description String
    isDone      Boolean @default(false)
    user        User?    @relation(fields: [userId], references: [id])
    userId      Int?

    @@allow('all', auth() == user)   // full access to owner
    @@allow('read', auth() != null)  // readable to all login users
psl=}

Not sure if you guys already started to work on an authz solution yet.

Martinsos commented 6 months ago

@Case-E had some interesting insights into extending automatic CRUD!

Discord convo: https://discord.com/channels/686873244791210014/867713251479519232/1231994987156340736 and https://discord.com/channels/686873244791210014/867713251479519232/1234893790708240414 .

Important bits:

I am eager to see when you implement Automatic CRUD with where conditions. For example, getAll Tasks created by authenticated user or some other where condition like getAll Tasks Where authenticated user is a collaborator or any other where condition. Any insight on when this might be coming?

Mine (use case) is more of a RBAC where I can specify which user can access which resources and features based on their org level role. It'd be great if there were automatic CRUD ops where I could specify the conditions/user roles.