From a69aedfcc215a9d177723558a5ecf1fc4400bd87 Mon Sep 17 00:00:00 2001
From: Jan-Niclas Struewer <j.n.struewer@gmail.com>
Date: Tue, 12 Dec 2023 15:19:26 +0100
Subject: [PATCH] Updated toolrun response. added cookie check to get tool run
 endpoint

---
 .../gitlab/service/OpenCodeGitlabApi.kt       |  8 ++++-
 .../controller/RepositoryController.kt        | 31 +++++++++++++------
 .../repository/dto/ToolRunResponseDto.kt      |  5 +++
 .../dataprovider/user/service/UserService.kt  | 17 ----------
 .../resources/application-local.properties    |  1 +
 .../resources/application-prod.properties     |  1 +
 6 files changed, 35 insertions(+), 28 deletions(-)
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/ToolRunResponseDto.kt

diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/service/OpenCodeGitlabApi.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/service/OpenCodeGitlabApi.kt
index 437ff18f..60e1a490 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/service/OpenCodeGitlabApi.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/service/OpenCodeGitlabApi.kt
@@ -77,7 +77,13 @@ class OpenCodeGitlabApi(openCodeGitlabConfiguration: OpenCodeGitlabApiProperties
             return@coroutineScope repoDetailsDto
         }
 
-    suspend fun getProjectMembers(projectId: Long): List<MemberDto> {
+    suspend fun userIsProjectMember(projectId: Long, gitlabUserId: Long): Boolean {
+        val projectMembers = getProjectMembers(projectId)
+
+        return projectMembers.any { it.id == gitlabUserId }
+    }
+
+    private suspend fun getProjectMembers(projectId: Long): List<MemberDto> {
         return gitlabApi.projectApi.getAllMembers(projectId).map { memberResponse ->
             MemberDto(
                 id = memberResponse.id,
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/controller/RepositoryController.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/controller/RepositoryController.kt
index bcd8bc9c..d0ac1164 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/controller/RepositoryController.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/controller/RepositoryController.kt
@@ -3,16 +3,13 @@ package de.fraunhofer.iem.dataprovider.repository.controller
 import de.fraunhofer.iem.dataprovider.configuration.ApiPaths
 import de.fraunhofer.iem.dataprovider.configuration.security.JwtContentDto
 import de.fraunhofer.iem.dataprovider.configuration.security.JwtService
+import de.fraunhofer.iem.dataprovider.gitlab.service.OpenCodeGitlabApi
 import de.fraunhofer.iem.dataprovider.kpi.dto.KPITreeResponseDto
 import de.fraunhofer.iem.dataprovider.kpi.service.KPIService
 import de.fraunhofer.iem.dataprovider.logger.getLogger
-import de.fraunhofer.iem.dataprovider.repository.dto.RawKpiDto
-import de.fraunhofer.iem.dataprovider.repository.dto.RepositoryConsentDto
-import de.fraunhofer.iem.dataprovider.repository.dto.RepositoryResponseDto
-import de.fraunhofer.iem.dataprovider.repository.dto.ScoreCardResponseDto
+import de.fraunhofer.iem.dataprovider.repository.dto.*
 import de.fraunhofer.iem.dataprovider.repository.entity.RepositoryEntity
 import de.fraunhofer.iem.dataprovider.repository.service.RepositoryService
-import de.fraunhofer.iem.dataprovider.toolRun.dto.ToolRunDto
 import de.fraunhofer.iem.dataprovider.toolRun.service.ToolRunService
 import de.fraunhofer.iem.dataprovider.user.dto.ValidateUserDto
 import de.fraunhofer.iem.dataprovider.user.service.UserService
@@ -31,7 +28,8 @@ class RepositoryController(
     private val kpiService: KPIService,
     private val toolRunService: ToolRunService,
     private val userService: UserService,
-    private val jwtService: JwtService
+    private val jwtService: JwtService,
+    private val gitlabApi: OpenCodeGitlabApi
 ) {
 
     private val logger = getLogger(javaClass)
@@ -136,13 +134,28 @@ class RepositoryController(
     }
 
     @GetMapping(ApiPaths.REPOSITORY_TOOL_RUN)
-    suspend fun getToolRunForRepository(@PathVariable id: Long): ToolRunDto {
+    suspend fun getToolRunForRepository(
+        @CookieValue("gitlabIdToken") gitlabCookie: String,
+        @PathVariable id: Long
+    ): ToolRunResponseDto {
+        println("Cookie value $gitlabCookie")
+
+        val isProjectMember = jwtService.getContentIfValid(gitlabCookie)?.let {
+            gitlabApi.userIsProjectMember(projectId = id, gitlabUserId = it.gitlabId)
+        } ?: false
+
         logger.info("Get repository with id $id")
         val repositoryEntity = this.repositoryService.findRepoById(id) ?: throw ResponseStatusException(
             HttpStatus.NOT_FOUND, "repository not found"
         )
 
-        return toolRunService.getToolRunForRepository(repositoryEntity)
+        return ToolRunResponseDto(
+            isProjectMember = isProjectMember,
+            toolRun = toolRunService.getToolRunForRepository(
+                repo = repositoryEntity,
+                includeFindings = isProjectMember
+            )
+        )
     }
 
     @PostMapping(ApiPaths.REPOSITORY_UPDATE_CONSENT)
@@ -155,8 +168,6 @@ class RepositoryController(
         @PathVariable id: Long,
         @RequestBody validateDto: ValidateUserDto
     ): ResponseEntity<Unit> {
-//        val isProjectMember = userService.userIsProjectMember(projectId = id, validateUserDto = validateDto)
-//        println("User in ProjectMembers for is $isProjectMember")
         val gitlabUserId = userService.getGitlabUserId(validateUserDto = validateDto)
         val jwt = jwtService.createJWT(JwtContentDto(gitlabId = gitlabUserId))
         val gitlabCookie = ResponseCookie.from("gitlabIdToken", jwt ?: "")
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/ToolRunResponseDto.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/ToolRunResponseDto.kt
new file mode 100644
index 00000000..7be525a1
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/repository/dto/ToolRunResponseDto.kt
@@ -0,0 +1,5 @@
+package de.fraunhofer.iem.dataprovider.repository.dto
+
+import de.fraunhofer.iem.dataprovider.toolRun.dto.ToolRunDto
+
+data class ToolRunResponseDto(val isProjectMember: Boolean = false, val toolRun: ToolRunDto)
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/user/service/UserService.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/user/service/UserService.kt
index 5ead1010..981e0a83 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/user/service/UserService.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/user/service/UserService.kt
@@ -1,7 +1,6 @@
 package de.fraunhofer.iem.dataprovider.user.service
 
 import de.fraunhofer.iem.dataprovider.configuration.OpenCodeApiProperties
-import de.fraunhofer.iem.dataprovider.gitlab.service.OpenCodeGitlabApi
 import de.fraunhofer.iem.dataprovider.user.dto.UserResponseDto
 import de.fraunhofer.iem.dataprovider.user.dto.ValidateUserDto
 import io.ktor.client.*
@@ -12,18 +11,13 @@ import io.ktor.client.plugins.cookies.*
 import io.ktor.client.request.*
 import io.ktor.http.*
 import io.ktor.serialization.kotlinx.json.*
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.async
 import kotlinx.serialization.json.Json
 import org.springframework.stereotype.Service
 
 @Service
 class UserService(
-    private val openCodeGitlabApi: OpenCodeGitlabApi,
     private val openCodeApiProperties: OpenCodeApiProperties
 ) {
-    private val ioScope = CoroutineScope(Dispatchers.IO)
 
     private val httpClient: HttpClient = HttpClient(CIO) {
         install(HttpCookies)
@@ -34,17 +28,6 @@ class UserService(
         }
     }
 
-    suspend fun userIsProjectMember(projectId: Long, validateUserDto: ValidateUserDto): Boolean {
-        val userIdDeferred = ioScope.async { getGitlabUserId(validateUserDto) }
-        val projectMembersDeferred = ioScope.async { openCodeGitlabApi.getProjectMembers(projectId) }
-
-        val userId = userIdDeferred.await()
-        val projectMembers = projectMembersDeferred.await()
-
-        println("UserId $userId Project Members $projectMembers")
-
-        return projectMembers.any { it.id == userId }
-    }
 
     suspend fun getGitlabUserId(validateUserDto: ValidateUserDto): Long {
         val userCookieResponse = httpClient.get(openCodeApiProperties.auth) {
diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties
index e781bb45..d2230a2c 100644
--- a/src/main/resources/application-local.properties
+++ b/src/main/resources/application-local.properties
@@ -17,6 +17,7 @@ security.api-key=${API_KEY:}
 security.admin-password=${ADMIN_PASSWORD:}
 security.admin-username=${ADMIN_USERNAME:}
 security.cors-origin=${CORS_ORIGIN:}
+security.hmac-key=${HMAC_KEY:}
 # OCCMD specific settings
 # path to the occmd tool executable
 # this can e.g, be the occmd.sh script in this project
diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties
index 3129782f..325aae17 100644
--- a/src/main/resources/application-prod.properties
+++ b/src/main/resources/application-prod.properties
@@ -15,6 +15,7 @@ security.api-key=${API_KEY:}
 security.admin-password=${ADMIN_PASSWORD:}
 security.admin-username=${ADMIN_USERNAME:}
 security.cors-origin=${CORS_ORIGIN:}
+security.hmac-key=${HMAC_KEY:}
 # OCCMD specific settings
 # path to the occmd tool executable
 # this can e.g, be the occmd.sh script in this project
-- 
GitLab