-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
[12.0][add] New decorator @api.allowed_groups #2026
[12.0][add] New decorator @api.allowed_groups #2026
Conversation
5dd0a23
to
e319f45
Compare
IMO providing this functionality through a module is not appropriate for this kind of feature. It's not a per database functionality and once the addon is into the path (I think it's not required to install-it), the decorator is available for the whole runtime. |
Seems very interesting. Would help a lot to make functions more secure in an easy way. Some tests would definitely be helpful. I do not know how to evaluate the performance impact, except by testing it in practice. But certainly for some methods, checking the groups has to be done anyway. |
groups= in view should only be reserved to hide elements you have right to see / activate. And this PR make this possible so 👍 I have concerns about how it behave when :
|
Hi @lmignon. Regarding the lib vs module design.
You was right, but this point is obsolete in recent Odoo version. The code of the module
You can read a more detailled explanation here : OCA/OpenUpgrade#2440 (comment)
|
if func: | ||
group_xml_ids = getattr(func, "_allowed_groups", False) | ||
if group_xml_ids: | ||
node.set("groups", ",".join(group_xml_ids)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe emit a warning if groups is already set and not equivalent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about that point, and I'm not sure.
Consider you have an Odoo / OCA module with a def my_action(self)
defined, and a button defined in a view with groups="module_1._group_A"
.
In a custom module, you want to change the group, so you simply write
@api.allowed_groups("module_2.group_B")
def my_action(self):
return super().my_action(self)
If you do so, it will raise a false warning, forcing developpers to overload the view in the custom module, to remove the group.
I so just added in the USAGE.rst
file this text :
The groups defined in the decorators take precedence over the groups that would be defined in the existing views.
What do you think ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My preference would be to emit the warning. It seems to me that the value of this module is mainly for methods introduced in modules that use this decorator in the first place, rather than overriding existing methods, and in that case, aligning the views is the proper thing to do to avoid confusion. But it's just my preference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about combining the groups in the button and in the decorator, so you can only limit the authorities by either method, but never grant authorities?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say that is not the way I would expect and want such a mechanism to work. I guess it depends on whether you take a security perspective or a usability perspective.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is what I would expect. But I think I expressed myself poorly. Combining should be interpreted as: when groups are defined on the button and in the decorator, only the groups that are valid in both should be shown. When this leaves no valid groups, at least a warning should be shown, or maybe even an exception thrown.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe emit a warning if groups is already set and not equivalent?
You're right. 👍
I added this point to the roadmap. Better to add a warning. We can remove it in a second time, if we consider later, that it is not relevant in some cases.
when groups are defined on the button and in the decorator, only the groups that are valid in both should be shown
do you mean :
- if
groups="base.group_A,base.group_B"
- and
@api.allowed_groups("base.group_B", "base.group_C")
-> the result shouldgroups="base.group_B"
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only the groups that are valid in both should be shown
Ah indeed, I misunderstood. This would improve the usability as well as the security. 👍
"To execute the function {}, you should be member" | ||
" of one of the following groups:\n {}".format( | ||
method, | ||
', '.join(group_xml_ids)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe applying format
on user controlled input (such as a translatable string) has security implications (except that format
is applied here to the translation source instead of the translation value but that is another thing).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
applied here to the translation source instead of the translation value but that is another thing
Thanks ! Fixed.
applying format on user controlled input (such as a translatable string) has security implications
I didn't know. I replaced by %s
. Is it better ? ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, see OCA/pylint-odoo#302
Do you know if decorators like this have to be repeated when their methods are overridden? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice!
…orator_allowed_groups
…ule decorator_allowed_groups
…new module decorator_allowed_groups
… [ADD] new module decorator_allowed_groups
Regarding inheritance, @hpar said :
and @StefanRijnhart said :
Well, it was not correctly handled, but I refactored a little bit the code to make inheritance working. here is the text added in the USAGE.rst file. Inheritance mechanismsit is possible to change accreditation level in custom module. For exemple, if a module A defines a function like this:
In a custom module B, that depends on module A :
I wrote some dummy code, available here. you can play with that code grap/odoo-addons-extra#1, if you want to test. |
… fixup! [ADD] new module decorator_allowed_groups
Thank you for your clarification regarding overrides.
Just to be clear, is it the case that the check is executed when |
In fact, writing test, It seems that it doesnt work exactly as I have described it. But that is the objective !
I'll test it, but I guess, yes. |
For sure the decorator will not be available in the My comment is not a blocking comment, it's just my thought about the right way to provide such a functionality. |
from odoo.exceptions import AccessError | ||
|
||
|
||
def allowed_groups(*group_xml_ids): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The decorator is not a model. IMO it should be moved into decorator_allowed_groups/api.py
|
||
.. code-block:: python | ||
|
||
@api.allowed_groups("purchase.group_purchase_manager") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@legalsylvain IMO it's not a good practice to import the decorator from odoo.api
this will only works if you add the addon into the server_wide_modules
list and will require to modify the configuration file each time this addon is used to avoid strange error at server start. (Could become a pain in OCA repos). from odoo.addons.decorator.allowed_groups.api import allowed_groups
will work in every case without requiring to add the addon into the server_wide_modules
list
@legalsylvain Will you still be working on this? |
Hi @thomaspaulb. Thanks for your interest. My PoV : I still think that :
But, now, I think that creating a dedicated OCA module is not a good idea. This feature should be put in the odoo At the last Open Days 2023, I spoke briefly about this subject with @rco-odoo. Perhaps the idea will finally be taken up by the Odoo Core team... |
There hasn't been any activity on this pull request in the past 4 months, so it has been marked as stale and it will be closed automatically if no further activity occurs in the next 30 days. |
Hi all,
The recent PR made by @StefanRijnhart here odoo/odoo#66505 made me think of an old idea that we talked about here #944 and here OCA/oca-decorators#7.
I so made a little PoC, and it works quite well.
@OCA Members : What do you think ? CC : @lasley, @pedrobaeza, @NL66278, @lmignon, @sbidoul
@odoo Team : Any chance to see this feature integrated in the Odoo core directly ? I don't know who ping in the team. @Yenthe666 any idea ?
Note
I finally made my PoC using a module design and not integrating the code in the current oca lib https://github.com/OCA/oca-decorators because I was more comfortable with this type of design, and that the reasons for using a library seems obsolete in recent versions of Odoo.
Description
This module is a technical module for developpers.
It adds a new decorator, named
@api.allowed_groups
.When the function is executed, it checks if the user belong to one of the given groups.
It also adds automatically group(s) in the according form views to hide
buttons if the user doesn't belong to one of the given groups.
Interests
In Odoo, there are many places where an action is hidden in the Form view, but the function can be called in particular by XML-RPC calls, that makes a lot a security issue, included
in recent version.
Ref : odoo/odoo#66505
where the groups are defined instead two places without this module (XML and Python code)
Usage
Once installed, the following code:
can be replaced by:
Multi-group membership checks
It is possible to list many groups. In that case, the action will be allowed
if the user belong to at least one group.
Conflict between view and decorators definition
The groups defined in the decorators take precedence over the groups that would be defined in the existing views.
Inheritance mechanisms
it is possible to change accreditation level in custom module.
For exemple, if a module A defines a function like this:
In a custom module B, that depends on module A :