Não tem problema, você tem que criar tais permissões e implementar manualmente o controle de acesso com o suporte do django-guardian.
Como o controle de acesso?
Como posso implementar essa funcionalidade?
Django-guardian é uma biblioteca de controle de acesso para qualquer objeto. Esses objetos também podem ser grupos. Veja controle de acesso no projeto de exemplo. Consulte https://github.com/django-guardian/django-guardian/blob/devel/example_project/articles/views.py#L35 .
Perfeito!
Este é o meu código de snippet:
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)
Preciso ter permissão para adicionar / remover para todos os usuários do grupo.
Eu não sei onde você tem um problema. Você precisa de algo como:
class ProtectedGroupUpdateView(PermissionRequiredMixin, GroupUpdateView):
permission_required = ['change_group', ]
...
e atribuir permissão ao grupo quando criado.
Tentei adicionar a permissão "pode adicionar membro", mas é possível para todos os grupos e não para a equipe.
Eu não tenho certeza do que você quer dizer. Os privilégios django-guardian são sempre concedidos a usuários ou grupos de usuários. Não é possível conceder privilégios com base na função ou condições especiais. Se você deseja conceder permissão aos membros da equipe para gerenciar o grupo "X", crie um grupo "Equipe", adicione membros da equipe a ele, adicione o grupo "X" e dê ao grupo "Equipe" a permissão para gerenciar "X" grupo.
Eu precisaria de um usuário que pertencesse a um grupo
"X" pode adicionar ou remover apenas para o grupo "X", infelizmente agora não é mais assim se você tiver a permissão "você pode adicionar usuários" pode fazer isso para todos os grupos e não para o de aprendiz.
Desculpe pelo meu ingles ruim
Infelizmente, não consigo entender suas expectativas. Examine o projeto de exemplo com cuidado. Isso deve ser suficiente em tal caso.
"X" can add or remove only for group "X"
significa:
Na verdade, preciso ter certeza de que um usuário que pertence a um grupo "x" seria capaz de adicionar ou remover apenas outros usuários de seu próprio grupo
@ Allan-Nava, Os privilégios django-guardian são sempre concedidos a usuários ou grupos de usuários. Não é possível conceder privilégios com base na função ou condições especiais. Se você deseja que os usuários gerenciem seus grupos, dê permissão ao grupo para gerenciá-lo como um objeto.
Você sabe como atribuir e verificar a permissão do grupo "X" para gerenciar o grupo "X"?
Deve ser como o netflix (mas todos os membros têm possibilidade de fazer o login): cada usuário deve ter um grupo pessoal onde pode adicionar ou remover usuários de acordo com sua preferência. O problema é que se você der essa permissão, adicione usuários, e isso influencia todos os outros grupos, não os usuários que pertencem a esse
O problema é que se você der essa permissão, adicione usuários, e isso influencia todos os outros grupos, não os usuários que pertencem a esse
Definitivamente não é verdade. Esta frase é verdadeira para o núcleo do Django. Se você estiver usando a permissão Django-guardian correta concedida ao grupo de gerenciamento X para o grupo X se aplica apenas ao grupo X. Assim como em um projeto de exemplo, conceder o direito de gerenciar um artigo específico não significa que outros artigos possam ser editados por esse usuário.
Quero criar uma única permissão que permita a todos os usuários adicionar outras pessoas ao seu grupo de associação. Cada vez que crio um novo usuário, com seu grupo de associação 'X', quero que uma nova permissão seja criada, chamada 'Pode adicionar grupo para X', e essa permissão deve ter o grupo 'X' como objeto.
Assim:
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)
Anormal é a criação de mil permissões. assign_perm('manage_group',group,group)
ou assign_perm('manage_group',user,group)
deve ser o suficiente. O resto é validar se o usuário tem autoridade para gerenciar um determinado grupo.
Ok perfeito, mas na visualização do templare, como posso verificar?
{{perms.groups_manager.canaddmemberx2}}
@ ad-m Ok, obrigado, então meu código de snippet:
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 Tentei este código, mas encontrei uma exceção.
#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)")
@ Allan-Nava, o que não está claro para você na mensagem de erro?
@ ad-m
Eu tenho este bug:
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
@ Allan-Nava, o que não está claro para você na mensagem de erro?
@ ad-m não entendo onde está o problema
@ Allan-Nava, não existe esse tipo de permissão. Leia a documentação sobre as permissões existentes .
Ok, li, mas preciso criar permissão N para grupos / usuários N quando crio um novo usuário?
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,
)
Como disse antes:
Anormal é a criação de mil permissões.
Uma permissão por tipo de ação.
Ok, mas como posso criar a permissão geral?
Como a documentação principal do Django disse. Vinculado acima.
Ok, eu uso o Django Groups Manager:
Este é o meu grupo modelo:
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'),
)
E este é o meu perfil de modelo:
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 é por gerenciamento de permissão de objeto único, então conceda permissão de usuário / grupo único para objeto único.
Ok, perfeito, mas ainda não está funcionando, embora eu tenha adicionado a permissão no grupo do modelo
O que não funciona?
Está linha:
#Assign permission for the groups
assign_perm('can_add_member_custom', instance, group)
print("assign_perm('can_add_member_custom', instance, group)")
instância é o objeto de usuário, mas adiciono ao modelo de grupo a permissão
# this is just required for easy explanation
class Meta(GroupMixin.Meta):
abstract = False
permissions = (
('can_add_member_custom', 'Can Add Member Custom'),
)
Eu usei este django-groups-manager
Eu sou estúpido, tenho que fazer migrações e migrar:
python3 manage.py makemigrations
python3 manage.py migrate
Obrigado pela paciência 👍 @ ad-m
Mas na visualização do modelo, como posso verificar?
isto:
jack.has_perm('change_group', admins)
Com django shell funciona: