Browse Source

Defensive testuitls for permissions, small cleanup of permission forms handling.

Rafał Pitoń 11 years ago
parent
commit
4d208a1d20

+ 2 - 2
misago/acl/__init__.py

@@ -1,8 +1,8 @@
 from misago.acl.providers import providers  # noqa
 
 
-def get_change_permissions_forms(role):
-    return providers.get_change_permissions_forms(role)
+def get_change_permissions_forms(role, data=None):
+    return providers.get_change_permissions_forms(role, data)
 
 
 def build_acl_cache(roles):

+ 33 - 3
misago/acl/providers.py

@@ -18,20 +18,50 @@ class PermissionProviders(object):
             self._providers.append((namespace, import_module(namespace)))
             self._providers_dict[namespace] = import_module(namespace)
 
-    def get_change_permissions_forms(self, role):
+    def get_default_permissions(self):
+        default_permissions = {}
+
+        for provider, module in self._providers:
+            try:
+                default_data = module.DEFAULT_PERMISSIONS
+            except AttributeError:
+                message = "'%s' object has no attribute '%s'"
+                raise AttributeError(
+                    message % (provider, 'DEFAULT_PERMISSIONS'))
+
+        default_permissions
+
+
+    def get_change_permissions_forms(self, role, data=None):
         self.initialize_providers()
+        role_permissions = role.permissions
 
         forms = []
         for provider, module in self._providers:
             try:
+                default_data = module.DEFAULT_PERMISSIONS
+            except AttributeError:
+                message = "'%s' object has no attribute '%s'"
+                raise AttributeError(
+                    message % (provider, 'DEFAULT_PERMISSIONS'))
+            try:
                 module.change_permissions_form
             except AttributeError:
                 message = "'%s' object has no attribute '%s'"
                 raise AttributeError(
                     message % (provider, 'change_permissions_form'))
-            forms.append(module.change_permissions_form(role))
 
-        return [f for f in forms if f]
+            FormType = module.change_permissions_form(role)
+
+            if FormType:
+                if data:
+                    forms.append(FormType(data, prefix=provider))
+                else:
+                    initial_data = role_permissions.get(provider, default_data)
+                    forms.append(FormType(initial=initial_data,
+                                          prefix=provider))
+
+        return forms
 
     def build_acl_cache(self, roles):
         self.initialize_providers()

+ 3 - 5
misago/acl/tests/test_forumroleadmin_views.py

@@ -1,14 +1,12 @@
 from django.core.urlresolvers import reverse
+from misago.acl import get_change_permissions_forms
 from misago.admin.testutils import AdminTestCase
 from misago.acl.models import ForumRole
+from misago.acl.testutils import fake_post_data
 
 
 def fake_data(data_dict):
-    data_dict.update({
-        'can_see_forum': 0,
-        'can_browse_forum': 0,
-    })
-    return data_dict
+    return fake_post_data(ForumRole(), data_dict)
 
 
 class ForumRoleAdminViewsTests(AdminTestCase):

+ 2 - 14
misago/acl/tests/test_roleadmin_views.py

@@ -1,23 +1,11 @@
 from django.core.urlresolvers import reverse
 from misago.admin.testutils import AdminTestCase
 from misago.acl.models import Role
+from misago.acl.testutils import fake_post_data
 
 
 def fake_data(data_dict):
-    data_dict.update({
-        'name_changes_allowed': 0,
-        'changes_expire': 0,
-        'can_use_signature': 0,
-        'allow_signature_links': 0,
-        'allow_signature_images': 0,
-        'can_destroy_user_newer_than': 0,
-        'can_destroy_users_with_less_posts_than': 0,
-        'can_search_users': 0,
-        'can_see_users_emails': 0,
-        'can_see_users_ips': 0,
-        'can_see_hidden_users': 0,
-    })
-    return data_dict
+    return fake_post_data(Role(), data_dict)
 
 
 class RoleAdminViewsTests(AdminTestCase):

+ 17 - 0
misago/acl/tests/test_testutils.py

@@ -0,0 +1,17 @@
+from django.test import TestCase
+from misago.acl.models import Role, ForumRole
+from misago.acl.testutils import fake_post_data
+
+
+class FakeTestDataTests(TestCase):
+    def test_fake_post_data_for_role(self):
+        """fake data was created for Role"""
+        test_data = fake_post_data(Role(), {'can_fly': 1})
+
+        self.assertIn('can_fly', test_data)
+
+    def test_fake_post_data_for_forumrole(self):
+        """fake data was created for ForumRole"""
+        test_data = fake_post_data(ForumRole(), {'can_swim': 1})
+
+        self.assertIn('can_swim', test_data)

+ 18 - 0
misago/acl/testutils.py

@@ -0,0 +1,18 @@
+from misago.acl import get_change_permissions_forms
+
+
+def fake_post_data(target, data_dict):
+    """
+    In order for form to don't fail submission, all permission fields need
+    to receive values. This function populates data dict with default values
+    for permissions, making form validation pass
+    """
+    for form in get_change_permissions_forms(target):
+        for field in form:
+            if field.value() == True:
+                data_dict[field.html_name] = 1
+            elif field.value() == False:
+                data_dict[field.html_name] = 0
+            else:
+                data_dict[field.html_name] = field.value()
+    return data_dict

+ 4 - 3
misago/acl/views/forumroles.py

@@ -26,7 +26,7 @@ class RoleFormMixin(object):
         perms_forms = get_change_permissions_forms(target)
 
         if request.method == 'POST':
-            perms_forms = [f(request.POST) for f in perms_forms]
+            perms_forms = get_change_permissions_forms(target, request.POST)
             valid_forms = 0
             for permissions_form in perms_forms:
                 if permissions_form.is_valid():
@@ -36,7 +36,8 @@ class RoleFormMixin(object):
             if form.is_valid() and len(perms_forms) == valid_forms:
                 new_permissions = {}
                 for permissions_form in perms_forms:
-                    new_permissions.update(permissions_form.cleaned_data)
+                    cleaned_data = permissions_form.cleaned_data
+                    new_permissions[permissions_form.prefix] = cleaned_data
 
                 form.instance.permissions = new_permissions
                 form.instance.save()
@@ -48,7 +49,7 @@ class RoleFormMixin(object):
                 else:
                     return redirect(self.root_link)
         else:
-            perms_forms = [f(initial=role_permissions) for f in perms_forms]
+            perms_forms = get_change_permissions_forms(target)
 
         return self.render(
             request,

+ 4 - 3
misago/acl/views/roles.py

@@ -26,7 +26,7 @@ class RoleFormMixin(object):
         perms_forms = get_change_permissions_forms(target)
 
         if request.method == 'POST':
-            perms_forms = [f(request.POST) for f in perms_forms]
+            perms_forms = get_change_permissions_forms(target, request.POST)
             valid_forms = 0
             for permissions_form in perms_forms:
                 if permissions_form.is_valid():
@@ -36,7 +36,8 @@ class RoleFormMixin(object):
             if form.is_valid() and len(perms_forms) == valid_forms:
                 new_permissions = {}
                 for permissions_form in perms_forms:
-                    new_permissions.update(permissions_form.cleaned_data)
+                    cleaned_data = permissions_form.cleaned_data
+                    new_permissions[permissions_form.prefix] = cleaned_data
 
                 form.instance.permissions = new_permissions
                 form.instance.save()
@@ -48,7 +49,7 @@ class RoleFormMixin(object):
                 else:
                     return redirect(self.root_link)
         else:
-            perms_forms = [f(initial=role_permissions) for f in perms_forms]
+            perms_forms = get_change_permissions_forms(target)
 
         return self.render(
             request,

+ 8 - 2
misago/forums/permissions.py

@@ -3,10 +3,16 @@ from misago.acl.models import ForumRole
 from misago.core import forms
 
 
+DEFAULT_PERMISSIONS = {
+    'can_see': False,
+    'can_browse': False
+}
+
+
 class PermissionsForm(forms.Form):
     legend = _("Destroying user accounts")
-    can_see_forum = forms.YesNoSwitch(label=_("Can see forum"))
-    can_browse_forum = forms.YesNoSwitch(label=_("Can see forum contents"))
+    can_see = forms.YesNoSwitch(label=_("Can see forum"))
+    can_browse = forms.YesNoSwitch(label=_("Can see forum contents"))
 
 
 def change_permissions_form(role):

+ 12 - 2
misago/users/permissions/account.py

@@ -3,6 +3,15 @@ from misago.acl.models import Role
 from misago.core import forms
 
 
+DEFAULT_PERMISSIONS = {
+    'name_changes_allowed': 1,
+    'changes_expire': 0,
+    'can_use_signature': True,
+    'allow_signature_links': True,
+    'allow_signature_images': False,
+}
+
+
 class PermissionsForm(forms.Form):
     legend = _("Account settings")
     name_changes_allowed = forms.IntegerField(
@@ -16,9 +25,10 @@ class PermissionsForm(forms.Form):
         initial=0)
     can_use_signature = forms.YesNoSwitch(
         label=_("Can have signature"),
-        initial=False)
+        initial=True)
     allow_signature_links = forms.YesNoSwitch(
-        label=_("Can put links in signature"))
+        label=_("Can put links in signature"),
+        initial=True)
     allow_signature_images = forms.YesNoSwitch(
         label=_("Can put images in signature"))
 

+ 6 - 2
misago/users/permissions/destroying.py

@@ -3,17 +3,21 @@ from misago.acl.models import Role
 from misago.core import forms
 
 
+DEFAULT_PERMISSIONS = {
+    'can_destroy_user_newer_than': 0,
+    'can_destroy_users_with_less_posts_than': 0,
+}
+
+
 class PermissionsForm(forms.Form):
     legend = _("Destroying user accounts")
     can_destroy_user_newer_than = forms.IntegerField(
         label=_("Maximum age of destroyed account (in days)"),
         help_text=_("Enter zero to disable this check."),
-        initial=0,
         min_value=0)
     can_destroy_users_with_less_posts_than = forms.IntegerField(
         label=_("Maximum number of posts on destroyed account"),
         help_text=_("Enter zero to disable this check."),
-        initial=0,
         min_value=0)
 
 

+ 9 - 1
misago/users/permissions/profiles.py

@@ -3,12 +3,20 @@ from misago.acl.models import Role
 from misago.core import forms
 
 
+DEFAULT_PERMISSIONS = {
+    'can_search_users': True,
+    'can_see_users_emails': False,
+    'can_see_users_ips': False,
+    'can_see_hidden_users': False,
+}
+
+
 class PermissionsForm(forms.Form):
     legend = _("User profiles")
     can_search_users = forms.YesNoSwitch(
         label=_("Can search user profiles"))
     can_see_users_emails = forms.YesNoSwitch(
-        label=_("Can see members e-mail's"))
+        label=_("Can see members e-mails"))
     can_see_users_ips = forms.YesNoSwitch(
         label=_("Can see members IPs"))
     can_see_hidden_users = forms.YesNoSwitch(