vittoriozamboni / django-groups-manager

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

Group membership in descendants #65

Closed raulsperoni closed 2 years ago

raulsperoni commented 2 years ago

Hello, I'm trying to build a test that checks permissions and memberships as I'm still trying to understand how I will use this permissions. I have custom Member and Group (app core):

class Usuario(Member):
    ...

    class Meta:
        verbose_name = "Usuario"
        verbose_name_plural = "Usuarios"
class Organizacion(Group):

      ....

      class Meta:
          verbose_name = "Organizacion"
          verbose_name_plural = "Organizaciones"

     class GroupsModelMeta:
            model_name = 'core.Usuario'

And the (simplified) test is:

# Prep
org = Organizacion.objects.create(name="org")
org_child = Organizacion.objects.create(name="org_child", parent=org)
org_grand_child = Organizacion.objects.create(name="org_grand_child", parent=org_child)

user1 = Usuarios.objects.create(username="user1")
org.add_member(user1)
user2 = Usuarios.objects.create(username="user2")
org_child.add_member(user2)
user3 = Usuarios.objects.create(username="user3")
org_grand_child.add_member(user3)

# Test Membership
self.assertTrue(user_1 in org.members) 

self.assertTrue(user_2 in org_child.members)
self.assertTrue(user_2 in org.members)

self.assertTrue(user_3 in org_grand_child.members)
self.assertTrue(user_3 in org_child.members)
self.assertTrue(user_3 in org.members)

All asserts fails here as members are instances of Member and not Usuario. If I use this instead:

class Organizacion(Group):

      ....

      class Meta:
          verbose_name = "Organizacion"
          verbose_name_plural = "Organizaciones"

       class GroupsManagerMeta:
            member_model = "core.Usuario"

users are of instance Usuario in the main Organizacion but not in it's children.

Any ideas? Thank you!

vittoriozamboni commented 2 years ago

Hi @raulsperoni , thank you for the code snippet and example. I see your intent now.

To make it work properly (with the first configuration), you need to assert the member pointer:

self.assertTrue(user_3.member_ptr in org_grand_child.members)

To make it work via the Usuario model instead you need to write your own OrganisacionGroupMember subclassing from GroupMemberMixin, so you can override the member foreign key to point to your model.

This works with Proxies as well.

raulsperoni commented 2 years ago

oh I see now. Thank you!

Do you think there's any advantage or need for me to subclass GroupMember? I only care about correct permissions, I don't need any further fields in membership.

thanks

vittoriozamboni commented 2 years ago

Then no, I wouldn't do it! If you are starting a big project and you know you might require them in the future, setting this up now would save you a couple of migrations in the future, but if you think it will not be relevant then you can just use the .member_ptr.

raulsperoni commented 2 years ago

Thank you!