Merge pull request #92 from fundatillus/dependabot/pip/django-db-geventpool-4.0.1
[mygpo.git] / mygpo / decorators.py
blobd84a2abb8585befa5a99653c35efc569d7bd7c8f
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
28 logger = logging.getLogger(__name__)
31 def requires_token(token_name, denied_template=None):
32 """
33 returns a decorator that checks if the security token in the 'token' GET
34 parameter matches the requires token for the resource. The protected
35 resource is indicated by
36 * the username parameter passed to the decorated function
37 * token_name passed to this method
39 The decorated method is returned, if
40 * no token is required for the resource
41 * the token in the 'token' GET parameter matches the required token
43 If the passed token does not match
44 * the denied_template is rendered and returned if given
45 * HttpResponseForbidden is returned, if denied_template is not given
46 """
48 def decorator(fn):
49 @wraps(fn)
50 def tmp(request, username, *args, **kwargs):
52 User = get_user_model()
53 user = get_object_or_404(User, username=username)
54 token = user.profile.get_token(token_name)
55 u_token = request.GET.get("token", "")
57 if token == "" or token == u_token:
58 return fn(request, username, *args, **kwargs)
60 else:
61 if denied_template:
62 return render(request, denied_template, {"other_user": user})
64 else:
65 return HttpResponseForbidden()
67 return tmp
69 return decorator
72 def allowed_methods(methods):
73 def decorator(fn):
74 @wraps(fn)
75 def tmp(request, *args, **kwargs):
76 if request.method in methods:
77 return fn(request, *args, **kwargs)
78 else:
79 return HttpResponseNotAllowed(methods)
81 return tmp
83 return decorator
86 def query_if_required():
87 """If required, queries some resource before calling the function
89 The decorated method is expected to be bound and its class is
90 expected to have define the methods _needs_query() and _query().
91 """
93 def decorator(f):
94 @wraps(f)
95 def wrapper(self, *args, **kwargs):
97 if self._needs_query():
98 self._query()
100 return f(self, *args, **kwargs)
102 return wrapper
104 return decorator
107 def cors_origin(allowed_origin="*"):
108 """Adds an Access-Control-Allow-Origin header to the response"""
110 def decorator(f):
111 @wraps(f)
112 def wrapper(*args, **kwargs):
113 resp = f(*args, **kwargs)
114 resp["Access-Control-Allow-Origin"] = allowed_origin
115 return resp
117 return wrapper
119 return decorator