Compare commits

..

8 Commits

Author SHA1 Message Date
Jari 36da51d9a6 client worker & auth 2025-03-19 15:24:00 +01:00
Jari 9421c9f593 better clients worker auth everything 2025-03-12 22:50:05 +01:00
Jari e2cd042e59 package name change 2025-03-12 13:21:12 +01:00
Jari 1910f30289 User & Worker link 2025-03-11 21:08:05 +01:00
Jari 4a1b808b2c User & Worker link 2025-03-11 21:07:37 +01:00
Jari eaed2a1e04 add claims & user in JWT 2025-03-10 23:45:18 +01:00
Jari 85dcbad805 base commit 2025-03-10 23:02:01 +01:00
Jari 444eee2394 base commit 2025-03-10 23:00:30 +01:00
104 changed files with 1009 additions and 390 deletions

View File

View File

@ -8,7 +8,7 @@ plugins {
}
group = "org.js"
group = "org.octopus"
version = "0.0.1-SNAPSHOT"

View File

View File

@ -1 +0,0 @@
rootProject.name = "lorca-core"

View File

@ -1,8 +0,0 @@
package org.js.lorca_core.business.mappers
import org.js.lorca_core.business.models.Client
import org.js.lorca_core.db.entities.ClientEntity
import org.mapstruct.Mapper
@Mapper(componentModel = "spring")
interface ClientMapper : GenericMapper<Client, ClientEntity>

View File

@ -1,8 +0,0 @@
package org.js.lorca_core.business.mappers
import org.js.lorca_core.business.models.UserAuthClaim
import org.js.lorca_core.db.entities.UserAuthClaimEntity
import org.mapstruct.Mapper
@Mapper(componentModel = "spring")
interface UserAuthClaimMapper : GenericMapper<UserAuthClaim, UserAuthClaimEntity>

View File

@ -1,7 +0,0 @@
package org.js.lorca_core.business.models
data class Client(
var id: Long?,
var name: String,
var surname: String
)

View File

@ -1,8 +0,0 @@
package org.js.lorca_core.business.models
import org.js.lorca_core.common.enums.EUserRoles
data class UserAuthClaim(
var id: Long,
var name: EUserRoles
)

View File

@ -1,10 +0,0 @@
package org.js.lorca_core.business.repositories
import org.js.lorca_core.business.models.Client
interface ClientRepository {
fun createClient(client: Client): Client
fun getAll(): MutableList<Client>
fun getById(id: Long): Client
}

View File

@ -1,10 +0,0 @@
package org.js.lorca_core.business.repositories
import org.js.lorca_core.common.enums.EUserRoles
import org.js.lorca_core.db.entities.UserAuthEntity
interface UserAuthRepository {
fun getByUsername(username: String): UserAuthEntity
fun save(userAuth: UserAuthEntity): UserAuthEntity
fun getClaimsForuser(user: UserAuthEntity): List<EUserRoles>
}

View File

@ -1,30 +0,0 @@
package org.js.lorca_core.business.repositories.impl
import org.js.lorca_core.business.mappers.UserAuthClaimMapper
import org.js.lorca_core.business.repositories.UserAuthRepository
import org.js.lorca_core.common.enums.EBusinessException
import org.js.lorca_core.common.enums.EUserRoles
import org.js.lorca_core.common.exceptions.LorcaException
import org.js.lorca_core.db.UserAuthJpa
import org.js.lorca_core.db.entities.UserAuthEntity
import org.springframework.stereotype.Component
@Component
class UserAuthRepositoryImpl(
protected val jpa: UserAuthJpa,
protected val claimMapper: UserAuthClaimMapper
) : UserAuthRepository {
override fun getByUsername(username: String): UserAuthEntity {
return jpa.findByUsr(username)
.orElseThrow { LorcaException.create(EBusinessException.USER_NOT_FOUND, username) }
}
override fun save(userAuth: UserAuthEntity): UserAuthEntity {
return jpa.save(userAuth)
}
override fun getClaimsForuser(user: UserAuthEntity): List<EUserRoles> {
return claimMapper.toModels(user.claims).map { it.name }.toList()
}
}

View File

@ -1,5 +0,0 @@
package org.js.lorca_core.common.enums
enum class EWorkerCategory(name: String) {
FISIO("FISIO")
}

View File

@ -1,6 +0,0 @@
package org.js.lorca_core.db
import org.js.lorca_core.db.entities.ClientEntity
import org.springframework.data.jpa.repository.JpaRepository
interface ClientJpa : JpaRepository<ClientEntity, Long>

View File

@ -1,11 +0,0 @@
package org.js.lorca_core.db
import org.js.lorca_core.common.enums.EWorkerCategory
import org.js.lorca_core.db.entities.WorkerEntity
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.repository.query.Param
interface WorkerJpa : JpaRepository<WorkerEntity, Long> {
fun findAllByCategoryName(@Param("category") category: EWorkerCategory): MutableList<WorkerEntity>
}

View File

@ -1,14 +0,0 @@
package org.js.lorca_core.db.entities
import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id
@Entity(name = "clients")
data class ClientEntity(
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long = 0L,
var name: String,
var surname: String
)

View File

@ -1,14 +0,0 @@
package org.js.lorca_core.db.entities
import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id
import org.js.lorca_core.common.enums.EUserRoles
@Entity(name = "user_auth_claims")
data class UserAuthClaimEntity(
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long = 0L,
var name: EUserRoles
)

View File

@ -1,14 +0,0 @@
package org.js.lorca_core.db.entities
import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id
import org.js.lorca_core.common.enums.EWorkerCategory
@Entity(name = "worker_categories")
data class WorkerCategoryEntity(
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long = 0L,
var name: EWorkerCategory
)

View File

@ -1,13 +0,0 @@
package org.js.lorca_core.db.entities
import jakarta.persistence.*
@Entity(name = "workers")
data class WorkerEntity(
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long = 0L,
var name: String,
var surname: String,
@ManyToOne(fetch = FetchType.LAZY)
val category: WorkerCategoryEntity
)

View File

@ -1,13 +0,0 @@
package org.js.lorca_core.services
import org.js.lorca_core.common.enums.EUserRoles
import org.js.lorca_core.db.entities.UserAuthEntity
import org.js.lorca_core.web.dtos.UserAuthDto
interface AuthenticationService {
fun register(input: UserAuthDto): Boolean
fun login(input: UserAuthDto): UserAuthEntity
fun getClaimsForUser(user: UserAuthEntity): List<EUserRoles>
}

View File

@ -1,10 +0,0 @@
package org.js.lorca_core.services
import org.js.lorca_core.business.models.Client
import org.js.lorca_core.web.dtos.ClientDto
interface ClientService {
fun getAllClients(name: String?, surname: String?): MutableList<Client>
fun getClientById(id: Long): Client
fun createClient(clientDto: ClientDto): Client
}

View File

@ -1,44 +0,0 @@
package org.js.lorca_core.services.impl
import org.js.lorca_core.business.repositories.UserAuthRepository
import org.js.lorca_core.common.enums.EUserRoles
import org.js.lorca_core.db.entities.UserAuthEntity
import org.js.lorca_core.services.AuthenticationService
import org.js.lorca_core.web.dtos.UserAuthDto
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.stereotype.Service
@Service
class AuthenticationServiceImpl(
private val userAuthRepository: UserAuthRepository,
private val authenticationManager: AuthenticationManager,
private val passwordEncoder: PasswordEncoder
) : AuthenticationService {
override fun register(input: UserAuthDto): Boolean {
val user = UserAuthEntity()
user.username = input.username
user.password = passwordEncoder.encode(input.password)
userAuthRepository.save(user)
return true
}
override fun login(input: UserAuthDto): UserAuthEntity {
authenticationManager.authenticate(
UsernamePasswordAuthenticationToken(
input.username,
input.password
)
)
return userAuthRepository.getByUsername(input.username)
}
override fun getClaimsForUser(user: UserAuthEntity): List<EUserRoles> {
return userAuthRepository.getClaimsForuser(user)
}
}

View File

@ -1,22 +0,0 @@
package org.js.lorca_core.services.impl
import org.js.lorca_core.business.models.Client
import org.js.lorca_core.business.repositories.ClientRepository
import org.js.lorca_core.services.ClientService
import org.js.lorca_core.web.dtos.ClientDto
import org.springframework.stereotype.Service
@Service
class ClientServiceImpl(val repo: ClientRepository) : ClientService {
override fun getAllClients(name: String?, surname: String?): MutableList<Client> {
return repo.getAll()
}
override fun getClientById(id: Long): Client {
return repo.getById(id)
}
override fun createClient(clientDto: ClientDto): Client {
return repo.createClient(Client(null, clientDto.name, clientDto.surname))
}
}

View File

@ -1,10 +0,0 @@
package org.js.lorca_core.web.dtos
import org.js.lorca_core.web.dtos.validators.NameValidator
data class ClientDto(
@field:NameValidator.Validate
val name: String,
@field:NameValidator.Validate
val surname: String
)

View File

@ -1,11 +0,0 @@
package org.js.lorca_core.web.dtos
import org.js.lorca_core.web.dtos.validators.B64Validator
import org.js.lorca_core.web.dtos.validators.UsernameValidator
data class UserAuthDto(
@field:UsernameValidator.Validate
val username: String,
@field:B64Validator.Validate
val password: String
)

View File

@ -1,9 +0,0 @@
package org.js.lorca_core.web.responses
import org.js.lorca_core.common.enums.EUserRoles
data class LoginResponse(
val token: String,
val expiresIn: Long,
val claims: List<EUserRoles>
)

1
psql/.gitignore vendored
View File

@ -1 +0,0 @@
.env

View File

@ -1,21 +0,0 @@
services:
postgres:
container_name: postgres
image: postgres:latest
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PW}
- POSTGRES_DB=${POSTGRES_DB}
ports:
- "5432:5432"
restart: always
pgadmin:
container_name: pgadmin
image: dpage/pgadmin4:latest
environment:
- PGADMIN_DEFAULT_EMAIL=${PGADMIN_MAIL}
- PGADMIN_DEFAULT_PASSWORD=${PGADMIN_PW}
ports:
- "5050:80"
restart: always

1
settings.gradle.kts Normal file
View File

@ -0,0 +1 @@
rootProject.name = "lorca-gestionale-be"

View File

@ -1,9 +1,9 @@
package org.js.lorca_core
package org.octopus.lorca_core
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication(scanBasePackages = ["org.js.lorca_core"])
@SpringBootApplication(scanBasePackages = ["org.octopus.lorca_core"])
class LorcaCoreApplication
fun main(args: Array<String>) {

View File

@ -1,6 +1,8 @@
package org.js.lorca_core.common.enums
package org.octopus.lorca_core.common.enums
enum class EBusinessException(val msg: String) {
IMPOSSIBLE_ADD_ROLES("Impossible to add roles for username: '%s'. Check logs."),
USER_ALREADY_EXISTS("Username: '%s' already exists"),
USER_NOT_FOUND("Username: '%s' not found"),
ENTITY_WITH_ID_NOT_FOUND("%s with id %s not found"),
INVALID_REQUEST("Invalid request for %s with reason: %s")

View File

@ -1,8 +1,9 @@
package org.js.lorca_core.common.enums
package org.octopus.lorca_core.common.enums
enum class EUserRoles(val role: String) {
FISIO("FISIO"),
PSICO("PSICO"),
ALL("ALL"),
ADMIN("ADMIN")
ADMIN("ADMIN"),
BASE("BASE")
}

View File

@ -0,0 +1,5 @@
package org.octopus.lorca_core.common.enums
enum class EWorkerCategory {
FISIO
}

View File

@ -1,6 +1,6 @@
package org.js.lorca_core.common.exceptions
package org.octopus.lorca_core.common.exceptions
import org.js.lorca_core.common.enums.EBusinessException
import org.octopus.lorca_core.common.enums.EBusinessException
class LorcaException(val ex: EBusinessException, override val message: String) : Exception() {

View File

@ -0,0 +1,8 @@
package org.octopus.lorca_core.common.mappers
import org.mapstruct.Mapper
import org.octopus.lorca_core.common.models.Client
import org.octopus.lorca_core.db.entities.ClientEntity
@Mapper(componentModel = "spring")
interface ClientMapper : GenericMapper<Client, ClientEntity>

View File

@ -1,4 +1,4 @@
package org.js.lorca_core.business.mappers
package org.octopus.lorca_core.common.mappers
interface GenericMapper<M, E> {

View File

@ -0,0 +1,8 @@
package org.octopus.lorca_core.common.mappers
import org.mapstruct.Mapper
import org.octopus.lorca_core.common.models.Report
import org.octopus.lorca_core.db.entities.ReportEntity
@Mapper(componentModel = "spring")
interface ReportMapper : GenericMapper<Report, ReportEntity>

View File

@ -0,0 +1,12 @@
package org.octopus.lorca_core.common.mappers
import org.mapstruct.Mapper
import org.mapstruct.Mapping
import org.octopus.lorca_core.common.models.Worker
import org.octopus.lorca_core.db.entities.WorkerEntity
@Mapper(componentModel = "spring")
interface WorkerMapper : GenericMapper<Worker, WorkerEntity> {
@Mapping(target = "authUser", ignore = true)
override fun toEntity(model: Worker): WorkerEntity
}

View File

@ -0,0 +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
)

View File

@ -0,0 +1,10 @@
package org.octopus.lorca_core.common.models
import java.util.*
data class Report(
var id: Long = 0L,
var reportDate: Date,
val filedBy: Worker,
val clients: MutableList<Client> = mutableListOf()
)

View File

@ -0,0 +1,14 @@
package org.octopus.lorca_core.common.models
import org.octopus.lorca_core.common.enums.EWorkerCategory
import java.util.*
data class Worker(
var id: Long,
var name: String,
var surname: String,
var birthDate: Date,
var dni: String,
var email: String,
var category: EWorkerCategory,
)

View File

@ -1,6 +1,6 @@
package org.js.lorca_core.config.auth
package org.octopus.lorca_core.config.security
import org.js.lorca_core.business.repositories.UserAuthRepository
import org.octopus.lorca_core.repositories.UserAuthRepository
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.authentication.AuthenticationManager

View File

@ -1,13 +1,14 @@
package org.js.lorca_core.config.auth
package org.octopus.lorca_core.config.security
import jakarta.servlet.FilterChain
import jakarta.servlet.ServletException
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import org.js.lorca_core.services.JwtService
import org.octopus.lorca_core.services.JwtService
import org.springframework.lang.NonNull
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.Authentication
import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.security.core.userdetails.UserDetailsService
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource
@ -44,11 +45,13 @@ class JwtAuthenticationFilter(
if (authentication == null) {
val userDetails = userDetailsService.loadUserByUsername(userEmail)
val roles = jwtService.getRoles(jwt)
if (jwtService.isTokenValid(jwt, userDetails)) {
val authToken = UsernamePasswordAuthenticationToken(
userDetails,
null,
userDetails.authorities
roles.map { SimpleGrantedAuthority("ROLE_$it") }
)
authToken.details = WebAuthenticationDetailsSource().buildDetails(request)

View File

@ -1,9 +1,11 @@
package org.js.lorca_core.config
package org.octopus.lorca_core.config.security
import org.js.lorca_core.config.auth.JwtAuthenticationFilter
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
import org.springframework.security.config.http.SessionCreationPolicy
@ -13,6 +15,8 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(securedEnabled = true)
class SecurityConfig(
val authenticationProvider: AuthenticationProvider,
val jwtAuthenticationFilter: JwtAuthenticationFilter
@ -23,8 +27,13 @@ class SecurityConfig(
http
.authorizeHttpRequests { auth ->
auth
.requestMatchers("/**").permitAll()
.anyRequest().authenticated()
.requestMatchers("/auth/**").permitAll()
.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)

View File

@ -0,0 +1,8 @@
package org.octopus.lorca_core.db
import org.octopus.lorca_core.db.entities.ClientEntity
import org.springframework.data.jpa.repository.JpaRepository
interface ClientJpa : JpaRepository<ClientEntity, Long> {
fun findAllByDeactivatedIsFalse(): MutableList<ClientEntity>
}

View File

@ -0,0 +1,6 @@
package org.octopus.lorca_core.db
import org.octopus.lorca_core.db.entities.ReportEntity
import org.springframework.data.jpa.repository.JpaRepository
interface ReportJpa : JpaRepository<ReportEntity, Long>

View File

@ -1,9 +1,10 @@
package org.js.lorca_core.db
package org.octopus.lorca_core.db
import org.js.lorca_core.db.entities.UserAuthEntity
import org.octopus.lorca_core.db.entities.UserAuthEntity
import org.springframework.data.jpa.repository.JpaRepository
import java.util.*
interface UserAuthJpa : JpaRepository<UserAuthEntity, Long> {
fun findByUsr(username: String): Optional<UserAuthEntity>
fun existsByUsr(username: String): Boolean
}

View File

@ -0,0 +1,11 @@
package org.octopus.lorca_core.db
import org.octopus.lorca_core.common.enums.EWorkerCategory
import org.octopus.lorca_core.db.entities.WorkerEntity
import org.springframework.data.jpa.repository.JpaRepository
import java.util.*
interface WorkerJpa : JpaRepository<WorkerEntity, Long> {
fun findByAuthUserUsr(username: String): Optional<WorkerEntity>
fun findAllByCategory(category: EWorkerCategory): MutableList<WorkerEntity>
}

View File

@ -0,0 +1,20 @@
package org.octopus.lorca_core.db.entities
import jakarta.persistence.*
import java.util.*
@Entity(name = "clients")
data class ClientEntity(
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long = 0L,
var name: String,
var surname: String,
var dni: String,
val phoneNumber: String,
@Column(unique = true)
val expNumber: String,
@Column(unique = true)
val userNumber: String,
val birthDate: Date,
val deactivated: Boolean
)

View File

@ -1,4 +1,4 @@
package org.js.lorca_core.db.entities
package org.octopus.lorca_core.db.entities
import jakarta.persistence.*
import java.util.*
@ -13,5 +13,5 @@ data class ReportEntity(
val filedBy: WorkerEntity,
@OneToMany(fetch = FetchType.LAZY, cascade = [CascadeType.DETACH])
val clientEntities: MutableList<ClientEntity> = mutableListOf()
val clients: MutableList<ClientEntity> = mutableListOf()
)

View File

@ -1,19 +1,37 @@
package org.js.lorca_core.db.entities
package org.octopus.lorca_core.db.entities
import jakarta.persistence.*
import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue
import jakarta.persistence.Id
import org.octopus.lorca_core.common.enums.EUserRoles
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.userdetails.UserDetails
@Entity(name = "user_auth")
class UserAuthEntity : UserDetails {
class UserAuthEntity(usr: String, pwd: String) : UserDetails {
@Id
@GeneratedValue
var id: Long? = null
var usr: String? = null
var pwd: String? = null
@ManyToMany(cascade = [CascadeType.DETACH])
var claims: MutableList<UserAuthClaimEntity> = mutableListOf()
@Column(nullable = false, unique = true)
var usr: String? = usr
@Column(nullable = false, unique = true)
var pwd: String? = pwd
@Column(length = 255)
var claims: String = ""
fun getClaimsList(): List<EUserRoles> {
return claims.split(",").mapNotNull {
runCatching { EUserRoles.valueOf(it) }.getOrNull()
}
}
fun setClaimsList(roles: List<EUserRoles>) {
claims = roles.joinToString(",") { it.name }
}
override fun getAuthorities(): Collection<GrantedAuthority> {
return listOf()

View File

@ -0,0 +1,19 @@
package org.octopus.lorca_core.db.entities
import jakarta.persistence.*
import org.octopus.lorca_core.common.enums.EWorkerCategory
import java.util.*
@Entity(name = "workers")
data class WorkerEntity(
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long = 0L,
var name: String,
var surname: String,
var birthDate: Date,
var dni: String,
var email: String,
var category: EWorkerCategory,
@OneToOne
var authUser: UserAuthEntity
)

View File

@ -0,0 +1,10 @@
package org.octopus.lorca_core.repositories
import org.octopus.lorca_core.common.models.Client
interface ClientRepository {
fun createClient(client: Client): Client
fun getAll(includeNotActive: Boolean): MutableList<Client>
fun getById(id: Long): Client
}

View File

@ -0,0 +1,10 @@
package org.octopus.lorca_core.repositories
import org.octopus.lorca_core.common.models.Client
import org.octopus.lorca_core.common.models.Report
import org.octopus.lorca_core.common.models.Worker
import java.util.*
interface ReportRepository {
fun createReport(filedBy: Worker, clients: List<Client>, scheduledDate: Date?): Report
}

View File

@ -0,0 +1,11 @@
package org.octopus.lorca_core.repositories
import org.octopus.lorca_core.common.enums.EUserRoles
import org.octopus.lorca_core.db.entities.UserAuthEntity
interface UserAuthRepository {
fun existsByUsername(username: String): Boolean
fun getByUsername(username: String): UserAuthEntity
fun save(userAuth: UserAuthEntity): UserAuthEntity
fun modifyClaims(username: String, claims: List<EUserRoles>): Boolean
}

View File

@ -0,0 +1,12 @@
package org.octopus.lorca_core.repositories
import org.octopus.lorca_core.common.enums.EWorkerCategory
import org.octopus.lorca_core.common.models.Worker
import org.octopus.lorca_core.db.entities.UserAuthEntity
interface WorkerRepository {
fun getByUsername(username: String): Worker?
fun createForUser(worker: Worker, userAuth: UserAuthEntity): Worker
fun getAll(): MutableList<Worker>
fun getAllByCategory(category: EWorkerCategory): MutableList<Worker>
}

View File

@ -1,11 +1,11 @@
package org.js.lorca_core.business.repositories.impl
package org.octopus.lorca_core.repositories.impl
import org.js.lorca_core.business.mappers.ClientMapper
import org.js.lorca_core.business.models.Client
import org.js.lorca_core.business.repositories.ClientRepository
import org.js.lorca_core.common.enums.EBusinessException
import org.js.lorca_core.common.exceptions.LorcaException
import org.js.lorca_core.db.ClientJpa
import org.octopus.lorca_core.common.enums.EBusinessException
import org.octopus.lorca_core.common.exceptions.LorcaException
import org.octopus.lorca_core.common.mappers.ClientMapper
import org.octopus.lorca_core.common.models.Client
import org.octopus.lorca_core.db.ClientJpa
import org.octopus.lorca_core.repositories.ClientRepository
import org.springframework.stereotype.Component
@Component
@ -18,8 +18,14 @@ class ClientRepositoryImpl(
}
override fun getAll(): MutableList<Client> {
return mapper.toModels(jpa.findAll())
override fun getAll(includeNotActive: Boolean): MutableList<Client> {
return mapper.toModels(
if (includeNotActive) {
jpa.findAll()
} else {
jpa.findAllByDeactivatedIsFalse()
}
)
}
override fun getById(id: Long): Client {

View File

@ -0,0 +1,31 @@
package org.octopus.lorca_core.repositories.impl
import org.octopus.lorca_core.common.mappers.ReportMapper
import org.octopus.lorca_core.common.models.Client
import org.octopus.lorca_core.common.models.Report
import org.octopus.lorca_core.common.models.Worker
import org.octopus.lorca_core.db.ReportJpa
import org.octopus.lorca_core.repositories.ReportRepository
import org.springframework.stereotype.Component
import java.util.*
@Component
class ReportRepositoryImpl(
protected val jpa: ReportJpa,
protected val mapper: ReportMapper
) : ReportRepository {
override fun createReport(filedBy: Worker, clients: List<Client>, scheduledDate: Date?): Report {
return mapper.toModel(
jpa.save(
mapper.toEntity(
Report(
id = 0,
reportDate = scheduledDate ?: Date(),
filedBy = filedBy,
clients = clients.toMutableList()
)
)
)
)
}
}

View File

@ -0,0 +1,38 @@
package org.octopus.lorca_core.repositories.impl
import org.octopus.lorca_core.common.enums.EBusinessException
import org.octopus.lorca_core.common.enums.EUserRoles
import org.octopus.lorca_core.common.exceptions.LorcaException
import org.octopus.lorca_core.db.UserAuthJpa
import org.octopus.lorca_core.db.entities.UserAuthEntity
import org.octopus.lorca_core.repositories.UserAuthRepository
import org.springframework.stereotype.Component
@Component
class UserAuthRepositoryImpl(
protected val jpa: UserAuthJpa
) : UserAuthRepository {
override fun getByUsername(username: String): UserAuthEntity {
return jpa.findByUsr(username)
.orElseThrow { LorcaException.create(EBusinessException.USER_NOT_FOUND, username) }
}
override fun save(userAuth: UserAuthEntity): UserAuthEntity {
return jpa.save(userAuth)
}
override fun modifyClaims(username: String, claims: List<EUserRoles>): Boolean {
if (!existsByUsername(username)) {
return false
}
val uae = getByUsername(username)
uae.setClaimsList(roles = claims)
save(uae)
return true
}
override fun existsByUsername(username: String): Boolean {
return jpa.existsByUsr(username)
}
}

View File

@ -0,0 +1,48 @@
package org.octopus.lorca_core.repositories.impl
import org.octopus.lorca_core.common.enums.EUserRoles
import org.octopus.lorca_core.common.enums.EWorkerCategory
import org.octopus.lorca_core.common.mappers.WorkerMapper
import org.octopus.lorca_core.common.models.Worker
import org.octopus.lorca_core.db.WorkerJpa
import org.octopus.lorca_core.db.entities.UserAuthEntity
import org.octopus.lorca_core.db.entities.WorkerEntity
import org.octopus.lorca_core.repositories.WorkerRepository
import org.springframework.stereotype.Component
import kotlin.jvm.optionals.getOrNull
@Component
class WorkerRepositoryImpl(
val jpa: WorkerJpa,
val mapper: WorkerMapper
) : WorkerRepository {
override fun getByUsername(username: String): Worker? {
val user = jpa.findByAuthUserUsr(username).getOrNull()
return if (user != null) mapper.toModel(user) else null
}
override fun createForUser(worker: Worker, userAuth: UserAuthEntity): Worker {
userAuth.setClaimsList(listOf(EUserRoles.FISIO, EUserRoles.ADMIN))
val w = WorkerEntity(
id = 0L,
name = worker.name,
surname = worker.surname,
email = worker.email,
dni = worker.dni,
birthDate = worker.birthDate,
category = worker.category,
authUser = userAuth
)
val ent = jpa.save(w)
return mapper.toModel(ent)
}
override fun getAll(): MutableList<Worker> {
return mapper.toModels(jpa.findAll())
}
override fun getAllByCategory(category: EWorkerCategory): MutableList<Worker> {
return mapper.toModels(jpa.findAllByCategory(category))
}
}

View File

@ -0,0 +1,7 @@
package org.octopus.lorca_core.services
import org.octopus.lorca_core.common.enums.EUserRoles
interface AdminService {
fun modifyRoles(username: String, claims: List<EUserRoles>)
}

View File

@ -0,0 +1,10 @@
package org.octopus.lorca_core.services
import org.octopus.lorca_core.web.utils.dtos.UserAuthDto
import org.octopus.lorca_core.web.utils.responses.LoginResponse
interface AuthenticationService {
fun register(dto: UserAuthDto): Boolean
fun login(dto: UserAuthDto): LoginResponse
}

View File

@ -0,0 +1,10 @@
package org.octopus.lorca_core.services
import org.octopus.lorca_core.common.models.Client
import org.octopus.lorca_core.web.utils.dtos.ClientDto
interface ClientService {
fun getAllClients(includeDeactivated: Boolean): MutableList<Client>
fun getClientById(id: Long): Client
fun createClient(clientDto: ClientDto): Client
}

View File

@ -1,6 +1,7 @@
package org.js.lorca_core.services
package org.octopus.lorca_core.services
import io.jsonwebtoken.Claims
import org.octopus.lorca_core.common.enums.EUserRoles
import org.springframework.security.core.userdetails.UserDetails
import java.util.function.Function
@ -17,4 +18,6 @@ interface JwtService {
fun getExpirationTime(): Long
fun isTokenValid(token: String, userDetails: UserDetails): Boolean
fun getRoles(token: String): List<EUserRoles>
}

View File

@ -0,0 +1,11 @@
package org.octopus.lorca_core.services
import org.octopus.lorca_core.common.enums.EWorkerCategory
import org.octopus.lorca_core.common.models.Worker
import org.octopus.lorca_core.web.utils.dtos.WorkerDto
interface WorkerService {
fun getAllWorkers(): List<Worker>
fun getAllWorkersForCategory(workCategory: EWorkerCategory): List<Worker>
fun createWorker(workerDto: WorkerDto, username: String): Worker
}

View File

@ -0,0 +1,19 @@
package org.octopus.lorca_core.services.impl
import org.octopus.lorca_core.common.enums.EBusinessException
import org.octopus.lorca_core.common.enums.EUserRoles
import org.octopus.lorca_core.common.exceptions.LorcaException
import org.octopus.lorca_core.repositories.UserAuthRepository
import org.octopus.lorca_core.services.AdminService
import org.springframework.stereotype.Service
@Service
class AdminServiceImpl(
val userAuthRepository: UserAuthRepository
) : AdminService {
override fun modifyRoles(username: String, claims: List<EUserRoles>) {
if (!userAuthRepository.modifyClaims(username, claims)) {
throw LorcaException.create(EBusinessException.IMPOSSIBLE_ADD_ROLES, username)
}
}
}

View File

@ -0,0 +1,52 @@
package org.octopus.lorca_core.services.impl
import org.octopus.lorca_core.common.enums.EBusinessException
import org.octopus.lorca_core.common.exceptions.LorcaException
import org.octopus.lorca_core.db.entities.UserAuthEntity
import org.octopus.lorca_core.repositories.UserAuthRepository
import org.octopus.lorca_core.repositories.WorkerRepository
import org.octopus.lorca_core.services.AuthenticationService
import org.octopus.lorca_core.services.JwtService
import org.octopus.lorca_core.web.utils.dtos.UserAuthDto
import org.octopus.lorca_core.web.utils.responses.LoginResponse
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.stereotype.Service
@Service
class AuthenticationServiceImpl(
private val userAuthRepository: UserAuthRepository,
private val authenticationManager: AuthenticationManager,
private val passwordEncoder: PasswordEncoder,
private val jwtService: JwtService,
private val workerRepository: WorkerRepository
) : AuthenticationService {
override fun register(dto: UserAuthDto): Boolean {
if (userAuthRepository.existsByUsername(dto.username)) {
throw LorcaException.create(EBusinessException.USER_ALREADY_EXISTS, dto.username)
}
userAuthRepository.save(UserAuthEntity(dto.username, passwordEncoder.encode(dto.password)))
return true
}
override fun login(dto: UserAuthDto): LoginResponse {
authenticationManager.authenticate(
UsernamePasswordAuthenticationToken(
dto.username,
dto.password
)
)
val userAuth = userAuthRepository.getByUsername(dto.username)
var userInfo = workerRepository.getByUsername(dto.username)
return LoginResponse(
jwtService.generateToken(userAuth),
userInfo
)
}
}

View File

@ -0,0 +1,34 @@
package org.octopus.lorca_core.services.impl
import org.octopus.lorca_core.common.models.Client
import org.octopus.lorca_core.repositories.ClientRepository
import org.octopus.lorca_core.services.ClientService
import org.octopus.lorca_core.web.utils.dtos.ClientDto
import org.springframework.stereotype.Service
@Service
class ClientServiceImpl(val repo: ClientRepository) : ClientService {
override fun getAllClients(includeDeactivated: Boolean): MutableList<Client> {
return repo.getAll(includeDeactivated)
}
override fun getClientById(id: Long): Client {
return repo.getById(id)
}
override fun createClient(clientDto: ClientDto): Client {
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
)
)
}
}

View File

@ -1,10 +1,12 @@
package org.js.lorca_core.services.impl
package org.octopus.lorca_core.services.impl
import io.jsonwebtoken.Claims
import io.jsonwebtoken.Jwts
import io.jsonwebtoken.io.Decoders
import io.jsonwebtoken.security.Keys
import org.js.lorca_core.services.JwtService
import org.octopus.lorca_core.common.enums.EUserRoles
import org.octopus.lorca_core.repositories.UserAuthRepository
import org.octopus.lorca_core.services.JwtService
import org.springframework.beans.factory.annotation.Value
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.stereotype.Service
@ -13,7 +15,9 @@ import java.util.function.Function
import javax.crypto.SecretKey
@Service
class JwtServiceImpl : JwtService {
class JwtServiceImpl(
private val userAuthRepository: UserAuthRepository
) : JwtService {
@Value("\${security.jwt.secret-key}")
private lateinit var secretKey: String
@ -31,7 +35,16 @@ class JwtServiceImpl : JwtService {
}
override fun generateToken(userDetails: UserDetails): String {
return generateToken(emptyMap(), userDetails)
val extraClaims: MutableMap<String, Any> = mutableMapOf()
userAuthRepository.getByUsername(userDetails.username).getClaimsList().let { claims ->
if (claims.isNotEmpty()) {
extraClaims["roles"] = claims
}
}
return generateToken(
extraClaims, userDetails
)
}
override fun generateToken(extraClaims: Map<String, Any>, userDetails: UserDetails): String {
@ -61,6 +74,13 @@ class JwtServiceImpl : JwtService {
return (username == userDetails.username) && !isTokenExpired(token)
}
override fun getRoles(token: String): List<EUserRoles> {
extractAllClaims(token)["roles"]?.let { roles ->
return (roles as List<String>).map { EUserRoles.valueOf(it) }
}
return listOf()
}
private fun isTokenExpired(token: String): Boolean {
return extractExpiration(token).before(Date())
}

View File

@ -0,0 +1,34 @@
package org.octopus.lorca_core.services.impl
import org.octopus.lorca_core.common.enums.EWorkerCategory
import org.octopus.lorca_core.common.models.Worker
import org.octopus.lorca_core.repositories.UserAuthRepository
import org.octopus.lorca_core.repositories.WorkerRepository
import org.octopus.lorca_core.services.WorkerService
import org.octopus.lorca_core.web.utils.dtos.WorkerDto
import org.springframework.stereotype.Service
@Service
class WorkerServiceImpl(val repo: WorkerRepository, val authRepository: UserAuthRepository) : WorkerService {
override fun getAllWorkers(): List<Worker> {
return repo.getAll().toList()
}
override fun getAllWorkersForCategory(workCategory: EWorkerCategory): List<Worker> {
return repo.getAllByCategory(workCategory)
}
override fun createWorker(workerDto: WorkerDto, username: String): Worker {
val worker = Worker(
id = 0L,
name = workerDto.name,
surname = workerDto.surname,
birthDate = workerDto.dateOfBirth,
email = workerDto.email,
category = workerDto.category,
dni = workerDto.dni
)
return repo.createForUser(worker, authRepository.getByUsername(username))
}
}

View File

@ -0,0 +1,24 @@
package org.octopus.lorca_core.web.controllers
import jakarta.validation.Valid
import lombok.AllArgsConstructor
import org.octopus.lorca_core.services.AdminService
import org.octopus.lorca_core.web.utils.dtos.AddRoleDto
import org.octopus.lorca_core.web.utils.responses.WebResponse
import org.springframework.web.bind.annotation.PutMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/admin")
@AllArgsConstructor
class AdminController(val adminService: AdminService) {
@PutMapping("/modifyRoles")
fun addRoles(@Valid @RequestBody addRoleDto: AddRoleDto): WebResponse<Unit> {
adminService.modifyRoles(addRoleDto.username, addRoleDto.roles)
return WebResponse.ok()
}
}

View File

@ -1,12 +1,11 @@
package org.js.lorca_core.web.controllers
package org.octopus.lorca_core.web.controllers
import jakarta.validation.Valid
import lombok.AllArgsConstructor
import org.js.lorca_core.services.AuthenticationService
import org.js.lorca_core.services.JwtService
import org.js.lorca_core.web.advices.WebResponse
import org.js.lorca_core.web.dtos.UserAuthDto
import org.js.lorca_core.web.responses.LoginResponse
import org.octopus.lorca_core.services.AuthenticationService
import org.octopus.lorca_core.web.utils.dtos.UserAuthDto
import org.octopus.lorca_core.web.utils.responses.LoginResponse
import org.octopus.lorca_core.web.utils.responses.WebResponse
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
@ -17,25 +16,19 @@ import org.springframework.web.bind.annotation.RestController
@RequestMapping("/auth")
@AllArgsConstructor
class AuthController(
val authenticationService: AuthenticationService,
val jwtService: JwtService
val authenticationService: AuthenticationService
) {
@PostMapping("/register")
fun register(@Valid @RequestBody registerUserDto: UserAuthDto): WebResponse<Nothing> {
fun register(@Valid @RequestBody registerUserDto: UserAuthDto): WebResponse<Unit> {
authenticationService.register(registerUserDto)
return WebResponse.ok()
}
@PostMapping("/login")
fun authenticate(@Valid @RequestBody loginUserDto: UserAuthDto): WebResponse<LoginResponse> {
val user = authenticationService.login(loginUserDto)
return WebResponse.ok(
LoginResponse(
jwtService.generateToken(user),
jwtService.getExpirationTime(),
authenticationService.getClaimsForUser(user)
)
authenticationService.login(loginUserDto)
)
}

View File

@ -1,11 +1,11 @@
package org.js.lorca_core.web.controllers
package org.octopus.lorca_core.web.controllers
import jakarta.validation.Valid
import lombok.AllArgsConstructor
import org.js.lorca_core.business.models.Client
import org.js.lorca_core.services.ClientService
import org.js.lorca_core.web.advices.WebResponse
import org.js.lorca_core.web.dtos.ClientDto
import org.octopus.lorca_core.common.models.Client
import org.octopus.lorca_core.services.ClientService
import org.octopus.lorca_core.web.utils.dtos.ClientDto
import org.octopus.lorca_core.web.utils.responses.WebResponse
import org.springframework.web.bind.annotation.*
@RestController
@ -17,10 +17,12 @@ class ClientController(
@GetMapping
fun getAllClients(
@RequestParam("name", required = false, defaultValue = "") name: String,
@RequestParam("surname", required = false, defaultValue = "") surname: String
@RequestParam(
"includeDeactivated",
required = false
) includeDeactivated: Boolean = false
): WebResponse<List<Client>> {
return WebResponse.ok(clientService.getAllClients(name, surname))
return WebResponse.ok(clientService.getAllClients(includeDeactivated))
}
@PostMapping

View File

@ -0,0 +1,10 @@
package org.octopus.lorca_core.web.controllers
import lombok.AllArgsConstructor
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/reports")
@AllArgsConstructor
class ReportController

View File

@ -0,0 +1,47 @@
package org.octopus.lorca_core.web.controllers
import jakarta.validation.Valid
import lombok.AllArgsConstructor
import org.octopus.lorca_core.common.enums.EWorkerCategory
import org.octopus.lorca_core.common.models.Worker
import org.octopus.lorca_core.services.WorkerService
import org.octopus.lorca_core.web.utils.dtos.WorkerDto
import org.octopus.lorca_core.web.utils.responses.WebResponse
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("/workers")
@AllArgsConstructor
class WorkerController(
val workerService: WorkerService
) {
@GetMapping
fun getAllWorkers(
@RequestParam(
"category",
required = false
) category: EWorkerCategory?
): WebResponse<List<Worker>> {
return WebResponse.ok(
if (category != null) {
workerService.getAllWorkersForCategory(category)
} else {
workerService.getAllWorkers()
}
)
}
@PostMapping("/register")
fun registerAsWorker(@Valid @RequestBody workerDto: WorkerDto): WebResponse<Worker> {
val username = SecurityContextHolder.getContext().authentication.name
return WebResponse.ok(workerService.createWorker(workerDto, username))
}
@PostMapping("/test")
fun createTestData(): WebResponse<Unit> {
// workerService.createTestData()
return WebResponse.ok()
}
}

View File

@ -1,9 +1,11 @@
package org.js.lorca_core.web.advices
package org.octopus.lorca_core.web.utils
import org.js.lorca_core.common.enums.EBusinessException
import org.js.lorca_core.common.exceptions.LorcaException
import org.octopus.lorca_core.common.enums.EBusinessException
import org.octopus.lorca_core.common.exceptions.LorcaException
import org.octopus.lorca_core.web.utils.responses.WebResponse
import org.springframework.http.HttpStatus
import org.springframework.http.converter.HttpMessageNotReadableException
import org.springframework.security.authorization.AuthorizationDeniedException
import org.springframework.web.HttpRequestMethodNotSupportedException
import org.springframework.web.bind.MethodArgumentNotValidException
import org.springframework.web.bind.annotation.ExceptionHandler
@ -19,7 +21,7 @@ class BaseAdvice {
fun handleLorcaBusinessException(
ex: LorcaException,
request: WebRequest
): WebResponse<Nothing> {
): WebResponse<Unit> {
return WebResponse.ko(
deductStatus(ex.ex),
ex.message
@ -28,6 +30,8 @@ class BaseAdvice {
private fun deductStatus(ex: EBusinessException): HttpStatus {
return when (ex) {
EBusinessException.IMPOSSIBLE_ADD_ROLES -> HttpStatus.EXPECTATION_FAILED
EBusinessException.USER_ALREADY_EXISTS -> HttpStatus.UNPROCESSABLE_ENTITY
EBusinessException.USER_NOT_FOUND -> HttpStatus.NOT_FOUND
EBusinessException.ENTITY_WITH_ID_NOT_FOUND -> HttpStatus.NOT_FOUND
EBusinessException.INVALID_REQUEST -> HttpStatus.BAD_REQUEST
@ -38,7 +42,7 @@ class BaseAdvice {
fun handleNumberFormatException(
ex: NumberFormatException,
request: WebRequest
): WebResponse<Nothing> {
): WebResponse<Unit> {
return WebResponse.ko(
HttpStatus.BAD_REQUEST,
"${HttpStatus.BAD_REQUEST.reasonPhrase}: ${ex.message}"
@ -50,7 +54,7 @@ class BaseAdvice {
fun handleNoResourceFoundException(
ex: NoResourceFoundException,
request: WebRequest
): WebResponse<Nothing> {
): WebResponse<Unit> {
return WebResponse.ko(
HttpStatus.NOT_FOUND,
"${HttpStatus.NOT_FOUND.reasonPhrase}: ${(request as ServletWebRequest).request.requestURI}"
@ -62,7 +66,7 @@ class BaseAdvice {
fun handleHttpRequestMethodNotSupportedException(
ex: HttpRequestMethodNotSupportedException,
request: WebRequest
): WebResponse<Nothing> {
): WebResponse<Unit> {
return WebResponse.ko(
HttpStatus.METHOD_NOT_ALLOWED,
"${HttpStatus.METHOD_NOT_ALLOWED.reasonPhrase}: ${(request as ServletWebRequest).request.requestURI}"
@ -75,7 +79,7 @@ class BaseAdvice {
fun handleMethodArgumentNotValidException(
ex: MethodArgumentNotValidException,
request: WebRequest
): WebResponse<Nothing> {
): WebResponse<Unit> {
val errors =
ex.bindingResult.fieldErrors.map {
"${it.field} - ${it.defaultMessage}"
@ -91,7 +95,7 @@ class BaseAdvice {
fun handleHttpMessageNotReadableException(
ex: HttpMessageNotReadableException,
request: WebRequest
): WebResponse<Nothing> {
): WebResponse<Unit> {
return WebResponse.ko(
HttpStatus.NOT_ACCEPTABLE,
"${HttpStatus.NOT_ACCEPTABLE.reasonPhrase}: JSON parse error"
@ -99,12 +103,24 @@ class BaseAdvice {
)
}
@ExceptionHandler(AuthorizationDeniedException::class)
fun handleAuthorizationDeniedException(
ex: AuthorizationDeniedException,
request: WebRequest
): WebResponse<Unit> {
return WebResponse.ko(
HttpStatus.FORBIDDEN,
"${HttpStatus.FORBIDDEN.reasonPhrase}: ${ex.message}"
)
}
@ExceptionHandler(Exception::class)
fun handleException(
ex: Exception,
request: WebRequest
): WebResponse<Nothing> {
): WebResponse<Unit> {
return WebResponse.ko(
HttpStatus.INTERNAL_SERVER_ERROR,
ex.message

View File

@ -1,10 +1,10 @@
package org.js.lorca_core.web.advices
package org.octopus.lorca_core.web.utils
//@Aspect
//@Component
class LoggingAspect {
// @Around("execution(* org.js.lorca_core.web.controllers.*.*(..))")
// @Around("execution(* org.octopus.lorca_core.web.controllers.*.*(..))")
// @Throws(Throwable::class)
// fun logMethodDetails(proceedingJoinPoint: ProceedingJoinPoint): Any? {
// val methodName = proceedingJoinPoint.signature.toShortString()

View File

@ -0,0 +1,10 @@
package org.octopus.lorca_core.web.utils.dtos
import org.octopus.lorca_core.common.enums.EUserRoles
import org.octopus.lorca_core.web.utils.dtos.validators.UsernameValidator
data class AddRoleDto(
@field:UsernameValidator.Validate
val username: String,
val roles: List<EUserRoles>
)

View File

@ -0,0 +1,24 @@
package org.octopus.lorca_core.web.utils.dtos
import org.octopus.lorca_core.web.utils.dtos.validators.DniValidator
import org.octopus.lorca_core.web.utils.dtos.validators.ExpValidator
import org.octopus.lorca_core.web.utils.dtos.validators.NameValidator
import org.octopus.lorca_core.web.utils.dtos.validators.PhoneValidator
import java.util.*
data class ClientDto(
@field:NameValidator.Validate
val name: String,
@field:NameValidator.Validate
val surname: String,
@field:DniValidator.Validate
val dni: String,
@field:PhoneValidator.Validate
val phone: String,
@field:ExpValidator.Validate
val numExp: String,
@field:ExpValidator.Validate
val numUser: String,
val dateOfBirth: Date,
val deactivated: Boolean? = false
)

View File

@ -0,0 +1,11 @@
package org.octopus.lorca_core.web.utils.dtos
import org.octopus.lorca_core.web.utils.dtos.validators.B64Validator
import org.octopus.lorca_core.web.utils.dtos.validators.UsernameValidator
data class UserAuthDto(
@field:UsernameValidator.Validate
val username: String,
@field:B64Validator.Validate
val password: String
)

View File

@ -0,0 +1,20 @@
package org.octopus.lorca_core.web.utils.dtos
import org.octopus.lorca_core.common.enums.EWorkerCategory
import org.octopus.lorca_core.web.utils.dtos.validators.DniValidator
import org.octopus.lorca_core.web.utils.dtos.validators.EmailValidator
import org.octopus.lorca_core.web.utils.dtos.validators.NameValidator
import java.util.*
data class WorkerDto(
@field:NameValidator.Validate
val name: String,
@field:NameValidator.Validate
val surname: String,
@field:DniValidator.Validate
val dni: String,
val dateOfBirth: Date,
@field:EmailValidator.Validate
val email: String,
val category: EWorkerCategory
)

View File

@ -1,4 +1,4 @@
package org.js.lorca_core.web.dtos.validators
package org.octopus.lorca_core.web.utils.dtos.validators
import jakarta.validation.Constraint
import jakarta.validation.ConstraintValidator
@ -15,7 +15,7 @@ class B64Validator : ConstraintValidator<B64Validator.Validate, String> {
}
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

View File

@ -0,0 +1,34 @@
package org.octopus.lorca_core.web.utils.dtos.validators
import jakarta.validation.Constraint
import jakarta.validation.ConstraintValidator
import jakarta.validation.ConstraintValidatorContext
import jakarta.validation.Payload
import kotlin.reflect.KClass
class DniValidator : ConstraintValidator<DniValidator.Validate, String> {
override fun isValid(value: String?, context: ConstraintValidatorContext): Boolean {
val pattern = Regex("^\\d{8}[A-Z]$")
if (value == null || value.matches(pattern)) {
return true
}
context.disableDefaultConstraintViolation()
context.buildConstraintViolationWithTemplate("Invalid value '$value' : 8 numbers and a letter are expected.")
.addConstraintViolation()
return false
}
@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
@Constraint(validatedBy = [DniValidator::class])
annotation class Validate(
val message: String = "",
val groups: Array<KClass<*>> = [],
val payload: Array<KClass<out Payload>> = []
)
}

View File

@ -0,0 +1,33 @@
package org.octopus.lorca_core.web.utils.dtos.validators
import jakarta.validation.Constraint
import jakarta.validation.ConstraintValidator
import jakarta.validation.ConstraintValidatorContext
import jakarta.validation.Payload
import kotlin.reflect.KClass
class EmailValidator : ConstraintValidator<EmailValidator.Validate, String> {
override fun isValid(value: String?, context: ConstraintValidatorContext): Boolean {
val pattern = Regex("^(?=.{1,64}@.{1,255}$)([a-zA-Z0-9._%+-]{1,64})@([a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})$")
if (value == null || value.matches(pattern)) {
return true
}
context.disableDefaultConstraintViolation()
context.buildConstraintViolationWithTemplate("Invalid value '$value' : Email pattern is wrong.")
.addConstraintViolation()
return false
}
@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
@Constraint(validatedBy = [EmailValidator::class])
annotation class Validate(
val message: String = "",
val groups: Array<KClass<*>> = [],
val payload: Array<KClass<out Payload>> = []
)
}

View File

@ -0,0 +1,34 @@
package org.octopus.lorca_core.web.utils.dtos.validators
import jakarta.validation.Constraint
import jakarta.validation.ConstraintValidator
import jakarta.validation.ConstraintValidatorContext
import jakarta.validation.Payload
import kotlin.reflect.KClass
class ExpValidator : ConstraintValidator<ExpValidator.Validate, String> {
override fun isValid(value: String?, context: ConstraintValidatorContext): Boolean {
val pattern = Regex("\\d+/[0-9]{4}")
if (value == null || value.matches(pattern)) {
return true
}
context.disableDefaultConstraintViolation()
context.buildConstraintViolationWithTemplate("Invalid value '$value' : digits/full_year is expected")
.addConstraintViolation()
return false
}
@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
@Constraint(validatedBy = [ExpValidator::class])
annotation class Validate(
val message: String = "",
val groups: Array<KClass<*>> = [],
val payload: Array<KClass<out Payload>> = []
)
}

View File

@ -1,4 +1,4 @@
package org.js.lorca_core.web.dtos.validators
package org.octopus.lorca_core.web.utils.dtos.validators
import jakarta.validation.Constraint
import jakarta.validation.ConstraintValidator

View File

@ -0,0 +1,34 @@
package org.octopus.lorca_core.web.utils.dtos.validators
import jakarta.validation.Constraint
import jakarta.validation.ConstraintValidator
import jakarta.validation.ConstraintValidatorContext
import jakarta.validation.Payload
import kotlin.reflect.KClass
class PhoneValidator : ConstraintValidator<PhoneValidator.Validate, String> {
override fun isValid(value: String?, context: ConstraintValidatorContext): Boolean {
val pattern = Regex("^[6789]\\d{8}$")
if (value == null || value.matches(pattern)) {
return true
}
context.disableDefaultConstraintViolation()
context.buildConstraintViolationWithTemplate("Invalid value '$value' : Phone must start with [6,7,8,9] and 8 more numbers are expected.")
.addConstraintViolation()
return false
}
@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
@Constraint(validatedBy = [PhoneValidator::class])
annotation class Validate(
val message: String = "",
val groups: Array<KClass<*>> = [],
val payload: Array<KClass<out Payload>> = []
)
}

View File

@ -1,4 +1,4 @@
package org.js.lorca_core.web.dtos.validators
package org.octopus.lorca_core.web.utils.dtos.validators
import jakarta.validation.Constraint
import jakarta.validation.ConstraintValidator

View File

@ -0,0 +1,8 @@
package org.octopus.lorca_core.web.utils.responses
import org.octopus.lorca_core.common.models.Worker
data class LoginResponse(
val token: String,
val userInfo: Worker?
)

View File

@ -1,4 +1,4 @@
package org.js.lorca_core.web.advices
package org.octopus.lorca_core.web.utils.responses
import org.springframework.http.HttpStatus
@ -10,7 +10,7 @@ data class WebResponse<T>(
) {
companion object {
fun <T> ok(): WebResponse<T> {
fun ok(): WebResponse<Unit> {
return WebResponse(status = HttpStatus.OK)
}

View File

@ -1,5 +1,9 @@
server.servlet.context-path=/api
spring.application.name=lorca-core
spring.application.name=lorca-gestionale-be
#
#
# DATABASE
#
spring.datasource.url=jdbc:postgresql://0.0.0.0:5432/lorca_db
spring.datasource.username=lorca_usr
spring.datasource.password=lorca_pwd
@ -7,8 +11,15 @@ spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
# HOW TO GENERATE THIS KEY AT :
#
#
# HOW TO GENERATE THIS KEY AT : https://www.devglan.com/online-tools/hmac-sha256-online?ref=blog.tericcabrel.com
# PLAIN TEXT: Boh che cazzo ne so bel testo peró complimenti
# SECRET KEY: Ma che minchia ne so quale puo essere una bella chiave segreta dio negraccio
security.jwt.secret-key=93d5326c5ae622c9332f291c6a9868d237e6b41fc47c5f2581448d4d90e90a1a
security.jwt.expiration-time=3600000
#
#
# WHATSAPP API: https://developers.facebook.com/docs/whatsapp/cloud-api/overview
# MAIL SERVICE: https://sendgrid.com/en-us/pricing
#

View File

@ -1,6 +1,6 @@
package org.js.lorca_core
package org.octopus.lorca_core
import org.js.lorca_core.db.entities.WorkerEntity
import org.octopus.lorca_core.db.entities.WorkerEntity
import org.springframework.boot.test.context.SpringBootTest
@SpringBootTest

View File

@ -0,0 +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":"newtest","password":"cGFzc3dvcmQ="}'

View File

@ -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"

View File

@ -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/workers/register \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Test","surname": "Test","dni": "12345678A","dateOfBirth": "1990-05-15","email": "jari.sciampi@mailbox.org","category":"FISIO"}'

Some files were not shown because too many files have changed in this diff Show More