Ralfp 12 лет назад
Родитель
Сommit
6e5fe32d15

+ 34 - 2
misago/acl/builder.py

@@ -1,5 +1,37 @@
 from django.conf import settings
 from django.utils.importlib import import_module
+from misago.forms import Form
 
-def build_form(request, form, target):
-    return form
+def build_form(request, role):
+    form_type = type('ACLForm', (Form,), dict(layout=[]))
+    for provider in settings.PERMISSION_PROVIDERS:
+        app_module = import_module(provider)
+        try:
+            app_module.make_form(request, role, form_type)
+        except AttributeError:
+            pass
+    return form_type
+
+
+class BaseACL(object):
+    def __init__(self):
+        self.acl = {}
+
+
+class ACL(object):
+    def __init__(self, version):
+        self.version = version
+
+
+def build_acl(request, roles):
+    acl = ACL(request.monitor['acl_version'])
+    perms = []
+    for role in roles:
+        perms.append(role.get_permissions())
+    for provider in settings.PERMISSION_PROVIDERS:
+        app_module = import_module(provider)
+        try:
+            app_module.build(acl, perms)
+        except AttributeError:
+            pass
+    return acl

+ 23 - 0
misago/acl/middleware.py

@@ -0,0 +1,23 @@
+from django.core.cache import cache, InvalidCacheBackendError
+from misago.acl.builder import build_acl
+
+class ACLMiddleware(object):
+    def process_request(self, request):
+        if request.user.is_authenticated():
+            acl_key = request.user.make_acl_key()
+        else:
+            acl_key = request.session.get('acl_key')
+            if not acl_key:
+                acl_key = request.user.make_acl_key()
+                request.session['acl_key'] = acl_key
+        
+        try:
+            user_acl = cache.get(acl_key)
+            if user_acl.version != request.monitor['acl_version']:
+                raise InvalidCacheBackendError()
+        except AttributeError, InvalidCacheBackendError:
+            user_acl = build_acl(request, request.user.get_roles())
+            cache.set(acl_key, user_acl, 2592000)
+
+        request.acl = user_acl
+        

+ 22 - 7
misago/admin/acl.py

@@ -1,11 +1,26 @@
-def form(request, role, fields, layout):
-    pass
+from django.utils.translation import ugettext_lazy as _
+from django import forms
+from misago.acl.builder import BaseACL
+from misago.forms import YesNoSwitch
 
+def make_form(request, role, form):
+    if role.token != 'admin' and request.user.is_god():
+        form.base_fields['can_use_acp'] = forms.BooleanField(widget=YesNoSwitch,initial=False,required=False)
+        form.layout.append((
+                            _("Admin Control Panel"),
+                            (('can_use_acp', {'label': _("Can use Admin Control Panel"), 'help_text': _("Change this permission to yes to grant admin access for users with this role.")}),),
+                            ))
 
-def dehydrate(acl, data):
-    pass
 
+class AdminACL(BaseACL):
+    def is_admin(self):
+        return self.acl['can_use_acp']
+    
 
-def build(data):
-    pass
-
+def build(acl, roles):
+    acl.admin = AdminACL()
+    acl.admin.acl['can_use_acp'] = False
+    
+    for role in roles:
+        if 'can_use_acp' in role and role['can_use_acp'] > acl.admin.acl['can_use_acp']:
+            acl.admin.acl['can_use_acp'] = role['can_use_acp']

+ 1 - 5
misago/roles/forms.py

@@ -11,8 +11,4 @@ class RoleForm(Form):
                 ('name', {'label': _("Role Name"), 'help_text': _("Role Name is used to identify this role in Admin Control Panel.")}),
                 ),
               ),
-             )
-
-
-class PermsForm(Form):
-    layout = []
+             )

+ 0 - 3
misago/roles/middleware.py

@@ -1,3 +0,0 @@
-class ACLMiddleware(object):
-    def process_request(self, request):
-        print 'ACL MIDDLEWARE!!!'

+ 4 - 4
misago/roles/models.py

@@ -5,7 +5,7 @@ try:
     import cPickle as pickle
 except ImportError:
     import pickle
-    
+
 class Role(models.Model):
     """
     Misago User Role model
@@ -24,16 +24,16 @@ class Role(models.Model):
     
     def get_permissions(self):
         if self.permissions_cache:
-            return permissions_cache
+            return self.permissions_cache
         
         try:
-            self.permissions_cache = base64.decodestring(pickle.loads(self.permissions))
+            self.permissions_cache = pickle.loads(base64.decodestring(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
+        return self.permissions_cache
     
     def set_permissions(self, permissions):
         self.permissions_cache = permissions

+ 5 - 5
misago/roles/views.py

@@ -1,10 +1,11 @@
+import copy
 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, PermsForm
+from misago.roles.forms import RoleForm
 from misago.roles.models import Role
 
 def reverse(route, target=None):
@@ -103,13 +104,12 @@ class ACL(FormWidget):
     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)
+        self.form = build_form(request, target)
         return self.form
     
     def get_url(self, request, model):
@@ -127,12 +127,12 @@ class ACL(FormWidget):
         return initial
     
     def submit_form(self, request, form, target):
-        raw_acl = model.get_permissions()
+        raw_acl = target.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
+        request.monitor['acl_version'] = int(request.monitor['acl_version']) + 1
         
         return target, Message(_('Role "%(name)s" permissions have been changed.') % {'name': self.original_name}, 'success')
 

+ 2 - 1
misago/settings_base.py

@@ -83,12 +83,13 @@ MIDDLEWARE_CLASSES = (
     'misago.banning.middleware.BanningMiddleware',
     'misago.messages.middleware.MessagesMiddleware',
     'misago.users.middleware.UserMiddleware',
-    'misago.roles.middleware.ACLMiddleware',
+    'misago.acl.middleware.ACLMiddleware',
     'django.middleware.common.CommonMiddleware',
 )
 
 # List of application permission providers
 PERMISSION_PROVIDERS = (
+    'misago.usercp.acl',
     'misago.admin.acl',
 )
 

+ 26 - 0
misago/usercp/acl.py

@@ -0,0 +1,26 @@
+from django.utils.translation import ugettext_lazy as _
+from django import forms
+from misago.acl.builder import BaseACL
+from misago.forms import YesNoSwitch
+
+def make_form(request, role, form):
+    form.base_fields['can_use_signature'] = forms.BooleanField(widget=YesNoSwitch,initial=False,required=False)
+    form.layout.append((
+                        _("Signature"),
+                        (('can_use_signature', {'label': _("Can have signature")}),),
+                        ))
+
+
+class UserCPACL(BaseACL):
+    def can_use_signature(self):
+        return self.acl['signature']
+
+
+def build(acl, roles):
+    acl.usercp = UserCPACL()
+    acl.usercp.acl['signature'] = False
+    
+    for role in roles:
+        if 'can_use_signature' in role and role['can_use_signature'] > acl.usercp.acl['signature']:
+            acl.usercp.acl['signature'] = role['can_use_signature']
+

+ 24 - 4
misago/users/models.py

@@ -5,13 +5,16 @@ from path import path
 from django.conf import settings
 from django.contrib.auth.hashers import (
     check_password, make_password, is_password_usable, UNUSABLE_PASSWORD)
+from django.core.cache import cache, InvalidCacheBackendError
 from django.core.exceptions import ValidationError
 from django.core.mail import EmailMultiAlternatives
 from django.db import models
 from django.template import RequestContext
 from django.utils import timezone as tz_util
 from django.utils.translation import ugettext_lazy as _
+from misago.acl.builder import build_acl
 from misago.monitor.monitor import Monitor
+from misago.roles.models import Role
 from misago.settings.settings import Settings as DBSettings
 from misago.users.validators import validate_username, validate_password, validate_email
 from misago.utils import get_random_string, slugify
@@ -351,6 +354,9 @@ class User(models.Model):
             raw_password = password_reversed
         return check_password(raw_password, self.password, setter)
     
+    def get_roles(self):
+        return self.roles.all()
+        
     def make_acl_key(self):
         roles_ids = []
         for role in self.roles.all():
@@ -358,9 +364,17 @@ class User(models.Model):
         self.acl_key = 'acl_%s' % hashlib.md5('_'.join(roles_ids)).hexdigest()[0:8]
         return self.acl_key
     
-    def get_acl(self):
-        pass
-    
+    def get_acl(self, request):
+        try:
+            acl = cache.get(self.acl_key)
+            if acl.version != request.monitor.acl_version:
+                raise InvalidCacheBackendError()
+        except AttributeError, InvalidCacheBackendError:
+            # build acl cache
+            acl = build_acl(request, self.get_roles())
+            cache.set(self.acl_key, acl, 2592000)
+        return acl
+            
     def get_avatar(self, size='normal'):
         # Get uploaded avatar
         if self.avatar_type == 'upload':
@@ -436,8 +450,14 @@ class Guest(object):
     def is_crawler(self):
         return False
         
+    def get_roles(self):
+        return Role.objects.find(token='guest')
+    
+    def make_acl_key(self):
+        return 'acl_%s' % hashlib.md5(Role.objects.get(token='guest').pk).hexdigest()[0:8]
+
         
-class Crawler(object): 
+class Crawler(Guest): 
     """
     Misago Crawler dummy
     """