diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..f3ff108 --- /dev/null +++ b/.env.example @@ -0,0 +1,5 @@ +# Backend host port for the normal containerized app +APP_PORT=8080 + +# Backend host port for live-reload dev mode +APP_DEV_PORT=8081 diff --git a/Dockerfile b/Dockerfile index 3be2eb1..5b75bbe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,12 @@ -FROM gradle:8-jdk-alpine AS build +FROM gradle:8.5-jdk17 AS build WORKDIR /app COPY . . -RUN ./gradlew clean bootJar +RUN ./gradlew --no-daemon clean bootJar - -FROM openjdk:17 +FROM eclipse-temurin:17-jre USER nobody WORKDIR /app COPY --from=build /app/build/libs/*.jar app.jar EXPOSE 8080 -ENTRYPOINT ["java", "-jar", "app.jar"] \ No newline at end of file +ENTRYPOINT ["java", "-jar", "app.jar"] diff --git a/README.md b/README.md index f492ea3..9b98a10 100644 --- a/README.md +++ b/README.md @@ -4,22 +4,103 @@ Autobank is a Kotlin Spring Boot application designed for managing financial rec ## 🚀 Quick Start -### Running the Application +Use one of these three modes depending on what you want to test. -1. **Clone the repository** - ```bash - git clone https://github.com/appKom/gnocchitony.git - cd gnocchitony - ``` +### Copy-Paste Cheatsheet -2. **Configure environment variables** +```bash +# Local backend (no token required) +./gradlew bootRun -3. **Run the application** - ```bash - ./gradlew bootRun - ``` +# Docker backend + database +docker compose up -d --build -The application will start on `http://localhost:8080` +# Docker backend + database with live reload +docker compose --profile dev up -d dev-database backend-dev + +# Test production auth mode locally (token required) +./gradlew bootRun --args='--environment=prod' + +# Stop Docker services +docker compose down +docker compose --profile dev down +``` + +### 1. Local Development (fastest feedback) + +```bash +./gradlew bootRun +``` + +What happens: + +- Runs backend on port 8080 from your machine. +- Uses `application-local.properties`. +- `environment=dev` disables JWT auth, so you can call APIs without a token. + +Useful URLs: + +- API: `http://localhost:8080` +- Swagger UI: `http://localhost:8080/swagger-ui/index.html` + +### 2. Docker Development (backend + database) + +```bash +docker compose up -d --build +``` + +What happens: + +- Starts MySQL and backend in containers. +- Backend is on `http://localhost:8080` (or `APP_PORT` from `.env`). +- MySQL is internal to Docker network (not published on host). +- Uses local profile (`SPRING_PROFILES_ACTIVE=local`), so `environment=dev` and no JWT required. + +Stop: + +```bash +docker compose down +``` + +### 3. Docker Development with Live Reload (Kotlin changes) + +```bash +docker compose --profile dev up -d dev-database backend-dev +``` + +What happens: + +- Runs backend via Gradle `bootRun --continuous` inside container. +- Mounts your project into the container. +- Code changes trigger rebuild/restart automatically. +- Backend is exposed on `http://localhost:8081` by default (`APP_DEV_PORT`). + +Stop: + +```bash +docker compose --profile dev down +``` + +### 4. Test Production Auth Locally (require token) + +If you want to test real JWT/Auth0 behavior, run with `environment=prod`. + +Local JVM: + +```bash +./gradlew bootRun --args='--environment=prod' +``` + +Docker: + +```bash +ENVIRONMENT=prod docker compose up -d --build +``` + +What changes in prod mode: + +- All protected endpoints require Bearer token. +- Auth0 issuer/audience validation is enforced. ## 📋 Features @@ -58,11 +139,15 @@ All API endpoints require authentication via Bearer token: Authorization: Bearer ``` -**Note**: In development mode (`environment=dev`), security is disabled for easier testing. +Authentication mode is controlled by `environment`: + +- `environment=prod`: JWT/Auth0 is required. +- Any non-prod value (for example `environment=dev`): token auth is disabled for easier local development. ## 🛠️ Development ### Project Structure + ``` src/main/kotlin/com/example/autobank/ ├── controller/ # REST controllers @@ -94,4 +179,3 @@ For complete API documentation, see [docs/api-routes.md](docs/api-routes.md). ## 📄 License This project is part of NTNU Online's application suite. - diff --git a/docker-compose.yml b/docker-compose.yml index bdd7a3d..5f3ff26 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,12 +3,57 @@ services: image: mysql:8.0 container_name: spring-local-mysq environment: - MYSQL_ROOT_PASSWORD: gLp(43 + auth.anyRequest().permitAll() + } + + return http.build() + } + http .cors { it.configurationSource(corsConfigurationSource()) } // Add this .csrf { it.disable() } // Typically disabled for APIs diff --git a/src/main/kotlin/com/example/autobank/service/AuthenticationService.kt b/src/main/kotlin/com/example/autobank/service/AuthenticationService.kt index 93eb550..9b5388d 100644 --- a/src/main/kotlin/com/example/autobank/service/AuthenticationService.kt +++ b/src/main/kotlin/com/example/autobank/service/AuthenticationService.kt @@ -30,6 +30,8 @@ class AuthenticationService( @Value("\${auth0.domain}") private val domain: String, @Value("\${environment}") private val environment: String, @Value("\${api.base.domain}") private val apiBaseDomain: String, + @Value("\${dev.user.sub:local-dev-user}") private val localDevUserSub: String, + @Value("\${dev.user.full-name:Local Dev User}") private val localDevUserFullName: String, ) { private val restTemplate = RestTemplate() @@ -53,13 +55,15 @@ class AuthenticationService( return if (authentication is JwtAuthenticationToken) { val token = authentication.token token.getClaim("sub") + } else if (environment != "prod") { + localDevUserSub } else { "" } } fun getFullName(): String { - return ""; + return if (environment != "prod") localDevUserFullName else "" } fun getAccessToken(): String {