Merge branch 'master' into py3
[mygpo.git] / mygpo / userfeeds / auth.py
blobba4e87855833cd072d191fc8c95b38900ee4cc24
2 # This file is part of my.gpodder.org.
4 # my.gpodder.org is free software: you can redistribute it and/or modify it
5 # under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or (at your
7 # option) any later version.
9 # my.gpodder.org is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
12 # License for more details.
14 # You should have received a copy of the GNU Affero General Public License
15 # along with my.gpodder.org. If not, see <http://www.gnu.org/licenses/>.
18 from functools import wraps
20 from django.http import HttpResponse, HttpResponseBadRequest, Http404
21 from django.shortcuts import get_object_or_404
22 from django.contrib.auth import get_user_model
25 #############################################################################
27 def view_or_basicauth(view, request, username, token_name, realm = "", *args, **kwargs):
29 User = get_user_model()
30 user = get_object_or_404(User, username=username)
32 token = getattr(user, token_name, '')
34 # check if a token is required at all
35 if token == '':
36 return view(request, username, *args, **kwargs)
38 # this header format is used when passing auth-headers
39 # from Aapache to fcgi
40 if 'AUTHORIZATION' in request.META:
41 auth = request.META['AUTHORIZATION']
43 elif 'HTTP_AUTHORIZATION' in request.META:
44 auth = request.META['HTTP_AUTHORIZATION']
46 else:
47 return auth_request()
50 auth = auth.split(None, 1)
52 if len(auth) == 2:
53 auth_type, credentials = auth
55 # NOTE: We are only support basic authentication for now.
56 if auth_type.lower() == 'basic':
57 credentials = credentials.decode('base64').split(':', 1)
58 if len(credentials) == 2:
60 uname, passwd = credentials
62 if uname != username:
63 return auth_request()
65 if token == passwd:
66 return view(request, uname, *args, **kwargs)
68 return auth_request()
71 def auth_request(realm=''):
72 # Either they did not provide an authorization header or
73 # something in the authorization attempt failed. Send a 401
74 # back to them to ask them to authenticate.
75 response = HttpResponse()
76 response.status_code = 401
77 response['WWW-Authenticate'] = 'Basic realm="%s"' % realm
78 return response
81 #############################################################################
83 def require_token_auth(token_name):
84 def wrapper(protected_view):
86 @wraps(protected_view)
87 def tmp(request, username, *args, **kwargs):
88 return view_or_basicauth(protected_view, \
89 request, \
90 username, \
91 token_name, \
92 '', \
93 *args, \
94 **kwargs)
95 return tmp
96 return wrapper