question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Return rule denial reasons (and improved integration with rest framework)

See original GitHub issue

Thanks for the great library! I love the philosophy to use rules written in simple python functions over database tables.

I ran into a few troubles trying to integrate it with a django rest framework project - we don’t use django permissions, which means we can’t use DjangoObjectPermissions easily.

I thought to connect django-rules directly to drf permissions - ends up similar-ish to dry-rest-permissions but using django-rules.

I also wanted to be able to return custom error messages explaining why a permission was denied.

I managed to implement this by subclassing stuff in django-rules so that you can use it like this:

# in rules.py

@predicate(messages=('Team is archived', 'Team is not archived'))
def is_team_archived(_, team):
  return team.status = 'archived'

can_archive_team = ~is_team_archived

# standalone use

result, message = can_archive_team.test_with_message(user, team)
if result:
  print('yes')
else:
  print('no:', message) # prints "no: Team is archived"

# use in a @detail_route

# creates a drf compatible permission class
CanArchiveTeam = create_permission_class('CanArchiveTeam', can_archive_team)

@detail_route(
    methods=['POST'],
    permission_classes=(IsAuthenticated, CanArchiveTeam)
)
def archive(self, request, pk=None):
  # do archiving

If the CanArchiveTeam does not pass, then it returns a permission denied error with the message Team is archived.

There is a bit more information in our project discussion.

I wanted to avoid magic naming conventions (the approach taken by dry-rest-permissions) or referring to permissions using string names - explicit imports are much clearer to me.

Actually, the only API change for rules is changing/adding a method that returns (result, message) instead of result, and accepting messages as predicate args.

My questions are:

  • would you be interested in having something this inside django-rules?
  • if not, would you be interested in making django-rules officially extendable so I don’t need to use private methods/variables which might break in future versions?

The alternative is a fork, but I don’t want to contribute to the ever fragmenting django permissions ecosystem. Thanks!

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:4
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
dfuncktcommented, Jul 22, 2018

I think a good approach would be to allow a predicate to fail by raising a specific type of exception instead of returning falserules could catch that, turn the result into false, stash the exception as the denial reason and offer a way for the caller to retrieve it.

0reactions
benwhalleycommented, Oct 17, 2019

Perhaps a nicer way to avoid breaking backwards compatibility for predicates would be to return either True/False as now or True/Failed where Failed is a new object that is false-y but also contains a message string that is processed by rules?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Permissions - Django REST framework
Permissions are used to grant or deny access for different classes of users to different parts of the API. The simplest style of...
Read more >
How to get OR permissions instead of AND in REST framework
I know. But then the problem is that once this permission class returns False, permission to the resource is denied. The logic I...
Read more >
Web API implementation - Best practices for cloud applications
Learn about best practices for implementing a web API and publishing it to make it available to client applications.
Read more >
Output from an Amazon API Gateway Lambda authorizer
Here, a policy statement specifies whether to allow or deny ( Effect ) the API Gateway execution service to invoke ( Action )...
Read more >
Fix the Most Common API Gateway Request Errors - Dashbird
This is a rule of thumb, and if you don't have any logic bugs in your backend, it holds. But nobody is perfect,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found