首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >django-fsm:不引发异常的权限

django-fsm:不引发异常的权限
EN

Stack Overflow用户
提问于 2017-06-17 01:33:28
回答 1查看 805关注 0票数 4

django-密克罗尼西亚联邦 (有限状态机)中,我得到了基于源和目标规则的转换装饰器.现在我正在尝试添加权限处理。这看起来很简单,但是不管我做什么,都会执行转换,而不管用户的权限或缺乏权限。根据文档,我尝试使用Django权限字符串,并尝试使用lambda。我试过所有这些:

代码语言:javascript
复制
@transition(field=state, source='prog', target='appr', permission='claims.change_claim')

代码语言:javascript
复制
@transition(field=state, source='prog', target='appr', permission=lambda instance, user: not user.has_perm('claims.change_claim'),)

而且,作为一次双重检查,由于permission应该响应任何可调用的返回真假,只需:

代码语言:javascript
复制
@transition(field=state, source='prog', target='appr', permission=False)
def approve(self):

在访问转换时,应该为所有用户引发一个TransitionNotAllowed。但是,即使没有权限的基本用户仍然可以执行转换(claim.approve())。

为了证明我的权限字符串是正确的:

代码语言:javascript
复制
print(has_transition_perm(claim.approve, request.user))

印错了。我正在进行如下验证(针对源/目标的工作):

代码语言:javascript
复制
class ClaimEditForm(forms.ModelForm):
    '''
    Some users can transition claims through allowable states
    '''

    def clean_state(self):
        state = self.cleaned_data['state']
        if state == 'appr':
            try:
                self.instance.approve()
            except TransitionNotAllowed:
                raise forms.ValidationError("Claim could not be approved")
        return state

    class Meta:
        model = Claim
        fields = (
            'state',
        )

视图处理程序是标准的:

代码语言:javascript
复制
if request.method == "POST":
    claim_edit_form = ClaimEditForm(request.POST, instance=claim)
    if claim_edit_form.is_valid():  # Validate transition rules

我遗漏了什么?谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-06-17 15:53:36

问题是,permission属性与源/目标验证器进行不同的验证。您必须评估代码中其他地方在装饰器中建立的权限,而不是装饰器引发的错误。因此,要从表单执行权限验证,您需要传递用户对象,在表单的init中接收用户,然后与has_transition_perm的结果进行比较。因此,这是可行的:

代码语言:javascript
复制
# model
@transition(field=state, source='prog', target='appr', permission='claims.change_claim')
def approve(self):
....

# view
if request.method == "POST":
    claim_edit_form = ClaimEditForm(request.user, request.POST, instance=claim)
        ....

# form
from django_fsm import has_transition_perm

class ClaimEditForm(forms.ModelForm):
    '''
    Some users can transition claims through allowable states
    (see permission property on claim.approve() decorator)
    '''

    def __init__(self, user, *args, **kwargs):
        # We need to pass the user into the form to validate permissions
        self.user = user
        super(ClaimEditForm, self).__init__(*args, **kwargs)

    def clean_state(self):
        state = self.cleaned_data['state']
        if state == 'appr':
            if not has_transition_perm(self.instance.approve, self.user):
                raise forms.ValidationError("You do not have permission for this transition")
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44599963

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档