Django-guardian: Tambah/Hapus anggota hanya untuk grup tertentu

Dibuat pada 20 Nov 2017  ·  35Komentar  ·  Sumber: django-guardian/django-guardian

Hai, saya perlu memiliki izin, yang memungkinkan pengguna grup tertentu untuk menambah, menghapus, atau menghapus hanya untuk grup milik.

Semua 35 komentar

Tidak masalah, Anda harus membuat izin tersebut dan secara manual menerapkan kontrol akses dengan dukungan django-guardian.

Kontrol akses seperti?

Bagaimana saya bisa mengimplementasikan fungsi ini?

Django-guardian adalah perpustakaan kontrol akses untuk objek apapun. Objek tersebut juga dapat berupa kelompok. Lihat kontrol akses dalam proyek contoh. Lihat https://github.com/django-guardian/django-guardian/blob/devel/example_project/articles/views.py#L35 .

Sempurna!

Ini adalah kode cuplikan saya:

def create_user_profile(sender, instance, created, **kwargs):
    print("create_user_profile")
    try:
        print("created: "+ str(created))
        if created:
            Profile.objects.create(user=instance)
            print("Member.objects.get_or_create(django_user=instance)")
            #Create a user into groups_manager_member
            member = Member.objects.create(django_user=instance, first_name=instance.first_name, last_name=instance.last_name, username=instance.username, email=instance.email)
            print("member instance created")
            print(member)
            print("Group.objects.create(name=ID_GROUP+instance.username)")

            #Create a group into groups_manager_group
            group = Group.objects.create(name=ID_GROUP+instance.username)
            print("group instance created")
            print(group)
            #Add member into the group correct
            group.add_member(member=member)
            print("member added into the group correct")

    except Exception as e:
        print("Exception: "+str(e))
        pass


def save_user_profile(sender, instance, **kwargs):
    print("save_user_profile")
    try:
        instance.profile.save()

    except Exception as e:
        print("Exception: "+str(e))
        pass

post_save.connect(create_user_profile, sender=User)
post_save.connect(save_user_profile, sender=User)

Saya perlu memiliki izin untuk menambah/menghapus untuk semua pengguna grup.

Saya tidak tahu di mana Anda memiliki masalah. Anda membutuhkan sesuatu seperti:

class ProtectedGroupUpdateView(PermissionRequiredMixin, GroupUpdateView):
    permission_required = ['change_group', ]
    ...

dan tetapkan izin ke grup saat dibuat.

Saya mencoba menambahkan izin "dapat menambahkan anggota", tetapi memungkinkan untuk semua grup dan bukan untuk staf.

Saya tidak yakin apa yang Anda maksud. Hak istimewa django-guardian selalu diberikan kepada pengguna atau grup pengguna. Tidak mungkin memberikan hak istimewa berdasarkan peran atau kondisi khusus. Jika Anda ingin memberikan izin kepada anggota staf untuk mengelola grup "X", buat grup "Staf", tambahkan anggota staf ke dalamnya, tambahkan grup "X", dan berikan izin kepada grup "Staf" untuk mengelola "X" kelompok.

Saya akan membutuhkan pengguna yang termasuk dalam grup
"X" dapat menambah atau menghapus hanya untuk grup "X", sayangnya sekarang tidak jadi jika Anda memiliki izin "Anda dapat menambahkan pengguna" dapat melakukannya untuk semua grup dan bukan untuk magang.

Maaf untuk bahasa Inggris saya yang buruk

Sayangnya, saya tidak dapat memahami harapan Anda. Periksa proyek contoh dengan hati-hati. Ini harus cukup dalam kasus seperti itu.

"X" can add or remove only for group "X" artinya:

  1. buat grup X,
  2. tambahkan anggota grup X
  3. tetapkan izin grup X untuk mengelola grup X.

Saya benar-benar perlu memastikan bahwa pengguna yang termasuk dalam grup "x" hanya dapat menambah atau menghapus pengguna lain dari grupnya sendiri

@Allan-Nava , Hak istimewa django-guardian selalu diberikan kepada pengguna atau grup pengguna. Tidak mungkin memberikan hak istimewa berdasarkan peran atau kondisi khusus. Jika Anda ingin pengguna mengelola grup mereka, berikan izin kepada grup untuk mengelola grup tersebut sebagai objek.

Apakah Anda memahami cara menetapkan & memeriksa izin grup "X" untuk mengelola grup "X"?

Seharusnya seperti netflix (tetapi semua anggota memiliki kemungkinan untuk masuk): setiap pengguna harus memiliki grup pribadi di mana ia dapat menambah atau menghapus pengguna sesuai dengan keinginannya. Masalahnya adalah jika Anda memberikan izin ini, tambahkan pengguna, dan ini memengaruhi semua grup lain, bukan pengguna yang termasuk dalam grup itu

Masalahnya adalah jika Anda memberikan izin ini, tambahkan pengguna, dan ini memengaruhi semua grup lain, bukan pengguna yang termasuk dalam grup itu

Ini jelas tidak benar. Kalimat ini benar untuk inti Django. Jika Anda menggunakan izin Django-guardian yang benar yang diberikan kepada grup manajemen X untuk grup X hanya berlaku untuk grup X. Sama seperti dalam proyek contoh, memberikan hak untuk mengelola artikel tertentu tidak berarti bahwa artikel lain dapat diedit oleh pengguna itu.

Saya ingin membuat satu izin yang memungkinkan semua pengguna menambahkan orang lain ke grup keanggotaan mereka. Setiap kali saya membuat pengguna baru, dengan grup keanggotaannya 'X', saya ingin izin baru dibuat, yang disebut 'Dapat menambahkan grup untuk X', dan izin itu harus memiliki grup 'X' sebagai objek.

Seperti ini:

def create_user_profile(sender, instance, created, **kwargs):
    print("create_user_profile")
    try:
        print("created: "+ str(created))
        if created:
            Profile.objects.create(user=instance)
            print("Member.objects.get_or_create(django_user=instance)")
            #Create a user into groups_manager_member
            member = Member.objects.create(django_user=instance, first_name=instance.first_name, last_name=instance.last_name, username=instance.username, email=instance.email)
            print("member instance created")
            print(member)
            print("Group.objects.create(name=ID_GROUP+instance.username)")

            #Create a group into groups_manager_group
            group = Group.objects.create(name=ID_GROUP+instance.username)
            print("group instance created")
            print(group)
            #Add member into the group correct
            group.add_member(member=member)
            print("member added into the group correct")
            UserObjectPermission.objects.assign_perm('can_add_member_for_xgroup', member, obj=group)

    except Exception as e:
        print("Exception: "+str(e))
        pass


def save_user_profile(sender, instance, **kwargs):
    print("save_user_profile")
    try:
        instance.profile.save()

    except Exception as e:
        print("Exception: "+str(e))
        pass

post_save.connect(create_user_profile, sender=User)
post_save.connect(save_user_profile, sender=User)



Abnormal adalah penciptaan seribu izin. assign_perm('manage_group',group,group) atau assign_perm('manage_group',user,group) sudah cukup. Sisanya adalah untuk memvalidasi apakah pengguna memiliki wewenang untuk mengelola grup tertentu.

Ok sempurna, tetapi dalam tampilan templare bagaimana saya bisa memeriksanya?

{{ perms.groups_manager.canaddmemberx2}}

@Allan-Nava , sekali lagi, periksa contoh proyek dengan cermat, terutama template dan RTFD .

@ad-m Oke terima kasih, jadi kode cuplikan saya:

from guardian.shortcuts import assign_perm

def create_user_profile(sender, instance, created, **kwargs):
    print("create_user_profile")
    try:
        print("created: "+ str(created))
        if created:
            Profile.objects.create(user=instance)
            print("Member.objects.get_or_create(django_user=instance)")
            #Create a user into groups_manager_member
            member = Member.objects.create(django_user=instance, first_name=instance.first_name, last_name=instance.last_name, username=instance.username, email=instance.email)
            print("member instance created")
            print(member)
            print("Group.objects.create(name=ID_GROUP+instance.username)")

            #Create a group into groups_manager_group
            group = Group.objects.create(name=ID_GROUP+instance.username)
            print("group instance created")
            print(group)
            #Add member into the group correct
            group.add_member(member=member)
            print("member added into the group correct")
            #UserObjectPermission.objects.assign_perm('can_add_member_for_xgroup', member, obj=group)
            assign_perm('groups_manager.can_add_member_custom', member, group)

    except Exception as e:
        print("Exception: "+str(e))
        pass


def save_user_profile(sender, instance, **kwargs):
    print("save_user_profile")
    try:
        instance.profile.save()

    except Exception as e:
        print("Exception: "+str(e))
        pass

post_save.connect(create_user_profile, sender=User)
post_save.connect(save_user_profile, sender=User)

@ad-m Saya mencoba kode ini, tetapi saya mendapat pengecualian.

#Add member into the group correct
            group.add_member(member=member)
            print("member added into the group correct")

            #Assign permission for the groups
            assign_perm('groups_manager.can_add_member_custom', member, group)
            print("assign_perm('groups_manager.can_add_member_custom', member, group)")

screen shot 2017-11-21 at 10 14 30

@Allan-Nava , apa yang tidak jelas bagi Anda dalam pesan kesalahan?

@ad-m
Saya mendapatkan bug ini:

def create_user_profile(sender, instance, created, **kwargs):
    print("create_user_profile")
    try:
        print("created: "+ str(created))
        if created:
            Profile.objects.create(user=instance)
            print("Member.objects.get_or_create(django_user=instance)")
            #Create a user into groups_manager_member
            member = Member.objects.create(django_user=instance, first_name=instance.first_name, last_name=instance.last_name, username=instance.username, email=instance.email)
            print("member instance created")
            print(member)
            print("Group.objects.create(name=ID_GROUP+instance.username)")

            #Create a group into groups_manager_group
            group = Group.objects.create(name=ID_GROUP+instance.username)
            print("group instance created")
            print(group)
            #Add member into the group correct
            group.add_member(member=member)
            print("member added into the group correct")

            #Assign permission for the groups
            assign_perm('groups_manager.can_add_member_custom', instance, group)
            print("assign_perm('groups_manager.can_add_member_custom', instance, group)")

    except Exception as e:
        print("Exception: "+str(e))
        pass

screen shot 2017-11-21 at 12 53 38

@Allan-Nava , apa yang tidak jelas bagi Anda dalam pesan kesalahan?

@ad-m saya tidak mengerti di mana masalahnya

@Allan-Nava , tidak ada izin semacam ini. Baca dokumen izin apa yang ada .

Oke saya baca, tapi saya perlu membuat izin N untuk grup/pengguna N saat saya membuat pengguna baru?

content_type = ContentType.objects.get_for_model(Group)
permission = Permission.objects.create(
    codename='can_add_member_custom',
    name='Can Add Member Custom',
    content_type=content_type,
)

Seperti yang dikatakan sebelumnya :

Abnormal adalah penciptaan seribu izin.

Satu izin per jenis tindakan.

Seperti dikatakan di atas:
Abnormal adalah penciptaan seribu izin.
Satu izin per jenis tindakan.

Ok, tapi bagaimana saya bisa membuat izin umum?

Seperti yang dikatakan dokumen inti Django. Tertaut di atas.

Oke, saya menggunakan Manajer Grup Django:

Ini adalah Grup model saya:

class Group(GroupMixin):

    group_type = models.ForeignKey(GroupType, null=True, blank=True, on_delete=models.SET_NULL,
                                   related_name='%(app_label)s_%(class)s_set')
    group_entities = models.ManyToManyField(GroupEntity, blank=True,
                                            related_name='%(app_label)s_%(class)s_set')

    django_group = models.ForeignKey(DjangoGroup, null=True, blank=True, on_delete=models.SET_NULL)
    group_members = models.ManyToManyField(Member, through='GroupMember',
                                           related_name='%(app_label)s_%(class)s_set')

    # this is just required for easy explanation
    class Meta(GroupMixin.Meta):
        abstract = False
        permissions = (
            ('can_add_member_custom', 'Can Add Member Custom'),
        )

Dan ini adalah Profil model saya:

from __future__ import unicode_literals

import hashlib
import os.path
import urllib

from django.conf import settings
from django.contrib.auth.models import User
from django.db import models
from django.db.models.signals import post_save
from django.utils.encoding import python_2_unicode_compatible

from bootcamp.activities.models import Notification
#Custom class - ParentsProfile
from bootcamp.parents.models import ParentsProfile
#Custom class - MemberMixin TO CREATE INTO groups_manager_member
from bootcamp.groups_manager.models import MemberMixin, Member, Group
#Import django guardian assign_perm
from guardian.shortcuts import assign_perm
#import UserObjectPermission
from guardian.models import UserObjectPermission

import datetime

ID_GROUP = "Group_"

'''
User Model - Authentication
'''
<strong i="12">@python_2_unicode_compatible</strong>
class Profile(models.Model):
    user = models.OneToOneField(User)
    location = models.CharField(max_length=50, null=True, blank=True)
    url = models.CharField(max_length=50, null=True, blank=True)
    job_title = models.CharField(max_length=50, null=True, blank=True)

    #I need to delete the parents application

    #Other tascout attributes
    birthdate = models.DateField(default=datetime.date.today)
    address = models.CharField(max_length=255, null=True, blank=True)
    main_role = models.CharField(max_length=255, null=True, blank=True)
    other_roles = models.CharField(max_length=255, null=True, blank=True)
    mobile = models.CharField(max_length=255, null=True, blank=True)
    background_photo = models.CharField(max_length=255, null=True, blank=True)
    profile_photo = models.CharField(max_length=255, null=True, blank=True)
    biography = models.TextField(null=True, blank=True)
    idols = models.TextField(null=True, blank=True)
    weight = models.IntegerField(default=0)
    height = models.IntegerField(default=0)
    favorite_team = models.CharField(max_length=255, null=True, blank=True)
    level = models.IntegerField(default=0)
    sex = models.CharField(max_length=1, default="M")
    nationality = models.CharField(max_length=255, null=True, blank=True)
    city = models.CharField(max_length=255, null=True, blank=True)
    postal_code = models.CharField(max_length=255, null=True, blank=True)
    province = models.CharField(max_length=255, null=True, blank=True)
    number = models.CharField(max_length=255, null=True, blank=True)
    latitude = models.DecimalField( null=True, blank=True, max_digits=9, decimal_places=6)
    longitude = models.DecimalField( null=True, blank=True, max_digits=9, decimal_places=6)

    class Meta:
        db_table = 'auth_profile'

    def __str__(self):
        return self.user.username

    def get_url(self):
        url = self.url
        if "http://" not in self.url and "https://" not in self.url and len(self.url) > 0:  # noqa: E501
            url = "http://" + str(self.url)

        return url

    def get_picture(self):
        no_picture = settings.MEDIA_URL +'/profile_pictures/user.png'
        try:
            filename = settings.MEDIA_ROOT + '/profile_pictures/' +\
                self.user.username + '.jpg'
            picture_url = settings.MEDIA_URL + 'profile_pictures/' +\
                self.user.username + '.jpg'
            if os.path.isfile(filename):  # pragma: no cover
                return picture_url
            else:  # pragma: no cover
                gravatar_url = 'http://www.gravatar.com/avatar/{0}?{1}'.format(
                    hashlib.md5(self.user.email.lower()).hexdigest(),
                    urllib.urlencode({'d': no_picture, 's': '256'})
                    )
                return gravatar_url

        except Exception:
            return no_picture

    #Retrieve users' cover
    def get_cover(self):
        no_cover = settings.MEDIA_ROOT +'profile_covers/cover.jpg'
        try:
            filename = settings.MEDIA_ROOT + '/profile_covers/' +\
                self.user.username + '.jpg'
            cover_url = settings.MEDIA_URL + 'profile_covers/' +\
                self.user.username + '.jpg'
            if os.path.isfile(filename) and os.path.exists(filename):  # pragma: no cover
                if cover_url != None:
                    return cover_url
                else:
                    return no_cover
            else:
                no_cover
        except Exception:
            return no_cover

    def get_screen_name(self):
        try:
            if self.user.get_full_name():
                return self.user.get_full_name()
            else:
                return self.user.username
        except:
            return self.user.username

    def notify_liked(self, feed):
        if self.user != feed.user:
            Notification(notification_type=Notification.LIKED,
                         from_user=self.user, to_user=feed.user,
                         feed=feed).save()

    def unotify_liked(self, feed):
        if self.user != feed.user:
            Notification.objects.filter(notification_type=Notification.LIKED,
                                        from_user=self.user, to_user=feed.user,
                                        feed=feed).delete()

    def notify_commented(self, feed):
        if self.user != feed.user:
            Notification(notification_type=Notification.COMMENTED,
                         from_user=self.user, to_user=feed.user,
                         feed=feed).save()

    def notify_also_commented(self, feed):
        comments = feed.get_comments()
        users = []
        for comment in comments:
            if comment.user != self.user and comment.user != feed.user:
                users.append(comment.user.pk)

        users = list(set(users))
        for user in users:
            Notification(notification_type=Notification.ALSO_COMMENTED,
                         from_user=self.user,
                         to_user=User(id=user), feed=feed).save()

    def notify_favorited(self, question):
        if self.user != question.user:
            Notification(notification_type=Notification.FAVORITED,
                         from_user=self.user, to_user=question.user,
                         question=question).save()

    def unotify_favorited(self, question):
        if self.user != question.user:
            Notification.objects.filter(
                notification_type=Notification.FAVORITED,
                from_user=self.user,
                to_user=question.user,
                question=question).delete()

    def notify_answered(self, question):
        if self.user != question.user:
            Notification(notification_type=Notification.ANSWERED,
                         from_user=self.user,
                         to_user=question.user,
                         question=question).save()

    def notify_accepted(self, answer):
        if self.user != answer.user:
            Notification(notification_type=Notification.ACCEPTED_ANSWER,
                         from_user=self.user,
                         to_user=answer.user,
                         answer=answer).save()

    def unotify_accepted(self, answer):
        if self.user != answer.user:
            Notification.objects.filter(
                notification_type=Notification.ACCEPTED_ANSWER,
                from_user=self.user,
                to_user=answer.user,
                answer=answer).delete()

def create_user_profile(sender, instance, created, **kwargs):
    print("create_user_profile")
    try:
        print("created: "+ str(created))
        if created:
            Profile.objects.create(user=instance)
            print("Member.objects.get_or_create(django_user=instance)")
            #Create a user into groups_manager_member
            member = Member.objects.create(django_user=instance, first_name=instance.first_name, last_name=instance.last_name, username=instance.username, email=instance.email)
            print("member instance created")
            print(member)
            print("Group.objects.create(name=ID_GROUP+instance.username)")

            #Create a group into groups_manager_group
            group = Group.objects.create(name=ID_GROUP+instance.username)
            print("group instance created")
            print(group)
            #Add member into the group correct
            group.add_member(member=member)
            print("member added into the group correct")

            #Assign permission for the groups
            assign_perm('can_add_member_custom', instance, group)
            #print("assign_perm('can_add_member_custom', instance, group)")

    except Exception as e:
        print("Exception: "+str(e))
        pass


def save_user_profile(sender, instance, **kwargs):
    print("save_user_profile")
    try:
        instance.profile.save()

    except Exception as e:
        print("Exception: "+str(e))
        pass

post_save.connect(create_user_profile, sender=User)
post_save.connect(save_user_profile, sender=User)

Django-guardian adalah per manajemen izin objek tunggal, jadi berikan izin pengguna/grup tunggal ke objek tunggal.

Ok sempurna, tetapi masih tidak berfungsi meskipun saya menambahkan izin dalam model Grup

Apa yang tidak berfungsi?

Garis ini:

#Assign permission for the groups
            assign_perm('can_add_member_custom', instance, group)
            print("assign_perm('can_add_member_custom', instance, group)")

instance adalah objek pengguna tetapi saya menambahkan izin ke model Grup

# this is just required for easy explanation
    class Meta(GroupMixin.Meta):
        abstract = False
        permissions = (
            ('can_add_member_custom', 'Can Add Member Custom'),
        )

Saya menggunakan django-groups-manager ini

Saya bodoh, saya harus bermigrasi dan bermigrasi:

python3 manage.py makemigrations
python3 manage.py migrate

Terima kasih atas kesabarannya 👍 @ad-m

Tetapi dalam tampilan template, bagaimana saya bisa memeriksanya?
ini:
jack.has_perm('change_group', admins)

Dengan Django Shell berfungsi:
screen shot 2017-11-21 at 16 42 17

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

xuhcc picture xuhcc  ·  10Komentar

johnthagen picture johnthagen  ·  9Komentar

g-as picture g-as  ·  10Komentar

brianmay picture brianmay  ·  16Komentar

Dzejkob picture Dzejkob  ·  28Komentar