reflex-dev / reflex

🕸️ Web apps in pure Python 🐍
https://reflex.dev
Apache License 2.0
19k stars 1.07k forks source link

Authorization System #3622

Open raayu83 opened 2 months ago

raayu83 commented 2 months ago

Hi @Alek99,

as discussed in Discord, I'm writing down some ideas about an Authorization system (as opposed to Authentication System, though I'd love to see a standards based pluggable integration there too).

Personally, I'd be happy with something along the lines of Django, including the Django Admin section that provides a User Interface for administration of the permissions. I don't have any experience with more recent tooling in this aspect, so what I'm going to write might be a bit outdated and should be taken with a grain of salt.

For this kind of Authorization, there are mainly the following Models needed:

  1. User are just that - physical Users. At the very least User ID and Name or E-Mail would be required here, though it probably would make sense to do something bigger that integrates well with First Party and Third Party Authentication Modules
  2. Permissions contains the information which kind of permissions exist. This should support both referencing a Model whose permission you want to set as well as custom permissions. For each permission, there should be variants for "View", "Change", "Add" and "Delete" actions by default, but it should be possible to define your own instead. For assignment of Permissions to Models, maybe decorators could be used? If possible (might be for a later stage), there should also be a system in place for how to handle changes in referenced models (e.g. model is renamed) and cleaning up unused permissions (e.g. model is deleted completely.
  3. Groups can be assigned to users. When a User has multiple groups, a Union of the permissions of all these groups defines the effective permissions. Additionally, a user can be assigned individual permissions, which will be added to the Union of permissions.

As far as applying the permissions is concerned... I think for Models that have a permission assigned it would be great if corresponding permissions would be checked automatically when doing operation on the models (with an option to override). As for how to do that, I'm unsure. As a foundation, it might be worth using exceptions. However catching exceptions every time you try to save an object seems like a hassle. I wonder if it is possible to add some abstraction layer on top of permission exceptions that allows to handle this more globally and automatically show nicely formatted errors in the User interface....

Additionally, it would love if there was an Row based Authorization system, but I don't know enough about these to write here.

masenf commented 1 month ago

Thanks for taking the time to write up these requirements. I've been developing a authorization system for reflex that addresses most of these concerns, but I do have a question about the permission model.

In my prototype, permissions are a binary: either the user/group has the permission set as "allow" or "deny" (with deny taking precedence). To me this seemed easier to implement and more flexible than a multi-state permission system.

I'll share my prototype in the next week or so for review/critique.

raayu83 commented 1 month ago

Hi @masenf ,

this sounds very interesting!

By binary permissions you mean that you don't differentiate between view/change/add/delete? Looking at the kind of projects I've been doing recently, this would be a very important feature.

masenf commented 1 month ago

By binary permissions you mean that you don't differentiate between view/change/add/delete?

That's correct. So if I had some kind of object, like a Post, i might define permissions like the following

These permissions would then be assigned to users or groups with ALLOW or DENY.

In my opinion, this seems to give the developer the most flexibility to define their permissions as needed for the given application.

raayu83 commented 1 month ago

This seems fine to me 👍

benedikt-bartscher commented 1 month ago

Maybe we could somehow integrate reflex States into an Authorization System. Currently, every user can access all State vars and all event handlers. IMO, a Model based permission system has not much to do with reflex, because reflex (unlike django f.e.) doesn't have auto-generated admin model pages. I still don't quite understand what the model-based "Authorization System" proposed in this Issue should do. The only useful thing I could image is providing a protected/scoped sqlalchemy/sqlmodel session. But that could be a separate project outside of reflex as well.

raayu83 commented 1 month ago

As mentioned in the initial post, my experience with permissions stems from Django and might be a bit dated (and not suited for reflex). I'd be open for anything that solves permission handling in a good way.

paoloemilioserra commented 1 month ago

I'm also interested in this topic for a project I'm working on and I'm very open to suggestions. Our use case has different accessibility for the objects:

On top of that for each resource we have permissions:

onexay commented 1 month ago

Is casbin https://casbin.org/ a better solution which can address varying needs?

amd-srijaroy commented 1 month ago

Can you please add Okta Authentication like Google oAuth ?

https://developer.okta.com/code/

Python SDK : https://github.com/okta/okta-sdk-python. Example : https://github.com/okta/samples-python-flask

React SDK : https://github.com/okta/okta-react Example : https://github.com/okta-samples/okta-react-sample