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