|
a/Allura/allura/controllers/discuss.py |
|
b/Allura/allura/controllers/discuss.py |
|
... |
|
... |
13 |
from allura import model as M
|
13 |
from allura import model as M
|
14 |
from base import BaseController
|
14 |
from base import BaseController
|
15 |
from allura.lib import utils
|
15 |
from allura.lib import utils
|
16 |
from allura.lib import helpers as h
|
16 |
from allura.lib import helpers as h
|
17 |
from allura.lib.decorators import require_post
|
17 |
from allura.lib.decorators import require_post
|
18 |
from allura.lib.security import require, has_artifact_access
|
18 |
from allura.lib.security import require, has_access, require_access
|
19 |
from allura.lib.helpers import DateTimeConverter
|
19 |
from allura.lib.helpers import DateTimeConverter
|
20 |
|
20 |
|
21 |
from allura.lib.widgets import discuss as DW
|
21 |
from allura.lib.widgets import discuss as DW
|
22 |
from .attachments import AttachmentsController, AttachmentController
|
22 |
from .attachments import AttachmentsController, AttachmentController
|
23 |
|
23 |
|
|
... |
|
... |
141 |
ThreadController=h.attrproxy('_discussion_controller', 'ThreadController')
|
141 |
ThreadController=h.attrproxy('_discussion_controller', 'ThreadController')
|
142 |
PostController=h.attrproxy('_discussion_controller', 'PostController')
|
142 |
PostController=h.attrproxy('_discussion_controller', 'PostController')
|
143 |
AttachmentController=h.attrproxy('_discussion_controller', 'AttachmentController')
|
143 |
AttachmentController=h.attrproxy('_discussion_controller', 'AttachmentController')
|
144 |
|
144 |
|
145 |
def _check_security(self):
|
145 |
def _check_security(self):
|
146 |
require(has_artifact_access('read', self.thread))
|
146 |
require_access(self.thread, 'read')
|
147 |
|
147 |
|
148 |
def __init__(self, discussion_controller, thread_id):
|
148 |
def __init__(self, discussion_controller, thread_id):
|
149 |
self._discussion_controller = discussion_controller
|
149 |
self._discussion_controller = discussion_controller
|
150 |
self.discussion = discussion_controller.discussion
|
150 |
self.discussion = discussion_controller.discussion
|
151 |
self.thread = self.M.Thread.query.get(_id=thread_id)
|
151 |
self.thread = self.M.Thread.query.get(_id=thread_id)
|
|
... |
|
... |
173 |
@h.vardec
|
173 |
@h.vardec
|
174 |
@expose()
|
174 |
@expose()
|
175 |
@require_post()
|
175 |
@require_post()
|
176 |
@validate(pass_validator, error_handler=index)
|
176 |
@validate(pass_validator, error_handler=index)
|
177 |
def post(self, **kw):
|
177 |
def post(self, **kw):
|
178 |
require(has_artifact_access('post', self.thread))
|
178 |
require_access(self.thread, 'post', self.thread)
|
179 |
kw = self.W.edit_post.to_python(kw, None)
|
179 |
kw = self.W.edit_post.to_python(kw, None)
|
180 |
if not kw['text']:
|
180 |
if not kw['text']:
|
181 |
flash('Your post was not saved. You must provide content.', 'error')
|
181 |
flash('Your post was not saved. You must provide content.', 'error')
|
182 |
redirect(request.referer)
|
182 |
redirect(request.referer)
|
183 |
file_info = kw.pop('file_info', None)
|
183 |
file_info = kw.pop('file_info', None)
|
|
... |
|
... |
194 |
redirect(request.referer)
|
194 |
redirect(request.referer)
|
195 |
|
195 |
|
196 |
@expose()
|
196 |
@expose()
|
197 |
@require_post()
|
197 |
@require_post()
|
198 |
def tag(self, labels, **kw):
|
198 |
def tag(self, labels, **kw):
|
199 |
require(has_artifact_access('post', self.thread))
|
199 |
require_access(self.thread, 'post')
|
200 |
self.thread.labels = labels.split(',')
|
200 |
self.thread.labels = labels.split(',')
|
201 |
redirect(request.referer)
|
201 |
redirect(request.referer)
|
202 |
|
202 |
|
203 |
@expose()
|
203 |
@expose()
|
204 |
@require_post()
|
204 |
@require_post()
|
205 |
def flag_as_spam(self, **kw):
|
205 |
def flag_as_spam(self, **kw):
|
206 |
require(has_artifact_access('moderate', self.thread))
|
206 |
require_access(self.thread, 'moderate')
|
207 |
self.thread.first_post.status='spam'
|
207 |
self.thread.first_post.status='spam'
|
208 |
flash('Thread flagged as spam.')
|
208 |
flash('Thread flagged as spam.')
|
209 |
redirect(request.referer)
|
209 |
redirect(request.referer)
|
210 |
|
210 |
|
211 |
@without_trailing_slash
|
211 |
@without_trailing_slash
|
|
... |
|
... |
239 |
ThreadController=h.attrproxy('_discussion_controller', 'ThreadController')
|
239 |
ThreadController=h.attrproxy('_discussion_controller', 'ThreadController')
|
240 |
PostController=h.attrproxy('_discussion_controller', 'PostController')
|
240 |
PostController=h.attrproxy('_discussion_controller', 'PostController')
|
241 |
AttachmentController=h.attrproxy('_discussion_controller', 'AttachmentController')
|
241 |
AttachmentController=h.attrproxy('_discussion_controller', 'AttachmentController')
|
242 |
|
242 |
|
243 |
def _check_security(self):
|
243 |
def _check_security(self):
|
244 |
require(has_artifact_access('read', self.post))
|
244 |
require_access(self.post, 'read')
|
245 |
|
245 |
|
246 |
def __init__(self, discussion_controller, thread, slug):
|
246 |
def __init__(self, discussion_controller, thread, slug):
|
247 |
self._discussion_controller = discussion_controller
|
247 |
self._discussion_controller = discussion_controller
|
248 |
self.thread = thread
|
248 |
self.thread = thread
|
249 |
self._post_slug = slug
|
249 |
self._post_slug = slug
|
|
... |
|
... |
263 |
@expose('jinja:allura:templates/discussion/post.html')
|
263 |
@expose('jinja:allura:templates/discussion/post.html')
|
264 |
@validate(pass_validator)
|
264 |
@validate(pass_validator)
|
265 |
def index(self, version=None, **kw):
|
265 |
def index(self, version=None, **kw):
|
266 |
c.post = self.W.post
|
266 |
c.post = self.W.post
|
267 |
if request.method == 'POST':
|
267 |
if request.method == 'POST':
|
268 |
require(has_artifact_access('moderate', self.post))
|
268 |
require_access(self.post, 'moderate')
|
269 |
post_fields = self.W.edit_post.to_python(kw, None)
|
269 |
post_fields = self.W.edit_post.to_python(kw, None)
|
270 |
file_info = post_fields.pop('file_info', None)
|
270 |
file_info = post_fields.pop('file_info', None)
|
271 |
if hasattr(file_info, 'file'):
|
271 |
if hasattr(file_info, 'file'):
|
272 |
self.post.attach(
|
272 |
self.post.attach(
|
273 |
file_info.filename, file_info.file, content_type=file_info.type,
|
273 |
file_info.filename, file_info.file, content_type=file_info.type,
|
|
... |
|
... |
307 |
@expose()
|
307 |
@expose()
|
308 |
@require_post()
|
308 |
@require_post()
|
309 |
@validate(pass_validator, error_handler=index)
|
309 |
@validate(pass_validator, error_handler=index)
|
310 |
@require_post(redir='.')
|
310 |
@require_post(redir='.')
|
311 |
def reply(self, **kw):
|
311 |
def reply(self, **kw):
|
312 |
require(has_artifact_access('post', self.thread))
|
312 |
require_access(self.thread, 'post')
|
313 |
kw = self.W.edit_post.to_python(kw, None)
|
313 |
kw = self.W.edit_post.to_python(kw, None)
|
314 |
self.thread.post(parent_id=self.post._id, **kw)
|
314 |
self.thread.post(parent_id=self.post._id, **kw)
|
315 |
self.thread.num_replies += 1
|
315 |
self.thread.num_replies += 1
|
316 |
redirect(request.referer)
|
316 |
redirect(request.referer)
|
317 |
|
317 |
|
318 |
@h.vardec
|
318 |
@h.vardec
|
319 |
@expose()
|
319 |
@expose()
|
320 |
@require_post()
|
320 |
@require_post()
|
321 |
@validate(pass_validator, error_handler=index)
|
321 |
@validate(pass_validator, error_handler=index)
|
322 |
def moderate(self, **kw):
|
322 |
def moderate(self, **kw):
|
323 |
require(has_artifact_access('moderate', self.post.thread))
|
323 |
require_access(self.post.thread, 'moderate')
|
324 |
if kw.pop('delete', None):
|
324 |
if kw.pop('delete', None):
|
325 |
self.post.delete()
|
325 |
self.post.delete()
|
326 |
self.thread.update_stats()
|
326 |
self.thread.update_stats()
|
327 |
elif kw.pop('spam', None):
|
327 |
elif kw.pop('spam', None):
|
328 |
self.post.status = 'spam'
|
328 |
self.post.status = 'spam'
|
|
... |
|
... |
342 |
|
342 |
|
343 |
@h.vardec
|
343 |
@h.vardec
|
344 |
@expose()
|
344 |
@expose()
|
345 |
@require_post()
|
345 |
@require_post()
|
346 |
def attach(self, file_info=None):
|
346 |
def attach(self, file_info=None):
|
347 |
require(has_artifact_access('moderate', self.post))
|
347 |
require_access(self.post, 'moderate')
|
348 |
if hasattr(file_info, 'file'):
|
348 |
if hasattr(file_info, 'file'):
|
349 |
mime_type = file_info.type
|
349 |
mime_type = file_info.type
|
350 |
# If mime type was not passed or bogus, guess it
|
350 |
# If mime type was not passed or bogus, guess it
|
351 |
if not mime_type or '/' not in mime_type:
|
351 |
if not mime_type or '/' not in mime_type:
|
352 |
mime_type = utils.guess_mime_type(file_info.filename)
|
352 |
mime_type = utils.guess_mime_type(file_info.filename)
|
|
... |
|
... |
380 |
PostController=h.attrproxy('_discussion_controller', 'PostController')
|
380 |
PostController=h.attrproxy('_discussion_controller', 'PostController')
|
381 |
AttachmentController=h.attrproxy('_discussion_controller', 'AttachmentController')
|
381 |
AttachmentController=h.attrproxy('_discussion_controller', 'AttachmentController')
|
382 |
|
382 |
|
383 |
|
383 |
|
384 |
def _check_security(self):
|
384 |
def _check_security(self):
|
385 |
require(has_artifact_access('moderate', self.discussion))
|
385 |
require_access(self.discussion, 'moderate')
|
386 |
|
386 |
|
387 |
def __init__(self, discussion_controller):
|
387 |
def __init__(self, discussion_controller):
|
388 |
self._discussion_controller = discussion_controller
|
388 |
self._discussion_controller = discussion_controller
|
389 |
|
389 |
|
390 |
@LazyProperty
|
390 |
@LazyProperty
|
|
... |
|
... |
450 |
@h.vardec
|
450 |
@h.vardec
|
451 |
@expose()
|
451 |
@expose()
|
452 |
@require_post()
|
452 |
@require_post()
|
453 |
@validate(pass_validator, error_handler=h.json_validation_error)
|
453 |
@validate(pass_validator, error_handler=h.json_validation_error)
|
454 |
def reply(self, **kw):
|
454 |
def reply(self, **kw):
|
455 |
require(has_artifact_access('post', self.thread))
|
455 |
require_access(self.thread, 'post')
|
456 |
kw = self.W.edit_post.to_python(kw, None)
|
456 |
kw = self.W.edit_post.to_python(kw, None)
|
457 |
post = self.thread.post(parent_id=self.post._id, **kw)
|
457 |
post = self.thread.post(parent_id=self.post._id, **kw)
|
458 |
self.thread.num_replies += 1
|
458 |
self.thread.num_replies += 1
|
459 |
redirect(post.slug.split('/')[-1] + '/')
|
459 |
redirect(post.slug.split('/')[-1] + '/')
|
460 |
|
460 |
|
|
... |
|
... |
467 |
@h.vardec
|
467 |
@h.vardec
|
468 |
@expose()
|
468 |
@expose()
|
469 |
@require_post()
|
469 |
@require_post()
|
470 |
@validate(pass_validator, error_handler=h.json_validation_error)
|
470 |
@validate(pass_validator, error_handler=h.json_validation_error)
|
471 |
def new(self, **kw):
|
471 |
def new(self, **kw):
|
472 |
require(has_artifact_access('post', self.thread))
|
472 |
require_access(self.thread, 'post')
|
473 |
kw = self.W.edit_post.to_python(kw, None)
|
473 |
kw = self.W.edit_post.to_python(kw, None)
|
474 |
p = self.thread.add_post(**kw)
|
474 |
p = self.thread.add_post(**kw)
|
475 |
redirect(p.slug + '/')
|
475 |
redirect(p.slug + '/')
|
476 |
|
476 |
|
477 |
class AppDiscussionRestController(AppDiscussionController):
|
477 |
class AppDiscussionRestController(AppDiscussionController):
|