Login

Support alternative authentication mechanisms with Piston

Author:
erikwright
Posted:
January 15, 2010
Language:
Python
Version:
1.1
Score:
2 (after 2 ratings)

This snippet for Piston allows you to offer a choice of authentication methods to clients.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
from django.http import HttpResponse

from piston.authentication import OAuthAuthentication, HttpBasicAuthentication

class MultiValueHttpResponse(HttpResponse):
    '''
    A subclass of HttpResponse that is capable of representing multiple instances of a header.
    Use 'add_header_value' to set or add a value for a header.
    Use 'get_header_values' to get all values for a header.
    'items' returns an array containing each value for each header.
    'get' and '__getitem__' return the first value for the requested header.
    '__setitem__' replaces all values for a header with the provided value.
    '''
    def __init__(self, *args, **kwargs):
        super(MultiValueHttpResponse, self).__init__(*args, **kwargs)
        self._multi_value_headers = {}
        # the constructor may set some headers already
        for item in super(MultiValueHttpResponse, self).items():
            self[item[0]] = item[1]

    def __str__(self):
        return '\n'.join(['%s: %s' % (key, value)
                          for key, value in self.items()]) + '\n\n' + self.content
    
    def __setitem__(self, header, value):
        header, value = self._convert_to_ascii(header, value)
        self._multi_value_headers[header.lower()] = [(header, value)]

    def __getitem__(self, header):
        return self._multi_value_headers[header.lower()][0][1]

    def items(self):
        items = []
        for header_values in self._multi_value_headers.values():
            for entry in header_values:
                items.append((entry[0], entry[1]))

        return items

    def get(self, header, alternate):
        return self._multi_value_headers.get(header.lower(), [(None, alternate)])[0][1]

    def add_header_value(self, header, value):
        header, value = self._convert_to_ascii(header, value)
        lower_header = header.lower()
        if not lower_header in self._multi_value_headers:
            self._multi_value_headers[lower_header] = []
        self._multi_value_headers[lower_header].append((header, value))

    def get_header_values(self, header):
        header = self._convert_to_ascii(header)

        return [header[1] for header in self._multi_value_headers.get(header.lower(), [])]

class MultipleAuthentication(object):
    def __init__(self, **methods):
        self.methods = methods
    
    def is_authenticated(self, request):
        auth_header = request.META.get('HTTP_AUTHORIZATION', None)
        if not auth_header:
            return False

        (method, auth) = auth_header.split(" ", 1)
        if method in self.methods:
            return self.methods[method].is_authenticated(request)

        return False

    def challenge(self):
        response = MultiValueHttpResponse('Authorization Required',
                                          content_type="text/plain", status=401)
        for method in self.methods.values():
            challenge = method.challenge().get('WWW-Authenticate', None)
            if challenge:
                response.add_header_value('WWW-Authenticate', challenge)

        return response

API_AUTHENTICATION = MultipleAuthentication(Basic=HttpBasicAuthentication(),
                                            OAuth=OAuthAuthentication())

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

Please login first before commenting.