Repository: WeblateOrg/weblate

Issue:
Add "delete user from group" into api
**Is your feature request related to a problem? Please describe.**
It's possible to add user to group by API, but not remove it (or it's missing in documentation).


Discussion:
The API does not exist, needs to be implmented. Presumably as `DELETE /api/users/(str: username)/groups/(int: group_id)/`.
Hi @nijel , I would like to work on this Issue.
@krishnan2098 you're welcome, I've just assigned this issue to you.
@nijel Has this feature request been added? If not, I would like to work on it
It has not been added yet, you are welcome to implement it.
@nijel what about a `PATCH` API for updating the group members, I think of adding in [Group's API](https://github.com/WeblateOrg/weblate/blob/main/weblate/api/views.py#L426). Please let me know what do you think.
The groups API doesn't currently expose users. The users API does expose groups, that's why I was thinking about placing it there.
okay, Understood, Then I will go for this: `DELETE /api/users/(str: username)/groups/(int: group_id)/`

Resolving patch:
diff --git a/weblate/api/views.py b/weblate/api/views.py
--- a/weblate/api/views.py
+++ b/weblate/api/views.py
@@ -337,7 +337,7 @@ def destroy(self, request, *args, **kwargs):
         remove_user(instance, request)
         return Response(status=HTTP_204_NO_CONTENT)
 
-    @action(detail=True, methods=["post"])
+    @action(detail=True, methods=["post", "delete"])
     def groups(self, request, **kwargs):
         obj = self.get_object()
         self.perm_check(request)
@@ -350,7 +350,10 @@ def groups(self, request, **kwargs):
         except (Group.DoesNotExist, ValueError) as error:
             raise ValidationError(str(error))
 
-        obj.groups.add(group)
+        if request.method == "POST":
+            obj.groups.add(group)
+        if request.method == "DELETE":
+            obj.groups.remove(group)
         serializer = self.get_serializer_class()(obj, context={"request": request})
 
         return Response(serializer.data, status=HTTP_200_OK)


Test patch:
diff --git a/weblate/api/tests.py b/weblate/api/tests.py
--- a/weblate/api/tests.py
+++ b/weblate/api/tests.py
@@ -215,6 +215,43 @@ def test_add_group(self):
             request={"group_id": group.id},
         )
 
+    def test_remove_group(self):
+        group = Group.objects.get(name="Viewers")
+        username = User.objects.filter(is_active=True).first().username
+        self.do_request(
+            "api:user-groups",
+            kwargs={"username": username},
+            method="post",
+            code=403,
+            request={"group_id": group.id},
+        )
+        self.do_request(
+            "api:user-groups",
+            kwargs={"username": username},
+            method="post",
+            superuser=True,
+            code=400,
+            request={"group_id": -1},
+        )
+        response = self.do_request(
+            "api:user-groups",
+            kwargs={"username": username},
+            method="post",
+            superuser=True,
+            code=200,
+            request={"group_id": group.id},
+        )
+        self.assertIn("http://example.com/api/groups/2/", response.data["groups"])
+        response = self.do_request(
+            "api:user-groups",
+            kwargs={"username": username},
+            method="delete",
+            superuser=True,
+            code=200,
+            request={"group_id": group.id},
+        )
+        self.assertNotIn("http://example.com/api/groups/2/", response.data["groups"])
+
     def test_list_notifications(self):
         response = self.do_request(
             "api:user-notifications",