From a2f464ef2e84de70eda1ecd47137482b00fdaf61 Mon Sep 17 00:00:00 2001
From: Joel von der Weid <joel.von-der-weid@hesge.ch>
Date: Tue, 25 Jun 2024 14:40:17 +0200
Subject: [PATCH] Add users to sonar projects

---
 ExpressAPI/src/managers/SonarManager.ts   | 42 +++++++++++++++++++++++
 ExpressAPI/src/routes/AssignmentRoutes.ts |  6 ++++
 ExpressAPI/src/routes/ExerciseRoutes.ts   | 19 ++++++++++
 3 files changed, 67 insertions(+)

diff --git a/ExpressAPI/src/managers/SonarManager.ts b/ExpressAPI/src/managers/SonarManager.ts
index ed08283..38bc133 100644
--- a/ExpressAPI/src/managers/SonarManager.ts
+++ b/ExpressAPI/src/managers/SonarManager.ts
@@ -155,6 +155,48 @@ class SonarManager {
             return false;
         }
     }
+
+    /**
+     * Return the sonar user login name associated with the gitlab username
+     * @param gitlabUsername Username to look up
+     */
+    async findUserFromGitlabUser(gitlabUsername: string) {
+        const formData = new FormData();
+        formData.append('q', gitlabUsername);
+
+        const resp = await this.executeGetRequest<{ users: { login: string, name: string }[] }>(this.getApiUrl(SonarRoute.SEARCH_USER), formData);
+        for (const u of resp.users) {
+            if ( u.name == gitlabUsername ) {
+                return u.login;
+            }
+        }
+        return undefined;
+    }
+
+    async addUserToProject(username: string, projectKey: string, privileged: boolean) {
+        const permissions = ['user', 'codeviewer'];
+        if (privileged) {
+            permissions.push('issueadmin');
+        }
+
+        for (const perm of permissions) {
+            const formData = new FormData();
+            formData.append('projectKey', projectKey);
+            formData.append('permission', perm);
+            formData.append('login', username);
+
+            await this.executePostRequest(this.getApiUrl(SonarRoute.PROJECT_ADD_USER), formData)
+        }
+    }
+
+    async addGitlabUserToProject(gitlabUsername: string, projectKey: string, privileged: boolean) {
+        const username = await this.findUserFromGitlabUser(gitlabUsername);
+        if (username == undefined) {
+            return false;
+        }
+        await this.addUserToProject(username, projectKey, privileged);
+        return true;
+    }
 }
 
 export default new SonarManager();
\ No newline at end of file
diff --git a/ExpressAPI/src/routes/AssignmentRoutes.ts b/ExpressAPI/src/routes/AssignmentRoutes.ts
index deade95..a5cce0e 100644
--- a/ExpressAPI/src/routes/AssignmentRoutes.ts
+++ b/ExpressAPI/src/routes/AssignmentRoutes.ts
@@ -203,6 +203,12 @@ class AssignmentRoutes implements RoutesManager {
                 if ( sonarProject == undefined ) {
                     return;
                 }
+
+                await GlobalHelper.repoCreationFnExecCreator(req, res, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_ERROR, DojoStatusCode.ASSIGNMENT_CREATION_INTERNAL_ERROR, repository, sonarProject)(async () => {
+                    if ( !(await Promise.all(params.members.map(member => SonarManager.addGitlabUserToProject(member.username, sonarProject!.project.key, true)))).every(Boolean) ) {
+                        throw new Error();
+                    }
+                }, 'Sonar add member error');
             }
 
             const assignment: Assignment = await repoCreationFnExec(() => db.assignment.create({
diff --git a/ExpressAPI/src/routes/ExerciseRoutes.ts b/ExpressAPI/src/routes/ExerciseRoutes.ts
index 48db534..1762ea7 100644
--- a/ExpressAPI/src/routes/ExerciseRoutes.ts
+++ b/ExpressAPI/src/routes/ExerciseRoutes.ts
@@ -277,6 +277,25 @@ class ExerciseRoutes implements RoutesManager {
                 if ( sonarProject == undefined ) {
                     return;
                 }
+
+                try {
+                    for ( const u of assignment.staff ) {
+                        const success = await SonarManager.addGitlabUserToProject(u.gitlabUsername, sonarProject.project.key, true);
+                        if (!success) {
+                            return GlobalHelper.repositoryCreationError('Sonar add member error', undefined, req, res, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_MEMBER, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_MEMBER, repository, sonarProject);
+                        }
+                    }
+                    for ( const u of params.members ) {
+                        const success = await SonarManager.addGitlabUserToProject(u.username, sonarProject.project.key, false);
+                        if (!success) {
+                            return GlobalHelper.repositoryCreationError('Sonar add member error', undefined, req, res, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_MEMBER, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_MEMBER, repository, sonarProject);
+                        }
+                    }
+                } catch ( error ) {
+                    logger.error('Sonar add member error');
+                    logger.error(error);
+                    return GlobalHelper.repositoryCreationError('Sonar add member error', error, req, res, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_ERROR, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_ERROR, repository, sonarProject);
+                }
             }
 
 
-- 
GitLab