def make_project_permissions_formset(project): roles = project.roles.all() project_perms= get_all_project_permissions().order_by('content_type') class ProjectRoleFormSet(BaseModelFormSet): def __init__(self, *args, **kwargs): kwargs['queryset'] = roles super(ProjectRoleFormSet, self).__init__(*args, **kwargs) class ProjectRoleForm(ModelForm): permissions = forms.ModelMultipleChoiceField( required=False, queryset=project_perms, widget=forms.CheckboxSelectMultiple) class Meta: model = ProjectRole fields = ('role', 'permissions',) def __init__(self, *args, **kwargs): super(ProjectRoleForm, self).__init__(*args, **kwargs) if self.instance and self.instance.is_super_role: self.fields['permissions'].widget.attrs['readonly'] = True self.fields['permissions'].widget.attrs['checked'] = True elif self.instance and self.instance.id: self.fields['permissions'].initial = self.instance.group.permissions.all() def save(self, *args, **kwargs): # We are NOT committing the change here, because we only save the # form if the object already exists. This is because it was # difficult to deal with the M2M relations (permissions => the new # group which is created along with the project role) when doing # that. We are calling save, however, to bound this form to an # instance if it exists, so that we can proceed in the right way # afterwards (create a ProjectRole manually if no existing instance; # save form otherwise). kwargs['commit'] = False obj = super(ProjectRoleForm, self).save(*args, **kwargs) perms = self.cleaned_data['permissions'] if not obj.id: new_role = ProjectRole.objects.create_project_role( project, self.cleaned_data['role']) new_role.group.permissions.add(*perms) else: obj.save() obj.group.permissions.clear() obj.group.permissions.add(*perms) return obj formset = modelformset_factory(ProjectRole, formset=ProjectRoleFormSet, form=ProjectRoleForm, can_delete=True, extra=1) formset.all_perms = project_perms return formset
def test_super_role(self): from editorsnotes.main.management import get_all_project_permissions role = self.project.roles.get() self.assertEqual(role, self.project.roles.get_for_user(self.user)) # "Super roles" should have all project-specific permissions self.assertEqual(len(self.user.get_project_permissions(self.project)), len(get_all_project_permissions())) self.assertTrue( self.user.has_project_perm(self.project, 'main.add_note')) # Even if this is a super-role, return False for a made up permission. # Maybe not, though? self.assertFalse( self.user.has_project_perm(self.project, 'made up permission'))
def test_super_role(self): from editorsnotes.main.management import get_all_project_permissions role = self.project.roles.get() self.assertEqual(role, self.project.roles.get_for_user(self.user)) # "Super roles" should have all project-specific permissions self.assertEqual(len(self.user.get_project_permissions(self.project)), len(get_all_project_permissions())) self.assertTrue(self.user.has_project_perm( self.project, 'main.add_note')) # Even if this is a super-role, return False for a made up permission. # Maybe not, though? self.assertFalse(self.user.has_project_perm( self.project, 'made up permission'))
def get_project_permission_objects(self, project): """ Get all of a user's permissions within a project. I thought about implementing this in an authentication backend, where a perm would be `{projectslug}-{app}.{perm}` instead of the typical `{app}.{perm}`, but this is more explicit. If we ever decide to roll this UserProfile into a custom User model, it would make sense to move this method to a custom backend. """ role = self._get_project_role(project) if self.is_superuser or (role is not None and role.is_super_role): perm_list = get_all_project_permissions() elif role is None: perm_list = [] else: perm_list = role.get_permissions() return perm_list
def make_project_permissions_formset(project): roles = project.roles.all() project_perms = get_all_project_permissions().order_by('content_type') class ProjectRoleFormSet(BaseModelFormSet): def __init__(self, *args, **kwargs): kwargs['queryset'] = roles super(ProjectRoleFormSet, self).__init__(*args, **kwargs) class ProjectRoleForm(ModelForm): permissions = forms.ModelMultipleChoiceField( required=False, queryset=project_perms, widget=forms.CheckboxSelectMultiple) class Meta: model = ProjectRole fields = ( 'role', 'permissions', ) def __init__(self, *args, **kwargs): super(ProjectRoleForm, self).__init__(*args, **kwargs) if self.instance and self.instance.is_super_role: self.fields['permissions'].widget.attrs['readonly'] = True self.fields['permissions'].widget.attrs['checked'] = True elif self.instance and self.instance.id: self.fields[ 'permissions'].initial = self.instance.group.permissions.all( ) def save(self, *args, **kwargs): # We are NOT committing the change here, because we only save the # form if the object already exists. This is because it was # difficult to deal with the M2M relations (permissions => the new # group which is created along with the project role) when doing # that. We are calling save, however, to bound this form to an # instance if it exists, so that we can proceed in the right way # afterwards (create a ProjectRole manually if no existing instance; # save form otherwise). kwargs['commit'] = False obj = super(ProjectRoleForm, self).save(*args, **kwargs) perms = self.cleaned_data['permissions'] if not obj.id: new_role = ProjectRole.objects.create_project_role( project, self.cleaned_data['role']) new_role.group.permissions.add(*perms) else: obj.save() obj.group.permissions.clear() obj.group.permissions.add(*perms) return obj formset = modelformset_factory(ProjectRole, formset=ProjectRoleFormSet, form=ProjectRoleForm, can_delete=True, extra=1) formset.all_perms = project_perms return formset
def _get_valid_permissions(self): if not hasattr(self, '_valid_permissions_cache'): self._valid_permissions_cache = get_all_project_permissions() return self._valid_permissions_cache