root/python/ac/httpauth.py

Revision 45, 4.4 kB (checked in by sgk, 3 years ago)

ライセンス、コメントの英語化。

Line 
1'''
2Django middleware for HTTP authentication.
3
4Copyright (c) 2007, Accense Technology, Inc.
5
6All rights reserved.
7
8Redistribution and use in source and binary forms, with or without
9modification, are permitted provided that the following conditions are met:
10
11  * Redistributions of source code must retain the above copyright notice,
12    this list of conditions and the following disclaimer.
13  * Redistributions in binary form must reproduce the above copyright notice,
14    this list of conditions and the following disclaimer in the documentation
15    and/or other materials provided with the distribution.
16  * Neither the name of the Accense Technology nor the names of its
17    contributors may be used to endorse or promote products derived from
18    this software without specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31'''
32
33from django.contrib.auth.models import User, AnonymousUser
34from django.http import HttpResponse
35import base64
36
37# Written by sgk.
38
39# This code depends on the implementation internals of the Django builtin
40# 'django.contrib.auth.middleware.AuthenticationMiddleware' authentication
41# middleware, specifically the 'request._cached_user' member.
42
43class ByHttpServerMiddleware(object):
44  '''
45  Reflect the authentication result by HTTP server which hosts Django.
46
47  This middleware must be placed in the 'settings.py' MIDDLEWARE_CLASSES
48  definition before the above Django builtin 'AuthenticationMiddleware'.
49  You can use the ordinaly '@login_required' decorator to restrict views
50  to authenticated users. Set the 'settings.py' LOGIN_URL definition
51  appropriately if required.
52  '''
53
54  def process_request(self, request):
55    if hasattr(request, '_cached_user'):
56      return None
57    try:
58      username = request.META['REMOTE_USER']
59      user = User.objects.get(username=username)
60    except (KeyError, User.DoesNotExist):
61      # Fallback to other authentication middleware.
62      return None
63    request._cached_user = user
64    return None
65
66
67class Middleware(object):
68  '''
69  Django implementation of the HTTP basic authentication.
70
71  This middleware must be placed in the 'settings.py' MIDDLEWARE_CLASSES
72  definition before the above Django builtin 'AuthenticationMiddleware'.
73  Set the 'settings.py' LOGIN_URL definition appropriately if required.
74
75  To show the browser generated login dialog to user, you have to use the
76  following '@http_login_required(realm=realm)' decorator instead of the
77  ordinaly '@login_required' decorator.
78  '''
79  def process_request(self, request):
80    if hasattr(request, '_cached_user'):
81      return None
82    try:
83      (method, encoded) = request.META['HTTP_AUTHORIZATION'].split()
84      if method.lower() != 'basic':
85        return None
86      (username, password) = base64.b64decode(encoded).split(':')
87      user = User.objects.get(username=username, is_active=True)
88      if not user.check_password(password):
89        user = AnonymousUser()
90    except (KeyError, TypeError, User.DoesNotExist):
91      # Fallback to other authentication middleware.
92      return None
93    request._cached_user = user
94    return None
95
96
97def http_login_required(realm=None):
98  '''
99  Decorator factory to restrict views to authenticated user and show the
100  browser generated login dialog if the user is not authenticated.
101
102  This is the function that returns a decorator. To use the decorator,
103  use '@http_login_required()' or '@http_login_required(realm='...')'.
104  '''
105  def decorator(func):
106    def handler(request, *args, **kw):
107      if request.user.is_authenticated():
108        return func(request, *args, **kw)
109      response = HttpResponse(status=401)
110      response['WWW-Authenticate'] = 'Basic realm="%s"' % (realm or 'Django')
111      return response
112    return handler
113  return decorator
Note: See TracBrowser for help on using the browser.