From 36da51d9a63832f4a4c5282b15078f8892f645e8 Mon Sep 17 00:00:00 2001 From: Jari Date: Wed, 19 Mar 2025 15:24:00 +0100 Subject: [PATCH] client worker & auth --- .../lorca_core/common/enums/EUserRoles.kt | 3 +-- .../lorca_core/common/models/Client.kt | 7 +++++++ .../security/JwtAuthenticationFilter.kt | 2 +- .../config/security/SecurityConfig.kt | 10 +++++++-- .../services/impl/ClientServiceImpl.kt | 14 ++++++++++++- .../services/impl/JwtServiceImpl.kt | 2 +- .../web/controllers/AdminController.kt | 2 +- .../web/controllers/AuthController.kt | 2 +- .../web/controllers/WorkerController.kt | 2 +- .../lorca_core/web/utils/BaseAdvice.kt | 16 +++++++------- .../lorca_core/web/utils/dtos/ClientDto.kt | 3 ++- .../web/utils/dtos/validators/B64Validator.kt | 2 +- .../web/utils/dtos/validators/ExpValidator.kt | 4 ++-- .../web/utils/responses/WebResponse.kt | 2 +- .../fullRegisterCinematic/0_register_user.sh | 7 ++++++- .../0b_newtest_list_all.sh | 21 +++++++++++++++++++ .../2_register_client.sh | 8 +++++++ 17 files changed, 83 insertions(+), 24 deletions(-) create mode 100644 testSuite/fullRegisterCinematic/0b_newtest_list_all.sh create mode 100644 testSuite/fullRegisterCinematic/2_register_client.sh diff --git a/src/main/kotlin/org/octopus/lorca_core/common/enums/EUserRoles.kt b/src/main/kotlin/org/octopus/lorca_core/common/enums/EUserRoles.kt index 5e94dd3..7edd0e4 100644 --- a/src/main/kotlin/org/octopus/lorca_core/common/enums/EUserRoles.kt +++ b/src/main/kotlin/org/octopus/lorca_core/common/enums/EUserRoles.kt @@ -5,6 +5,5 @@ enum class EUserRoles(val role: String) { PSICO("PSICO"), ALL("ALL"), ADMIN("ADMIN"), - BASE("BASE"), - EMPTY("") + BASE("BASE") } \ No newline at end of file diff --git a/src/main/kotlin/org/octopus/lorca_core/common/models/Client.kt b/src/main/kotlin/org/octopus/lorca_core/common/models/Client.kt index c0b7f8d..4306456 100644 --- a/src/main/kotlin/org/octopus/lorca_core/common/models/Client.kt +++ b/src/main/kotlin/org/octopus/lorca_core/common/models/Client.kt @@ -1,8 +1,15 @@ package org.octopus.lorca_core.common.models +import java.util.* + data class Client( var id: Long?, var name: String, var surname: String, + var dni: String, + val phoneNumber: String, + val expNumber: String, + val userNumber: String, + val birthDate: Date, val deactivated: Boolean ) \ No newline at end of file diff --git a/src/main/kotlin/org/octopus/lorca_core/config/security/JwtAuthenticationFilter.kt b/src/main/kotlin/org/octopus/lorca_core/config/security/JwtAuthenticationFilter.kt index 9c2ff52..0173468 100644 --- a/src/main/kotlin/org/octopus/lorca_core/config/security/JwtAuthenticationFilter.kt +++ b/src/main/kotlin/org/octopus/lorca_core/config/security/JwtAuthenticationFilter.kt @@ -47,7 +47,7 @@ class JwtAuthenticationFilter( val roles = jwtService.getRoles(jwt) - if (jwtService.isTokenValid(jwt, userDetails) && roles.isNotEmpty()) { + if (jwtService.isTokenValid(jwt, userDetails)) { val authToken = UsernamePasswordAuthenticationToken( userDetails, null, diff --git a/src/main/kotlin/org/octopus/lorca_core/config/security/SecurityConfig.kt b/src/main/kotlin/org/octopus/lorca_core/config/security/SecurityConfig.kt index e168db4..2d81948 100644 --- a/src/main/kotlin/org/octopus/lorca_core/config/security/SecurityConfig.kt +++ b/src/main/kotlin/org/octopus/lorca_core/config/security/SecurityConfig.kt @@ -1,8 +1,10 @@ package org.octopus.lorca_core.config.security +import org.octopus.lorca_core.common.enums.EUserRoles import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.security.authentication.AuthenticationProvider +import org.springframework.security.authorization.AuthorizationDecision import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity @@ -26,8 +28,12 @@ class SecurityConfig( .authorizeHttpRequests { auth -> auth .requestMatchers("/auth/**").permitAll() - .requestMatchers("/workers/register/**").hasRole("EMPTY") - .anyRequest().authenticated() + .requestMatchers("/workers/register/**").access { authentication, _ -> + AuthorizationDecision( + authentication.get().isAuthenticated && authentication.get().authorities.isEmpty() + ) + } + .anyRequest().hasAnyRole(*EUserRoles.entries.map { role -> role.role }.toTypedArray()) } .sessionManagement { session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS) diff --git a/src/main/kotlin/org/octopus/lorca_core/services/impl/ClientServiceImpl.kt b/src/main/kotlin/org/octopus/lorca_core/services/impl/ClientServiceImpl.kt index b0c5c5f..c9625ac 100644 --- a/src/main/kotlin/org/octopus/lorca_core/services/impl/ClientServiceImpl.kt +++ b/src/main/kotlin/org/octopus/lorca_core/services/impl/ClientServiceImpl.kt @@ -17,6 +17,18 @@ class ClientServiceImpl(val repo: ClientRepository) : ClientService { } override fun createClient(clientDto: ClientDto): Client { - return repo.createClient(Client(null, clientDto.name, clientDto.surname, clientDto.deactivated)) + return repo.createClient( + Client( + id = 0L, + name = clientDto.name, + surname = clientDto.surname, + dni = clientDto.dni, + birthDate = clientDto.dateOfBirth, + userNumber = clientDto.numUser, + expNumber = clientDto.numExp, + phoneNumber = clientDto.phone, + deactivated = clientDto.deactivated ?: false + ) + ) } } \ No newline at end of file diff --git a/src/main/kotlin/org/octopus/lorca_core/services/impl/JwtServiceImpl.kt b/src/main/kotlin/org/octopus/lorca_core/services/impl/JwtServiceImpl.kt index 476f708..2e290c3 100644 --- a/src/main/kotlin/org/octopus/lorca_core/services/impl/JwtServiceImpl.kt +++ b/src/main/kotlin/org/octopus/lorca_core/services/impl/JwtServiceImpl.kt @@ -78,7 +78,7 @@ class JwtServiceImpl( extractAllClaims(token)["roles"]?.let { roles -> return (roles as List).map { EUserRoles.valueOf(it) } } - return listOf(EUserRoles.EMPTY) + return listOf() } private fun isTokenExpired(token: String): Boolean { diff --git a/src/main/kotlin/org/octopus/lorca_core/web/controllers/AdminController.kt b/src/main/kotlin/org/octopus/lorca_core/web/controllers/AdminController.kt index e026704..6605f04 100644 --- a/src/main/kotlin/org/octopus/lorca_core/web/controllers/AdminController.kt +++ b/src/main/kotlin/org/octopus/lorca_core/web/controllers/AdminController.kt @@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.RestController class AdminController(val adminService: AdminService) { @PutMapping("/modifyRoles") - fun addRoles(@Valid @RequestBody addRoleDto: AddRoleDto): WebResponse { + fun addRoles(@Valid @RequestBody addRoleDto: AddRoleDto): WebResponse { adminService.modifyRoles(addRoleDto.username, addRoleDto.roles) return WebResponse.ok() } diff --git a/src/main/kotlin/org/octopus/lorca_core/web/controllers/AuthController.kt b/src/main/kotlin/org/octopus/lorca_core/web/controllers/AuthController.kt index c8693e0..68a17bf 100644 --- a/src/main/kotlin/org/octopus/lorca_core/web/controllers/AuthController.kt +++ b/src/main/kotlin/org/octopus/lorca_core/web/controllers/AuthController.kt @@ -20,7 +20,7 @@ class AuthController( ) { @PostMapping("/register") - fun register(@Valid @RequestBody registerUserDto: UserAuthDto): WebResponse { + fun register(@Valid @RequestBody registerUserDto: UserAuthDto): WebResponse { authenticationService.register(registerUserDto) return WebResponse.ok() } diff --git a/src/main/kotlin/org/octopus/lorca_core/web/controllers/WorkerController.kt b/src/main/kotlin/org/octopus/lorca_core/web/controllers/WorkerController.kt index 400b4a3..59ee386 100644 --- a/src/main/kotlin/org/octopus/lorca_core/web/controllers/WorkerController.kt +++ b/src/main/kotlin/org/octopus/lorca_core/web/controllers/WorkerController.kt @@ -40,7 +40,7 @@ class WorkerController( } @PostMapping("/test") - fun createTestData(): WebResponse { + fun createTestData(): WebResponse { // workerService.createTestData() return WebResponse.ok() } diff --git a/src/main/kotlin/org/octopus/lorca_core/web/utils/BaseAdvice.kt b/src/main/kotlin/org/octopus/lorca_core/web/utils/BaseAdvice.kt index ad03070..2c546bc 100644 --- a/src/main/kotlin/org/octopus/lorca_core/web/utils/BaseAdvice.kt +++ b/src/main/kotlin/org/octopus/lorca_core/web/utils/BaseAdvice.kt @@ -21,7 +21,7 @@ class BaseAdvice { fun handleLorcaBusinessException( ex: LorcaException, request: WebRequest - ): WebResponse { + ): WebResponse { return WebResponse.ko( deductStatus(ex.ex), ex.message @@ -42,7 +42,7 @@ class BaseAdvice { fun handleNumberFormatException( ex: NumberFormatException, request: WebRequest - ): WebResponse { + ): WebResponse { return WebResponse.ko( HttpStatus.BAD_REQUEST, "${HttpStatus.BAD_REQUEST.reasonPhrase}: ${ex.message}" @@ -54,7 +54,7 @@ class BaseAdvice { fun handleNoResourceFoundException( ex: NoResourceFoundException, request: WebRequest - ): WebResponse { + ): WebResponse { return WebResponse.ko( HttpStatus.NOT_FOUND, "${HttpStatus.NOT_FOUND.reasonPhrase}: ${(request as ServletWebRequest).request.requestURI}" @@ -66,7 +66,7 @@ class BaseAdvice { fun handleHttpRequestMethodNotSupportedException( ex: HttpRequestMethodNotSupportedException, request: WebRequest - ): WebResponse { + ): WebResponse { return WebResponse.ko( HttpStatus.METHOD_NOT_ALLOWED, "${HttpStatus.METHOD_NOT_ALLOWED.reasonPhrase}: ${(request as ServletWebRequest).request.requestURI}" @@ -79,7 +79,7 @@ class BaseAdvice { fun handleMethodArgumentNotValidException( ex: MethodArgumentNotValidException, request: WebRequest - ): WebResponse { + ): WebResponse { val errors = ex.bindingResult.fieldErrors.map { "${it.field} - ${it.defaultMessage}" @@ -95,7 +95,7 @@ class BaseAdvice { fun handleHttpMessageNotReadableException( ex: HttpMessageNotReadableException, request: WebRequest - ): WebResponse { + ): WebResponse { return WebResponse.ko( HttpStatus.NOT_ACCEPTABLE, "${HttpStatus.NOT_ACCEPTABLE.reasonPhrase}: JSON parse error" @@ -107,7 +107,7 @@ class BaseAdvice { fun handleAuthorizationDeniedException( ex: AuthorizationDeniedException, request: WebRequest - ): WebResponse { + ): WebResponse { return WebResponse.ko( HttpStatus.FORBIDDEN, "${HttpStatus.FORBIDDEN.reasonPhrase}: ${ex.message}" @@ -120,7 +120,7 @@ class BaseAdvice { fun handleException( ex: Exception, request: WebRequest - ): WebResponse { + ): WebResponse { return WebResponse.ko( HttpStatus.INTERNAL_SERVER_ERROR, ex.message diff --git a/src/main/kotlin/org/octopus/lorca_core/web/utils/dtos/ClientDto.kt b/src/main/kotlin/org/octopus/lorca_core/web/utils/dtos/ClientDto.kt index 2b5b999..2a2d756 100644 --- a/src/main/kotlin/org/octopus/lorca_core/web/utils/dtos/ClientDto.kt +++ b/src/main/kotlin/org/octopus/lorca_core/web/utils/dtos/ClientDto.kt @@ -17,7 +17,8 @@ data class ClientDto( val phone: String, @field:ExpValidator.Validate val numExp: String, + @field:ExpValidator.Validate val numUser: String, val dateOfBirth: Date, - val deactivated: Boolean + val deactivated: Boolean? = false ) \ No newline at end of file diff --git a/src/main/kotlin/org/octopus/lorca_core/web/utils/dtos/validators/B64Validator.kt b/src/main/kotlin/org/octopus/lorca_core/web/utils/dtos/validators/B64Validator.kt index 8b9a54f..4cee988 100644 --- a/src/main/kotlin/org/octopus/lorca_core/web/utils/dtos/validators/B64Validator.kt +++ b/src/main/kotlin/org/octopus/lorca_core/web/utils/dtos/validators/B64Validator.kt @@ -15,7 +15,7 @@ class B64Validator : ConstraintValidator { } context.disableDefaultConstraintViolation() - context.buildConstraintViolationWithTemplate("Invalid value '$value' : Only 4 to 16 lowercase letters are allowed") + context.buildConstraintViolationWithTemplate("Invalid value '$value' : this is not b64") .addConstraintViolation() return false diff --git a/src/main/kotlin/org/octopus/lorca_core/web/utils/dtos/validators/ExpValidator.kt b/src/main/kotlin/org/octopus/lorca_core/web/utils/dtos/validators/ExpValidator.kt index 1493087..f4736b0 100644 --- a/src/main/kotlin/org/octopus/lorca_core/web/utils/dtos/validators/ExpValidator.kt +++ b/src/main/kotlin/org/octopus/lorca_core/web/utils/dtos/validators/ExpValidator.kt @@ -9,14 +9,14 @@ import kotlin.reflect.KClass class ExpValidator : ConstraintValidator { override fun isValid(value: String?, context: ConstraintValidatorContext): Boolean { - val pattern = Regex("") + val pattern = Regex("\\d+/[0-9]{4}") if (value == null || value.matches(pattern)) { return true } context.disableDefaultConstraintViolation() - context.buildConstraintViolationWithTemplate("Invalid value '$value' : 8 numbers and a letter are expected.") + context.buildConstraintViolationWithTemplate("Invalid value '$value' : digits/full_year is expected") .addConstraintViolation() return false diff --git a/src/main/kotlin/org/octopus/lorca_core/web/utils/responses/WebResponse.kt b/src/main/kotlin/org/octopus/lorca_core/web/utils/responses/WebResponse.kt index 4cae6b8..13e3b11 100644 --- a/src/main/kotlin/org/octopus/lorca_core/web/utils/responses/WebResponse.kt +++ b/src/main/kotlin/org/octopus/lorca_core/web/utils/responses/WebResponse.kt @@ -10,7 +10,7 @@ data class WebResponse( ) { companion object { - fun ok(): WebResponse { + fun ok(): WebResponse { return WebResponse(status = HttpStatus.OK) } diff --git a/testSuite/fullRegisterCinematic/0_register_user.sh b/testSuite/fullRegisterCinematic/0_register_user.sh index f0aaf06..938752f 100644 --- a/testSuite/fullRegisterCinematic/0_register_user.sh +++ b/testSuite/fullRegisterCinematic/0_register_user.sh @@ -1,3 +1,8 @@ +#curl -X POST http://localhost:8080/api/auth/register \ +# -H "Content-Type: application/json" \ +# -d '{"username":"test","password":"cGFzc3dvcmQ="}' + + curl -X POST http://localhost:8080/api/auth/register \ -H "Content-Type: application/json" \ - -d '{"username":"test","password":"cGFzc3dvcmQ="}' + -d '{"username":"newtest","password":"cGFzc3dvcmQ="}' diff --git a/testSuite/fullRegisterCinematic/0b_newtest_list_all.sh b/testSuite/fullRegisterCinematic/0b_newtest_list_all.sh new file mode 100644 index 0000000..f22f2c0 --- /dev/null +++ b/testSuite/fullRegisterCinematic/0b_newtest_list_all.sh @@ -0,0 +1,21 @@ +TOKEN=$(curl -s -X POST http://localhost:8080/api/auth/login \ + -H "Content-Type: application/json" \ + -d '{"username":"newtest","password":"cGFzc3dvcmQ="}' | sed -n 's/.*"token":"\([^"]*\)".*/\1/p') + + +curl -X GET http://localhost:8080/api/workers \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" + + +# UNCOMMENT BELOW TO REGISTER USER +# +#curl -X POST http://localhost:8080/api/workers/register \ +# -H "Authorization: Bearer $TOKEN" \ +# -H "Content-Type: application/json" \ +# -d '{"name": "TestTest","surname": "TestTest","dni": "12345678B","dateOfBirth": "1990-05-15","email": "example@domain.org","category":"FISIO"}' +# +# +#curl -X GET http://localhost:8080/api/workers \ +# -H "Authorization: Bearer $TOKEN" \ +# -H "Content-Type: application/json" diff --git a/testSuite/fullRegisterCinematic/2_register_client.sh b/testSuite/fullRegisterCinematic/2_register_client.sh new file mode 100644 index 0000000..5e82777 --- /dev/null +++ b/testSuite/fullRegisterCinematic/2_register_client.sh @@ -0,0 +1,8 @@ +TOKEN=$(curl -s -X POST http://localhost:8080/api/auth/login \ + -H "Content-Type: application/json" \ + -d '{"username":"test","password":"cGFzc3dvcmQ="}' | sed -n 's/.*"token":"\([^"]*\)".*/\1/p') + +curl -X POST http://localhost:8080/api/clients \ + -H "Authorization: Bearer $TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"name": "TestClient","surname": "TestClient","dni": "87654321Z","dateOfBirth": "1990-05-15","email": "client_one@mailbox.org", "deactivated":false, "phone":"665872262","numExp":"4/2024", "numUser":"100/2025"}'