Skip to main content

Authorization library for Django, with ACL, not depends on models.

Project description

django-keeper

Authorization library for Django, not depends on models.

  • Won't depend on models
  • Won't save assignments/permissions into datastores

Supported versions:

  • Python 3.6
  • Python 3.7
  • Django 1.10
  • Django 1.11
  • Django 2.0
  • Django 2.1
  • Django 2.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.

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

FAQ

  • Can I filter models by using ACL?
    • Not supported

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-keeper-0.1.14.tar.gz (6.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_keeper-0.1.14-py3-none-any.whl (7.7 kB view details)

Uploaded Python 3

File details

Details for the file django-keeper-0.1.14.tar.gz.

File metadata

  • Download URL: django-keeper-0.1.14.tar.gz
  • Upload date:
  • Size: 6.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.1

File hashes

Hashes for django-keeper-0.1.14.tar.gz
Algorithm Hash digest
SHA256 f04c3e140a1ff9194b50f53ea1c6fda6436549f260bf5f0f446676bc03c415d9
MD5 957597d4dbfc4202ba268ec068ee833d
BLAKE2b-256 e6bf8c278a81c0f07fb75453179f9c22afb54b1bd764c9227574893e1febf066

See more details on using hashes here.

File details

Details for the file django_keeper-0.1.14-py3-none-any.whl.

File metadata

  • Download URL: django_keeper-0.1.14-py3-none-any.whl
  • Upload date:
  • Size: 7.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.7.1

File hashes

Hashes for django_keeper-0.1.14-py3-none-any.whl
Algorithm Hash digest
SHA256 f717d62a8d620a2303e9c57bf3c989947ec0401739b87f129a2744bcefd45d2e
MD5 50d680f8fe218a44e6ac85d56d6823eb
BLAKE2b-256 81c7ebd2400bd1646ff22b4062029722ae99b211b38567ce5fcade125799b72d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page