From f81217a5af31f56e7ae1efc43daf25b143b8cf15 Mon Sep 17 00:00:00 2001
From: Emmanuel Ormancey <emmanuel.ormancey@cern.ch>
Date: Thu, 31 Mar 2022 17:47:07 +0200
Subject: [PATCH] [#149] Check user exists by id or email before trying to
 recreate

---
 package.json                                      |  2 +-
 .../impl/channels/add-member-to-channel.ts        |  6 ++++++
 src/services/impl/users/get-or-create-user.ts     | 15 +++++++--------
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/package.json b/package.json
index 589a9a42..dbd68ea6 100644
--- a/package.json
+++ b/package.json
@@ -72,4 +72,4 @@
     "ts-node": "^8.5.2",
     "typescript": "^3.7.2"
   }
-}
\ No newline at end of file
+}
diff --git a/src/services/impl/channels/add-member-to-channel.ts b/src/services/impl/channels/add-member-to-channel.ts
index 8fe6dfbe..bf2d1336 100644
--- a/src/services/impl/channels/add-member-to-channel.ts
+++ b/src/services/impl/channels/add-member-to-channel.ts
@@ -37,6 +37,12 @@ export class AddMemberToChannel implements Command {
     }
 
     const userToAdd = await this.usersService.GetOrCreateUserFromUsernameOrEmail(this.membername);
+    //if resolved new user is already a direct member or a group member
+    if (await channel.isMember(userToAdd)) {
+      throw new ForbiddenError(
+        `User ${this.membername} / ${userToAdd.email} is already a member or in a member group.`,
+      );
+    }
 
     channel.addMember(userToAdd);
     //const ret = await transactionManager.save(channel);
diff --git a/src/services/impl/users/get-or-create-user.ts b/src/services/impl/users/get-or-create-user.ts
index 824400f7..a211912d 100644
--- a/src/services/impl/users/get-or-create-user.ts
+++ b/src/services/impl/users/get-or-create-user.ts
@@ -14,10 +14,7 @@ export class GetOrCreateUserFromUsernameOrEmail implements Command {
 
   async execute(transactionManager: EntityManager): Promise<User> {
     let userToAdd = await transactionManager.findOne(User, {
-      where: [
-        { username: this.userIdentifier },
-        { email: this.userIdentifier },
-      ],
+      where: [{ username: this.userIdentifier }, { email: this.userIdentifier }],
     });
 
     // If not found, let's verify if email is like login@cern.ch to reinitiate a search on login
@@ -31,10 +28,12 @@ export class GetOrCreateUserFromUsernameOrEmail implements Command {
     }
 
     if (!userToAdd) {
-      const user = await this.usersService.GetUserFromExternal(
-        this.userIdentifier,
-      );
-      userToAdd = await this.authService.createUserWithDefaults(user);
+      const user = await this.usersService.GetUserFromExternal(this.userIdentifier);
+      // Check again in DB if user already there in case it's a mapped user in Auth systems
+      userToAdd = await transactionManager.findOne(User, {
+        where: [{ username: user.username }, { email: user.email }],
+      });
+      if (!userToAdd) userToAdd = await this.authService.createUserWithDefaults(user);
     }
 
     return userToAdd;
-- 
GitLab