def has_change_permission(self, request, obj=None): """ Returns True if the given request has permission to change the given Django model instance. If `obj` is None, this should return True if the given request has permission to change *any* object of the given type. If request is GET type, at least view_permission is needed. In case of POST request change permission is needed. """ cfield = model_category_fk_value(obj) if obj is None or not cfield: if request.method == 'POST': return super(NewmanModelAdmin, self).has_change_permission(request, obj) else: return self.has_model_view_permission(request, obj) opts = self.opts change_perm = '%s.%s' % ( opts.app_label, opts.get_change_permission() ) view_perm = '%s.view_%s' % ( opts.app_label, opts.object_name.lower() ) can_view = has_category_permission( request.user, cfield, view_perm ) can_change = has_category_permission( request.user, cfield, change_perm ) if request.method == 'POST' and can_change: return True elif request.method == 'GET' and (can_view or can_change): return True return False
def has_change_permission(self, request, obj=None): """ Returns True if the given request has permission to change the given Django model instance. If `obj` is None, this should return True if the given request has permission to change *any* object of the given type. If request is GET type, at least view_permission is needed. In case of POST request change permission is needed. """ cfield = model_category_fk_value(obj) if obj is None or not cfield: if request.method == 'POST': return super(NewmanModelAdmin, self).has_change_permission(request, obj) else: return self.has_model_view_permission(request, obj) opts = self.opts change_perm = '%s.%s' % (opts.app_label, opts.get_change_permission()) view_perm = '%s.view_%s' % (opts.app_label, opts.object_name.lower()) can_view = has_category_permission(request.user, cfield, view_perm) can_change = has_category_permission(request.user, cfield, change_perm) if request.method == 'POST' and can_change: return True elif request.method == 'GET' and (can_view or can_change): return True return False
def test_has_category_permission_success(self): tools.assert_true( has_category_permission(self.user, self.nested_second_level_two, 'articles.view_article')) tools.assert_true( has_category_permission(self.user, self.nested_second_level_two, 'articles.add_article')) tools.assert_true( has_category_permission(self.user, self.nested_second_level_two, 'articles.change_article')) tools.assert_true( has_category_permission(self.user, self.nested_second_level_two, 'articles.delete_article'))
def full_clean(self): super(BaseGenericInlineFormSet, self).full_clean() cfield = model_category_fk(self.instance) if not cfield: return #cat = model_category_fk_value(self.instance) # next part is category-based permissions (only for objects with category field) def add_field_error(form, field_name, message): err_list = ErrorList( (message,) ) form._errors[field_name] = err_list user = self.form._magic_user # Adding new object for form in self.extra_forms: change_perm = get_permission('change', form.instance) if not form.has_changed(): continue if cfield.name not in form.changed_data: continue add_perm = get_permission('add', form.instance) if not has_object_permission(user, form.instance, change_perm): self._non_form_errors = _('Creating objects is not permitted.') continue c = form.cleaned_data[cfield.name] if not has_category_permission(user, c, add_perm): add_field_error( form, cfield.name, _('Category not permitted') ) # Changing existing object for form in self.initial_forms: change_perm = get_permission('change', form.instance) delete_perm = get_permission('delete', form.instance) if self.can_delete and hasattr(form, 'cleaned_data') and form.cleaned_data[DELETION_FIELD_NAME]: if not has_object_permission(user, form.instance, delete_perm): self._non_form_errors = _('Object deletion is not permitted.') continue if model_category_fk(form.instance) is not None and not has_category_permission(user, form.instance.category, delete_perm): self._non_form_errors = _('Object deletion is not permitted.') continue if cfield.name not in form.changed_data: continue if not has_object_permission(user, form.instance, change_perm): self._non_form_errors = _('Object change is not permitted.') continue c = form.cleaned_data[cfield.name] if not has_category_permission(user, c, change_perm): add_field_error( form, cfield.name, _('Category not permitted') )
def clean(self, value): cvalue = super(CategoryChoiceField, self).clean(value) return cvalue # TODO unable to realize if field was modified or not (when user has view permission a hits Save.) # Permissions checks are placed in FormSets for now. CategoryChoiceField restricts category # choices at the moment. # next part is category-based permissions (only for objects with category field) # attempt: to do role-permission checks here (add new and change permissions checking) # Adding new object #TODO check wheter field was modified or not. add_perm = get_permission('add', self.model) if not has_category_permission(self.user, cvalue, add_perm): raise ValidationError(_('Category not permitted')) # Changing existing object change_perm = get_permission('change', self.model) if not has_category_permission(self.user, cvalue, change_perm): raise ValidationError(_('Category not permitted')) return cvalue
def test_has_category_permission_permission_not_given(self): tools.assert_false(has_category_permission(self.user, self.nested_first_level_two, 'articles.delete_article'))
def test_has_category_permission_invalid_permission_name(self): tools.assert_false(has_category_permission(self.user, self.nested_second_level_two, 'articles.nonexistent'))
def test_has_category_permission_success(self): tools.assert_true(has_category_permission(self.user, self.nested_second_level_two, 'articles.view_article')) tools.assert_true(has_category_permission(self.user, self.nested_second_level_two, 'articles.add_article')) tools.assert_true(has_category_permission(self.user, self.nested_second_level_two, 'articles.change_article')) tools.assert_true(has_category_permission(self.user, self.nested_second_level_two, 'articles.delete_article'))
def test_has_category_permission_permission_not_given(self): tools.assert_false( has_category_permission(self.user, self.nested_first_level_two, 'articles.delete_article'))
def test_has_category_permission_invalid_permission_name(self): tools.assert_false( has_category_permission(self.user, self.nested_second_level_two, 'articles.nonexistent'))