openlibhums / openlibhums/janeway
Composable permissions decorator
@mauromsl is already working on this.
Since Nov 20, 2025.
- Dominant language
- Python
- Stars
- 238
- Forks
- 97
- Avg merge
- 9d 1h
- Merged PRs (30d)
- 8
Description
Is your feature request related to a problem? Please describe.
This is a design pattern proposal rather than an actual journal feature.
The current security model on views is implemented with decorators that can verify a number of conditions on the user attached to the request, as well as additional arguments such as articles.
This decorator functions hold the logic to decide whether to call the decorated function or raise a PermissionDenied exception instead. Views often have a combination of conditions to be checked where one, some or all conditions must pass for the user to be granted access to the requested resource. As a result, there is a long list of functions under core.security.decorators.py such as article_stage_accepted_or_later_or_staff_required which in some cases are specific to just one view.
Describe the solution you'd like
I've worked on a solution to a similar problem before where we used a composition model to declare permissions at the decorator level. It looked something like this:
@auth_required(Any(superuser, staff)
def foo():
@auth_required(All(authenticated, owner)
def bar():
Logical constructs can be combined like `@auth_required(Any(All(authenticated, owner), superuser))
Testing this model is much simpler as it just requires testing each individual entity (All, owner, authenticated...), Instead of requiring a test for each combination of conditions.
Describe alternatives you've considered
An alternative approach I've considered would be to use an ownership model over the resources, (similar to the Unix permission model) where privileges and permissions are linked to the ownership of each resource (journal, article, review assignment) for each CRUD operation. However this would be impractical to implement as it would involve modifications to every current view. Instead, my proposed solution could be implemented and used for new views and then be expanded to other views where deemed necessary.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.