No hay problema, debe crear dichos permisos e implementar manualmente el control de acceso con el soporte de django-guardian.
¿Control de acceso como?
¿Cómo puedo implementar esta funcionalidad?
Django-guardian es una biblioteca de control de acceso para cualquier objeto. Tal objeto también puede ser grupos. Ver control de acceso en proyecto de ejemplo. Consulte https://github.com/django-guardian/django-guardian/blob/devel/example_project/articles/views.py#L35 .
¡Perfecto!
Este es mi código de fragmento:
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)
Necesito tener permiso para agregar / eliminar para todos los usuarios del grupo.
No sé dónde tienes un problema. Necesitas algo como:
class ProtectedGroupUpdateView(PermissionRequiredMixin, GroupUpdateView):
permission_required = ['change_group', ]
...
y asignar permiso al grupo cuando se crea.
Intenté agregar el permiso "se puede agregar un miembro", pero es posible para todos los grupos y no para el personal.
No estoy seguro de a qué te refieres. Los privilegios de django-guardian siempre se otorgan a usuarios o grupos de usuarios. No es posible otorgar privilegios basados en roles o condiciones especiales. Si desea otorgar a los miembros del personal permiso para administrar el grupo "X", cree un grupo "Personal", agregue miembros del personal, agregue el grupo "X" y otorgue al grupo "Personal" el permiso para administrar "X" grupo.
Necesitaría un usuario que pertenezca a un grupo
"X" se puede agregar o quitar solo para el grupo "X", lamentablemente ahora no es así si tienes el permiso "puedes agregar usuarios" puedes hacerlo para todos los grupos y no para el de aprendiz.
Perdón por mi mal ingles
Desafortunadamente, no puedo entender sus expectativas. Examine el proyecto de ejemplo con atención. Esto debería ser suficiente en tal caso.
"X" can add or remove only for group "X"
significa:
De hecho, necesito asegurarme de que un usuario que pertenece a un grupo "x" pueda agregar o eliminar solo otros usuarios de su propio grupo
@ Allan-Nava, Los privilegios de django-guardian siempre se otorgan a usuarios o grupos de usuarios. No es posible otorgar privilegios basados en roles o condiciones especiales. Si desea que los usuarios administren sus grupos, otorgue permiso al grupo para administrar ese grupo como un objeto.
¿Entiende cómo asignar y verificar el permiso de grupo "X" para administrar el grupo "X"?
Debería ser como netflix (pero todos los miembros tienen la posibilidad de iniciar sesión): cada usuario debe tener un grupo personal donde pueda agregar o eliminar usuarios según lo que prefiera. El problema es que si le das este permiso agrega usuarios, y esto influye en todos los demás grupos, no en los usuarios que pertenecen a ese
El problema es que si le das este permiso agrega usuarios, y esto influye en todos los demás grupos, no en los usuarios que pertenecen a ese
Definitivamente no es cierto. Esta oración es cierta para el núcleo de Django. Si está utilizando el permiso correcto de Django-guardian otorgado al grupo de administración X para el grupo X, aplique solo al grupo X. Al igual que en un proyecto de ejemplo, otorgar el derecho de administrar un artículo en particular no significa que otros artículos puedan ser editados. por ese usuario.
Quiero crear un permiso único que permita a todos los usuarios agregar otras personas a su grupo de membresía. Cada vez que creo un nuevo usuario, con su grupo de membresía 'X', quiero que se cree un nuevo permiso, llamado 'Puede agregar un grupo para X', y ese permiso debe tener el grupo 'X' como objeto.
Como esto:
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 es la creación de mil permisos. assign_perm('manage_group',group,group)
o assign_perm('manage_group',user,group)
debería ser suficiente. El resto es para validar si el usuario tiene la autoridad para administrar un grupo en particular.
Ok, perfecto, pero en la vista de templare, ¿cómo puedo comprobar?
{{perms.groups_manager.canaddmemberx2}}
@ Allan-Nava, nuevamente, examine cuidadosamente el proyecto de ejemplo, especialmente las plantillas y RTFD .
@ ad-m Ok, gracias, entonces mi código de fragmento:
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 Probé este código, pero obtuve una excepción.
#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, ¿qué no le queda claro en el mensaje de error?
@ ad-m
Tengo este error:
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, ¿qué no le queda claro en el mensaje de error?
@ ad-m No entiendo dónde está el problema
@ Allan-Nava, no existe este tipo de permiso. Lea los documentos sobre qué permiso existe .
Ok, leí, pero necesito crear N permisos para N grupos / usuarios cuando creo un nuevo usuario.
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 se dijo antes:
Anormal es la creación de mil permisos.
Un permiso por tipo de acción.
Ok, pero ¿cómo puedo crear el permiso general?
Como dijo Django core docs. Vinculado arriba.
Ok, uso el Administrador de grupos de Django:
Este es mi 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'),
)
Y este es mi 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 es para la administración de permisos de un solo objeto, por lo tanto, otorgue permiso de un solo usuario / grupo a un solo objeto.
Ok, perfecto, pero todavía no funciona, aunque agregué el permiso en el grupo de modelos
¿Qué no funciona?
Esta línea:
#Assign permission for the groups
assign_perm('can_add_member_custom', instance, group)
print("assign_perm('can_add_member_custom', instance, group)")
instancia es el objeto de usuario pero agrego en el modelo de grupo el permiso
# this is just required for easy explanation
class Meta(GroupMixin.Meta):
abstract = False
permissions = (
('can_add_member_custom', 'Can Add Member Custom'),
)
Usé este
Soy estúpido, tengo que hacer migraciones y migrar:
python3 manage.py makemigrations
python3 manage.py migrate
Gracias por la paciencia 👍 @ ad-m
Pero en la vista de plantilla, ¿cómo puedo verificar?
esta:
jack.has_perm('change_group', admins)
Con django shell funciona: