-
Notifications
You must be signed in to change notification settings - Fork 54
Fix management UI and API access permissions for #1425 #1431
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
Conversation
Signed-off-by: David Wallace <david.wallace@tu-darmstadt.de>
Signed-off-by: David Wallace <david.wallace@tu-darmstadt.de>
Signed-off-by: David Wallace <david.wallace@tu-darmstadt.de>
Signed-off-by: David Wallace <david.wallace@tu-darmstadt.de>
Signed-off-by: David Wallace <david.wallace@tu-darmstadt.de>
Signed-off-by: David Wallace <david.wallace@tu-darmstadt.de>
Signed-off-by: David Wallace <david.wallace@tu-darmstadt.de>
Signed-off-by: David Wallace <david.wallace@tu-darmstadt.de>
Signed-off-by: David Wallace <david.wallace@tu-darmstadt.de>
Signed-off-by: David Wallace <david.wallace@tu-darmstadt.de>
Signed-off-by: David Wallace <david.wallace@tu-darmstadt.de>
Signed-off-by: David Wallace <david.wallace@tu-darmstadt.de>
Signed-off-by: David Wallace <david.wallace@tu-darmstadt.de>
|
|
||
|
|
||
| # Add rules | ||
| rules.add_rule('management.can_view_management', |
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.
this will break the backwards compatibility on the base_navigation template, should I keep the the add_rule in there just to not break the possible deployed custom templates?
Otherwise instance admins would need to update the theme for that. Think that it is better to use add_perm than add_rule..
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 agree, but can we have both and remove one in RDMO 3?
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.
Actually, I think add_rule fits better since this is just a predicate "exposed" to the user instance in views etc. I think we should use add_rule for all things can_... and add_perm for model/object permissions. management.can_view_management has no input model or instance. Same for management.can_upload_files and management.can_import_elements.
ChatGPT explained it nicely:
🔹 rules.add_rule(name, function)
- What it does: Registers a predicate function under a name.
- A predicate is just a Python function that takes
(user, obj)and returnsTrueorFalse. - Predicates are reusable building blocks.
- Example:
import rules
# Define a predicate
@rules.predicate
def is_staff(user):
return user.is_staff
# Register it under a name
rules.add_rule('is_staff', is_staff)Now you can reference "is_staff" as a condition in permissions or combine it with others.
🔹 rules.add_perm(name, rule)
- What it does: Registers a permission under a name and attaches it to one or more rules (predicates).
- A permission is basically a "named check" that can be used in your app (e.g. in
user.has_perm()or decorators). - Example:
# Define a permission based on our predicate
rules.add_perm('app.view_secret', is_staff)Now, anywhere in Django, you can do:
user.has_perm('app.view_secret')and it will use the is_staff predicate internally.
✅ Summary
add_rule→ defines a predicate (logic building block).add_perm→ defines a permission that Django can check, usually built from rules/predicates.
Think of it like this:
- Rule = ingredient
- Permission = finished dish 🍲
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.
ok now I see that its actually used as a permission in ManagementView so I guess has_perm is the better idea. Maybe we should remove the can_ from the perms then:
management.view_management, management.upload_files, management.import_elements
maybe even management.upload_elements?
Then the naming is consistent and management and elements are kind of "fake" models, if you know what I mean.
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.
Same for projects.can_view_all_projects to projects.view_projects.
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.
ok, Ive renamed the permissions like that. The has_perm is better for when it will be used on a user object anyway..
rdmo/core/permissions.py
Outdated
| return super().has_permission(request, view) | ||
|
|
||
|
|
||
| class HasRulesPermission(BasePermission): |
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.
this is for the Upload and Import viewsets
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! I checked the drf and rules code, because I was wondering if there is something like this already. This just introduces the permission_required class attribute in the same way as the regular django views, right? I would rename the class to HasPermission, since also all the other Permissions somehow depend on rules.
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.
ok, HasPermission it is..
rdmo/management/viewsets.py
Outdated
|
|
||
| permission_classes = (IsAuthenticated, ) | ||
| permission_classes = [HasRulesPermission] | ||
| permission_required = 'management.can_view_management' |
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.
is the meta used anywhere outside of the management as well??
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.
No, I don't thin so.
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.
Meta should stay IsAuthenticated since it is just the static information about fields and help texts etc.
jochenklar
left a comment
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.
Very nice, thanks! I have the usual naming requests and the lengthy discussion with myself (and ChatGPT) which I want to share with you 😃
|
|
||
|
|
||
| # Add rules | ||
| rules.add_rule('management.can_view_management', |
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 agree, but can we have both and remove one in RDMO 3?
|
|
||
|
|
||
| # Add rules | ||
| rules.add_rule('management.can_view_management', |
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.
Actually, I think add_rule fits better since this is just a predicate "exposed" to the user instance in views etc. I think we should use add_rule for all things can_... and add_perm for model/object permissions. management.can_view_management has no input model or instance. Same for management.can_upload_files and management.can_import_elements.
ChatGPT explained it nicely:
🔹 rules.add_rule(name, function)
- What it does: Registers a predicate function under a name.
- A predicate is just a Python function that takes
(user, obj)and returnsTrueorFalse. - Predicates are reusable building blocks.
- Example:
import rules
# Define a predicate
@rules.predicate
def is_staff(user):
return user.is_staff
# Register it under a name
rules.add_rule('is_staff', is_staff)Now you can reference "is_staff" as a condition in permissions or combine it with others.
🔹 rules.add_perm(name, rule)
- What it does: Registers a permission under a name and attaches it to one or more rules (predicates).
- A permission is basically a "named check" that can be used in your app (e.g. in
user.has_perm()or decorators). - Example:
# Define a permission based on our predicate
rules.add_perm('app.view_secret', is_staff)Now, anywhere in Django, you can do:
user.has_perm('app.view_secret')and it will use the is_staff predicate internally.
✅ Summary
add_rule→ defines a predicate (logic building block).add_perm→ defines a permission that Django can check, usually built from rules/predicates.
Think of it like this:
- Rule = ingredient
- Permission = finished dish 🍲
rdmo/management/viewsets.py
Outdated
|
|
||
| permission_classes = (IsAuthenticated, ) | ||
| permission_classes = [HasRulesPermission] | ||
| permission_required = 'management.can_view_management' |
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.
No, I don't thin so.
rdmo/management/viewsets.py
Outdated
|
|
||
| permission_classes = (IsAuthenticated, ) | ||
| permission_classes = [HasRulesPermission] | ||
| permission_required = 'management.can_view_management' |
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.
Meta should stay IsAuthenticated since it is just the static information about fields and help texts etc.
|
|
||
|
|
||
| # Add rules | ||
| rules.add_rule('management.can_view_management', |
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.
ok now I see that its actually used as a permission in ManagementView so I guess has_perm is the better idea. Maybe we should remove the can_ from the perms then:
management.view_management, management.upload_files, management.import_elements
maybe even management.upload_elements?
Then the naming is consistent and management and elements are kind of "fake" models, if you know what I mean.
|
|
||
|
|
||
| # Add rules | ||
| rules.add_rule('management.can_view_management', |
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.
Same for projects.can_view_all_projects to projects.view_projects.
rdmo/core/permissions.py
Outdated
| return False | ||
|
|
||
| # prefer a view-level override when present | ||
| perm = getattr(view, 'permission_required', None) |
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 None is not needed and I would turn it around, check the perm if perm and raise the error at the bottom.
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 now simply return:
# the viewset needs to set permission_required
return request.user.has_perm(view.permission_required)I think it should only be used like that anyway and break when we would forget to set a permission_required on the viewset.
rdmo/core/permissions.py
Outdated
| return super().has_permission(request, view) | ||
|
|
||
|
|
||
| class HasRulesPermission(BasePermission): |
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! I checked the drf and rules code, because I was wondering if there is something like this already. This just introduces the permission_required class attribute in the same way as the regular django views, right? I would rename the class to HasPermission, since also all the other Permissions somehow depend on rules.
Signed-off-by: David Wallace <mypydavid@proton.me>
Signed-off-by: David Wallace <mypydavid@proton.me>
jochenklar
left a comment
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.
Great work! I think we are done here.
| {% back_to_project_link %} | ||
|
|
||
| {% test_rule 'management.can_view_management' request.user request.site as can_view_management %} | ||
| {% comment %}the test_rule will be removed in RDMO 3.0{% endcomment %} |
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 think here we can just use {% has_perm 'management.view_management' request.user as can_view_management %} only test_rule should still exist for the legacy templates.
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.
ah yes, that would work without breaking it! 😅
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, thanks, Ive changed it now to that.
Signed-off-by: David Wallace <david.wallace@tu-darmstadt.de>
Signed-off-by: David Wallace <david.wallace@tu-darmstadt.de>
jochenklar
left a comment
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.
🚀
…nterview-fixes Refactor ProjectOverviewSerializer
|
Ok I merged my subbranch so this can be merged now, I guess. |
Description
Related issue: #1425