diff --git a/permissions/backends.py b/permissions/backends.py index 7aa67c6..9096281 100644 --- a/permissions/backends.py +++ b/permissions/backends.py @@ -7,7 +7,7 @@ from permissions.models import GlobalPermission def user_has_perm(user, perm, perms): for p in perms: # this perm allow that action and the user is concerned by this perm - if hasattr(p, perm) and getattr(p, perm) and p.granted_to(user): + if perm in p.all_perms and getattr(p, perm) and p.granted_to(user): return True diff --git a/permissions/migrations/0005_auto_20140902_0521.py b/permissions/migrations/0005_auto_20140902_0521.py new file mode 100644 index 0000000..45e84e3 --- /dev/null +++ b/permissions/migrations/0005_auto_20140902_0521.py @@ -0,0 +1,150 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import permissions.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('permissions', '0004_auto_20140830_2318'), + ] + + operations = [ + migrations.AlterField( + model_name='globalpermission', + name='access_project', + field=permissions.models.ProjectPermissionField(default=False), + ), + migrations.AlterField( + model_name='globalpermission', + name='create_comment', + field=permissions.models.ProjectPermissionField(default=False), + ), + migrations.AlterField( + model_name='globalpermission', + name='create_issue', + field=permissions.models.ProjectPermissionField(default=False), + ), + migrations.AlterField( + model_name='globalpermission', + name='create_project', + field=permissions.models.GlobalPermissionField(default=True, verbose_name='Create project'), + ), + migrations.AlterField( + model_name='globalpermission', + name='delete_comment', + field=permissions.models.ProjectPermissionField(default=False), + ), + migrations.AlterField( + model_name='globalpermission', + name='delete_issue', + field=permissions.models.ProjectPermissionField(default=False), + ), + migrations.AlterField( + model_name='globalpermission', + name='delete_project', + field=permissions.models.GlobalPermissionField(default=False), + ), + migrations.AlterField( + model_name='globalpermission', + name='delete_tags', + field=permissions.models.ProjectPermissionField(default=False), + ), + migrations.AlterField( + model_name='globalpermission', + name='manage_accounts', + field=permissions.models.GlobalPermissionField(default=False), + ), + migrations.AlterField( + model_name='globalpermission', + name='manage_global_permission', + field=permissions.models.GlobalPermissionField(default=False), + ), + migrations.AlterField( + model_name='globalpermission', + name='manage_issue', + field=permissions.models.ProjectPermissionField(default=False), + ), + migrations.AlterField( + model_name='globalpermission', + name='manage_project_permission', + field=permissions.models.ProjectPermissionField(default=False), + ), + migrations.AlterField( + model_name='globalpermission', + name='manage_settings', + field=permissions.models.GlobalPermissionField(default=False), + ), + migrations.AlterField( + model_name='globalpermission', + name='manage_tags', + field=permissions.models.ProjectPermissionField(default=False), + ), + migrations.AlterField( + model_name='globalpermission', + name='modify_comment', + field=permissions.models.ProjectPermissionField(default=False), + ), + migrations.AlterField( + model_name='globalpermission', + name='modify_issue', + field=permissions.models.ProjectPermissionField(default=False), + ), + migrations.AlterField( + model_name='globalpermission', + name='modify_project', + field=permissions.models.GlobalPermissionField(default=False), + ), + migrations.AlterField( + model_name='projectpermission', + name='create_comment', + field=permissions.models.PermissionField(default=True), + ), + migrations.AlterField( + model_name='projectpermission', + name='create_issue', + field=permissions.models.PermissionField(default=True), + ), + migrations.AlterField( + model_name='projectpermission', + name='delete_comment', + field=permissions.models.PermissionField(default=False), + ), + migrations.AlterField( + model_name='projectpermission', + name='delete_issue', + field=permissions.models.PermissionField(default=False), + ), + migrations.AlterField( + model_name='projectpermission', + name='delete_tags', + field=permissions.models.PermissionField(default=False), + ), + migrations.AlterField( + model_name='projectpermission', + name='manage_issue', + field=permissions.models.PermissionField(default=False), + ), + migrations.AlterField( + model_name='projectpermission', + name='manage_project_permission', + field=permissions.models.PermissionField(default=False), + ), + migrations.AlterField( + model_name='projectpermission', + name='manage_tags', + field=permissions.models.PermissionField(default=False), + ), + migrations.AlterField( + model_name='projectpermission', + name='modify_comment', + field=permissions.models.PermissionField(default=False), + ), + migrations.AlterField( + model_name='projectpermission', + name='modify_issue', + field=permissions.models.PermissionField(default=False), + ), + ] diff --git a/permissions/models.py b/permissions/models.py index 84edee0..d103fb3 100644 --- a/permissions/models.py +++ b/permissions/models.py @@ -10,6 +10,19 @@ from accounts.models import * __all__ = ['GlobalPermission', 'ProjectPermission'] +@python_2_unicode_compatible +class PermissionField(models.BooleanField): + pass + + +class GlobalPermissionField(PermissionField): + pass + + +class ProjectPermissionField(PermissionField): + pass + + @python_2_unicode_compatible class PermissionModel(models.Model): @@ -66,6 +79,18 @@ class PermissionModel(models.Model): else: return False + @property + def all_perms(self): + for field in self._meta.fields: + if isinstance(field, PermissionField): + yield field.name + + @property + def all_perms_fields_values(self): + for field in self._meta.fields: + if isinstance(field, PermissionField): + yield (field, getattr(self, field.name)) + @property def type(self): return self.get_grantee_type_display() @@ -84,33 +109,62 @@ class GlobalPermission(PermissionModel): class Meta: unique_together = ('grantee_type', 'grantee_id') + @property + def global_perms_fields_values(self): + for field in self._meta.fields: + if isinstance(field, GlobalPermissionField): + yield (field, getattr(self, field.name)) + + @property + def project_perms_fields_values(self): + for field in self._meta.fields: + if isinstance(field, ProjectPermissionField): + yield (field, getattr(self, field.name)) + # Global permissions - create_project = models.BooleanField(default=True) - modify_project = models.BooleanField(default=False) - delete_project = models.BooleanField(default=False) + create_project = GlobalPermissionField(default=True, + verbose_name='Create project') + modify_project = GlobalPermissionField(default=False, + verbose_name='Modify project') + delete_project = GlobalPermissionField(default=False, + verbose_name='Delete project') - manage_settings = models.BooleanField(default=False) - manage_accounts = models.BooleanField(default=False) - manage_global_permission = models.BooleanField(default=False) + manage_settings = GlobalPermissionField(default=False, + verbose_name='Manage settings') + manage_accounts = GlobalPermissionField(default=False, + verbose_name='Manage users, groups and teams') + manage_global_permission = GlobalPermissionField(default=False, + verbose_name='Manage global permissions') # Project permissions, given on ALL projects - access_project = models.BooleanField(default=False) + access_project = ProjectPermissionField(default=False, + verbose_name='Access all project') - create_issue = models.BooleanField(default=False) - modify_issue = models.BooleanField(default=False) - manage_issue = models.BooleanField(default=False) - delete_issue = models.BooleanField(default=False) + create_issue = ProjectPermissionField(default=False, + verbose_name='Create issue') + modify_issue = ProjectPermissionField(default=False, + verbose_name='Modify issue') + manage_issue = ProjectPermissionField(default=False, + verbose_name='Manage issue') + delete_issue = ProjectPermissionField(default=False, + verbose_name='Delete issue') - create_comment = models.BooleanField(default=False) - modify_comment = models.BooleanField(default=False) - delete_comment = models.BooleanField(default=False) + create_comment = ProjectPermissionField(default=False, + verbose_name='Create comment') + modify_comment = ProjectPermissionField(default=False, + verbose_name='Modify comment') + delete_comment = ProjectPermissionField(default=False, + verbose_name='Delete comment') - manage_tags = models.BooleanField(default=False) - delete_tags = models.BooleanField(default=False) + manage_tags = ProjectPermissionField(default=False, + verbose_name='Assign and remove labels and milestones') + delete_tags = ProjectPermissionField(default=False, + verbose_name='Delete labels and milestones') - manage_project_permission = models.BooleanField(default=False) + manage_project_permission = ProjectPermissionField(default=False, + verbose_name='Manage project permissions') def __str__(self): return self.grantee.__str__() + "'s global permissions" @@ -124,19 +178,29 @@ class ProjectPermission(PermissionModel): project = models.ForeignKey(Project, related_name='permissions') - manage_project_permission = models.BooleanField(default=False) + create_issue = PermissionField(default=False, + verbose_name='Create issue') + modify_issue = PermissionField(default=False, + verbose_name='Modify issue') + manage_issue = PermissionField(default=False, + verbose_name='Manage issue') + delete_issue = PermissionField(default=False, + verbose_name='Delete issue') - create_issue = models.BooleanField(default=True) - modify_issue = models.BooleanField(default=False) - manage_issue = models.BooleanField(default=False) - delete_issue = models.BooleanField(default=False) + create_comment = PermissionField(default=False, + verbose_name='Create comment') + modify_comment = PermissionField(default=False, + verbose_name='Modify comment') + delete_comment = PermissionField(default=False, + verbose_name='Delete comment') - create_comment = models.BooleanField(default=True) - modify_comment = models.BooleanField(default=False) - delete_comment = models.BooleanField(default=False) + manage_tags = PermissionField(default=False, + verbose_name='Assign and remove labels and milestones') + delete_tags = PermissionField(default=False, + verbose_name='Delete labels and milestones') - manage_tags = models.BooleanField(default=False) - delete_tags = models.BooleanField(default=False) + manage_project_permission = PermissionField(default=False, + verbose_name='Manage project permissions') def __str__(self): return self.grantee.__str__() + "'s permissions on " \ diff --git a/permissions/urls.py b/permissions/urls.py index 90cc3e7..7a84ade 100644 --- a/permissions/urls.py +++ b/permissions/urls.py @@ -7,11 +7,11 @@ urlpatterns = [ url(r'^admin/permissions/add/$', 'permissions.views.global_perm_edit', name='add-global-permission'), url(r'^admin/permissions/(?P[0-9]+)/edit/$', 'permissions.views.global_perm_edit', name='edit-global-permission'), url(r'^admin/permissions/(?P[0-9]+)/delete/$', 'permissions.views.global_perm_delete', name='delete-global-permission'), - url(r'^admin/permissions/(?P[0-9]+)/toggle/(?P[a-z-]+)/$', 'permissions.views.global_perm_toggle', name='toggle-global-permission'), + url(r'^admin/permissions/(?P[0-9]+)/toggle/(?P[a-z_]+)/$', 'permissions.views.global_perm_toggle', name='toggle-global-permission'), # Project permissions url(r'^(?P[-\w]+)/permissions/$', 'permissions.views.project_perm_list', name='list-project-permission'), url(r'^(?P[-\w]+)/permissions/add/$', 'permissions.views.project_perm_edit', name='add-project-permission'), url(r'^(?P[-\w]+)/permissions/(?P[0-9]+)/edit/$', 'permissions.views.project_perm_edit', name='edit-project-permission'), url(r'^(?P[-\w]+)/permissions/(?P[0-9]+)/delete/$', 'permissions.views.project_perm_delete', name='delete-project-permission'), - url(r'^(?P[-\w]+)/permissions/(?P[0-9]+)/toggle/(?P[a-z-]+)/$', 'permissions.views.project_perm_toggle', name='toggle-project-permission'), + url(r'^(?P[-\w]+)/permissions/(?P[0-9]+)/toggle/(?P[a-z_]+)/$', 'permissions.views.project_perm_toggle', name='toggle-project-permission'), ] diff --git a/permissions/views.py b/permissions/views.py index 02cd03d..13ba3db 100644 --- a/permissions/views.py +++ b/permissions/views.py @@ -56,17 +56,12 @@ def global_perm_delete(request, id): @project_perm_required('manage_global_permission') def global_perm_toggle(request, id, perm): permission = get_object_or_404(GlobalPermission, id=id) - # to be sure to dont modify other attribut with the following trick - if '-' not in perm: - raise Http404 - perm = perm.replace('-', '_') - if hasattr(permission, perm): - state = not getattr(permission, perm) - setattr(permission, perm, state) - permission.save() - return HttpResponse('1' if state else '0') - else: + if perm not in permission.all_perms: raise Http404 + state = not getattr(permission, perm) + setattr(permission, perm, state) + permission.save() + return HttpResponse('1' if state else '0') @project_perm_required('manage_project_permission') @@ -119,14 +114,9 @@ def project_perm_delete(request, project, id): @project_perm_required('manage_project_permission') def project_perm_toggle(request, project, id, perm): permission = get_object_or_404(ProjectPermission, project=project, id=id) - # to be sure to dont modify other attribut with the following trick - if '-' not in perm: - raise Http404 - perm = perm.replace('-', '_') - if hasattr(permission, perm): - state = not getattr(permission, perm) - setattr(permission, perm, state) - permission.save() - return HttpResponse('1' if state else '0') - else: + if perm not in permission.all_perms: raise Http404 + state = not getattr(permission, perm) + setattr(permission, perm, state) + permission.save() + return HttpResponse('1' if state else '0') diff --git a/templates/permissions/global_perm_list.html b/templates/permissions/global_perm_list.html index b1c2278..231b75a 100644 --- a/templates/permissions/global_perm_list.html +++ b/templates/permissions/global_perm_list.html @@ -38,82 +38,22 @@
diff --git a/templates/permissions/project_perm_list.html b/templates/permissions/project_perm_list.html index 8f28ed5..0e11195 100644 --- a/templates/permissions/project_perm_list.html +++ b/templates/permissions/project_perm_list.html @@ -33,46 +33,12 @@