All Projects → hirokiky → django-keeper

hirokiky / django-keeper

Licence: MIT license
Authorization library for Django, with ACL, not depends on models.

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to django-keeper

Appy
🚀 A full stack boilerplate web app
Stars: ✭ 225 (+378.72%)
Mutual labels:  permissions, authorization
spicedb
Open Source, Google Zanzibar-inspired fine-grained permissions database
Stars: ✭ 3,358 (+7044.68%)
Mutual labels:  permissions, authorization
Vue Router User Roles
A Vue.js plugin that protects routes based on user roles. Add your own authentication.
Stars: ✭ 237 (+404.26%)
Mutual labels:  permissions, authorization
Laravel Authz
An authorization library that supports access control models like ACL, RBAC, ABAC in Laravel.
Stars: ✭ 136 (+189.36%)
Mutual labels:  permissions, authorization
django-cancan
🔓Authorization library for Django
Stars: ✭ 36 (-23.4%)
Mutual labels:  permissions, authorization
Think Authz
An authorization library that supports access control models like ACL, RBAC, ABAC in ThinkPHP 6.0 .
Stars: ✭ 155 (+229.79%)
Mutual labels:  permissions, authorization
Rbac
Hierarchical Role-Based Access Control for Node.js
Stars: ✭ 254 (+440.43%)
Mutual labels:  permissions, authorization
Laravel Auth
A powerful authentication, authorization and verification package built on top of Laravel. It provides developers with Role Based Access Control, Two-Factor Authentication, Social Authentication, and much more, compatible Laravel’s standard API and fully featured out of the box.
Stars: ✭ 128 (+172.34%)
Mutual labels:  permissions, authorization
rbac-tool
Rapid7 | insightCloudSec | Kubernetes RBAC Power Toys - Visualize, Analyze, Generate & Query
Stars: ✭ 546 (+1061.7%)
Mutual labels:  permissions, authorization
nova-permissions
Add Permissions based authorization for your Nova installation via User-based Roles and Permissions. Roles are defined in the database whereas Permissions are defined in the code base.
Stars: ✭ 115 (+144.68%)
Mutual labels:  permissions, authorization
feathers-casl
feathers.js + casl: hooks & channels
Stars: ✭ 25 (-46.81%)
Mutual labels:  permissions, authorization
HeimGuard
🛡 A simple library that allows you to easily manage permissions in your .NET projects.
Stars: ✭ 77 (+63.83%)
Mutual labels:  permissions, authorization
Laratrust
Handle roles and permissions in your Laravel application
Stars: ✭ 1,799 (+3727.66%)
Mutual labels:  permissions, authorization
Drf Access Policy
Declarative access policies/permissions modeled after AWS' IAM policies.
Stars: ✭ 200 (+325.53%)
Mutual labels:  permissions, authorization
Laravel Governor
Manage authorization with granular role-based permissions in your Laravel Apps.
Stars: ✭ 131 (+178.72%)
Mutual labels:  permissions, authorization
Bouncer
Eloquent roles and abilities.
Stars: ✭ 2,763 (+5778.72%)
Mutual labels:  permissions, authorization
Rbac.dev
A collection of good practices and tools for Kubernetes RBAC
Stars: ✭ 115 (+144.68%)
Mutual labels:  permissions, authorization
Accesscontrol
Role and Attribute based Access Control for Node.js
Stars: ✭ 1,723 (+3565.96%)
Mutual labels:  permissions, authorization
graphql authorize
Authorization helpers for ruby-graphql fields
Stars: ✭ 23 (-51.06%)
Mutual labels:  permissions, authorization
riam
AWS IAM inspired policy engine in Rust
Stars: ✭ 19 (-59.57%)
Mutual labels:  permissions, authorization

django-keeper

Authorization library for Django, not depends on models.

  • Won't depend on models
  • Won't depend on datastores
  • Won't depend on Django's permission system
  • Won't depend on Django's User model

Supported versions:

  • Python 3.7
  • Python 3.8
  • Python 3.9
  • Django 2.2
  • Django 3.0
  • Django 3.1
  • Django 3.2

Install

$ pip install django-keeper

And add to INSTALLED_APPS

INSTALLED_APPS = [
    ...
    'keeper',
]

At A Glance

Declarative permission mapping for models.

from django.conf import settings
from keeper.security import Allow
from keeper.operators import Everyone, Authenticated, IsUser


class Issue(models.Model):
    author = models.ForeignKey(settings.AUTH_USER_MODEL)
    ...

    def __acl__(self):
        return [
            (Allow, Everyone, 'view'),
            (Allow, Authenticated, 'add_comment'),
            (Allow, IsUser(self.author), 'edit'),
        ]

Instances of model allow:

  • Every requests to view
  • Autheticated requests to add comments
  • it's author to edit

Then, apply @keeper for views.

from keeper.views import keeper


# Model Permissions
@keeper(
    'view',
    model=Issue,
    mapper=lambda request, issue_id: {'id': issue_id},
)
def issue_detail(request, issue_id):
    """ View requires 'view' permission of Issue model

    * An issue object will be retrieved
    * keeper will check whether the rquests has 'view' permission for the issue

    The third argument function can return keyword argument to retrieve the issue object.
    """
    request.k_context  # Will be instance of the issue object
    ...



@keeper(
    'add_comment',
    model=Issue,
    mapper=lambda request, issue_id: {'id': issue_id},
)
def add_comment(request, issue_id):
    ...

Global Permission

Not just for model permissions django-keeper can handle global permissions.

First, write class having __acl__ method in models.py.

class Root:
    def __acl__(self):
        return [
            (Allow, Authenticated, 'view_dashboard'),
            (Allow, Authenticated, 'add_issue'),
        ]

It's not necessary to put it in models.py, but easy to understand.

And specify it in settings.

KEEPER_GLOBAL_CONTEXT = 'myapp.models.Root'

Then you can use global permission in views. Simply just apply @keeper and permission names.

@keeper('add_issue')
def issue_list(request):
    """ View requires 'add_issue' permission of Root Context
    """

Operators

Operators is just Callable[[HttpRequest], bool]. By default django-keeper has these operators:

  • keeper.operators.Everyone
  • keeper.operators.Authenticated
  • keeper.operators.IsUser
  • keeper.operators.Staff

Also you can create your own operators easily.

from keeper.operators import Authenticated, Operator


class IsIP(Operator):
    def __init__(self, ip):
        self.ip = ip
        
    def __call__(self, request):
        return request.META.get('REMOTE_ADDR') == self.ip


class BelongsTeam(Authenticated):
    def __init__(self, team, role):
        self.team = team

    def __call__(self, request):
        if not super().__call__(request):
            return False
        return  request.user.team == self.team

Use it in ACL

class Article(models.Model):
    team = models.ForeignKey(Team)
    
    def __acl__(self):
        return [
            (Allow, Everyone, 'view'),
            (Allow, BelongsTeam(self.team), 'edit'),
            (Allow, IsIP(settings.COMPANY_IP_ADDRESS), 'edit'),
        ]

Combining operators

You can use bitwise operators to combine multiple "Operators".

class Article(models.Model):
    def __acl__(self):
        return [
            (Allow, Authenticated() & IsIP(settings.COMPANY_IP_ADDRESS), 'view'),
        ]

There operators can be used

  • a & b
  • a | b
  • a ^ b
  • ~a

On Fail Actions

You can change actions when requests can't pass ACLs.

from keeper.views import keeper, login_required

@keeper(
    'view_articles',
    on_fail=login_required(),
)
def dashboard(request):
    ...

This view will behave just like @login_required decorator of Django when requests don't have 'view' permission.

Also you can use other actions.

  • keeper.views.login_required
  • keeper.views.permission_denied
  • keeper.views.not_found
  • keeper.views.redirect

Use in template

Handling permissions in templates is also supported.

{% load keeper %}

{% has_permission issue 'edit' as can_edit %}

{% if can_edit %}
    <a href="...">Edit</a>
{% endif %}

When checking global permission, use has_global_permission.

{% load keeper %}

{% has_global_permission 'add_issue' as can_add_issue %}

{% if can_add_issue %}
    <a href="...">New Issue</a>
{% endif %}

With Django Core

Add the authentication backend:

AUTHENTICATION_BACKENDS = (
    'keeper.permissions.ObjectPermissionBackend',
    'django.contrib.auth.backends.ModelBackend',
)

Now User.has_perm method will consider permissions of django-keeper.

Alternative

  • django-guardian
    • It depends on databases
    • Not way to handle global permissions, not just for a model
  • django-rules
    • Basiaclly, rules is used with Django's permissions, but keeper isn't (basiacally).
    • rules doesn't support view decorators or mixins for it's "rules" system (for Django's permission, yes).

FAQ

  • Can I filter models by using ACL?
    • Not supported
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].