Browse Source

Roles Admin is now integrated with ACL app.

Ralfp 12 years ago
parent
commit
70cf0d9fdb
4 changed files with 73 additions and 5 deletions
  1. 1 0
      misago/admin/layout/users.py
  2. 4 1
      misago/roles/forms.py
  3. 26 3
      misago/roles/models.py
  4. 42 1
      misago/roles/views.py

+ 1 - 0
misago/admin/layout/users.py

@@ -65,6 +65,7 @@ ADMIN_ACTIONS=(
                urlpatterns=patterns('misago.roles.views',
                         url(r'^$', 'List', name='admin_roles'),
                         url(r'^new/$', 'New', name='admin_roles_new'),
+                        url(r'^acl/(?P<slug>([a-z0-9]|-)+)-(?P<target>\d+)/$', 'ACL', name='admin_roles_acl'),
                         url(r'^edit/(?P<slug>([a-z0-9]|-)+)-(?P<target>\d+)/$', 'Edit', name='admin_roles_edit'),
                         url(r'^delete/(?P<slug>([a-z0-9]|-)+)-(?P<target>\d+)/$', 'Delete', name='admin_roles_delete'),
                     ),

+ 4 - 1
misago/roles/forms.py

@@ -12,4 +12,7 @@ class RoleForm(Form):
                 ),
               ),
              )
-    
+
+
+class PermsForm(Form):
+    layout = []

+ 26 - 3
misago/roles/models.py

@@ -1,6 +1,11 @@
 from django.db import models
 from django.utils.translation import ugettext_lazy as _
-
+import base64
+try:
+    import cPickle as pickle
+except ImportError:
+    import pickle
+    
 class Role(models.Model):
     """
     Misago User Role model
@@ -9,9 +14,27 @@ class Role(models.Model):
     token = models.CharField(max_length=255,null=True,blank=True)
     protected = models.BooleanField(default=False)
     permissions = models.TextField(null=True,blank=True)
-     
+    permissions_cache = {}
+    
     def __unicode__(self):
         return unicode(_(self.name))
     
     def is_special(self):
-        return token
+        return token
+    
+    def get_permissions(self):
+        if self.permissions_cache:
+            return permissions_cache
+        
+        try:
+            self.permissions_cache = base64.decodestring(pickle.loads(self.permissions))
+        except Exception:
+            # ValueError, SuspiciousOperation, unpickling exceptions. If any of
+            # these happen, just return an empty dictionary (an empty permissions list).
+            self.permissions_cache = {}
+            
+        return permissions_cache
+    
+    def set_permissions(self, permissions):
+        self.permissions_cache = permissions
+        self.permissions = base64.encodestring(pickle.dumps(permissions, pickle.HIGHEST_PROTOCOL))

+ 42 - 1
misago/roles/views.py

@@ -1,9 +1,10 @@
 from django.core.urlresolvers import reverse as django_reverse
 from django.utils.translation import ugettext as _
+from misago.acl.builder import build_form 
 from misago.admin import site
 from misago.admin.widgets import *
 from misago.utils import slugify
-from misago.roles.forms import RoleForm
+from misago.roles.forms import RoleForm, PermsForm
 from misago.roles.models import Role
 
 def reverse(route, target=None):
@@ -30,6 +31,7 @@ class List(ListWidget):
     
     def get_item_actions(self, request, item):
         return (
+                self.action('adjust', _("Role Permissions"), reverse('admin_roles_acl', item)),
                 self.action('pencil', _("Edit Role"), reverse('admin_roles_edit', item)),
                 self.action('remove', _("Delete Role"), reverse('admin_roles_delete', item), post=True, prompt=_("Are you sure you want to delete this role?")),
                 )
@@ -96,6 +98,45 @@ class Edit(FormWidget):
         return target, Message(_('Changes in role "%(name)s" have been saved.') % {'name': self.original_name}, 'success')
 
 
+class ACL(FormWidget):
+    admin = site.get_action('roles')
+    id = 'acl'
+    name = _("Change Role Permissions")
+    fallback = 'admin_roles'
+    form = PermsForm
+    target_name = 'name'
+    notfound_message = _('Requested Role could not be found.')
+    submit_fallback = True
+    
+    def get_form(self, request, target):
+        self.form = build_form(request, self.form, target)
+        return self.form
+    
+    def get_url(self, request, model):
+        return reverse('admin_roles_acl', model)
+    
+    def get_edit_url(self, request, model):
+        return self.get_url(request, model)
+    
+    def get_initial_data(self, request, model):
+        raw_acl = model.get_permissions()
+        initial = {}
+        for field in self.form.base_fields:
+            if field in raw_acl:
+                initial[field] = raw_acl[field]
+        return initial
+    
+    def submit_form(self, request, form, target):
+        raw_acl = model.get_permissions()
+        for perm in form.cleaned_data:
+            raw_acl[perm] = form.cleaned_data[perm]
+        target.set_permissions(raw_acl)
+        target.save(force_update=True)
+        request.model['acl_version'] = int(request.model['acl_version']) + 1
+        
+        return target, Message(_('Role "%(name)s" permissions have been changed.') % {'name': self.original_name}, 'success')
+
+
 class Delete(ButtonWidget):
     admin = site.get_action('roles')
     id = 'delete'