threads.py 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. from django import forms
  2. from django.db import models
  3. from django.db.models import Q
  4. from django.utils.translation import ugettext_lazy as _
  5. from misago.acl.builder import BaseACL
  6. from misago.acl.exceptions import ACLError403, ACLError404
  7. from misago.forms import YesNoSwitch
  8. def make_forum_form(request, role, form):
  9. form.base_fields['can_read_threads'] = forms.TypedChoiceField(choices=(
  10. (0, _("No")),
  11. (1, _("Yes, owned")),
  12. (2, _("Yes, all")),
  13. ), coerce=int)
  14. form.base_fields['can_start_threads'] = forms.TypedChoiceField(choices=(
  15. (0, _("No")),
  16. (1, _("Yes, with moderation")),
  17. (2, _("Yes")),
  18. ), coerce=int)
  19. form.base_fields['can_edit_own_threads'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  20. form.base_fields['can_soft_delete_own_threads'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  21. form.base_fields['can_write_posts'] = forms.TypedChoiceField(choices=(
  22. (0, _("No")),
  23. (1, _("Yes, with moderation")),
  24. (2, _("Yes")),
  25. ), coerce=int)
  26. form.base_fields['can_edit_own_posts'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  27. form.base_fields['can_soft_delete_own_posts'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  28. form.base_fields['can_upvote_posts'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  29. form.base_fields['can_downvote_posts'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  30. form.base_fields['can_see_posts_scores'] = forms.TypedChoiceField(choices=(
  31. (0, _("No")),
  32. (1, _("Yes, final score")),
  33. (2, _("Yes, both up and down-votes")),
  34. ), coerce=int)
  35. form.base_fields['can_see_votes'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  36. form.base_fields['can_make_polls'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  37. form.base_fields['can_vote_in_polls'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  38. form.base_fields['can_see_poll_votes'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  39. form.base_fields['can_see_attachments'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  40. form.base_fields['can_upload_attachments'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  41. form.base_fields['can_download_attachments'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  42. form.base_fields['attachment_size'] = forms.IntegerField(min_value=0, initial=100)
  43. form.base_fields['attachment_limit'] = forms.IntegerField(min_value=0, initial=3)
  44. form.base_fields['can_approve'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  45. form.base_fields['can_edit_labels'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  46. form.base_fields['can_see_changelog'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  47. form.base_fields['can_pin_threads'] = forms.TypedChoiceField(choices=(
  48. (0, _("No")),
  49. (1, _("Yes, to stickies")),
  50. (2, _("Yes, to announcements")),
  51. ), coerce=int)
  52. form.base_fields['can_edit_threads_posts'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  53. form.base_fields['can_move_threads_posts'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  54. form.base_fields['can_close_threads'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  55. form.base_fields['can_protect_posts'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  56. form.base_fields['can_delete_threads'] = forms.TypedChoiceField(choices=(
  57. (0, _("No")),
  58. (1, _("Yes, soft-delete")),
  59. (2, _("Yes, hard-delete")),
  60. ), coerce=int)
  61. form.base_fields['can_delete_posts'] = forms.TypedChoiceField(choices=(
  62. (0, _("No")),
  63. (1, _("Yes, soft-delete")),
  64. (2, _("Yes, hard-delete")),
  65. ), coerce=int)
  66. form.base_fields['can_delete_polls'] = forms.TypedChoiceField(choices=(
  67. (0, _("No")),
  68. (1, _("Yes, soft-delete")),
  69. (2, _("Yes, hard-delete")),
  70. ), coerce=int)
  71. form.base_fields['can_delete_attachments'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  72. form.base_fields['can_delete_checkpoints'] = forms.TypedChoiceField(choices=(
  73. (0, _("No")),
  74. (1, _("Yes, soft-delete")),
  75. (2, _("Yes, hard-delete")),
  76. ), coerce=int)
  77. form.base_fields['can_see_deleted_checkpoints'] = forms.BooleanField(widget=YesNoSwitch, initial=False, required=False)
  78. form.layout.append((
  79. _("Threads"),
  80. (
  81. ('can_read_threads', {'label': _("Can read threads")}),
  82. ('can_start_threads', {'label': _("Can start new threads")}),
  83. ('can_edit_own_threads', {'label': _("Can edit own threads")}),
  84. ('can_soft_delete_own_threads', {'label': _("Can soft-delete own threads")}),
  85. ),
  86. ),)
  87. form.layout.append((
  88. _("Posts"),
  89. (
  90. ('can_write_posts', {'label': _("Can write posts")}),
  91. ('can_edit_own_posts', {'label': _("Can edit own posts")}),
  92. ('can_soft_delete_own_posts', {'label': _("Can soft-delete own posts")}),
  93. ),
  94. ),)
  95. form.layout.append((
  96. _("Karma"),
  97. (
  98. ('can_upvote_posts', {'label': _("Can upvote posts")}),
  99. ('can_downvote_posts', {'label': _("Can downvote posts")}),
  100. ('can_see_posts_scores', {'label': _("Can see post score")}),
  101. ('can_see_votes', {'label': _("Can see who voted on post")}),
  102. ),
  103. ),)
  104. form.layout.append((
  105. _("Polls"),
  106. (
  107. ('can_make_polls', {'label': _("Can make polls")}),
  108. ('can_vote_in_polls', {'label': _("Can vote in polls")}),
  109. ('can_see_poll_votes', {'label': _("Can see who voted in poll")}),
  110. ),
  111. ),)
  112. form.layout.append((
  113. _("Attachments"),
  114. (
  115. ('can_see_attachments', {'label': _("Can see attachments")}),
  116. ('can_upload_attachments', {'label': _("Can upload attachments")}),
  117. ('can_download_attachments', {'label': _("Can download attachments")}),
  118. ('attachment_size', {'label': _("Max size of single attachment (in Kb)"), 'help_text': _("Enter zero for no limit.")}),
  119. ('attachment_limit', {'label': _("Max number of attachments per post"), 'help_text': _("Enter zero for no limit.")}),
  120. ),
  121. ),)
  122. form.layout.append((
  123. _("Moderation"),
  124. (
  125. ('can_approve', {'label': _("Can accept threads and posts")}),
  126. ('can_edit_labels', {'label': _("Can edit thread labels")}),
  127. ('can_see_changelog', {'label': _("Can see edits history")}),
  128. ('can_pin_threads', {'label': _("Can change threads weight")}),
  129. ('can_edit_threads_posts', {'label': _("Can edit threads and posts")}),
  130. ('can_move_threads_posts', {'label': _("Can move, merge and split threads and posts")}),
  131. ('can_close_threads', {'label': _("Can close threads")}),
  132. ('can_protect_posts', {'label': _("Can protect posts"), 'help_text': _("Protected posts cannot be changed by their owners.")}),
  133. ('can_delete_threads', {'label': _("Can delete threads")}),
  134. ('can_delete_posts', {'label': _("Can delete posts")}),
  135. ('can_delete_polls', {'label': _("Can delete polls")}),
  136. ('can_delete_attachments', {'label': _("Can delete attachments")}),
  137. ('can_delete_checkpoints', {'label': _("Can delete checkpoints")}),
  138. ('can_see_deleted_checkpoints', {'label': _("Can see deleted checkpoints")}),
  139. ),
  140. ),)
  141. class ThreadsACL(BaseACL):
  142. def get_role(self, forum):
  143. try:
  144. try:
  145. return self.acl[forum.pk]
  146. except AttributeError:
  147. return self.acl[forum]
  148. except KeyError:
  149. return {}
  150. def allow_thread_view(self, user, thread):
  151. try:
  152. forum_role = self.acl[thread.forum_id]
  153. if forum_role['can_read_threads'] == 0:
  154. raise ACLError403(_("You don't have permission to read threads in this forum."))
  155. if forum_role['can_read_threads'] == 1 and thread.weight < 2 and thread.start_poster_id != user.id:
  156. raise ACLError404()
  157. if thread.moderated and not (forum_role['can_approve'] or (user.is_authenticated() and user == thread.start_poster)):
  158. raise ACLError404()
  159. if thread.deleted and not forum_role['can_delete_threads']:
  160. raise ACLError404()
  161. except KeyError:
  162. raise ACLError403(_("You don't have permission to read threads in this forum."))
  163. def allow_post_view(self, user, thread, post):
  164. forum_role = self.acl[thread.forum_id]
  165. if post.moderated and not (forum_role['can_approve'] or (user.is_authenticated() and user == post.user)):
  166. raise ACLError404()
  167. if post.deleted and not (forum_role['can_delete_posts'] or (user.is_authenticated() and user == post.user)):
  168. raise ACLError404()
  169. def filter_threads(self, request, forum, queryset):
  170. try:
  171. forum_role = self.acl[forum.pk]
  172. if not forum_role['can_approve']:
  173. if request.user.is_authenticated():
  174. queryset = queryset.filter(Q(moderated=0) | Q(start_poster=request.user))
  175. else:
  176. queryset = queryset.filter(moderated=0)
  177. if forum_role['can_read_threads'] == 1:
  178. queryset = queryset.filter(Q(weight=2) | Q(start_poster_id=request.user.id))
  179. if not forum_role['can_delete_threads']:
  180. queryset = queryset.filter(deleted=False)
  181. except KeyError:
  182. return False
  183. return queryset
  184. def filter_posts(self, request, thread, queryset):
  185. try:
  186. forum_role = self.acl[thread.forum.pk]
  187. if not forum_role['can_approve']:
  188. if request.user.is_authenticated():
  189. queryset = queryset.filter(Q(moderated=0) | Q(user=request.user))
  190. else:
  191. queryset = queryset.filter(moderated=0)
  192. except KeyError:
  193. return False
  194. return queryset
  195. def can_read_threads(self, forum):
  196. try:
  197. forum_role = self.acl[forum.pk]
  198. return forum_role['can_read_threads']
  199. except KeyError:
  200. return False
  201. def can_start_threads(self, forum):
  202. try:
  203. forum_role = self.acl[forum.pk]
  204. if forum_role['can_read_threads'] == 0 or forum_role['can_start_threads'] == 0:
  205. return False
  206. if forum.closed and forum_role['can_close_threads'] == 0:
  207. return False
  208. return True
  209. except KeyError:
  210. return False
  211. def allow_new_threads(self, forum):
  212. try:
  213. forum_role = self.acl[forum.pk]
  214. if forum_role['can_read_threads'] == 0 or forum_role['can_start_threads'] == 0:
  215. raise ACLError403(_("You don't have permission to start new threads in this forum."))
  216. if forum.closed and forum_role['can_close_threads'] == 0:
  217. raise ACLError403(_("This forum is closed, you can't start new threads in it."))
  218. except KeyError:
  219. raise ACLError403(_("You don't have permission to start new threads in this forum."))
  220. def can_edit_thread(self, user, forum, thread, post):
  221. try:
  222. forum_role = self.acl[thread.forum_id]
  223. if forum_role['can_close_threads'] == 0 and (forum.closed or thread.closed):
  224. return False
  225. if forum_role['can_edit_threads_posts']:
  226. return True
  227. if forum_role['can_edit_own_threads'] and not post.protected and post.user_id == user.pk:
  228. return True
  229. return False
  230. except KeyError:
  231. return False
  232. def allow_thread_edit(self, user, forum, thread, post):
  233. try:
  234. forum_role = self.acl[thread.forum_id]
  235. if thread.deleted or post.deleted:
  236. self.allow_deleted_post_view(forum)
  237. if not forum_role['can_close_threads']:
  238. if forum.closed:
  239. raise ACLError403(_("You can't edit threads in closed forums."))
  240. if thread.closed:
  241. raise ACLError403(_("You can't edit closed threads."))
  242. if not forum_role['can_edit_threads_posts']:
  243. if post.user_id != user.pk:
  244. raise ACLError403(_("You can't edit other members threads."))
  245. if not forum_role['can_edit_own_threads']:
  246. raise ACLError403(_("You can't edit your threads."))
  247. if post.protected:
  248. raise ACLError403(_("This thread is protected, you cannot edit it."))
  249. except KeyError:
  250. raise ACLError403(_("You don't have permission to edit threads in this forum."))
  251. def can_reply(self, forum, thread):
  252. try:
  253. forum_role = self.acl[forum.pk]
  254. if forum_role['can_write_posts'] == 0:
  255. return False
  256. if (forum.closed or thread.closed) and forum_role['can_close_threads'] == 0:
  257. return False
  258. return True
  259. except KeyError:
  260. return False
  261. def allow_reply(self, forum, thread):
  262. try:
  263. forum_role = self.acl[thread.forum.pk]
  264. if forum_role['can_write_posts'] == 0:
  265. raise ACLError403(_("You don't have permission to write replies in this forum."))
  266. if forum_role['can_close_threads'] == 0:
  267. if forum.closed:
  268. raise ACLError403(_("You can't write replies in closed forums."))
  269. if thread.closed:
  270. raise ACLError403(_("You can't write replies in closed threads."))
  271. except KeyError:
  272. raise ACLError403(_("You don't have permission to write replies in this forum."))
  273. def can_edit_reply(self, user, forum, thread, post):
  274. try:
  275. forum_role = self.acl[thread.forum_id]
  276. if forum_role['can_close_threads'] == 0 and (forum.closed or thread.closed):
  277. return False
  278. if forum_role['can_edit_threads_posts']:
  279. return True
  280. if forum_role['can_edit_own_posts'] and not post.protected and post.user_id == user.pk:
  281. return True
  282. return False
  283. except KeyError:
  284. return False
  285. def allow_reply_edit(self, user, forum, thread, post):
  286. try:
  287. forum_role = self.acl[thread.forum_id]
  288. if thread.deleted or post.deleted:
  289. self.allow_deleted_post_view(forum)
  290. if not forum_role['can_close_threads']:
  291. if forum.closed:
  292. raise ACLError403(_("You can't edit replies in closed forums."))
  293. if thread.closed:
  294. raise ACLError403(_("You can't edit replies in closed threads."))
  295. if not forum_role['can_edit_threads_posts']:
  296. if post.user_id != user.pk:
  297. raise ACLError403(_("You can't edit other members replies."))
  298. if not forum_role['can_edit_own_posts']:
  299. raise ACLError403(_("You can't edit your replies."))
  300. if post.protected:
  301. raise ACLError403(_("This reply is protected, you cannot edit it."))
  302. except KeyError:
  303. raise ACLError403(_("You don't have permission to edit replies in this forum."))
  304. def can_see_changelog(self, user, forum, post):
  305. try:
  306. forum_role = self.acl[forum.pk]
  307. return forum_role['can_see_changelog'] or user.pk == post.user_id
  308. except KeyError:
  309. return False
  310. def allow_changelog_view(self, user, forum, post):
  311. try:
  312. forum_role = self.acl[forum.pk]
  313. if post.thread.deleted or post.deleted:
  314. self.allow_deleted_post_view(forum)
  315. if not (forum_role['can_see_changelog'] or user.pk == post.user_id):
  316. raise ACLError403(_("You don't have permission to see history of changes made to this post."))
  317. except KeyError:
  318. raise ACLError403(_("You don't have permission to see history of changes made to this post."))
  319. def can_make_revert(self, forum, thread):
  320. try:
  321. forum_role = self.acl[forum.pk]
  322. if not forum_role['can_close_threads'] and (forum.closed or thread.closed):
  323. return False
  324. return forum_role['can_edit_threads_posts']
  325. except KeyError:
  326. return False
  327. def allow_revert(self, forum, thread):
  328. try:
  329. forum_role = self.acl[forum.pk]
  330. if not forum_role['can_close_threads']:
  331. if forum.closed:
  332. raise ACLError403(_("You can't make reverts in closed forums."))
  333. if thread.closed:
  334. raise ACLError403(_("You can't make reverts in closed threads."))
  335. if not forum_role['can_edit_threads_posts']:
  336. raise ACLError403(_("You don't have permission to make reverts in this forum."))
  337. except KeyError:
  338. raise ACLError403(_("You don't have permission to make reverts in this forum."))
  339. def can_mod_threads(self, forum):
  340. try:
  341. forum_role = self.acl[forum.pk]
  342. return (
  343. forum_role['can_approve']
  344. or forum_role['can_pin_threads']
  345. or forum_role['can_move_threads_posts']
  346. or forum_role['can_close_threads']
  347. or forum_role['can_delete_threads']
  348. )
  349. except KeyError:
  350. return False
  351. def can_mod_posts(self, forum):
  352. try:
  353. forum_role = self.acl[forum.pk]
  354. return (
  355. forum_role['can_edit_threads_posts']
  356. or forum_role['can_move_threads_posts']
  357. or forum_role['can_close_threads']
  358. or forum_role['can_delete_threads']
  359. or forum_role['can_delete_posts']
  360. )
  361. except KeyError:
  362. return False
  363. def can_approve(self, forum):
  364. try:
  365. forum_role = self.acl[forum.pk]
  366. return forum_role['can_approve']
  367. except KeyError:
  368. return False
  369. def can_close(self, forum):
  370. try:
  371. forum_role = self.acl[forum.pk]
  372. return forum_role['can_close_threads']
  373. except KeyError:
  374. return False
  375. def can_protect(self, forum):
  376. try:
  377. forum_role = self.acl[forum.pk]
  378. return forum_role['can_protect_posts']
  379. except KeyError:
  380. return False
  381. def can_pin_threads(self, forum):
  382. try:
  383. forum_role = self.acl[forum.pk]
  384. return forum_role['can_pin_threads']
  385. except KeyError:
  386. return False
  387. def can_delete_thread(self, user, forum, thread, post):
  388. try:
  389. forum_role = self.acl[forum.pk]
  390. if post.pk != thread.start_post_id:
  391. return False
  392. if not forum_role['can_close_threads'] and (forum.closed or thread.closed):
  393. return False
  394. if post.protected and not forum_role['can_protect_posts'] and not forum_role['can_delete_threads']:
  395. return False
  396. if forum_role['can_delete_threads']:
  397. return forum_role['can_delete_threads']
  398. if thread.start_poster_id == user.pk and forum_role['can_soft_delete_own_threads']:
  399. return 1
  400. return False
  401. except KeyError:
  402. return False
  403. def allow_delete_thread(self, user, forum, thread, post, delete=False):
  404. try:
  405. forum_role = self.acl[forum.pk]
  406. if not forum_role['can_close_threads']:
  407. if forum.closed:
  408. raise ACLError403(_("You don't have permission to delete threads in closed forum."))
  409. if thread.closed:
  410. raise ACLError403(_("This thread is closed, you cannot delete it."))
  411. if post.protected and not forum_role['can_protect_posts'] and not forum_role['can_delete_threads']:
  412. raise ACLError403(_("This post is protected, you cannot delete it."))
  413. if not (forum_role['can_delete_threads'] == 2 or
  414. (not delete and (forum_role['can_delete_threads'] == 1 or
  415. (thread.start_poster_id == user.pk and forum_role['can_soft_delete_own_threads'])))):
  416. raise ACLError403(_("You don't have permission to delete this thread."))
  417. if thread.deleted and not delete:
  418. raise ACLError403(_("This thread is already deleted."))
  419. except KeyError:
  420. raise ACLError403(_("You don't have permission to delete this thread."))
  421. def can_delete_post(self, user, forum, thread, post):
  422. try:
  423. forum_role = self.acl[forum.pk]
  424. if post.pk == thread.start_post_id:
  425. return False
  426. if not forum_role['can_close_threads'] and (forum.closed or thread.closed):
  427. return False
  428. if post.protected and not forum_role['can_protect_posts'] and not forum_role['can_delete_posts']:
  429. return False
  430. if forum_role['can_delete_posts']:
  431. return forum_role['can_delete_posts']
  432. if post.user_id == user.pk and not post.protected and forum_role['can_soft_delete_own_posts']:
  433. return 1
  434. return False
  435. except KeyError:
  436. return False
  437. def allow_delete_post(self, user, forum, thread, post, delete=False):
  438. try:
  439. forum_role = self.acl[forum.pk]
  440. if not forum_role['can_close_threads']:
  441. if forum.closed:
  442. raise ACLError403(_("You don't have permission to delete posts in closed forum."))
  443. if thread.closed:
  444. raise ACLError403(_("This thread is closed, you cannot delete its posts."))
  445. if post.protected and not forum_role['can_protect_posts'] and not forum_role['can_delete_posts']:
  446. raise ACLError403(_("This post is protected, you cannot delete it."))
  447. if not (forum_role['can_delete_posts'] == 2 or
  448. (not delete and (forum_role['can_delete_posts'] == 1 or
  449. (post.user_id == user.pk and forum_role['can_soft_delete_own_posts'])))):
  450. raise ACLError403(_("You don't have permission to delete this post."))
  451. if post.deleted and not delete:
  452. raise ACLError403(_("This post is already deleted."))
  453. except KeyError:
  454. raise ACLError403(_("You don't have permission to delete this post."))
  455. def can_see_deleted_threads(self, forum):
  456. try:
  457. forum_role = self.acl[forum.pk]
  458. return forum_role['can_delete_threads']
  459. except KeyError:
  460. return False
  461. def can_see_deleted_posts(self, forum):
  462. try:
  463. forum_role = self.acl[forum.pk]
  464. return forum_role['can_delete_posts']
  465. except KeyError:
  466. return False
  467. def allow_deleted_post_view(self, forum):
  468. try:
  469. forum_role = self.acl[forum.pk]
  470. if not forum_role['can_delete_posts']:
  471. raise ACLError404()
  472. except KeyError:
  473. raise ACLError404()
  474. def can_upvote_posts(self, forum):
  475. try:
  476. forum_role = self.acl[forum.pk]
  477. return forum_role['can_upvote_posts']
  478. except KeyError:
  479. return False
  480. def can_downvote_posts(self, forum):
  481. try:
  482. forum_role = self.acl[forum.pk]
  483. return forum_role['can_downvote_posts']
  484. except KeyError:
  485. return False
  486. def can_see_post_score(self, forum):
  487. try:
  488. forum_role = self.acl[forum.pk]
  489. return forum_role['can_see_posts_scores']
  490. except KeyError:
  491. return False
  492. def can_see_post_votes(self, forum):
  493. try:
  494. forum_role = self.acl[forum.pk]
  495. return forum_role['can_see_votes']
  496. except KeyError:
  497. return False
  498. def allow_post_upvote(self, forum):
  499. try:
  500. forum_role = self.acl[forum.pk]
  501. if not forum_role['can_upvote_posts']:
  502. raise ACLError403(_("You cannot upvote posts in this forum."))
  503. except KeyError:
  504. raise ACLError403(_("You cannot upvote posts in this forum."))
  505. def allow_post_downvote(self, forum):
  506. try:
  507. forum_role = self.acl[forum.pk]
  508. if not forum_role['can_downvote_posts']:
  509. raise ACLError403(_("You cannot downvote posts in this forum."))
  510. except KeyError:
  511. raise ACLError403(_("You cannot downvote posts in this forum."))
  512. def allow_post_votes_view(self, forum):
  513. try:
  514. forum_role = self.acl[forum.pk]
  515. if not forum_role['can_see_votes']:
  516. raise ACLError403(_("You don't have permission to see who voted on this post."))
  517. except KeyError:
  518. raise ACLError403(_("You don't have permission to see who voted on this post."))
  519. def can_see_all_checkpoints(self, forum):
  520. try:
  521. return self.acl[forum.pk]['can_see_deleted_checkpoints']
  522. except KeyError:
  523. raise False
  524. def can_delete_checkpoint(self, forum):
  525. try:
  526. return self.acl[forum.pk]['can_delete_checkpoints']
  527. except KeyError:
  528. raise False
  529. def allow_checkpoint_view(self, forum, checkpoint):
  530. if checkpoint.deleted:
  531. try:
  532. forum_role = self.acl[forum.pk]
  533. if not forum_role['can_see_deleted_checkpoints']:
  534. raise ACLError403(_("Selected checkpoint could not be found."))
  535. except KeyError:
  536. raise ACLError403(_("Selected checkpoint could not be found."))
  537. def allow_checkpoint_hide(self, forum):
  538. try:
  539. forum_role = self.acl[forum.pk]
  540. if not forum_role['can_delete_checkpoints']:
  541. raise ACLError403(_("You cannot hide checkpoints!"))
  542. except KeyError:
  543. raise ACLError403(_("You cannot hide checkpoints!"))
  544. def allow_checkpoint_delete(self, forum):
  545. try:
  546. forum_role = self.acl[forum.pk]
  547. if forum_role['can_delete_checkpoints'] != 2:
  548. raise ACLError403(_("You cannot delete checkpoints!"))
  549. except KeyError:
  550. raise ACLError403(_("You cannot delete checkpoints!"))
  551. def allow_checkpoint_show(self, forum):
  552. try:
  553. forum_role = self.acl[forum.pk]
  554. if not forum_role['can_delete_checkpoints']:
  555. raise ACLError403(_("You cannot show checkpoints!"))
  556. except KeyError:
  557. raise ACLError403(_("You cannot show checkpoints!"))
  558. def build_forums(acl, perms, forums, forum_roles):
  559. acl.threads = ThreadsACL()
  560. for forum in forums:
  561. forum_role = {
  562. 'can_read_threads': 0,
  563. 'can_start_threads': 0,
  564. 'can_edit_own_threads': False,
  565. 'can_soft_delete_own_threads': False,
  566. 'can_write_posts': 0,
  567. 'can_edit_own_posts': False,
  568. 'can_soft_delete_own_posts': False,
  569. 'can_upvote_posts': False,
  570. 'can_downvote_posts': False,
  571. 'can_see_posts_scores': 0,
  572. 'can_see_votes': False,
  573. 'can_make_polls': False,
  574. 'can_vote_in_polls': False,
  575. 'can_see_poll_votes': False,
  576. 'can_see_attachments': False,
  577. 'can_upload_attachments': False,
  578. 'can_download_attachments': False,
  579. 'attachment_size': 100,
  580. 'attachment_limit': 3,
  581. 'can_approve': False,
  582. 'can_edit_labels': False,
  583. 'can_see_changelog': False,
  584. 'can_pin_threads': 0,
  585. 'can_edit_threads_posts': False,
  586. 'can_move_threads_posts': False,
  587. 'can_close_threads': False,
  588. 'can_protect_posts': False,
  589. 'can_delete_threads': 0,
  590. 'can_delete_posts': 0,
  591. 'can_delete_polls': 0,
  592. 'can_delete_attachments': False,
  593. 'can_see_deleted_checkpoints': False,
  594. 'can_delete_checkpoints': 0,
  595. }
  596. for perm in perms:
  597. try:
  598. role = forum_roles[perm['forums'][forum.pk]]
  599. for p in forum_role:
  600. try:
  601. if p in ['attachment_size', 'attachment_limit'] and role[p] == 0:
  602. forum_role[p] = 0
  603. elif role[p] > forum_role[p]:
  604. forum_role[p] = role[p]
  605. except KeyError:
  606. pass
  607. except KeyError:
  608. pass
  609. acl.threads.acl[forum.pk] = forum_role