9961be839cea7a8a786d344fcddec03408ba3e26
[mediagoblin.git] / mediagoblin / decorators.py
1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
3 #
4 # This program is free software: you can redistribute it and/or modify
5 # it 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
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU Affero General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17 from functools import wraps
18
19 from urlparse import urljoin
20 from urllib import urlencode
21
22 from webob import exc
23
24 from mediagoblin.db.util import ObjectId, InvalidId
25 from mediagoblin.tools.response import redirect, render_404
26
27
28 def require_active_login(controller):
29 """
30 Require an active login from the user.
31 """
32 @wraps(controller)
33 def new_controller_func(request, *args, **kwargs):
34 if request.user and \
35 request.user.get('status') == u'needs_email_verification':
36 return redirect(
37 request, 'mediagoblin.user_pages.user_home',
38 user=request.user.username)
39 elif not request.user or request.user.get('status') != u'active':
40 next_url = urljoin(
41 request.urlgen('mediagoblin.auth.login',
42 qualified=True),
43 request.url)
44
45 return exc.HTTPFound(
46 location='?'.join([
47 request.urlgen('mediagoblin.auth.login'),
48 urlencode({
49 'next': next_url})]))
50
51 return controller(request, *args, **kwargs)
52
53 return new_controller_func
54
55
56 def user_may_delete_media(controller):
57 """
58 Require user ownership of the MediaEntry to delete.
59 """
60 @wraps(controller)
61 def wrapper(request, *args, **kwargs):
62 uploader_id = request.db.MediaEntry.find_one(
63 {'_id': ObjectId(request.matchdict['media'])}).uploader
64 if not (request.user.is_admin or
65 request.user._id == uploader_id):
66 return exc.HTTPForbidden()
67
68 return controller(request, *args, **kwargs)
69
70 return wrapper
71
72
73 def uses_pagination(controller):
74 """
75 Check request GET 'page' key for wrong values
76 """
77 @wraps(controller)
78 def wrapper(request, *args, **kwargs):
79 try:
80 page = int(request.GET.get('page', 1))
81 if page < 0:
82 return render_404(request)
83 except ValueError:
84 return render_404(request)
85
86 return controller(request, page=page, *args, **kwargs)
87
88 return wrapper
89
90
91 def get_user_media_entry(controller):
92 """
93 Pass in a MediaEntry based off of a url component
94 """
95 @wraps(controller)
96 def wrapper(request, *args, **kwargs):
97 user = request.db.User.find_one(
98 {'username': request.matchdict['user']})
99
100 if not user:
101 return render_404(request)
102 media = request.db.MediaEntry.find_one(
103 {'slug': request.matchdict['media'],
104 'state': u'processed',
105 'uploader': user._id})
106
107 # no media via slug? Grab it via ObjectId
108 if not media:
109 try:
110 media = request.db.MediaEntry.find_one(
111 {'_id': ObjectId(request.matchdict['media']),
112 'state': u'processed',
113 'uploader': user._id})
114 except InvalidId:
115 return render_404(request)
116
117 # Still no media? Okay, 404.
118 if not media:
119 return render_404(request)
120
121 return controller(request, media=media, *args, **kwargs)
122
123 return wrapper
124
125
126 def get_media_entry_by_id(controller):
127 """
128 Pass in a MediaEntry based off of a url component
129 """
130 @wraps(controller)
131 def wrapper(request, *args, **kwargs):
132 try:
133 media = request.db.MediaEntry.find_one(
134 {'_id': ObjectId(request.matchdict['media']),
135 'state': u'processed'})
136 except InvalidId:
137 return render_404(request)
138
139 # Still no media? Okay, 404.
140 if not media:
141 return render_404(request)
142
143 return controller(request, media=media, *args, **kwargs)
144
145 return wrapper