diff --git a/ExpressAPI/assets/OpenAPI/OpenAPI.yaml b/ExpressAPI/assets/OpenAPI/OpenAPI.yaml
index ee331c56f8f99afbf3c871e03a38830d0e9e5224..c435bfe5e20e5b8e246c1b60acc610f95b197900 100644
--- a/ExpressAPI/assets/OpenAPI/OpenAPI.yaml
+++ b/ExpressAPI/assets/OpenAPI/OpenAPI.yaml
@@ -70,6 +70,13 @@ paths:
                                                         type: boolean
                                                         examples:
                                                             - true
+                                                    languages:
+                                                        type: array
+                                                        items: string
+                                                        examples:
+                                                            -   - c
+                                                                - cpp
+                                                                - js
                     description: OK
                 default:
                     $ref: '#/components/responses/ERROR'
@@ -303,6 +310,16 @@ paths:
                                     type: boolean
                                     default: false
                                     description: Whether or not to use the Sonar integration to validate the assignment and exercise solutions
+                                sonarGate:
+                                    type: string
+                                    default: ""
+                                    description: Sonar quality gate to use for the assignment
+                                sonarProfiles:
+                                    type: string
+                                    default: "[]"
+                                    description: Sonar quality profiles for the assignment, as a JSON array of strings
+                                    examples:
+                                        - "[\"Sonar Way\", \"ArchWeb Way\"]"
                                 language:
                                     type: string
                                     default: other
diff --git a/ExpressAPI/prisma/migrations/20240430135259_add_sonar_quality/migration.sql b/ExpressAPI/prisma/migrations/20240430135259_add_sonar_quality/migration.sql
new file mode 100644
index 0000000000000000000000000000000000000000..26e0361c56e525dfe04d56f2a00906842b62ca7b
--- /dev/null
+++ b/ExpressAPI/prisma/migrations/20240430135259_add_sonar_quality/migration.sql
@@ -0,0 +1,3 @@
+-- AlterTable
+ALTER TABLE `Assignment` ADD COLUMN `sonarGate` VARCHAR(191) NULL,
+    ADD COLUMN `sonarProfiles` JSON NULL;
diff --git a/ExpressAPI/prisma/schema.prisma b/ExpressAPI/prisma/schema.prisma
index b647317033ed8da0456e13303ff07c8abe29b0ae..87bf7d41c679ba53141669a0b538c6a5c5c41ccd 100644
--- a/ExpressAPI/prisma/schema.prisma
+++ b/ExpressAPI/prisma/schema.prisma
@@ -40,6 +40,8 @@ model Assignment {
     useSonar          Boolean @default(false)
     sonarKey          String?
     sonarCreationInfo Json?   @db.Json
+    sonarGate         String?
+    sonarProfiles     Json?   @db.Json
 
     exercises Exercise[]
     staff     User[]
diff --git a/ExpressAPI/src/managers/AssignmentManager.ts b/ExpressAPI/src/managers/AssignmentManager.ts
index ff16f6b1b60250b8729ea4a13811c6637654bd62..c405c9d2ec4c6335b4008521f97eede071d0bd4d 100644
--- a/ExpressAPI/src/managers/AssignmentManager.ts
+++ b/ExpressAPI/src/managers/AssignmentManager.ts
@@ -25,7 +25,7 @@ class AssignmentManager {
 
     async getByGitlabLink(gitlabLink: string, include: Prisma.AssignmentInclude | undefined = undefined): Promise<Assignment | undefined> {
         const nameInUrl = gitlabLink.replace('.git', '').split('/').pop()!;
-
+        console.log(nameInUrl);
         const result = await db.assignment.findMany({
                                                         where  : {
                                                             gitlabLink: {
@@ -34,11 +34,12 @@ class AssignmentManager {
                                                         },
                                                         include: include
                                                     }) as Array<Assignment>;
-
+        console.log(result);
         return result.length > 0 ? result[0] : undefined;
     }
 
     get(nameOrUrl: string, include: Prisma.AssignmentInclude | undefined = undefined): Promise<Assignment | undefined> {
+        console.log(nameOrUrl);
         if ( nameOrUrl.includes('://') ) {
             return this.getByGitlabLink(nameOrUrl, include);
         } else {
diff --git a/ExpressAPI/src/managers/SonarManager.ts b/ExpressAPI/src/managers/SonarManager.ts
index 3a5808c072423bc1108b83d5f474ce1060668a47..88320a4cca56bc618ef58c066a70e5df661a13ba 100644
--- a/ExpressAPI/src/managers/SonarManager.ts
+++ b/ExpressAPI/src/managers/SonarManager.ts
@@ -1,9 +1,13 @@
-import SharedConfig from '../shared/config/SharedConfig';
+import SharedConfig             from '../shared/config/SharedConfig';
 import SonarRoute               from '../shared/types/Sonar/SonarRoute';
 import axios, { AxiosInstance } from 'axios';
 import Config                   from '../config/Config';
-import SonarProjectCreation from '../shared/types/Sonar/SonarProjectCreation';
-import https from 'https';
+import SonarProjectCreation     from '../shared/types/Sonar/SonarProjectCreation';
+import https                    from 'https';
+import GlobalHelper             from '../helpers/GlobalHelper';
+import DojoStatusCode           from '../shared/types/Dojo/DojoStatusCode';
+import express                  from 'express';
+import GitlabRepository         from '../shared/types/Gitlab/GitlabRepository';
 
 
 class SonarManager {
@@ -59,6 +63,60 @@ class SonarManager {
         return await this.executePostRequest<SonarProjectCreation>(this.getApiUrl(SonarRoute.PROJECT_CREATE_GITLAB), formData)
     }
 
+    async addQualityGate(projectKey: string, qualityGate: string) {
+        const formData = new FormData();
+        formData.append('projectKey', projectKey);
+        formData.append('gateName', qualityGate);
+
+        return await this.executePostRequest<undefined>(this.getApiUrl(SonarRoute.PROJECT_ADD_GATE), formData);
+    }
+
+    async addQualityProfile(projectKey: string, qualityProfile: string, language: string) {
+        const formData = new FormData();
+        formData.append('project', projectKey);
+        formData.append('qualityProfile', qualityProfile);
+        formData.append('language', language);
+
+        return await this.executePostRequest<unknown>(this.getApiUrl(SonarRoute.PROJECT_ADD_PROFILE), formData);
+    }
+
+    async createProjectWithQualities(gitlabRepository: GitlabRepository, qualityGate: string | null, qualityProfiles: string[] | null, req: express.Request, res: express.Response) {
+        let sonarProject: SonarProjectCreation | undefined = undefined;
+        try {
+            sonarProject = await this.createProjectFromGitlab(gitlabRepository.id);
+            if (sonarProject == undefined) {
+                return await GlobalHelper.repositoryCreationError('Sonar error', undefined, req, res, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_ERROR, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_ERROR, gitlabRepository);
+            }
+        } catch ( error ) {
+            return await GlobalHelper.repositoryCreationError('Sonar project creation error', error, req, res, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_ERROR, DojoStatusCode.ASSIGNMENT_CREATION_INTERNAL_ERROR, gitlabRepository);
+        }
+        // Add gate and profiles to sonar project
+        if ( qualityGate != undefined && qualityGate != "" ) {
+            try {
+                await this.addQualityGate(sonarProject.project.key, qualityGate);
+            } catch ( error ) {
+                return await GlobalHelper.repositoryCreationError('Sonar gate error', error, req, res, DojoStatusCode.ASSIGNMENT_SONAR_GATE_NOT_FOUND, DojoStatusCode.ASSIGNMENT_SONAR_GATE_NOT_FOUND, gitlabRepository);
+            }
+        }
+
+        if ( qualityProfiles != undefined && qualityProfiles.length > 0 ) {
+            for ( const profile of qualityProfiles ) {
+                try {
+                    const [ lang, name ] = profile.split('/');
+                    if (lang.trim() != '' && name.trim() != '') {
+                        await this.addQualityProfile(sonarProject.project.key, name.trim(), lang.trim());
+                    } else {
+                        return await GlobalHelper.repositoryCreationError('Sonar profile invalid', undefined, req, res, DojoStatusCode.ASSIGNMENT_SONAR_PROFILE_NOT_FOUND, DojoStatusCode.ASSIGNMENT_SONAR_PROFILE_NOT_FOUND, gitlabRepository);
+                    }
+                } catch ( error ) {
+                    return await GlobalHelper.repositoryCreationError('Sonar profile not found', error, req, res, DojoStatusCode.ASSIGNMENT_SONAR_PROFILE_NOT_FOUND, DojoStatusCode.ASSIGNMENT_SONAR_PROFILE_NOT_FOUND, gitlabRepository);
+                }
+            }
+        }
+
+        return sonarProject;
+    }
+
     async getLanguages() {
         const resp = await this.executeGetRequest<{ languages: { key: string, name: string }[]}>(this.getApiUrl(SonarRoute.GET_LANGUAGES))
         return resp.languages.map(l => l.key)
diff --git a/ExpressAPI/src/routes/AssignmentRoutes.ts b/ExpressAPI/src/routes/AssignmentRoutes.ts
index 3423f5bed69ce52544d2b80dfc4edaa1bfebba2f..3229bb16b93c8f1e78e8a13b812dc0581203c61e 100644
--- a/ExpressAPI/src/routes/AssignmentRoutes.ts
+++ b/ExpressAPI/src/routes/AssignmentRoutes.ts
@@ -101,7 +101,7 @@ class AssignmentRoutes implements RoutesManager {
 
     private async createAssignment(req: express.Request, res: express.Response) {
         const params: {
-            name: string, members: Array<GitlabUser>, template: string, useSonar: string, language: string
+            name: string, members: Array<GitlabUser>, template: string, useSonar: string, sonarGate: string, sonarProfiles: string, language: string
         } = req.body;
         const useSonar = params.useSonar === 'true';
 
@@ -172,12 +172,13 @@ class AssignmentRoutes implements RoutesManager {
         // Create Sonar project
         let sonarProject: SonarProjectCreation | undefined = undefined;
         if ( useSonar ) {
-            try {
-                sonarProject = await SonarManager.createProjectFromGitlab(repository.id);
-            } catch ( error ) {
-                logger.error('Sonar project creation error');
-                logger.error(error);
-                return GlobalHelper.repositoryCreationError('Sonar error', error, req, res, DojoStatusCode.ASSIGNMENT_CREATION_SONAR_ERROR, DojoStatusCode.ASSIGNMENT_CREATION_INTERNAL_ERROR, repository);
+            const profiles: string[] = JSON.parse(params.sonarProfiles);
+            const resp = await SonarManager.createProjectWithQualities(repository, params.sonarGate, profiles, req, res);
+            if (resp == undefined) {
+                return resp;
+
+            } else {
+                sonarProject = resp;
             }
         }
 
@@ -193,6 +194,8 @@ class AssignmentRoutes implements RoutesManager {
                                                                               useSonar          : useSonar,
                                                                               sonarKey          : sonarProject?.project.key,
                                                                               sonarCreationInfo : sonarProject?.project,
+                                                                              sonarGate         : params.sonarGate,
+                                                                              sonarProfiles     : params.sonarProfiles,
                                                                               language          : Language[params.language as keyof typeof Language],
                                                                               staff             : {
                                                                                   connectOrCreate: [ ...params.members.map(gitlabUser => {
diff --git a/ExpressAPI/src/routes/ExerciseRoutes.ts b/ExpressAPI/src/routes/ExerciseRoutes.ts
index fe22cabf138b4f8c083b89966396afb0cdcb37f5..f56c3c4fd3e431d2a858f94abc46a6bef9659969 100644
--- a/ExpressAPI/src/routes/ExerciseRoutes.ts
+++ b/ExpressAPI/src/routes/ExerciseRoutes.ts
@@ -171,13 +171,14 @@ class ExerciseRoutes implements RoutesManager {
 
             // Create Sonar project
             let sonarProject: SonarProjectCreation | undefined = undefined;
-            if (assignment.useSonar) {
-                try {
-                    sonarProject = await SonarManager.createProjectFromGitlab(repository.id);
-                } catch ( error ) {
-                    logger.error("Sonar project creation error");
-                    logger.error(error);
-                    return GlobalHelper.repositoryCreationError('Sonar error', error, req, res, DojoStatusCode.EXERCISE_CREATION_SONAR_ERROR, DojoStatusCode.ASSIGNMENT_CREATION_INTERNAL_ERROR, repository);
+            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);
+                if (resp == undefined) {
+                    return resp;
+                } else {
+                    sonarProject = resp;
                 }
             }
 
diff --git a/ExpressAPI/src/shared b/ExpressAPI/src/shared
index 7f368ef971c8bbe9c5c693a6a8cf733f2ed1e3d2..102e79d9b78d79e495f7b82e5e767eb7898248db 160000
--- a/ExpressAPI/src/shared
+++ b/ExpressAPI/src/shared
@@ -1 +1 @@
-Subproject commit 7f368ef971c8bbe9c5c693a6a8cf733f2ed1e3d2
+Subproject commit 102e79d9b78d79e495f7b82e5e767eb7898248db