Django-guardian: Добавить / удалить участника только для определенной группы

Созданный на 20 нояб. 2017  ·  35Комментарии  ·  Источник: django-guardian/django-guardian

Привет, мне нужно иметь разрешение, которое позволяет пользователям определенной группы добавлять, удалять или удалять только для принадлежащей группе.

Все 35 Комментарий

Нет проблем, вам нужно создать такие разрешения и вручную реализовать контроль доступа с поддержкой django-guardian.

Контроль доступа нравится?

Как я могу реализовать эту функцию?

Django-guardian - это библиотека контроля доступа для любого объекта. Таким объектом также могут быть группы. См. Контроль доступа в примере проекта. См. Https://github.com/django-guardian/django-guardian/blob/devel/example_project/articles/views.py#L35 .

Идеально!

Это мой фрагмент кода:

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)

Мне нужно иметь разрешение на добавление / удаление для всех пользователей группы.

Не знаю, где у вас проблема. Вам понадобится что-то вроде:

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

и назначить разрешение группе при создании.

Я попытался добавить разрешение «может добавить участника», но это возможно для всех групп, а не для персонала.

Я не понимаю, что вы имеете в виду. Привилегии django-guardian всегда предоставляются пользователям или группам пользователей. Невозможно предоставить привилегии на основе ролей или особых условий. Если вы хотите предоставить сотрудникам разрешение на управление группой «X», создайте группу «Персонал», добавьте в нее сотрудников, добавьте группу «X» и дайте группе «Персонал» разрешение на управление «X» группа.

Мне нужен пользователь, который принадлежит к группе
«X» может добавлять или удалять только для группы «X», к сожалению, сейчас это не так, если у вас есть разрешение «вы можете добавлять пользователей», вы можете делать это для всех групп, а не для ученика.

Извините за мой плохой английский

К сожалению, я не могу понять ваших ожиданий. Внимательно изучите пример проекта . В таком случае этого должно быть достаточно.

"X" can add or remove only for group "X" означает:

  1. создать группу X,
  2. добавить участников группы X
  3. назначить группе X разрешение на управление группой X.

Мне действительно нужно убедиться, что пользователь, принадлежащий к группе "x", сможет добавлять или удалять только других пользователей из своей группы.

@ Allan-Nava, привилегии django-guardian всегда предоставляются пользователям или группам пользователей. Невозможно предоставить привилегии на основе ролей или особых условий. Если вы хотите, чтобы пользователи управляли своими группами, дайте группе разрешение управлять этой группой как объектом.

Вы понимаете, как назначить и проверить разрешение группы «X» для управления группой «X»?

Это должно быть похоже на netflix (но у всех участников есть возможность войти в систему): у каждого пользователя должна быть личная группа, в которой он может добавлять или удалять пользователей в зависимости от того, что он предпочитает. Проблема в том, что если вы дадите это разрешение, добавьте пользователей, и это повлияет на все другие группы, а не на пользователей, которые принадлежат к этой.

Проблема в том, что если вы дадите это разрешение, добавьте пользователей, и это повлияет на все другие группы, а не на пользователей, которые принадлежат к этой.

Это определенно неправда. Это предложение верно для ядра Django. Если вы используете правильное разрешение Django-guardian, предоставленное группе управления X для группы X, применяется только к группе X. Как и в примере проекта, предоставление права на управление определенной статьей не означает, что другие статьи можно редактировать. этим пользователем.

Я хочу создать единое разрешение, которое позволяет всем пользователям добавлять других людей в свою группу членства. Каждый раз, когда я создаю нового пользователя с его группой членства «X», я хочу, чтобы было создано новое разрешение под названием «Может добавлять группу для X», и это разрешение должно иметь группу «X» в качестве объекта.

Нравится:

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)



Ненормальным является создание тысячи разрешений. assign_perm('manage_group',group,group) или assign_perm('manage_group',user,group) должно хватить. Остальное - проверить, есть ли у пользователя полномочия на управление определенной группой.

Хорошо, отлично, но как я могу проверить в режиме просмотра Templare?

{{perms.groups_manager.canaddmemberx2}}

@ Allan-Nava, опять же, внимательно изучите пример проекта, особенно шаблоны и RTFD .

@ ad-m Хорошо, спасибо, мой фрагмент кода:

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 Я пробовал этот код, но у меня возникла исключительная ситуация.

#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, что вам непонятно в сообщении об ошибке?

@ ad-m
У меня такая ошибка:

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, что вам непонятно в сообщении об ошибке?

@ ad-m Я не понимаю, в чем проблема

@ Allan-Nava, такого разрешения нет. Прочтите документы, какие разрешения существуют .

Хорошо, я прочитал, но мне нужно создать разрешение N для N групп / пользователей при создании нового пользователя?

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,
)

Как было сказано ранее :

Ненормальным является создание тысячи разрешений.

Одно разрешение для каждого типа действия.

Как было сказано ранее:
Ненормальным является создание тысячи разрешений.
Одно разрешение для каждого типа действия.

Хорошо, но как я могу создать общее разрешение?

Как сказано в основных документах Django. Связано выше.

Хорошо, я использую Django Groups Manager:

Это моя модельная группа :

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'),
        )

А это мой профиль модели:

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 - это управление разрешениями для одного объекта, поэтому предоставьте разрешение одному пользователю / группе для одного объекта.

Хорошо, отлично, но все еще не работает, хотя я добавил разрешение в группе моделей

Что не работает?

Эта строка:

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

instance - это объект пользователя, но я добавляю в модель Group разрешение

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

Я использовал этот django-groups-manager

Я тупой, мне нужно делать миграции и мигрировать:

python3 manage.py makemigrations
python3 manage.py migrate

Спасибо за терпение 👍 @ ad-m

Но как я могу проверить в представлении шаблона?
это:
jack.has_perm('change_group', admins)

С оболочкой django это работает:
screen shot 2017-11-21 at 16 42 17

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

brianmay picture brianmay  ·  16Комментарии

ad-m picture ad-m  ·  13Комментарии

BenDevelopment picture BenDevelopment  ·  5Комментарии

lukaszb picture lukaszb  ·  14Комментарии

Dzejkob picture Dzejkob  ·  28Комментарии