Action authorizations at resource levels#3804
Conversation
4c3d960 to
f32c6b9
Compare
|
Hi @mrcasals, here am I again with extra work for you. I promise this is the last PR of this kind for a while. 😬 @decidim/developers I have a technical concern that I want to comment: In the admin zone, I'm reusing the existing command ( |
| @@ -1,26 +1,28 @@ | |||
| # frozen_string_literal: true | |||
|
|
|||
| require "hashdiff" | |||
There was a problem hiding this comment.
We should move this to the decidim-admin/lib/decidim/admin/engine.rb file, I think
| def resource | ||
| @resource ||= if params[:resource_id] && params[:resource_name] | ||
| manifest = Decidim.find_resource_manifest(params[:resource_name]) | ||
| manifest&.resource_scope(component)&.find_by(id: params[:resource_id]) |
There was a problem hiding this comment.
Coverage reports these lines as not tested, is that right?
There was a problem hiding this comment.
Yes, I'm completing participatory spaces system tests to cover this case 👍
There was a problem hiding this comment.
@leio10 nice, tell me when it's ready for a final review! 😄
|
Wow, really nice work @leio10! Thanks for your contributions! I left a couple of comments there, but code looks awesome 👏 |
|
@mrcasals Tests added! Do you think we need seeds for this feature? I didn't find seeds for regular component permissions, so I guess that the answer is no. |
|
@leio10 no, I don't think that's necessary! |
|
@leio10 should we wait for an answer from @decidim/product before merging this? |
|
@mrcasals I don't know 😁. I guess that we can wait if there is anyone available on these days who can review this feature. Also, we can merge this as is, and I can add additional PRs in the future if any change is needed. |
For our part we like this feature on a first sight, although I can't see that clear what kind of processes could need these kind of granularity. Maybe @leio10 can give us more details (like an User Story)? |
|
Kudos from me too, @leio10, awesome job!
Both situations seem like very nice features to have! 👍
What special actions do we have at the participatory space level, I can't seem to recall any... In any case, I think adding something this should be discussed separately from this PR. |
I'm with @deivid-rodriguez, let's discuss this somewhere else @isaacmg410 😄 |
|
Thanks for the feedback @andreslucena! Before giving some examples, I will try to explain what I think is the key to answer your question: the way of using authorizations handlers and all the naming discussion around it. I understand that they where created to allow to authenticate users against an official census. Once an authorization is granted, users won't be authorized anymore against it. I understand that in this scenario this feature doesn't add too much advantages. On the other hand, with PR #2438 we also allow to app developers to override this behavior, allowing to use authorization handlers to authorize users on each action performed (in other words, to ask: are you still in the census?). They also improve the ability for admin users to configure requirements to perform actions through options (are you older that 18? where do you participate? which document did you use to register in the census? which is your level of membership?). I think that in this scenario the need to have different authorization settings for different resources is clearer. Here are some examples that I can think (some are real, some aren't 😄):
Some of these restrictions could be implemented creating different components or participatory spaces and configuring differently in each case, but this would force admin users to group resources by permission needs instead of what is logical to end users. To summarize, I know that this can be useful or not based on the needs of each organization. That is why I was worried about adding extra complexity to users that will not use this feature. And that is why I suggested that I can remove it from any or all of the modified modules (budgets, meetings and proposals) or implement the option to disable it globally by code, by component in the admin zone or in both places. |
|
Thanks @isaacmg410! As @deivid-rodriguez said, currently participatory spaces don't have related actions, so currently we can't apply this improvement there. On the other hand, I don't know if I'm misunderstanding you, but I've seen the use of |
|
Hi @leio10 This is a great feature and contributes a lot to the grained permission strategy (related to #2056 in the user roles) that we have. Some comments below:
It is a good idea to increase the awareness. It is a very important feature for admins and it looks good to me to highlight the icon.
+1
Implement the option to disable/enable it by component in the admin zone could be a great solution. From @decidim/product +1 to go ahead with this. |
|
Great @arnaumonty!! I just implemented the enable/disable option and updated the docs and the changelog. I left the option enabled in all the modules, tell me if you prefer to be disabled by default in any or all of them. |
8b11caa to
e5bd64a
Compare
The code was already in CardMCell and two more classes, and I was needing it in `JoinMeetingButtonCell`, so it seems better to move it to the base class for all cells.
This allows to inform the user that the resource has different permissions settings from the component settings
e5bd64a to
755137a
Compare
|
|
||
| # Public: Whether the permissions for this object actions can be set at resource level. | ||
| def allow_resource_permissions? | ||
| false |
There was a problem hiding this comment.
This is the only line without coverage, because this method is overriden by all resourceables models.
I can change it to
def allow_resource_permissions?; endand it would work well, but I think is would be less clear.
I also can add a new dummy resource class that doesn't override this method, but I think that it doesn't worth it.
There was a problem hiding this comment.
It's OK for me as it is! 😄
There was a problem hiding this comment.
Does it need to be overridden? If so maybe add a raise NotImplementedError?
There was a problem hiding this comment.
NotImplementedError is not intended for this use case, I think...
There was a problem hiding this comment.
@oriolgual it doesn't need to be overridden. By default, resources shouldn't allow to set permissions at that level.
Also, I just realized that there are a lot of other resourceable models, we can just add a test for any of that model and complete the coverage.
|
@mrcasals I think this PR is ready to be reviewed. |
|
@leio10 thank you very much for your contributions! Much appreciated! 😄 |

🎩 What? Why?
This PR adds the ability to configure authorization actions at a resource level. It reuses all the permissions workflow developed for components, but allowing setting different configurations for different resources in the same component.
As with components, possible actions could be defined for resources. If the same action is defined both for a component and for a resource inside the component, it can be set at both levels. The authorization process will look for settings at a resource level first, and at a component level if not found.
I have two main reasons to introduce this change. The first reason is to give admin users the ability to define a set of related resources (proposals, meetings or any other resource) without having to use the same authorization settings for all of them.
The other reason is to allow authorization handlers to receive a reference to the resource that is affected by the action that the user is performing. This allows it to determine if a user can perform each action or not based on the resource information, in addition to the action itself and the user information. For example, this can be used to restrict a user to vote proposals by postal code or scope.
This are the steps for developers to use this feature:
edit_component_permissions_pathhelper method.resourcenamed parameter to the calls to theauthorized?method and to to theaction_authorized_link_toandaction_authorized_button_tohelpers.In this PR I also implemented this feature for budgets (vote action), meetings (join) and proposals (vote and endorse). I think that this could be useful, but if it's not or it adds too much complexity to the UI, I can revert those changes. Also, I can add some code to allow to enable/disable this feature globally in the decidim initializer, or to do it by component in the admin panel. Or I can do both. 😄
📌 Related Issues
📋 Subtasks
CHANGELOGentry📷 Screenshots (optional)