-
-
Notifications
You must be signed in to change notification settings - Fork 70
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
Permission system (guards) #43
Comments
@System-Glitch I have an idea on my mind. I'll write a proposal and we can discuss it. |
AbstractI propose a permission system based on RBAC. Every user will have a list of roles with specific permissions saved in the DB. The permissions will specify what a role is allowed to do and on what items. Anytime a validation is required, the validation will compare the permissions of the user passed with the request against the required permissions. BackgroundRBAC - (Role-based access control) is based on defining a list of roles and adding each user in the system to one or more roles. Permissions and privileges are then granted to each role, and users receive them via their membership in the role. ACL- (Access-control list) is a list of permissions attached to an object. It specifies which users or system processes are granted access to objects, as well as what operations are allowed on given objects. RBAC defines permissions from the view of the roles, which means: roleA can read objectA and write to objectB whereas ACL is set from the perspective of the item: objectA allows userA to delete it, and userB to read it. ProposalInitializationA new field named Permissions StructureThe following JSON depicts the structure of the permissions.
Few points to notice:
How it will be usedA new function called IsAuthorized will be added to Goyave. Its signature is:
RationaleThe reason I propose an RBAC solution instead of ACL is because the developer will have many resources in the system and not many roles. That way, it will be easier to define a small number of roles in relation to many resources instead of defining permissions on many resources. Feel free to comment if you have different suggestions or something is not clarified. 😃 After we settle on the proposal, I'll break the design into steps, and we'll start working from there. |
Great proposal. I do have a few questions and comments though. I think that the policy should be "Deny" by default, and that only "Allow" policies are needed. However, "Deny" could be useful in a case where the user has multiple roles, one allowing access to a resource and one denying it. In this scenario, which policy has priority? Roles should be put in a separate model and database table, to avoid redundancy and potential mismatches. The default
I like the resource field for URIs very much, but for models, I don't think we can implement that. At the time middleware is executed, we don't know which model or which action the controller handler is going to use. The same goes for permission list. About |
One last thing, I thought about more use cases for permission checking except using models for accessing the DB or for routes. For example, a user might want to have an option to clear the cache, restart a service, send a notification, etc.). By using |
Note: I took a lot of inspiration from the PHP Laravel framework for certain parts of Goyave. Laravel provides an Authorization feature which may be a good |
|
Calling In short: authorization should always be defined in the route definition, preferably as a middleware. However, the developer should still be able to check authorization in another context (with the I think custom authorization function is indeed a must, and is probably the best way to setup authorization on models and services that are not related to database records. I think we should focus on developing a base for the system and make it expandable, like the Goyave auth system: you can add more authenticators easily. |
I have most of it on my mind, but there are a few more points I'm not confident about yet. If it's possible for you, I think it's better if we sum it up over an audio call like zoom or even chat. |
I'll email you to know how we can contact each other. A summary of what's been said will be posted here as well. |
Summary of yesterday's chatRoles and policies will be dynamic and persistent: two tables will be created by the framework.
A type Permissionable struct {
Roles []Role `gorm:"many2many:user_roles;"`
} This allows us to take advantage of the relation handling in Gorm. Roles and policies will be manageable through standard functions such as
Most likely use-cases:
This system allows developers to move from use-case to another very easily and would require minimal changes to the application code to extend or shrink its roles functionalities mid-development. An authorization middleware will be implemented. This middleware will load the user's related roles and check if he has access to the requested route. Once loaded, the roles stay available and can be used inside custom middleware and controller handlers. Thanks to the Roles and users won't be loaded at all times into memory for better memory efficiency and scalability, at the cost of very slightly longer response time. On top of the URI authorization definition, developers will be able to implement custom authorization functions. These functions will be located in a new folder in the recommended directory structure. This directory name is still to be defined. |
I am still looking for contributors to implement this feature. |
I can help. |
Hello @dhairya0904 ! Thank you very much for your help ! Don't hesitate to contact me (via email, telegram or discord) if you have any question or if you need guidance. Shall I move this issue to "In progress"? |
Sure |
any update on this feature? |
@najib-baedlowi No work on this feature is currently scheduled on my end. It would still need a proper design phase too. Some of the points discussed in the summary above are outdated and a bit opposed to the new design philosophy that came with v5. I think we need to go back to the drawing board. |
Proposal
Guards are an extension of the authentication system using user-defined fields from the authenticator's user model to allow or deny specific actions to an authenticated user.
For example, a Goyave application will define a guard for forums moderation. A moderator is allowed to modify the posts of other users, but regular users aren't. A guard
update-others
will be implemented, using theIsModerator
field from the user model and the route parameter to check if the user is a moderator or if its own post.Guards could be used in two ways:
This system could support OAuth in some way too.
The implementation is not defined yet, so feel free to discuss and suggest one.
Possible drawbacks
None
.Additional information
This issue is a feature proposal and is meant to be discussed.
It is also a good candidate if you want to contribute to the project.
The text was updated successfully, but these errors were encountered: