root/python/ac/httpauth.py

リビジョン 45, 4.4 kB (コミッタ: sgk, コミット時期: 11 ヶ月 前)

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

Line 
1 '''
2 Django middleware for HTTP authentication.
3
4 Copyright (c) 2007, Accense Technology, Inc.
5
6 All rights reserved.
7
8 Redistribution and use in source and binary forms, with or without
9 modification, 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
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 '''
32
33 from django.contrib.auth.models import User, AnonymousUser
34 from django.http import HttpResponse
35 import 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
43 class 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
67 class 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
97 def 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: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。