vittoriozamboni / django-groups-manager

Manage django groups collection based on django-mptt.
MIT License
100 stars 23 forks source link

How can I adjust the page permission according to the member role? #40

Closed trueman61 closed 4 years ago

trueman61 commented 4 years ago

I can set the page permission according to the user in the group in the decorator below. So how can I set this up for the member's role? Thus, only the member with this role can see the page. I'm waiting for your help.

Screenshot

decorators.py

def sahip_only(view_func):
    def wrapper_function(request, *args, **kwargs):
        group = None
        if request.user.groups.exists():
            group = request.member.groups.all()[0].name
        if group == 'PC':
            return redirect('home')
        if group == 'Console':
            return view_func(request, *args, **kwargs)
        else:
            return HttpResponse('You are not authorized to access this page.')
    return wrapper_function

views.py

@login_required(login_url='/accounts/login/')
@sahip_only
def calisan(request):
    queryset = request.user.groups
    form = CalisanForm(request.POST or None, group_qs=queryset)
    if form.is_valid():
        user = form.save()
        group = form.cleaned_data['group']
        user.groups.add(AGroup.objects.get(name=group))
        username = form.cleaned_data['username']
        member = Member.objects.create(first_name=username)
        group = Group.objects.get(name=form.cleaned_data['group'])
        group.add_member(member, [form.cleaned_data.get('roles')])
        user.save()
        password = form.cleaned_data.get('password1')
        new_user = authenticate(username=user.username, password=password)
        return redirect('home')
    return render(request, 'accounts/calisan/calisan.html', {'form': form, 'title': 'Üye Ol'})

forms.py

class CalisanForm(UserCreationForm):
    username = forms.CharField(max_length=100, label='Kullanıcı Adı')
    email = forms.EmailField(max_length=200, help_text='Required')
    password1 = forms.CharField(max_length=100, label='Parola', widget=forms.PasswordInput)
    password2 = forms.CharField(max_length=100, label='Parola Doğrulama', widget=forms.PasswordInput)
    group = forms.ModelChoiceField(queryset=Group.objects.all(), widget=forms.widgets.RadioSelect(), empty_label=None)
    roles = forms.ModelChoiceField(queryset=GroupMemberRole.objects.all(), widget=forms.widgets.RadioSelect(), empty_label=None)

    def __init__(self, *args, **kwargs):
        qs = kwargs.pop("group_qs")
        super().__init__(*args, **kwargs)
        self.fields["group"].queryset = qs

    class Meta:
        model = User
        fields = [
            'username',
            'email',
            'password1',
            'password2',
            'group',
            'roles',
        ]

    def clean_password2(self):
        password1 = self.cleaned_data.get('password1')
        password2 = self.cleaned_data.get('password2')
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Parolalar eşleşmiyor!")
        return password2

    def clean_email(self):
        email = self.cleaned_data.get('email')
        lenghtw = len(User.objects.filter(email=email))
        if lenghtw > 0 :
            raise forms.ValidationError('Bu email adresine sahip bir kullanıcı zaten var.')
        return email
vittoriozamboni commented 4 years ago

If this is the only type of check you need, it can be done with the basic Django permissions, like described here https://docs.djangoproject.com/en/3.0/topics/auth/default/#limiting-access-to-logged-in-users-that-pass-a-test

Your test can be: request.user.groups.filter(name='Role2').exists()

If instead you want keep using this library,I suggest you to read the django guardian documentation to understand the difference between per-object permission and global permissions. It looks like you don’t need permissions for a specific entry, but for an entire view which can be achieved with Django auth models only.

trueman61 commented 4 years ago

Still, Role2 users cannot see the page. The role has no connection with the user. The role assignment depends on the member. So it doesn't depend on the member section?

def sahip_only(view_func):
    def wrapper_function(request, *args, **kwargs):
        group = None
        if request.user.groups.filter(name='Role2').exists():
            group = request.user.groups.all()[0].name
            return view_func(request, *args, **kwargs)
        else:
            return HttpResponse('You are not authorized to access this page.')
    return wrapper_function
vittoriozamboni commented 4 years ago

There are two types of members, this depends on how you setup the library:

The second type of members is not relevant for you I guess as you want to limit the page navigation, hence there must be a django user connected to the member.