From 68daa548609245688ed390e5ee794dca21d22f76 Mon Sep 17 00:00:00 2001 From: Henrique Pozzolini Date: Mon, 11 Nov 2024 21:31:39 -0300 Subject: [PATCH 01/11] BA-1779-be-multiple-profiles-member-list --- .../baseapp_profiles/graphql/object_types.py | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/baseapp-profiles/baseapp_profiles/graphql/object_types.py b/baseapp-profiles/baseapp_profiles/graphql/object_types.py index 9f39f558..24bf3bc4 100644 --- a/baseapp-profiles/baseapp_profiles/graphql/object_types.py +++ b/baseapp-profiles/baseapp_profiles/graphql/object_types.py @@ -9,7 +9,7 @@ ) from baseapp_pages.meta import AbstractMetadataObjectType from django.apps import apps -from django.db.models import Q +from django.db.models import Q, Case, When, Value, IntegerField from graphene import relay from graphene_django.filter import DjangoFilterConnectionField @@ -20,7 +20,6 @@ ProfileRoleTypesEnum = graphene.Enum.from_enum(ProfileUserRole.ProfileRoles) ProfileRoleStatusTypesEnum = graphene.Enum.from_enum(ProfileUserRole.ProfileRoleStatus) - class BaseProfileUserRoleObjectType: role = graphene.Field(ProfileRoleTypesEnum) status = graphene.Field(ProfileRoleStatusTypesEnum) @@ -94,8 +93,10 @@ class BaseProfileObjectType: target = graphene.Field(lambda: ProfileInterface) image = ThumbnailField(required=False) banner_image = ThumbnailField(required=False) - members = DjangoFilterConnectionField(get_object_type_for_model(ProfileUserRole)) - + members = DjangoFilterConnectionField( + get_object_type_for_model(ProfileUserRole), + order_by_status=graphene.String() + ) class Meta: interfaces = interfaces model = Profile @@ -126,10 +127,23 @@ def resolve_metadata(cls, instance, info): return ProfileMetadata(instance, info) @classmethod - def resolve_members(cls, instance, info, **kwargs): + def resolve_members(cls, instance, info, order_by_status=None, **kwargs): if not info.context.user.has_perm("baseapp_profiles.view_profile_members", instance): return instance.members.none() - return instance.members.all() + + members_queryset = instance.members.all() + + if order_by_status == "custom": + status_order = Case( + When(status=ProfileUserRole.ProfileRoleStatus.PENDING.value, then=Value(1)), + When(status=ProfileUserRole.ProfileRoleStatus.INACTIVE.value, then=Value(2)), + When(status=ProfileUserRole.ProfileRoleStatus.ACTIVE.value, then=Value(3)), + default=Value(4), + output_field=IntegerField() + ) + members_queryset = members_queryset.order_by(status_order) + + return members_queryset class ProfileObjectType(DjangoObjectType, BaseProfileObjectType): From ae2fea97c231b94600d95a2fbb7f8230c86f8962 Mon Sep 17 00:00:00 2001 From: Henrique Pozzolini Date: Tue, 12 Nov 2024 22:15:55 -0300 Subject: [PATCH 02/11] isort black and flake8 --- .../baseapp_profiles/graphql/object_types.py | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/baseapp-profiles/baseapp_profiles/graphql/object_types.py b/baseapp-profiles/baseapp_profiles/graphql/object_types.py index 24bf3bc4..67ab47d5 100644 --- a/baseapp-profiles/baseapp_profiles/graphql/object_types.py +++ b/baseapp-profiles/baseapp_profiles/graphql/object_types.py @@ -9,7 +9,7 @@ ) from baseapp_pages.meta import AbstractMetadataObjectType from django.apps import apps -from django.db.models import Q, Case, When, Value, IntegerField +from django.db.models import Case, IntegerField, Q, Value, When from graphene import relay from graphene_django.filter import DjangoFilterConnectionField @@ -20,6 +20,7 @@ ProfileRoleTypesEnum = graphene.Enum.from_enum(ProfileUserRole.ProfileRoles) ProfileRoleStatusTypesEnum = graphene.Enum.from_enum(ProfileUserRole.ProfileRoleStatus) + class BaseProfileUserRoleObjectType: role = graphene.Field(ProfileRoleTypesEnum) status = graphene.Field(ProfileRoleStatusTypesEnum) @@ -94,9 +95,9 @@ class BaseProfileObjectType: image = ThumbnailField(required=False) banner_image = ThumbnailField(required=False) members = DjangoFilterConnectionField( - get_object_type_for_model(ProfileUserRole), - order_by_status=graphene.String() + get_object_type_for_model(ProfileUserRole), order_by_status=graphene.String() ) + class Meta: interfaces = interfaces model = Profile @@ -132,15 +133,15 @@ def resolve_members(cls, instance, info, order_by_status=None, **kwargs): return instance.members.none() members_queryset = instance.members.all() - + if order_by_status == "custom": status_order = Case( - When(status=ProfileUserRole.ProfileRoleStatus.PENDING.value, then=Value(1)), - When(status=ProfileUserRole.ProfileRoleStatus.INACTIVE.value, then=Value(2)), - When(status=ProfileUserRole.ProfileRoleStatus.ACTIVE.value, then=Value(3)), - default=Value(4), - output_field=IntegerField() - ) + When(status=ProfileUserRole.ProfileRoleStatus.PENDING.value, then=Value(1)), + When(status=ProfileUserRole.ProfileRoleStatus.INACTIVE.value, then=Value(2)), + When(status=ProfileUserRole.ProfileRoleStatus.ACTIVE.value, then=Value(3)), + default=Value(4), + output_field=IntegerField(), + ) members_queryset = members_queryset.order_by(status_order) return members_queryset From 92fc886b48d0b66e671a6b77a6f3b9e0652dbab7 Mon Sep 17 00:00:00 2001 From: Henrique Pozzolini Date: Thu, 28 Nov 2024 14:08:25 -0300 Subject: [PATCH 03/11] BA-1863-be-multiple-profiles-edit-member-role --- .../baseapp_profiles/graphql/mutations.py | 36 ++++++ .../baseapp_profiles/permissions.py | 14 ++- .../tests/test_graphql_mutations_update.py | 117 +++++++++++++++++- 3 files changed, 165 insertions(+), 2 deletions(-) diff --git a/baseapp-profiles/baseapp_profiles/graphql/mutations.py b/baseapp-profiles/baseapp_profiles/graphql/mutations.py index 458a2ec6..cc125a25 100644 --- a/baseapp-profiles/baseapp_profiles/graphql/mutations.py +++ b/baseapp-profiles/baseapp_profiles/graphql/mutations.py @@ -112,7 +112,42 @@ def perform_mutate(cls, serializer, info): errors=None, profile=ProfileObjectType._meta.connection.Edge(node=obj), ) + +RoleTypeEnum = graphene.Enum.from_enum(ProfileUserRole.ProfileRoles) +class RoleUpdate(RelayMutation): + profile_user_role = graphene.Field(get_object_type_for_model(ProfileUserRole)) + class Input: + profile_id = graphene.ID(required=True) + user_id = graphene.ID(required=True) + role_type = graphene.Field(RoleTypeEnum) + + @classmethod + @login_required + def mutate_and_get_payload(cls, root, info, **input): + user_id = input.get("user_id") + profile_id = input.get("profile_id") + role_type = input.get("role_type") + user_pk = get_pk_from_relay_id(user_id) + profile_pk = get_pk_from_relay_id(profile_id) + + + try: + obj = ProfileUserRole.objects.get(user_id=user_pk, profile_id=profile_pk) + except ProfileUserRole.DoesNotExist: + raise ValueError(_("Role not found")) + + if not info.context.user.has_perm("baseapp_profiles.change_profileuserrole", obj.profile): + raise GraphQLError( + str(_("You don't have permission to perform this action")), + extensions={"code": "permission_required"}, + ) + + obj.role = role_type + obj.save() + + return RoleUpdate(profile_user_role=obj) + class ProfileUpdate(SerializerMutation): profile = graphene.Field(get_object_type_for_model(Profile)) @@ -197,3 +232,4 @@ class ProfilesMutations(object): # profile_create = ProfileCreate.Field() profile_update = ProfileUpdate.Field() profile_delete = ProfileDelete.Field() + role_update = RoleUpdate.Field() diff --git a/baseapp-profiles/baseapp_profiles/permissions.py b/baseapp-profiles/baseapp_profiles/permissions.py index 1d7b32ec..d6914284 100644 --- a/baseapp-profiles/baseapp_profiles/permissions.py +++ b/baseapp-profiles/baseapp_profiles/permissions.py @@ -1,9 +1,9 @@ import swapper from django.contrib.auth.backends import BaseBackend +from .models import ProfileUserRole Profile = swapper.load_model("baseapp_profiles", "Profile") - class ProfilesPermissionsBackend(BaseBackend): def has_perm(self, user_obj, perm, obj=None): if perm == "baseapp_profiles.view_profile": @@ -18,6 +18,7 @@ def has_perm(self, user_obj, perm, obj=None): obj.owner_id == user_obj.id or obj.members.filter(user_id=user_obj.id).exists() ) + if perm in ["baseapp_profiles.change_profile", "baseapp_profiles.delete_profile"]: if user_obj.is_authenticated and isinstance(obj, Profile): @@ -27,16 +28,19 @@ def has_perm(self, user_obj, perm, obj=None): # Anyone with permission can change and delete any profile return user_obj.has_perm(perm) + if perm == "baseapp_profiles.use_profile" and obj: if isinstance(obj, Profile): return ( obj.owner_id == user_obj.id or obj.members.filter(user_id=user_obj.id).exists() ) + if perm == "baseapp_profiles.delete_profile" and obj: if isinstance(obj, Profile): return obj.owner_id == user_obj.id + if perm == "baseapp_profiles.view_profile_members" and obj: if isinstance(obj, Profile): @@ -45,3 +49,11 @@ def has_perm(self, user_obj, perm, obj=None): or user_obj.is_superuser or obj.members.filter(user_id=user_obj.id).exists() ) + + + if perm == "baseapp_profiles.change_profileuserrole" and obj: + if isinstance(obj, Profile): + return ( + obj.owner_id == user_obj.id or obj.members.filter(user_id=user_obj.id, role=ProfileUserRole.ProfileRoles.ADMIN).exists() + ) + diff --git a/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py b/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py index eedb81e6..6ddd6358 100644 --- a/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py +++ b/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py @@ -1,10 +1,12 @@ import pytest import swapper +from baseapp_core.tests.factories import UserFactory from baseapp_pages.tests.factories import URLPathFactory from django.contrib.auth.models import Permission from django.test.client import MULTIPART_CONTENT -from .factories import ProfileFactory +from ..models import ProfileUserRole +from .factories import ProfileFactory, ProfileUserRoleFactory pytestmark = pytest.mark.django_db @@ -32,6 +34,49 @@ } """ +# PROFILE_ROLE_UPDATE_GRAPHQL = """ +# mutation ProfileRoleUpdateMutation($input: RoleUpdateInput!) { +# roleUpdate(input: $input) { +# profile { +# id +# members { +# totalCount +# edges { +# node { +# id +# role +# status +# } +# } +# pageInfo { +# endCursor +# hasNextPage +# } +# } +# } +# errors { +# field +# messages +# } +# } +# } +# """ + +PROFILE_ROLE_UPDATE_GRAPHQL = """ +mutation ProfileRoleUpdateMutation($input: RoleUpdateInput!) { + roleUpdate(input: $input) { + profileUserRole { + id + role + status + } + errors { + field + messages + } + } +} +""" def test_anon_cant_update_profile(graphql_client): profile = ProfileFactory() @@ -199,3 +244,73 @@ def test_user_with_permission_can_update_profile(django_user_client, graphql_use assert content["data"]["profileUpdate"]["profile"]["biography"] == new_biography profile.refresh_from_db() assert profile.biography == new_biography + +def test_user_profile_owner_can_update_role(django_user_client, graphql_user_client): + + perm = Permission.objects.get( + content_type__app_label="baseapp_profiles", codename="change_profileuserrole" + ) + + user = django_user_client.user + user_2 = UserFactory() + + user.user_permissions.add(perm) + profile = ProfileFactory(owner=user) + ProfileUserRoleFactory(profile=profile, user=user_2, role=ProfileUserRole.ProfileRoles.MANAGER) + + response = graphql_user_client( + PROFILE_ROLE_UPDATE_GRAPHQL, + variables={"input": {"userId": user_2.relay_id, "profileId": profile.relay_id, "roleType": "ADMIN"}}, + ) + content = response.json() + + assert content["data"]["roleUpdate"]["profileUserRole"]["role"] == "ADMIN" + profile.refresh_from_db() + +def test_user_with_permission_can_update_role(django_user_client, graphql_user_client): + + perm = Permission.objects.get( + content_type__app_label="baseapp_profiles", codename="change_profileuserrole" + ) + + user = django_user_client.user + user.user_permissions.add(perm) + user_2 = UserFactory() + user_3 = UserFactory() + + profile = ProfileFactory(owner=user_2) + ProfileUserRoleFactory(profile=profile, user=user, role=ProfileUserRole.ProfileRoles.ADMIN) + ProfileUserRoleFactory(profile=profile, user=user_3, role=ProfileUserRole.ProfileRoles.MANAGER) + + response = graphql_user_client( + PROFILE_ROLE_UPDATE_GRAPHQL, + variables={"input": {"userId": user_3.relay_id, "profileId": profile.relay_id, "roleType": "ADMIN"}}, + ) + content = response.json() + + assert content["data"]["roleUpdate"]["profileUserRole"]["role"] == "ADMIN" + profile.refresh_from_db() + +def test_user_without_permission_cant_update_role(django_user_client, graphql_user_client): + + perm = Permission.objects.get( + content_type__app_label="baseapp_profiles", codename="change_profileuserrole" + ) + + user = django_user_client.user + user.user_permissions.add(perm) + user_2 = UserFactory() + user_3 = UserFactory() + + profile = ProfileFactory(owner=user_2) + ProfileUserRoleFactory(profile=profile, user=user, role=ProfileUserRole.ProfileRoles.MANAGER) + ProfileUserRoleFactory(profile=profile, user=user_3, role=ProfileUserRole.ProfileRoles.MANAGER) + + response = graphql_user_client( + PROFILE_ROLE_UPDATE_GRAPHQL, + variables={"input": {"userId": user_3.relay_id, "profileId": profile.relay_id, "roleType": "ADMIN"}}, + ) + content = response.json() + print(content) + assert content["errors"][0]["message"] == "You don't have permission to perform this action" + profile.refresh_from_db() From 8809263b3f78f1a7c34325c00bfb2fedf6505d2b Mon Sep 17 00:00:00 2001 From: Henrique Pozzolini Date: Thu, 28 Nov 2024 21:11:13 -0300 Subject: [PATCH 04/11] run isort black and flake8 --- .../baseapp_profiles/graphql/mutations.py | 12 ++--- .../baseapp_profiles/permissions.py | 17 ++++--- .../tests/test_graphql_mutations_update.py | 44 ++++++++++++------- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/baseapp-profiles/baseapp_profiles/graphql/mutations.py b/baseapp-profiles/baseapp_profiles/graphql/mutations.py index cc125a25..f2ce5641 100644 --- a/baseapp-profiles/baseapp_profiles/graphql/mutations.py +++ b/baseapp-profiles/baseapp_profiles/graphql/mutations.py @@ -112,8 +112,11 @@ def perform_mutate(cls, serializer, info): errors=None, profile=ProfileObjectType._meta.connection.Edge(node=obj), ) - + + RoleTypeEnum = graphene.Enum.from_enum(ProfileUserRole.ProfileRoles) + + class RoleUpdate(RelayMutation): profile_user_role = graphene.Field(get_object_type_for_model(ProfileUserRole)) @@ -121,7 +124,7 @@ class Input: profile_id = graphene.ID(required=True) user_id = graphene.ID(required=True) role_type = graphene.Field(RoleTypeEnum) - + @classmethod @login_required def mutate_and_get_payload(cls, root, info, **input): @@ -130,13 +133,12 @@ def mutate_and_get_payload(cls, root, info, **input): role_type = input.get("role_type") user_pk = get_pk_from_relay_id(user_id) profile_pk = get_pk_from_relay_id(profile_id) - try: obj = ProfileUserRole.objects.get(user_id=user_pk, profile_id=profile_pk) except ProfileUserRole.DoesNotExist: raise ValueError(_("Role not found")) - + if not info.context.user.has_perm("baseapp_profiles.change_profileuserrole", obj.profile): raise GraphQLError( str(_("You don't have permission to perform this action")), @@ -147,7 +149,7 @@ def mutate_and_get_payload(cls, root, info, **input): obj.save() return RoleUpdate(profile_user_role=obj) - + class ProfileUpdate(SerializerMutation): profile = graphene.Field(get_object_type_for_model(Profile)) diff --git a/baseapp-profiles/baseapp_profiles/permissions.py b/baseapp-profiles/baseapp_profiles/permissions.py index d6914284..4f62f653 100644 --- a/baseapp-profiles/baseapp_profiles/permissions.py +++ b/baseapp-profiles/baseapp_profiles/permissions.py @@ -1,9 +1,11 @@ import swapper from django.contrib.auth.backends import BaseBackend + from .models import ProfileUserRole Profile = swapper.load_model("baseapp_profiles", "Profile") + class ProfilesPermissionsBackend(BaseBackend): def has_perm(self, user_obj, perm, obj=None): if perm == "baseapp_profiles.view_profile": @@ -18,7 +20,6 @@ def has_perm(self, user_obj, perm, obj=None): obj.owner_id == user_obj.id or obj.members.filter(user_id=user_obj.id).exists() ) - if perm in ["baseapp_profiles.change_profile", "baseapp_profiles.delete_profile"]: if user_obj.is_authenticated and isinstance(obj, Profile): @@ -28,19 +29,16 @@ def has_perm(self, user_obj, perm, obj=None): # Anyone with permission can change and delete any profile return user_obj.has_perm(perm) - if perm == "baseapp_profiles.use_profile" and obj: if isinstance(obj, Profile): return ( obj.owner_id == user_obj.id or obj.members.filter(user_id=user_obj.id).exists() ) - if perm == "baseapp_profiles.delete_profile" and obj: if isinstance(obj, Profile): return obj.owner_id == user_obj.id - if perm == "baseapp_profiles.view_profile_members" and obj: if isinstance(obj, Profile): @@ -49,11 +47,12 @@ def has_perm(self, user_obj, perm, obj=None): or user_obj.is_superuser or obj.members.filter(user_id=user_obj.id).exists() ) - - - if perm == "baseapp_profiles.change_profileuserrole" and obj: + + if perm == "baseapp_profiles.change_profileuserrole" and obj: if isinstance(obj, Profile): return ( - obj.owner_id == user_obj.id or obj.members.filter(user_id=user_obj.id, role=ProfileUserRole.ProfileRoles.ADMIN).exists() + obj.owner_id == user_obj.id + or obj.members.filter( + user_id=user_obj.id, role=ProfileUserRole.ProfileRoles.ADMIN + ).exists() ) - diff --git a/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py b/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py index 6ddd6358..e6e3029d 100644 --- a/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py +++ b/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py @@ -62,7 +62,7 @@ # } # """ -PROFILE_ROLE_UPDATE_GRAPHQL = """ +PROFILE_ROLE_UPDATE_GRAPHQL = """ mutation ProfileRoleUpdateMutation($input: RoleUpdateInput!) { roleUpdate(input: $input) { profileUserRole { @@ -76,7 +76,8 @@ } } } -""" +""" + def test_anon_cant_update_profile(graphql_client): profile = ProfileFactory() @@ -245,70 +246,79 @@ def test_user_with_permission_can_update_profile(django_user_client, graphql_use profile.refresh_from_db() assert profile.biography == new_biography + def test_user_profile_owner_can_update_role(django_user_client, graphql_user_client): - + perm = Permission.objects.get( content_type__app_label="baseapp_profiles", codename="change_profileuserrole" ) - + user = django_user_client.user user_2 = UserFactory() - + user.user_permissions.add(perm) profile = ProfileFactory(owner=user) ProfileUserRoleFactory(profile=profile, user=user_2, role=ProfileUserRole.ProfileRoles.MANAGER) response = graphql_user_client( PROFILE_ROLE_UPDATE_GRAPHQL, - variables={"input": {"userId": user_2.relay_id, "profileId": profile.relay_id, "roleType": "ADMIN"}}, + variables={ + "input": {"userId": user_2.relay_id, "profileId": profile.relay_id, "roleType": "ADMIN"} + }, ) content = response.json() - + assert content["data"]["roleUpdate"]["profileUserRole"]["role"] == "ADMIN" profile.refresh_from_db() + def test_user_with_permission_can_update_role(django_user_client, graphql_user_client): - + perm = Permission.objects.get( content_type__app_label="baseapp_profiles", codename="change_profileuserrole" ) - + user = django_user_client.user user.user_permissions.add(perm) user_2 = UserFactory() user_3 = UserFactory() - + profile = ProfileFactory(owner=user_2) ProfileUserRoleFactory(profile=profile, user=user, role=ProfileUserRole.ProfileRoles.ADMIN) ProfileUserRoleFactory(profile=profile, user=user_3, role=ProfileUserRole.ProfileRoles.MANAGER) response = graphql_user_client( PROFILE_ROLE_UPDATE_GRAPHQL, - variables={"input": {"userId": user_3.relay_id, "profileId": profile.relay_id, "roleType": "ADMIN"}}, + variables={ + "input": {"userId": user_3.relay_id, "profileId": profile.relay_id, "roleType": "ADMIN"} + }, ) content = response.json() - + assert content["data"]["roleUpdate"]["profileUserRole"]["role"] == "ADMIN" profile.refresh_from_db() - + + def test_user_without_permission_cant_update_role(django_user_client, graphql_user_client): - + perm = Permission.objects.get( content_type__app_label="baseapp_profiles", codename="change_profileuserrole" ) - + user = django_user_client.user user.user_permissions.add(perm) user_2 = UserFactory() user_3 = UserFactory() - + profile = ProfileFactory(owner=user_2) ProfileUserRoleFactory(profile=profile, user=user, role=ProfileUserRole.ProfileRoles.MANAGER) ProfileUserRoleFactory(profile=profile, user=user_3, role=ProfileUserRole.ProfileRoles.MANAGER) response = graphql_user_client( PROFILE_ROLE_UPDATE_GRAPHQL, - variables={"input": {"userId": user_3.relay_id, "profileId": profile.relay_id, "roleType": "ADMIN"}}, + variables={ + "input": {"userId": user_3.relay_id, "profileId": profile.relay_id, "roleType": "ADMIN"} + }, ) content = response.json() print(content) From 250d793736f75887fc73e6619926163a92f6a656 Mon Sep 17 00:00:00 2001 From: Henrique Pozzolini Date: Fri, 13 Dec 2024 12:04:11 -0300 Subject: [PATCH 05/11] bump baseapp-profiles version --- .../baseapp_profiles/graphql/mutations.py | 7 ++--- .../baseapp_profiles/graphql/object_types.py | 2 +- .../tests/test_graphql_mutations_update.py | 28 ------------------- baseapp-profiles/setup.cfg | 2 +- 4 files changed, 5 insertions(+), 34 deletions(-) diff --git a/baseapp-profiles/baseapp_profiles/graphql/mutations.py b/baseapp-profiles/baseapp_profiles/graphql/mutations.py index f2ce5641..cd38ade3 100644 --- a/baseapp-profiles/baseapp_profiles/graphql/mutations.py +++ b/baseapp-profiles/baseapp_profiles/graphql/mutations.py @@ -12,6 +12,8 @@ from graphql.error import GraphQLError from rest_framework import serializers +from .object_types import ProfileRoleTypesEnum + Profile = swapper.load_model("baseapp_profiles", "Profile") ProfileUserRole = swapper.load_model("baseapp_profiles", "ProfileUserRole") @@ -114,16 +116,13 @@ def perform_mutate(cls, serializer, info): ) -RoleTypeEnum = graphene.Enum.from_enum(ProfileUserRole.ProfileRoles) - - class RoleUpdate(RelayMutation): profile_user_role = graphene.Field(get_object_type_for_model(ProfileUserRole)) class Input: profile_id = graphene.ID(required=True) user_id = graphene.ID(required=True) - role_type = graphene.Field(RoleTypeEnum) + role_type = graphene.Field(ProfileRoleTypesEnum) @classmethod @login_required diff --git a/baseapp-profiles/baseapp_profiles/graphql/object_types.py b/baseapp-profiles/baseapp_profiles/graphql/object_types.py index 447e3186..817d162b 100644 --- a/baseapp-profiles/baseapp_profiles/graphql/object_types.py +++ b/baseapp-profiles/baseapp_profiles/graphql/object_types.py @@ -131,7 +131,7 @@ def resolve_metadata(cls, instance, info): return ProfileMetadata(instance, info) @classmethod - def resolve_members(cls, instance, info, order_by_status=None, **kwargs): + def resolve_members(cls, instance, info, **kwargs): if not info.context.user.has_perm("baseapp_profiles.view_profile_members", instance): return instance.members.none() diff --git a/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py b/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py index e6e3029d..f92e959b 100644 --- a/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py +++ b/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py @@ -34,34 +34,6 @@ } """ -# PROFILE_ROLE_UPDATE_GRAPHQL = """ -# mutation ProfileRoleUpdateMutation($input: RoleUpdateInput!) { -# roleUpdate(input: $input) { -# profile { -# id -# members { -# totalCount -# edges { -# node { -# id -# role -# status -# } -# } -# pageInfo { -# endCursor -# hasNextPage -# } -# } -# } -# errors { -# field -# messages -# } -# } -# } -# """ - PROFILE_ROLE_UPDATE_GRAPHQL = """ mutation ProfileRoleUpdateMutation($input: RoleUpdateInput!) { roleUpdate(input: $input) { diff --git a/baseapp-profiles/setup.cfg b/baseapp-profiles/setup.cfg index 5a69b252..d54be3e0 100644 --- a/baseapp-profiles/setup.cfg +++ b/baseapp-profiles/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = baseapp_profiles -version = 0.3.2 +version = 0.3.5 description = BaseApp Profiles long_description = file: README.md long_description_content_type = text/markdown From 09bb6f6b2993362a79ce94f2cd6848591952777e Mon Sep 17 00:00:00 2001 From: Henrique Pozzolini Date: Wed, 18 Dec 2024 16:00:46 -0300 Subject: [PATCH 06/11] bump baseapp-profiles version --- baseapp-profiles/setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/baseapp-profiles/setup.cfg b/baseapp-profiles/setup.cfg index d54be3e0..0fe64f92 100644 --- a/baseapp-profiles/setup.cfg +++ b/baseapp-profiles/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = baseapp_profiles -version = 0.3.5 +version = 0.3.6 description = BaseApp Profiles long_description = file: README.md long_description_content_type = text/markdown From 2dca3c9c22993280fd1df2ebce6cb3d55bdf687f Mon Sep 17 00:00:00 2001 From: Henrique Pozzolini Date: Thu, 19 Dec 2024 14:09:58 -0300 Subject: [PATCH 07/11] BA-1863-be-multiple-profiles-edit-member-role --- baseapp-profiles/baseapp_profiles/graphql/mutations.py | 4 ++-- baseapp-profiles/baseapp_profiles/permissions.py | 3 +-- .../baseapp_profiles/tests/test_graphql_mutations_update.py | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/baseapp-profiles/baseapp_profiles/graphql/mutations.py b/baseapp-profiles/baseapp_profiles/graphql/mutations.py index d6a5efd6..6e2b6781 100644 --- a/baseapp-profiles/baseapp_profiles/graphql/mutations.py +++ b/baseapp-profiles/baseapp_profiles/graphql/mutations.py @@ -142,7 +142,7 @@ def mutate_and_get_payload(cls, root, info, **input): try: obj = ProfileUserRole.objects.get(user_id=user_pk, profile_id=profile_pk) except ProfileUserRole.DoesNotExist: - raise ValueError(_("Role not found")) + raise GraphQLError(_("Role not found")) if not info.context.user.has_perm("baseapp_profiles.change_profileuserrole", obj.profile): raise GraphQLError( @@ -246,4 +246,4 @@ class ProfilesMutations(object): profile_create = ProfileCreate.Field() profile_update = ProfileUpdate.Field() profile_delete = ProfileDelete.Field() - role_update = RoleUpdate.Field() + profile_role_update = RoleUpdate.Field() diff --git a/baseapp-profiles/baseapp_profiles/permissions.py b/baseapp-profiles/baseapp_profiles/permissions.py index 4f62f653..29d2d1a0 100644 --- a/baseapp-profiles/baseapp_profiles/permissions.py +++ b/baseapp-profiles/baseapp_profiles/permissions.py @@ -1,8 +1,7 @@ import swapper from django.contrib.auth.backends import BaseBackend -from .models import ProfileUserRole - +ProfileUserRole = swapper.load_model("baseapp_profiles", "ProfileUserRole") Profile = swapper.load_model("baseapp_profiles", "Profile") diff --git a/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py b/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py index f92e959b..01428d55 100644 --- a/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py +++ b/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py @@ -293,6 +293,5 @@ def test_user_without_permission_cant_update_role(django_user_client, graphql_us }, ) content = response.json() - print(content) assert content["errors"][0]["message"] == "You don't have permission to perform this action" profile.refresh_from_db() From 966c80c129b4c0c713b88e7eb326392c81e46162 Mon Sep 17 00:00:00 2001 From: Henrique Pozzolini Date: Thu, 19 Dec 2024 14:40:32 -0300 Subject: [PATCH 08/11] change ProfileUserRole import --- baseapp-profiles/baseapp_profiles/tests/test_get_queries.py | 2 +- .../baseapp_profiles/tests/test_graphql_mutations_update.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/baseapp-profiles/baseapp_profiles/tests/test_get_queries.py b/baseapp-profiles/baseapp_profiles/tests/test_get_queries.py index d784da00..b81bca33 100644 --- a/baseapp-profiles/baseapp_profiles/tests/test_get_queries.py +++ b/baseapp-profiles/baseapp_profiles/tests/test_get_queries.py @@ -3,12 +3,12 @@ from baseapp_pages.tests.factories import URLPathFactory from django.contrib.contenttypes.models import ContentType -from ..models import ProfileUserRole from .factories import ProfileFactory, ProfileUserRoleFactory pytestmark = pytest.mark.django_db Profile = swapper.load_model("baseapp_profiles", "Profile") +ProfileUserRole = swapper.load_model("baseapp_profiles", "ProfileUserRole") GET_PROFILE_BY_PATH = """ query Profile($id: ID!) { diff --git a/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py b/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py index 01428d55..f802c915 100644 --- a/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py +++ b/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py @@ -5,12 +5,12 @@ from django.contrib.auth.models import Permission from django.test.client import MULTIPART_CONTENT -from ..models import ProfileUserRole from .factories import ProfileFactory, ProfileUserRoleFactory pytestmark = pytest.mark.django_db Profile = swapper.load_model("baseapp_profiles", "Profile") +ProfileUserRole = swapper.load_model("baseapp_profiles", "ProfileUserRole") PROFILE_UPDATE_GRAPHQL = """ mutation ProfileUpdateMutation($input: ProfileUpdateInput!) { From 226c4eb9dbfd08e596c62c3bf5e94ffb0f3c531b Mon Sep 17 00:00:00 2001 From: Henrique Pozzolini Date: Thu, 19 Dec 2024 15:30:29 -0300 Subject: [PATCH 09/11] update test_graphql_mutations_update --- .../baseapp_profiles/tests/test_graphql_mutations_update.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py b/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py index f802c915..51cefbd3 100644 --- a/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py +++ b/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py @@ -36,7 +36,7 @@ PROFILE_ROLE_UPDATE_GRAPHQL = """ mutation ProfileRoleUpdateMutation($input: RoleUpdateInput!) { - roleUpdate(input: $input) { + profileRoleUpdate(input: $input) { profileUserRole { id role From cfda54984b6cc8ce3fd9818687672e4e9c9344d4 Mon Sep 17 00:00:00 2001 From: Henrique Pozzolini Date: Thu, 19 Dec 2024 16:48:06 -0300 Subject: [PATCH 10/11] change profileRoleUpdate test key --- .../baseapp_profiles/tests/test_graphql_mutations_update.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py b/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py index 51cefbd3..92e21ece 100644 --- a/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py +++ b/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py @@ -36,7 +36,7 @@ PROFILE_ROLE_UPDATE_GRAPHQL = """ mutation ProfileRoleUpdateMutation($input: RoleUpdateInput!) { - profileRoleUpdate(input: $input) { + progiloleUpdate(input: $input) { profileUserRole { id role @@ -240,7 +240,7 @@ def test_user_profile_owner_can_update_role(django_user_client, graphql_user_cli ) content = response.json() - assert content["data"]["roleUpdate"]["profileUserRole"]["role"] == "ADMIN" + assert content["data"]["profileRoleUpdate"]["profileUserRole"]["role"] == "ADMIN" profile.refresh_from_db() @@ -267,7 +267,7 @@ def test_user_with_permission_can_update_role(django_user_client, graphql_user_c ) content = response.json() - assert content["data"]["roleUpdate"]["profileUserRole"]["role"] == "ADMIN" + assert content["data"]["profileRoleUpdate"]["profileUserRole"]["role"] == "ADMIN" profile.refresh_from_db() From eed41b6ab9fef611bb1ad7165ea47238074f130d Mon Sep 17 00:00:00 2001 From: Henrique Pozzolini Date: Thu, 19 Dec 2024 16:59:54 -0300 Subject: [PATCH 11/11] fix typo --- .../baseapp_profiles/tests/test_graphql_mutations_update.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py b/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py index 92e21ece..8767b2a2 100644 --- a/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py +++ b/baseapp-profiles/baseapp_profiles/tests/test_graphql_mutations_update.py @@ -36,7 +36,7 @@ PROFILE_ROLE_UPDATE_GRAPHQL = """ mutation ProfileRoleUpdateMutation($input: RoleUpdateInput!) { - progiloleUpdate(input: $input) { + profileRoleUpdate(input: $input) { profileUserRole { id role