Recipes

There are many different ways in which you may choose to use django-firefence. Here are some of the basic patterns that you can use:

Middleware

The easiest, but least flexible way to use django-firence is to simply install the FirefenceMiddleware middleware and define some default rules:

MIDDLEWARE += ['firefence.middleware.FirefenceMiddleware']

FIREFENCE= {
    'RULES': [
        {
            'action': 'ALLOW',
            'host': '192.168.1.1',
            'port': '80, 443',
        }
    ],
}

When using the middleware, ALL requests are filtered through the default rules.

By default the middleware uses the provided Fence backend, however you may change the DEFAULT_BACKEND setting to use a custom backend.

Decorator

django-firefence comes with a view decorator that you can use to protect individual views.

This decorator allows you to specify a set of rules to use as well what backend class to use. If either is not provided the defaults specified in the settings will be used.

Here are some examples of how to use the decorator

from firefence.decorators import fence_protected
from firefence.rules import Rule

from my_project.firefence_backends import CustomFence


# Use the default rules and backend
@fence_protected()
def my_view(request):
    return render(request, 'template.html')


# Use a custom set of rules
@fence_protected(rules=[
    Rule(action=Rule.ALLOW, host='192.168.1.1')
])
def another_view(request):
    return render(request, 'template.html')


# Use a custom backend
@fence_protected(backend_class=CustomFence)
def third_view(request):
    return render(request, 'template.html')

Fence

Sometimes you may have a common set of rules you wish to apply to a number of views. One way that you could do this is to create an instance of the Fence backend with those rules and use it to decorate the views:

from firefence.backends import Fence
from firefence.rules import Rule


fence = Fence([
    Rule(action=Rule.DENY, host='192.168.1.1', port=80),
    Rule(action=Rule.ALLOW, port=[80, 443]),
])


@fence.protect
def my_view(request):
    return render(request, 'template.html')


@fence.protect
def another_view(request):
    return render(request, 'template.html')

Custom Backend

The provided Fence backend raises a PermissionDenied error when a denial occurs. If this is not the desired behaviour, you must use a custom backend.

To make the process easy we provide a AbstractFence class that you can extend to easily create new backends. All you have to do is implement a reject method on the new backend. This method must either raise an exception that Django can handle or return an HttpResponse object.

from firefence.backends import AbstractFence


class CustomFence(AbstractFence):
    def reject(self, request):
        return render(request, 'denied.html')