views.py 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. import copy
  2. from django.core.urlresolvers import reverse as django_reverse
  3. from django.shortcuts import redirect
  4. from django.utils.translation import ugettext as _
  5. from misago.acl.builder import build_form
  6. from misago.admin import site
  7. from misago.apps.admin.widgets import *
  8. from misago.forms import Form, YesNoSwitch
  9. from misago.models import Forum, ForumRole, Role
  10. from misago.monitor import monitor, UpdatingMonitor
  11. from misago.utils.strings import slugify
  12. from misago.apps.admin.roles.forms import RoleForm
  13. def reverse(route, target=None):
  14. if target:
  15. return django_reverse(route, kwargs={'target': target.pk, 'slug': slugify(target.name)})
  16. return django_reverse(route)
  17. """
  18. Views
  19. """
  20. class List(ListWidget):
  21. admin = site.get_action('roles')
  22. id = 'list'
  23. columns=(
  24. ('role', _("Role")),
  25. )
  26. nothing_checked_message = _('You have to check at least one role.')
  27. actions=(
  28. ('delete', _("Delete selected roles"), _("Are you sure you want to delete selected roles?")),
  29. )
  30. def sort_items(self, page_items, sorting_method):
  31. return page_items.order_by('name')
  32. def get_item_actions(self, item):
  33. return (
  34. self.action('list', _("Forums Permissions"), reverse('admin_roles_masks', item)),
  35. self.action('adjust', _("Role Permissions"), reverse('admin_roles_acl', item)),
  36. self.action('pencil', _("Edit Role"), reverse('admin_roles_edit', item)),
  37. self.action('remove', _("Delete Role"), reverse('admin_roles_delete', item), post=True, prompt=_("Are you sure you want to delete this role?")),
  38. )
  39. def action_delete(self, items, checked):
  40. for item in items:
  41. if item.pk in checked:
  42. if item.special:
  43. return Message(_('You cannot delete system roles.'), 'error'), reverse('admin_roles')
  44. if item.protected and not self.request.user.is_god():
  45. return Message(_('You cannot delete protected roles.'), 'error'), reverse('admin_roles')
  46. if item.user_set.count() > 0:
  47. return Message(_('You cannot delete roles that are assigned to users.'), 'error'), reverse('admin_roles')
  48. Role.objects.filter(id__in=checked).delete()
  49. return Message(_('Selected roles have been deleted successfully.'), 'success'), reverse('admin_roles')
  50. class New(FormWidget):
  51. admin = site.get_action('roles')
  52. id = 'new'
  53. fallback = 'admin_roles'
  54. form = RoleForm
  55. submit_button = _("Save Role")
  56. def get_new_url(self, model):
  57. return reverse('admin_roles_new')
  58. def get_edit_url(self, model):
  59. return reverse('admin_roles_edit', model)
  60. def submit_form(self, form, target):
  61. new_role = Role(
  62. name = form.cleaned_data['name'],
  63. )
  64. new_role.save(force_insert=True)
  65. return new_role, Message(_('New Role has been created.'), 'success')
  66. class Edit(FormWidget):
  67. admin = site.get_action('roles')
  68. id = 'edit'
  69. name = _("Edit Role")
  70. fallback = 'admin_roles'
  71. form = RoleForm
  72. target_name = 'name'
  73. translate_target_name = True
  74. notfound_message = _('Requested Role could not be found.')
  75. submit_fallback = True
  76. def get_url(self, model):
  77. return reverse('admin_roles_edit', model)
  78. def get_edit_url(self, model):
  79. return self.get_url(model)
  80. def get_initial_data(self, model):
  81. if self.request.user.is_god():
  82. return {'name': model.name, 'protected': model.protected}
  83. return {'name': model.name}
  84. def get_and_validate_target(self, target):
  85. result = super(Edit, self).get_and_validate_target(target)
  86. if result and result.protected and not self.request.user.is_god():
  87. self.request.messages.set_flash(Message(_('Role "%(name)s" is protected, you cannot edit it.') % {'name': _(result.name)}), 'error', self.admin.id)
  88. return None
  89. return result
  90. def submit_form(self, form, target):
  91. target.name = form.cleaned_data['name']
  92. if self.request.user.is_god():
  93. target.protected = form.cleaned_data['protected']
  94. target.save(force_update=True)
  95. with UpdatingMonitor() as cm:
  96. monitor.increase('acl_version')
  97. return target, Message(_('Changes in role "%(name)s" have been saved.') % {'name': self.original_name}, 'success')
  98. class Forums(ListWidget):
  99. admin = site.get_action('roles')
  100. id = 'forums'
  101. hide_actions = True
  102. name = _('Role Forums Permissions')
  103. table_form_button = _('Change Permissions')
  104. empty_message = _('No forums are currently defined.')
  105. template = 'forums'
  106. def get_url(self):
  107. return reverse('admin_roles_masks', self.role)
  108. def get_items(self):
  109. return Forum.objects.get(special='root').get_descendants()
  110. def sort_items(self, page_items, sorting_method):
  111. return page_items.order_by('lft').all()
  112. def add_template_variables(self, variables):
  113. variables['target'] = _(self.role.name)
  114. return variables
  115. def get_table_form(self, page_items):
  116. perms = {}
  117. try:
  118. forums = self.role.permissions['forums']
  119. for fid in forums:
  120. perms[str(fid)] = str(forums[fid])
  121. except KeyError:
  122. pass
  123. perms_form = {}
  124. roles_select = [("0", _("No Access"))]
  125. for role in self.roles:
  126. roles_select.append((str(role.pk), _(role.name)))
  127. for item in page_items:
  128. perms_form['forum_' + str(item.pk)] = forms.ChoiceField(choices=roles_select,initial=(perms[str(item.pk)] if str(item.pk) in perms else "0"))
  129. # Turn dict into object
  130. return type('ChangeForumRolesForm', (Form,), perms_form)
  131. def table_action(self, page_items, cleaned_data):
  132. perms = {}
  133. for item in page_items:
  134. if cleaned_data['forum_' + str(item.pk)] != "0":
  135. perms[item.pk] = long(cleaned_data['forum_' + str(item.pk)])
  136. role_perms = self.role.permissions
  137. role_perms['forums'] = perms
  138. self.role.permissions = role_perms
  139. self.role.save(force_update=True)
  140. return Message(_('Forum permissions have been saved.'), 'success'), self.get_url()
  141. def __call__(self, request, slug, target):
  142. self.request = request
  143. try:
  144. self.role = Role.objects.get(id=target)
  145. if self.role and self.role.protected and not request.user.is_god():
  146. request.messages.set_flash(Message(_('Role "%(name)s" is protected, you cannot edit it.') % {'name': _(self.role.name)}), 'error', self.admin.id)
  147. return redirect(reverse('admin_roles'))
  148. except Role.DoesNotExist:
  149. request.messages.set_flash(Message(_('Requested Role could not be found.')), 'error', self.admin.id)
  150. return redirect(reverse('admin_roles'))
  151. self.roles = ForumRole.objects.order_by('name').all()
  152. if not self.roles:
  153. request.messages.set_flash(Message(_('No forum roles are currently set.')), 'error', self.admin.id)
  154. return redirect(reverse('admin_roles'))
  155. return super(Forums, self).__call__(request)
  156. class ACL(FormWidget):
  157. admin = site.get_action('roles')
  158. id = 'acl'
  159. name = _("Change Role Permissions")
  160. fallback = 'admin_roles'
  161. target_name = 'name'
  162. translate_target_name = True
  163. notfound_message = _('Requested Role could not be found.')
  164. submit_fallback = True
  165. template = 'acl_form'
  166. def get_form(self, target):
  167. self.form = build_form(self.request, target)
  168. return self.form
  169. def get_url(self, model):
  170. return reverse('admin_roles_acl', model)
  171. def get_edit_url(self, model):
  172. return self.get_url(model)
  173. def get_initial_data(self, model):
  174. raw_acl = model.permissions
  175. initial = {}
  176. for field in self.form.base_fields:
  177. if field in raw_acl:
  178. initial[field] = raw_acl[field]
  179. return initial
  180. def get_and_validate_target(self, target):
  181. result = super(ACL, self).get_and_validate_target(target)
  182. if result and result.protected and not self.request.user.is_god():
  183. self.request.messages.set_flash(Message(_('Role "%(name)s" is protected, you cannot edit it.') % {'name': _(result.name)}), 'error', self.admin.id)
  184. return None
  185. return result
  186. def submit_form(self, form, target):
  187. raw_acl = target.permissions
  188. for perm in form.cleaned_data:
  189. raw_acl[perm] = form.cleaned_data[perm]
  190. target.permissions = raw_acl
  191. target.save(force_update=True)
  192. with UpdatingMonitor() as cm:
  193. monitor.increase('acl_version')
  194. return target, Message(_('Role "%(name)s" permissions have been changed.') % {'name': self.original_name}, 'success')
  195. class Delete(ButtonWidget):
  196. admin = site.get_action('roles')
  197. id = 'delete'
  198. fallback = 'admin_roles'
  199. notfound_message = _('Requested Role could not be found.')
  200. def action(self, target):
  201. if target.special:
  202. return Message(_('You cannot delete system roles.'), 'error'), reverse('admin_roles')
  203. if target.protected and not self.request.user.is_god():
  204. return Message(_('This role is protected.'), 'error'), reverse('admin_roles')
  205. if target.user_set.count() > 0:
  206. return Message(_('This role is assigned to one or more users.'), 'error'), reverse('admin_roles')
  207. target.delete()
  208. return Message(_('Role "%(name)s" has been deleted.') % {'name': _(target.name)}, 'success'), False