GithubHelp home page GithubHelp logo

guardian's Introduction

Guardian

Open Source Love PyPI version

The django-rest middleware on steroids.

Overview

The guardian is highly flexible middleware for the django-rest class based views.

The current issue with the django-rest permission is that they are applied at class level and hence making it difficult to have seprarate permissions for individual methods. The guardian solves this issue by providing method based authentication.

Some reasons you might want to use Guardian:

  • It can be used to authenticate the user
  • It can be used to authorize the payload
  • Provides method based authentications as well as class based authentication.

Requirements

  • Python (2.x, 3.x)
  • Django (1.8+)
  • Django REST (3.x)

Installation

Install using pip...

pip install django-rest-guardian

Example

Let's take a look at a quick example of using guardian to build a simple middleware for authenticating user and authorizing payload.

1. User Authentication

Create a Permssion class in your desired file eg: app/permission.py by inherinting the permission class from guardian module and overriding the guard method

from django_rest_guardian.permission import AuthPermission

# The method gets request as params and need to return True or False depicting whether the user is verified or not.
class UserAuthenticator(AuthPermission):
    def guard(self, request):
        if request.user_type == 'user':
            return True
        else:
            return False
        

Let's use this permission in our view layer - app/views.py

from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from app.permission import UserAuthenticator
from django_rest_guardian import guardian

class UserView(APIView):
    
    @guardian(UserAuthenticator) # returns 401 if the UserAuthenticator returns False
    def get(self, request):
        print 'The user is authenticated if you are seeing this message'
        
        return Response({'result': True}, status=status.HTTP_200_OK)

We can also have multiple authenticator classes. So now let's create one more class and pass it to the guardian

app/permission.py

from django_rest_guardian.permission import AuthPermission

class UserAuthenticator(AuthPermission):
    def guard(self, request):
        if request.user_type == 'user':
            return True
        else:
            return False
        
 class AdminAuthenticator(AuthPermission):
    def guard(self, request):
        if request.user_type == 'admin':
            return True
        else:
            return False
        

The guardian uses a logical short circut OR on the both the authenticator class.

app/views.py

class UserView(APIView):
   
   @guardian(UserAuthenticator, AdminAuthenticator) # returns 401 if the UserAuthenticator returns False
   def get(self, request):
       print 'The user is authenticated if you are seeing this message'
       
       return Response({'result': True}, status=status.HTTP_200_OK)

2. Payload Authorization

The guardian can also be used to to authorize the payload sent by the frontend. Let's assume this is the payload sent by the frontend

{
   "id": 5,
   "name": "John",
   "hobbies": ["Footbal", "Fencing"]
}

Let's verify the payload

app/views.py

class UserView(APIView):
   
   # returns 400 if the payload is invalid
   @guardian(id=int, name=unicode, hobbies=list) # we use unicode because python treats the string as unicode for data.
   def post(self, request):
       print 'The payload is correct if you are seeing this message'
       
       return Response({'result': True}, status=status.HTTP_200_OK)

Guardian also supports validating n-dimensional lists.

What To Write What Happens
list simply validates if payload is list
[] works same as list
[ int ] Validates that a list should contain only integers. * int can be replaced by any acceptable python data type, even list.*
[[ unicode ]] Validates that payload should contain two-dimensional list of Strings.
[[[[[[ int ]]]]]] This validates for (count-no-of-square-brackets) dimensional list of integers. I think you get the point.

Guardian also supports validating insides of a dict.

What to Write What Happens
{ 'id': int } Checks in the payload that id should be an integer
{ 'user': {'name': unicode, 'email': unicode }} Checks that user is a dict which has name as unicode and email as unicode
{ 'ids': [int] } Checks that ids is a list of integers.

More Stuff

1. Both user authentication and payload verification

We can use user auth and payload verification both at the same time app/views.py

class UserView(APIView):
  
   @guardian(UserAuthenticator, AdminAuthenticator, id=int, name=unicode, hobbies=list)
   def post(self, request):
       print 'The user is authenticated and the payload is correct if you are seeing this message'
       
       return Response({'result': True}, status=status.HTTP_200_OK)

2. Pass additional parameter with request

We can pass additional parameter with request to views layer

app/permission.py

from django_rest_guardian.permission import AuthPermission

class UserAuthenticator(AuthPermission):
    def guard(self, request):
        if request.user_type == 'user':
            request.user = 'simon' # adding <user> param to request and returning it.
            return True
        else:
            return False

Now we can access this parameter in view layer app/views.py

class UserView(APIView):
  
   @guardian(UserAuthenticator)
   def post(self, request):
       print request.user # prints 'simon'
       
       return Response({'result': True}, status=status.HTTP_200_OK)

License

This project is licensed under the MIT License - see the LICENSE file for details

guardian's People

Contributors

droidlife avatar symphoria avatar

Stargazers

 avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.