From 06dda5f37d9bb18453b4b47e04d56caabc099421 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 | 13 +++++++
 ExpressAPI/src/routes/ExerciseRoutes.ts   | 20 ++++++++++-
 ExpressAPI/src/shared                     |  2 +-
 4 files changed, 75 insertions(+), 2 deletions(-)

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 ed9be07..640cdcc 100644
--- a/ExpressAPI/src/routes/AssignmentRoutes.ts
+++ b/ExpressAPI/src/routes/AssignmentRoutes.ts
@@ -180,6 +180,19 @@ class AssignmentRoutes implements RoutesManager {
             } else {
                 sonarProject = resp;
             }
+
+            try {
+                for ( const u of params.members ) {
+                    const success = await SonarManager.addGitlabUserToProject(u.username, 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);
+                    }
+                }
+            } 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);
+            }
         }
 
         try {
diff --git a/ExpressAPI/src/routes/ExerciseRoutes.ts b/ExpressAPI/src/routes/ExerciseRoutes.ts
index 69db635..cf3a4dd 100644
--- a/ExpressAPI/src/routes/ExerciseRoutes.ts
+++ b/ExpressAPI/src/routes/ExerciseRoutes.ts
@@ -173,7 +173,6 @@ class ExerciseRoutes implements RoutesManager {
             }));
 
             // Create Sonar project
-            console.log(assignment, repository);
             if (assignment.useSonar && assignment.sonarProfiles != null) {
                 const profiles: string[] = JSON.parse(assignment.sonarProfiles as string);
                 const resp = await SonarManager.createProjectWithQualities(repository, assignment.sonarGate, profiles, req, res);
@@ -182,6 +181,25 @@ class ExerciseRoutes implements RoutesManager {
                 } else {
                     sonarProject = resp;
                 }
+
+                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);
+                }
             }
 
             const exercise: Exercise = await db.exercise.create({
diff --git a/ExpressAPI/src/shared b/ExpressAPI/src/shared
index bd29fe7..8efab43 160000
--- a/ExpressAPI/src/shared
+++ b/ExpressAPI/src/shared
@@ -1 +1 @@
-Subproject commit bd29fe76fdb1b124e3fe2f23e995a2b3b70694a7
+Subproject commit 8efab438a60569011f2757c803a89c81bc46a174
-- 
GitLab