From 6304ec0856d251fbba0d9d4c9d997ba019f0c3c2 Mon Sep 17 00:00:00 2001
From: Valentin Tolmer <valentin@tolmer.fr>
Date: Fri, 24 Sep 2021 17:35:46 +0200
Subject: [PATCH] graphql: Add a method to delete a group

---
 schema.graphql                           | 1 +
 server/src/domain/handler.rs             | 2 ++
 server/src/domain/sql_backend_handler.rs | 9 +++++++++
 server/src/infra/graphql/mutation.rs     | 8 ++++++++
 server/src/infra/tcp_backend_handler.rs  | 1 +
 5 files changed, 21 insertions(+)

diff --git a/schema.graphql b/schema.graphql
index d002ceb..7a96ac8 100644
--- a/schema.graphql
+++ b/schema.graphql
@@ -9,6 +9,7 @@ type Mutation {
   addUserToGroup(userId: String!, groupId: Int!): Success!
   removeUserFromGroup(userId: String!, groupId: Int!): Success!
   deleteUser(userId: String!): Success!
+  deleteGroup(groupId: Int!): Success!
 }
 
 type Group {
diff --git a/server/src/domain/handler.rs b/server/src/domain/handler.rs
index fbee794..e53d141 100644
--- a/server/src/domain/handler.rs
+++ b/server/src/domain/handler.rs
@@ -90,6 +90,7 @@ pub trait BackendHandler: Clone + Send {
     async fn update_user(&self, request: UpdateUserRequest) -> Result<()>;
     async fn delete_user(&self, user_id: &str) -> Result<()>;
     async fn create_group(&self, group_name: &str) -> Result<GroupId>;
+    async fn delete_group(&self, group_id: GroupId) -> Result<()>;
     async fn add_user_to_group(&self, user_id: &str, group_id: GroupId) -> Result<()>;
     async fn remove_user_from_group(&self, user_id: &str, group_id: GroupId) -> Result<()>;
     async fn get_user_groups(&self, user: &str) -> Result<HashSet<GroupIdAndName>>;
@@ -110,6 +111,7 @@ mockall::mock! {
         async fn update_user(&self, request: UpdateUserRequest) -> Result<()>;
         async fn delete_user(&self, user_id: &str) -> Result<()>;
         async fn create_group(&self, group_name: &str) -> Result<GroupId>;
+        async fn delete_group(&self, group_id: GroupId) -> Result<()>;
         async fn get_user_groups(&self, user: &str) -> Result<HashSet<GroupIdAndName>>;
         async fn add_user_to_group(&self, user_id: &str, group_id: GroupId) -> Result<()>;
         async fn remove_user_from_group(&self, user_id: &str, group_id: GroupId) -> Result<()>;
diff --git a/server/src/domain/sql_backend_handler.rs b/server/src/domain/sql_backend_handler.rs
index 72f7886..2d33ab4 100644
--- a/server/src/domain/sql_backend_handler.rs
+++ b/server/src/domain/sql_backend_handler.rs
@@ -251,6 +251,15 @@ impl BackendHandler for SqlBackendHandler {
         Ok(GroupId(row.get::<i32, _>(&*Groups::GroupId.to_string())))
     }
 
+    async fn delete_group(&self, group_id: GroupId) -> Result<()> {
+        let delete_query = Query::delete()
+            .from_table(Groups::Table)
+            .and_where(Expr::col(Groups::GroupId).eq(group_id))
+            .to_string(DbQueryBuilder {});
+        sqlx::query(&delete_query).execute(&self.sql_pool).await?;
+        Ok(())
+    }
+
     async fn add_user_to_group(&self, user_id: &str, group_id: GroupId) -> Result<()> {
         let query = Query::insert()
             .into_table(Memberships::Table)
diff --git a/server/src/infra/graphql/mutation.rs b/server/src/infra/graphql/mutation.rs
index b803ae9..20068c5 100644
--- a/server/src/infra/graphql/mutation.rs
+++ b/server/src/infra/graphql/mutation.rs
@@ -131,4 +131,12 @@ impl<Handler: BackendHandler + Sync> Mutation<Handler> {
         context.handler.delete_user(&user_id).await?;
         Ok(Success::new())
     }
+
+    async fn delete_group(context: &Context<Handler>, group_id: i32) -> FieldResult<Success> {
+        if !context.validation_result.is_admin {
+            return Err("Unauthorized group deletion".into());
+        }
+        context.handler.delete_group(GroupId(group_id)).await?;
+        Ok(Success::new())
+    }
 }
diff --git a/server/src/infra/tcp_backend_handler.rs b/server/src/infra/tcp_backend_handler.rs
index 5899a40..4e29463 100644
--- a/server/src/infra/tcp_backend_handler.rs
+++ b/server/src/infra/tcp_backend_handler.rs
@@ -34,6 +34,7 @@ mockall::mock! {
         async fn update_user(&self, request: UpdateUserRequest) -> DomainResult<()>;
         async fn delete_user(&self, user_id: &str) -> DomainResult<()>;
         async fn create_group(&self, group_name: &str) -> DomainResult<GroupId>;
+        async fn delete_group(&self, group_id: GroupId) -> DomainResult<()>;
         async fn add_user_to_group(&self, user_id: &str, group_id: GroupId) -> DomainResult<()>;
         async fn remove_user_from_group(&self, user_id: &str, group_id: GroupId) -> DomainResult<()>;
     }