Provide tools.response.render_http_exception and use that
[mediagoblin.git] / mediagoblin / decorators.py
CommitLineData
bb3eaf20 1# GNU MediaGoblin -- federated, autonomous media hosting
cf29e8a8 2# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
bb3eaf20
CAW
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
1e03504e 17from functools import wraps
bb3eaf20 18
3a199328 19from urlparse import urljoin
059eaee4
SS
20from werkzeug.exceptions import Forbidden
21from werkzeug.urls import url_quote
bb3eaf20 22
3efdd97c 23from mediagoblin.db.util import ObjectId, InvalidId
ad742028 24from mediagoblin.db.sql.models import User
1e03504e 25from mediagoblin.tools.response import redirect, render_404
bb3eaf20
CAW
26
27
28def require_active_login(controller):
29 """
30 Require an active login from the user.
31 """
1e03504e 32 @wraps(controller)
bb3eaf20 33 def new_controller_func(request, *args, **kwargs):
a72c504b
CAW
34 if request.user and \
35 request.user.get('status') == u'needs_email_verification':
d43b472a
CAW
36 return redirect(
37 request, 'mediagoblin.user_pages.user_home',
5a4e3ff1 38 user=request.user.username)
bcec749b 39 elif not request.user or request.user.get('status') != u'active':
3a199328
JW
40 next_url = urljoin(
41 request.urlgen('mediagoblin.auth.login',
42 qualified=True),
43 request.url)
44
059eaee4
SS
45 return redirect(request, 'mediagoblin.auth.login',
46 next=url_quote(next_url))
bb3eaf20
CAW
47
48 return controller(request, *args, **kwargs)
49
1e03504e 50 return new_controller_func
3eb6fc4f 51
ad742028
SS
52def active_user_from_url(controller):
53 """Retrieve User() from <user> URL pattern and pass in as url_user=...
54
55 Returns a 404 if no such active user has been found"""
56 @wraps(controller)
57 def wrapper(request, *args, **kwargs):
58 user = User.query.filter_by(username=request.matchdict['user']).first()
59 if user is None:
60 return render_404(request)
61
62 return controller(request, *args, url_user=user, **kwargs)
63
64 return wrapper
65
53c5e0b0 66
502073f2
JW
67def user_may_delete_media(controller):
68 """
53c5e0b0 69 Require user ownership of the MediaEntry to delete.
502073f2 70 """
1e03504e 71 @wraps(controller)
502073f2 72 def wrapper(request, *args, **kwargs):
4deda94a 73 uploader_id = request.db.MediaEntry.find_one(
5c2b8486 74 {'id': ObjectId(request.matchdict['media'])}).uploader
bec591d8 75 if not (request.user.is_admin or
5c2b8486 76 request.user.id == uploader_id):
059eaee4 77 return Forbidden()
502073f2
JW
78
79 return controller(request, *args, **kwargs)
80
1e03504e 81 return wrapper
502073f2 82
3eb6fc4f 83
be5be115
AW
84def user_may_alter_collection(controller):
85 """
86 Require user ownership of the Collection to modify.
87 """
88 @wraps(controller)
89 def wrapper(request, *args, **kwargs):
90 creator_id = request.db.User.find_one(
91 {'username': request.matchdict['user']}).id
92 if not (request.user.is_admin or
5c2b8486 93 request.user.id == creator_id):
059eaee4 94 return Forbidden()
be5be115
AW
95
96 return controller(request, *args, **kwargs)
97
98 return wrapper
99
100
3eb6fc4f
BK
101def uses_pagination(controller):
102 """
103 Check request GET 'page' key for wrong values
104 """
1e03504e 105 @wraps(controller)
3eb6fc4f
BK
106 def wrapper(request, *args, **kwargs):
107 try:
1301a8ad 108 page = int(request.GET.get('page', 1))
3eb6fc4f 109 if page < 0:
de12b4e7 110 return render_404(request)
3eb6fc4f 111 except ValueError:
de12b4e7 112 return render_404(request)
3eb6fc4f 113
439e37f7 114 return controller(request, page=page, *args, **kwargs)
3eb6fc4f 115
1e03504e 116 return wrapper
724933b1
CAW
117
118
01674e10 119def get_user_media_entry(controller):
724933b1
CAW
120 """
121 Pass in a MediaEntry based off of a url component
122 """
1e03504e 123 @wraps(controller)
724933b1 124 def wrapper(request, *args, **kwargs):
01674e10
CAW
125 user = request.db.User.find_one(
126 {'username': request.matchdict['user']})
127
128 if not user:
de12b4e7 129 return render_404(request)
724933b1
CAW
130 media = request.db.MediaEntry.find_one(
131 {'slug': request.matchdict['media'],
5bd0adeb 132 'state': u'processed',
5c2b8486 133 'uploader': user.id})
724933b1
CAW
134
135 # no media via slug? Grab it via ObjectId
136 if not media:
01674e10
CAW
137 try:
138 media = request.db.MediaEntry.find_one(
5c2b8486 139 {'id': ObjectId(request.matchdict['media']),
5bd0adeb 140 'state': u'processed',
5c2b8486 141 'uploader': user.id})
01674e10 142 except InvalidId:
de12b4e7 143 return render_404(request)
724933b1
CAW
144
145 # Still no media? Okay, 404.
146 if not media:
de12b4e7 147 return render_404(request)
724933b1
CAW
148
149 return controller(request, media=media, *args, **kwargs)
150
1e03504e 151 return wrapper
aba81c9f 152
243c3843 153
be5be115
AW
154def get_user_collection(controller):
155 """
156 Pass in a Collection based off of a url component
157 """
158 @wraps(controller)
159 def wrapper(request, *args, **kwargs):
160 user = request.db.User.find_one(
161 {'username': request.matchdict['user']})
162
163 if not user:
164 return render_404(request)
165
166 collection = request.db.Collection.find_one(
167 {'slug': request.matchdict['collection'],
5c2b8486 168 'creator': user.id})
be5be115
AW
169
170 # Still no collection? Okay, 404.
171 if not collection:
172 return render_404(request)
173
174 return controller(request, collection=collection, *args, **kwargs)
175
176 return wrapper
177
178
179def get_user_collection_item(controller):
180 """
181 Pass in a CollectionItem based off of a url component
182 """
183 @wraps(controller)
184 def wrapper(request, *args, **kwargs):
185 user = request.db.User.find_one(
186 {'username': request.matchdict['user']})
187
188 if not user:
189 return render_404(request)
190
191 collection = request.db.Collection.find_one(
192 {'slug': request.matchdict['collection'],
5c2b8486 193 'creator': user.id})
be5be115
AW
194
195 collection_item = request.db.CollectionItem.find_one(
5c2b8486 196 {'id': request.matchdict['collection_item'] })
be5be115
AW
197
198 # Still no collection item? Okay, 404.
199 if not collection_item:
200 return render_404(request)
201
202 return controller(request, collection_item=collection_item, *args, **kwargs)
203
204 return wrapper
205
206
aba81c9f
E
207def get_media_entry_by_id(controller):
208 """
209 Pass in a MediaEntry based off of a url component
210 """
1e03504e 211 @wraps(controller)
aba81c9f
E
212 def wrapper(request, *args, **kwargs):
213 try:
214 media = request.db.MediaEntry.find_one(
5c2b8486 215 {'id': ObjectId(request.matchdict['media']),
5bd0adeb 216 'state': u'processed'})
aba81c9f 217 except InvalidId:
de12b4e7 218 return render_404(request)
aba81c9f
E
219
220 # Still no media? Okay, 404.
221 if not media:
de12b4e7 222 return render_404(request)
aba81c9f
E
223
224 return controller(request, media=media, *args, **kwargs)
225
1e03504e 226 return wrapper