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