diff --git a/src/apps/api/views/profiles.py b/src/apps/api/views/profiles.py index 65e2bb13c..2b3ce3f3d 100644 --- a/src/apps/api/views/profiles.py +++ b/src/apps/api/views/profiles.py @@ -1,5 +1,6 @@ import json +from django.conf import settings from django.contrib.auth import get_user_model from django.contrib.auth.decorators import login_required from django.db.models import Q @@ -180,6 +181,8 @@ def invite_users(self, request, pk=None): 'user': member.user, 'invite_url': f'{reverse("profiles:organization_accept_invite")}?token={member.token}', 'organization': org.name, + 'domain': settings.DOMAIN_NAME, + 'protocol': 'https' if self.request.is_secure() else 'http' }, subject=f'You have been invited to join {org.name}', html_file="profiles/emails/invite.html", @@ -253,6 +256,18 @@ def validate_invite(self, request): mem_ser = MembershipSerializer(membership) return Response(mem_ser.data, status=status.HTTP_200_OK) + @action(detail=True, methods=['delete'], permission_classes=[IsAuthenticated]) + def leave_organization(self, request, pk=None): + organization = self.get_object() + try: + member = organization.membership_set.get(user=request.user) + except Membership.DoesNotExist: + raise ValidationError('You are not a member of this organization') + if member.group == Membership.OWNER: + raise PermissionDenied('The owner cannot leave the organization') + organization.users.remove(request.user) + return Response({'success': True, 'message': 'You have left the organization'}, status=status.HTTP_200_OK) + @action(detail=True, methods=['delete']) def delete_organization(self, request, pk=None): try: diff --git a/src/apps/profiles/views.py b/src/apps/profiles/views.py index 81c8dc1de..b710027f1 100644 --- a/src/apps/profiles/views.py +++ b/src/apps/profiles/views.py @@ -418,11 +418,14 @@ def get_context_data(self, **kwargs): context['organization'] = OrganizationDetailSerializer(self.object).data membership = self.object.membership_set.filter(user=self.request.user) if len(membership) == 1: - context['is_editor'] = membership.first().group in Membership.EDITORS_GROUP - context['is_member'] = membership.first().group in Membership.SETTABLE_PERMISSIONS + group = membership.first().group + context['is_editor'] = group in Membership.EDITORS_GROUP + context['is_member'] = group in Membership.SETTABLE_PERMISSIONS + context['is_owner'] = group == Membership.OWNER else: context['is_editor'] = False context['is_member'] = False + context['is_owner'] = False return context diff --git a/src/static/js/ours/client.js b/src/static/js/ours/client.js index fa169c5a8..4d6e0aee6 100644 --- a/src/static/js/ours/client.js +++ b/src/static/js/ours/client.js @@ -335,6 +335,9 @@ CODALAB.api = { delete_organization: (id) => { return CODALAB.api.request('DELETE', `${URLS.API}organizations/${id}/delete_organization/`) }, + leave_organization: (id) => { + return CODALAB.api.request('DELETE', `${URLS.API}organizations/${id}/leave_organization/`) + }, /*--------------------------------------------------------------------- Participants ---------------------------------------------------------------------*/ diff --git a/src/static/riot/profiles/organization_edit.tag b/src/static/riot/profiles/organization_edit.tag index 2a2c52ca8..536118da1 100644 --- a/src/static/riot/profiles/organization_edit.tag +++ b/src/static/riot/profiles/organization_edit.tag @@ -56,10 +56,8 @@
- - - - + +