[Web] fix token handling
[mygpo.git] / mygpo / decorators.py
blob99bee437f9d163863a6e5f01507a7914a1b375d2
1 # -*- coding: utf-8 -*-
3 # gPodder - A media aggregator and podcast client
4 # Copyright (c) 2005-2009 Thomas Perl and the gPodder Team
6 # gPodder is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # gPodder is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 from functools import wraps
22 from django.shortcuts import render, get_object_or_404
23 from django.http import HttpResponseForbidden, HttpResponseNotAllowed
24 from django.contrib.auth import get_user_model
26 import logging
27 logger = logging.getLogger(__name__)
30 def requires_token(token_name, denied_template=None):
31 """
32 returns a decorator that checks if the security token in the 'token' GET
33 parameter matches the requires token for the resource. The protected
34 resource is indicated by
35 * the username parameter passed to the decorated function
36 * token_name passed to this method
38 The decorated method is returned, if
39 * no token is required for the resource
40 * the token in the 'token' GET parameter matches the required token
42 If the passed token does not match
43 * the denied_template is rendered and returned if given
44 * HttpResponseForbidden is returned, if denied_template is not given
45 """
46 def decorator(fn):
47 @wraps(fn)
48 def tmp(request, username, *args, **kwargs):
50 User = get_user_model()
51 user = get_object_or_404(User, username=username)
52 token = user.profile.get_token(token_name)
53 u_token = request.GET.get('token', '')
55 if token == '' or token == u_token:
56 return fn(request, username, *args, **kwargs)
58 else:
59 if denied_template:
60 return render(request, denied_template, {
61 'other_user': user
64 else:
65 return HttpResponseForbidden()
67 return tmp
68 return decorator
71 def allowed_methods(methods):
72 def decorator(fn):
73 @wraps(fn)
74 def tmp(request, *args, **kwargs):
75 if request.method in methods:
76 return fn(request, *args, **kwargs)
77 else:
78 return HttpResponseNotAllowed(methods)
80 return tmp
82 return decorator
85 def query_if_required():
86 """ If required, queries some resource before calling the function
88 The decorated method is expected to be bound and its class is
89 expected to have define the methods _needs_query() and _query().
90 """
92 def decorator(f):
93 @wraps(f)
94 def wrapper(self, *args, **kwargs):
96 if self._needs_query():
97 self._query()
99 return f(self, *args, **kwargs)
101 return wrapper
102 return decorator
105 def cors_origin(allowed_origin='*'):
106 """ Adds an Access-Control-Allow-Origin header to the response """
108 def decorator(f):
109 @wraps(f)
110 def wrapper(*args, **kwargs):
111 resp = f(*args, **kwargs)
112 resp['Access-Control-Allow-Origin'] = allowed_origin
113 return resp
115 return wrapper
116 return decorator