From 8ea30cf19870c81d05428eefadecae366f287e23 Mon Sep 17 00:00:00 2001 From: Niklas Kerkhoff Date: Mon, 25 Nov 2024 15:56:00 +0100 Subject: [PATCH] security, deployment --- deployment/docker-compose.yml | 6 +++--- .../lib/security/SecurityUtils.kt | 6 ++++++ .../modules/chat/controller/ChatController.kt | 7 +++++-- .../modules/chat/model/ChatRepo.kt | 2 +- .../modules/chat/model/ChatService.kt | 12 +++++++----- .../documents/applications/ApplicationController.kt | 6 ++++++ .../modules/documents/settings/SettingController.kt | 2 ++ 7 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/lib/security/SecurityUtils.kt diff --git a/deployment/docker-compose.yml b/deployment/docker-compose.yml index 96bacbe..5a32992 100644 --- a/deployment/docker-compose.yml +++ b/deployment/docker-compose.yml @@ -14,7 +14,7 @@ services: - tutor-assistant-keycloak tutor-assistant: - image: zaeunepyrite01/tutor-assistant:latest + image: ghcr.io/kit-sdq/tutor-assistant:latest container_name: tutor-assistant restart: always env_file: @@ -25,14 +25,14 @@ services: - tutor-assistant tutor-assistant-web: - image: zaeunepyrite01/tutor-assistant-web:latest + image: ghcr.io/kit-sdq/tutor-assistant-web:latest container_name: tutor-assistant-web restart: always networks: - tutor-assistant tutor-assistant-app-service: - image: zaeunepyrite01/tutor-assistant-app-service:latest + image: ghcr.io/kit-sdq/tutor-assistant-app-service:latest container_name: tutor-assistant-app-service restart: always depends_on: diff --git a/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/lib/security/SecurityUtils.kt b/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/lib/security/SecurityUtils.kt new file mode 100644 index 0000000..6868a40 --- /dev/null +++ b/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/lib/security/SecurityUtils.kt @@ -0,0 +1,6 @@ +package de.niklaskerkhoff.tutorassistantappservice.lib.security + +import org.springframework.security.core.authority.SimpleGrantedAuthority +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken + +fun JwtAuthenticationToken.hasAuthority(authority: String) = authorities.contains(SimpleGrantedAuthority(authority)) \ No newline at end of file diff --git a/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/chat/controller/ChatController.kt b/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/chat/controller/ChatController.kt index 970278d..f4d0aa5 100644 --- a/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/chat/controller/ChatController.kt +++ b/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/chat/controller/ChatController.kt @@ -1,6 +1,7 @@ package de.niklaskerkhoff.tutorassistantappservice.modules.chat.controller import de.niklaskerkhoff.tutorassistantappservice.lib.app_components.AppController +import de.niklaskerkhoff.tutorassistantappservice.lib.security.hasAuthority import de.niklaskerkhoff.tutorassistantappservice.modules.chat.model.ChatBaseData import de.niklaskerkhoff.tutorassistantappservice.modules.chat.model.ChatMainData import de.niklaskerkhoff.tutorassistantappservice.modules.chat.model.ChatService @@ -20,10 +21,12 @@ class ChatController( ) : AppController() { @GetMapping("{chatId}") fun getChatById(@PathVariable chatId: UUID, jwt: JwtAuthenticationToken): ChatMainData = - chatService.getChatById(chatId, jwt.name) + chatService.getChatById(chatId, jwt.name, !jwt.hasAuthority("ROLE_evaluator")) @GetMapping - fun getChats(jwt: JwtAuthenticationToken): List = chatService.getChats(jwt.name) + fun getChats(jwt: JwtAuthenticationToken): List = + if (jwt.hasAuthority("ROLE_evaluator")) chatService.getAllChats() + else chatService.getUsersChats(jwt.name) @PostMapping fun createChat(jwt: JwtAuthenticationToken): ChatBaseData = chatService.createChat(jwt.name) diff --git a/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/chat/model/ChatRepo.kt b/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/chat/model/ChatRepo.kt index 4557d46..c674f97 100644 --- a/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/chat/model/ChatRepo.kt +++ b/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/chat/model/ChatRepo.kt @@ -6,7 +6,7 @@ import org.springframework.data.jpa.repository.Query interface ChatRepo : AppEntityRepo { fun findByUserIdOrderByCreatedDateDesc(userId: String): List - fun findBySummaryIsNull(): List + fun findAllByOrderByCreatedDateDesc(): List @Query("select c from Chat c where size(c._messages) <= 1") fun findEmptyChats(): List diff --git a/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/chat/model/ChatService.kt b/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/chat/model/ChatService.kt index 03909b7..1b38751 100644 --- a/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/chat/model/ChatService.kt +++ b/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/chat/model/ChatService.kt @@ -41,10 +41,12 @@ class ChatService( @Value("\${app.tutor-assistant.base-url}") private lateinit var baseUrl: String - fun getChats(userId: String) = chatRepo.findByUserIdOrderByCreatedDateDesc(userId).map { ChatBaseData(it) } + fun getUsersChats(userId: String) = chatRepo.findByUserIdOrderByCreatedDateDesc(userId).map { ChatBaseData(it) } - fun getChatById(chatId: UUID, userId: String): ChatMainData { - val chat = chatRepo.findByIdOrThrow(chatId).requireUser(userId) + fun getAllChats() = chatRepo.findAllByOrderByCreatedDateDesc().map { ChatBaseData(it) } + + fun getChatById(chatId: UUID, userId: String, requiresMatchingUser: Boolean = true): ChatMainData { + val chat = chatRepo.findByIdOrThrow(chatId).requireUser(userId, requiresMatchingUser) return ChatMainData(chat) } @@ -186,8 +188,8 @@ class ChatService( return if (this?.has(key) == true) this[key] else null } - private fun Chat.requireUser(userId: String): Chat { - if (this.userId != userId) throw ResponseStatusException(HttpStatus.NOT_FOUND) + private fun Chat.requireUser(userId: String, requiresMatchingUser: Boolean = true): Chat { + if (requiresMatchingUser && this.userId != userId) throw ResponseStatusException(HttpStatus.NOT_FOUND) return this } } diff --git a/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/documents/applications/ApplicationController.kt b/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/documents/applications/ApplicationController.kt index b81dabc..1ae75b4 100644 --- a/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/documents/applications/ApplicationController.kt +++ b/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/documents/applications/ApplicationController.kt @@ -1,6 +1,7 @@ package de.niklaskerkhoff.tutorassistantappservice.modules.documents.applications import de.niklaskerkhoff.tutorassistantappservice.modules.documents.applications.entities.toDto +import org.springframework.security.access.prepost.PreAuthorize import org.springframework.web.bind.annotation.* import java.util.* @@ -16,17 +17,22 @@ class ApplicationController( fun getWebsiteDocuments() = applicationService.getWebsiteDocuments().map { it.toDto() } @PostMapping("index") + @PreAuthorize("hasRole('document-manager')") fun index(): Unit = applicationService.index() @PostMapping("files/{id}/reindex") + @PreAuthorize("hasRole('document-manager')") fun reindexFile(@PathVariable id: UUID): Unit = applicationService.reindexFileDocument(id) @PostMapping("websites/{id}/reindex") + @PreAuthorize("hasRole('document-manager')") fun reindexWebsite(@PathVariable id: UUID): Unit = applicationService.reindexWebsiteDocument(id) @DeleteMapping("files/{id}") + @PreAuthorize("hasRole('document-manager')") fun deleteFile(@PathVariable id: UUID): Unit = applicationService.deleteFileDocument(id) @DeleteMapping("websites/{id}") + @PreAuthorize("hasRole('document-manager')") fun deleteWebsite(@PathVariable id: UUID): Unit = applicationService.deleteWebsiteDocument(id) } diff --git a/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/documents/settings/SettingController.kt b/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/documents/settings/SettingController.kt index 78d7062..56e9340 100644 --- a/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/documents/settings/SettingController.kt +++ b/tutor-assistant-app-service/src/main/kotlin/de/niklaskerkhoff/tutorassistantappservice/modules/documents/settings/SettingController.kt @@ -2,12 +2,14 @@ package de.niklaskerkhoff.tutorassistantappservice.modules.documents.settings import de.niklaskerkhoff.tutorassistantappservice.modules.documents.settings.entities.SettingDto import de.niklaskerkhoff.tutorassistantappservice.modules.documents.settings.entities.toDto +import org.springframework.security.access.prepost.PreAuthorize import org.springframework.web.bind.annotation.* import org.springframework.web.multipart.MultipartFile import java.util.* @RestController @RequestMapping("documents/settings") +@PreAuthorize("hasRole('document-manager')") class SettingController( private val settingService: SettingService ) {