refactor: Migrate from monolithic to modular architecture

- Restructure project into domain-specific modules (core, masterdata, members, horses, events, infrastructure)
- Create shared client components in common-ui module
- Implement CI/CD workflows with GitHub Actions
- Consolidate documentation in docs directory
- Remove deprecated modules and documentation files
- Add cleanup and migration scripts for transition
- Update README with new project structure and setup instructions
This commit is contained in:
stefan
2025-07-22 18:44:18 +02:00
parent 8229e8e571
commit a256622f37
314 changed files with 5930 additions and 19817 deletions
@@ -0,0 +1,20 @@
plugins {
kotlin("jvm")
kotlin("plugin.spring")
}
dependencies {
implementation(projects.platform.platformDependencies)
implementation(projects.core.coreDomain)
implementation(projects.core.coreUtils)
// Spring Security
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.security:spring-security-oauth2-jose")
// JWT
implementation("com.auth0:java-jwt:4.4.0")
testImplementation(projects.platform.platformTesting)
}
@@ -0,0 +1,88 @@
package at.mocode.infrastructure.auth.client
import com.benasher44.uuid.Uuid
import java.time.LocalDateTime
/**
* Service for user authentication and password management.
*/
interface AuthenticationService {
/**
* Authenticates a user with the given username and password.
*
* @param username The username
* @param password The password
* @return The authentication result
*/
suspend fun authenticate(username: String, password: String): AuthResult
/**
* Changes a user's password.
*
* @param userId The user ID
* @param currentPassword The current password
* @param newPassword The new password
* @return The password change result
*/
suspend fun changePassword(userId: Uuid, currentPassword: String, newPassword: String): PasswordChangeResult
/**
* Possible results of an authentication attempt.
*/
sealed class AuthResult {
/**
* Authentication was successful.
*
* @param token The JWT token
* @param user The authenticated user
*/
data class Success(val token: String, val user: AuthenticatedUser) : AuthResult()
/**
* Authentication failed.
*
* @param reason The reason for the failure
*/
data class Failure(val reason: String) : AuthResult()
/**
* The account is locked.
*
* @param lockedUntil The time until which the account is locked
*/
data class Locked(val lockedUntil: LocalDateTime) : AuthResult()
}
/**
* Possible results of a password change attempt.
*/
sealed class PasswordChangeResult {
/**
* Password change was successful.
*/
object Success : PasswordChangeResult()
/**
* Password change failed.
*
* @param reason The reason for the failure
*/
data class Failure(val reason: String) : PasswordChangeResult()
/**
* The new password is too weak.
*/
object WeakPassword : PasswordChangeResult()
}
/**
* Represents an authenticated user.
*/
data class AuthenticatedUser(
val userId: Uuid,
val personId: Uuid,
val username: String,
val email: String,
val permissions: List<String>
)
}
@@ -0,0 +1,104 @@
package at.mocode.infrastructure.auth.client
import at.mocode.core.domain.model.BerechtigungE
import com.auth0.jwt.JWT
import com.auth0.jwt.algorithms.Algorithm
import java.util.*
/**
* Service for JWT token generation and validation.
*/
class JwtService(
private val secret: String,
private val issuer: String,
private val audience: String,
private val expirationInMinutes: Long = 60
) {
/**
* Generates a JWT token for the given user.
*
* @param userId The user ID
* @param username The username
* @param permissions The user's permissions
* @return The generated JWT token
*/
fun generateToken(
userId: String,
username: String,
permissions: List<BerechtigungE>
): String {
return JWT.create()
.withSubject(userId)
.withIssuer(issuer)
.withAudience(audience)
.withClaim("username", username)
.withArrayClaim("permissions", permissions.map { it.name }.toTypedArray())
.withExpiresAt(Date(System.currentTimeMillis() + expirationInMinutes * 60 * 1000))
.sign(Algorithm.HMAC512(secret))
}
/**
* Validates a JWT token.
*
* @param token The JWT token to validate
* @return True if the token is valid, false otherwise
*/
fun validateToken(token: String): Boolean {
return try {
JWT.require(Algorithm.HMAC512(secret))
.withIssuer(issuer)
.withAudience(audience)
.build()
.verify(token)
true
} catch (e: Exception) {
false
}
}
/**
* Gets the user ID from a JWT token.
*
* @param token The JWT token
* @return The user ID, or null if the token is invalid
*/
fun getUserIdFromToken(token: String): String? {
return try {
JWT.require(Algorithm.HMAC512(secret))
.withIssuer(issuer)
.withAudience(audience)
.build()
.verify(token)
.subject
} catch (e: Exception) {
null
}
}
/**
* Gets the permissions from a JWT token.
*
* @param token The JWT token
* @return The permissions, or an empty list if the token is invalid
*/
fun getPermissionsFromToken(token: String): List<BerechtigungE> {
return try {
val decodedJWT = JWT.require(Algorithm.HMAC512(secret))
.withIssuer(issuer)
.withAudience(audience)
.build()
.verify(token)
val permissionStrings = decodedJWT.getClaim("permissions").asArray(String::class.java)
permissionStrings.mapNotNull {
try {
BerechtigungE.valueOf(it)
} catch (e: Exception) {
null
}
}
} catch (e: Exception) {
emptyList()
}
}
}
@@ -0,0 +1,23 @@
plugins {
kotlin("jvm")
kotlin("plugin.spring")
id("org.springframework.boot")
}
// Configure main class for bootJar task
springBoot {
mainClass.set("at.mocode.infrastructure.auth.AuthServerApplicationKt")
}
dependencies {
implementation(projects.platform.platformDependencies)
implementation(projects.infrastructure.auth.authClient)
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server")
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.keycloak:keycloak-admin-client:23.0.0")
testImplementation(projects.platform.platformTesting)
}
@@ -0,0 +1,11 @@
package at.mocode.infrastructure.auth
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class AuthServerApplication
fun main(args: Array<String>) {
runApplication<AuthServerApplication>(*args)
}