|
1 | | -# beeatlas-fdm-auth-service |
| 1 | +## beeatlas-fdm-auth-service |
| 2 | + |
| 3 | +**beeatlas-fdm-auth-service** is an authorization and access management service for FDM products. |
| 4 | +The service is responsible for storing user profiles, roles and permissions, as well as checking user access rights to products. |
| 5 | +It works together with an API Gateway that performs authentication and forwards enriched user headers to this service. |
| 6 | + |
| 7 | +### Technology stack |
| 8 | + |
| 9 | +- **Java 17** |
| 10 | +- **Spring Boot 2.7.3** (`spring-boot-starter-web`, `spring-boot-starter-actuator`) |
| 11 | +- **Spring Data JPA** + **Hibernate** |
| 12 | +- **PostgreSQL** as the primary data store |
| 13 | +- **Flyway** for database migrations (`src/main/resources/db/migration`) |
| 14 | +- **Swagger (springfox)** for REST API documentation |
| 15 | +- **Micrometer + Prometheus** for metrics |
| 16 | +- **OpenTelemetry** (`opentelemetry-spring-boot-starter`) |
| 17 | +- Build: **Maven** |
| 18 | +- Containerization: **Docker**, **docker-compose** |
| 19 | + |
| 20 | +### Service responsibilities |
| 21 | + |
| 22 | +- **Roles**: role directory, role management, binding roles to users. |
| 23 | +- **Permissions**: permissions directory and binding permissions to roles. |
| 24 | +- **Products**: product storage and binding products to users. |
| 25 | +- **Integrations with external systems**: |
| 26 | + - BeeWorks (`BeeWorksController`, `BWEmployeeClient`) — fetching employee product information. |
| 27 | + - External notification/document/product services via URLs from environment variables. |
| 28 | + |
| 29 | +--- |
| 30 | + |
| 31 | +## Integration with API Gateway |
| 32 | + |
| 33 | +The service expects **API Gateway** to: |
| 34 | + |
| 35 | +- Perform user authentication (e.g. via JWT). |
| 36 | +- Resolve internal user identifier and his access rights. |
| 37 | +- Forward the following headers to `fdm-auth`: |
| 38 | + - `user-id` — user ID in the system. |
| 39 | + - `user-products-ids` — list of user product IDs. |
| 40 | + - `user-permission` — list of permissions. |
| 41 | + - `user-roles` — list of user roles (must contain `ADMINISTRATOR` for admin operations). |
| 42 | + |
| 43 | +These headers are used by `AccessControlAspect`: |
| 44 | + |
| 45 | +- `@AccessControl` annotation: |
| 46 | + - Validates that all required headers are present. |
| 47 | + - Verifies the presence of `ADMINISTRATOR` role in `user-roles`. |
| 48 | + - Throws `401 Unauthorized` if headers are missing. |
| 49 | + - Throws `403 Permission denied` if the user is not an administrator. |
| 50 | + |
| 51 | +- `@HeaderControl` annotation: |
| 52 | + - Validates only presence of required headers (`user-id`, `user-products-ids`, `user-permission`, `user-roles`). |
| 53 | + - Used, for example, in `ProductController` for admin-related endpoints. |
| 54 | + |
| 55 | +Swagger UI is configured with **Bearer** auth via `Authorization` header. |
| 56 | +The JWT token is decoded by the `JwtUtils` utility (`ru.beeline.fdmauth.utils.jwt.JwtUtils`). |
| 57 | + |
| 58 | +--- |
| 59 | + |
| 60 | +## Service run options |
| 61 | + |
| 62 | +### 1. Run with Docker Compose (recommended) |
| 63 | + |
| 64 | +**Requirements:** |
| 65 | + |
| 66 | +- Installed **Docker** and **docker-compose**. |
| 67 | + |
| 68 | +Run from the project root: |
| 69 | + |
| 70 | +```bash |
| 71 | +docker-compose up -d |
| 72 | +``` |
| 73 | + |
| 74 | +`docker-compose.yml` starts: |
| 75 | + |
| 76 | +- **fdm-auth-postgres** |
| 77 | + - Image: `postgres:15-alpine` |
| 78 | + - Parameters (can be overridden via env vars): |
| 79 | + - `POSTGRES_DB` (default `fdm-auth`) |
| 80 | + - `POSTGRES_USER` (default `postgres`) |
| 81 | + - `POSTGRES_PASSWORD` (default `postgres`) |
| 82 | + - Port: `${FDM_AUTH_POSTGRES_NODEPORT:-5432} -> 5432` |
| 83 | + |
| 84 | +- **fdm-auth-backend** |
| 85 | + - Built using the project `Dockerfile`. |
| 86 | + - Starts after Postgres healthcheck is successful. |
| 87 | + - Application port: `8080` inside container, external port: |
| 88 | + - `${FDM_AUTH_SERVICE_PORT:-8081} -> 8080` (by default service is available at `http://localhost:8081`). |
| 89 | + |
| 90 | +After successful startup: |
| 91 | + |
| 92 | +- Service healthcheck: `GET http://localhost:8081/actuator/health` |
| 93 | +- Test greeting: `GET http://localhost:8081/` |
| 94 | + Returns a string: `Welcome <app.name> <app.version>`. |
| 95 | + |
| 96 | +### 2. Local run without Docker |
| 97 | + |
| 98 | +**Requirements:** |
| 99 | + |
| 100 | +- **JDK 17** |
| 101 | +- **Maven 3.x** |
| 102 | +- Running **PostgreSQL** instance (local or via Docker). |
| 103 | + |
| 104 | +1. Start PostgreSQL (example via Docker): |
| 105 | + |
| 106 | +```bash |
| 107 | +docker run --name fdm-auth-postgres \ |
| 108 | + -e POSTGRES_DB=fdm-auth \ |
| 109 | + -e POSTGRES_USER=postgres \ |
| 110 | + -e POSTGRES_PASSWORD=postgres \ |
| 111 | + -p 5432:5432 \ |
| 112 | + -d postgres:15-alpine |
| 113 | +``` |
| 114 | + |
| 115 | +2. Set application environment variables (similar to `docker-compose.yml`): |
| 116 | + |
| 117 | +- `SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/fdm-auth` |
| 118 | +- `SPRING_DATASOURCE_USERNAME=postgres` |
| 119 | +- `SPRING_DATASOURCE_PASSWORD=postgres` |
| 120 | +- (optional) `SPRING_JPA_HIBERNATE_DDL_AUTO=none` |
| 121 | +- (optional) `SPRING_FLYWAY_DEFAULT_SCHEMA=user_auth` |
| 122 | + |
| 123 | +3. Build and run the service: |
| 124 | + |
| 125 | +```bash |
| 126 | +mvn clean package -DskipTests |
| 127 | +mvn spring-boot:run |
| 128 | +``` |
| 129 | + |
| 130 | +By default, the application starts on port `8080` (unless overridden via `server.port` / env vars). |
| 131 | + |
| 132 | +--- |
| 133 | + |
| 134 | +## Environment variables |
| 135 | + |
| 136 | +### Database (used in docker-compose) |
| 137 | + |
| 138 | +- **FDM_AUTH_POSTGRES_DB** — database name (default `fdm-auth`). |
| 139 | +- **FDM_AUTH_POSTGRES_USER** — database user (default `postgres`). |
| 140 | +- **FDM_AUTH_POSTGRES_PASSWORD** — database password (default `postgres`). |
| 141 | +- **FDM_AUTH_POSTGRES_NODEPORT** — external Postgres port (default `5432`). |
| 142 | + |
| 143 | +### Auth service |
| 144 | + |
| 145 | +- **FDM_AUTH_SERVICE_PORT** — external port for the application container (default `8081`). |
| 146 | + |
| 147 | +### Integrations with external services |
| 148 | + |
| 149 | +Defined in `docker-compose.yml` as examples and should be configured per environment: |
| 150 | + |
| 151 | +- **INTEGRATION_PRODUCTS_SERVER_URL** — product service URL. |
| 152 | + |
| 153 | +--- |
| 154 | + |
| 155 | +## Main REST endpoints (brief) |
| 156 | + |
| 157 | +Below is not an exhaustive list, but a guide to key controllers. |
| 158 | +For the full specification, use Swagger. |
| 159 | + |
| 160 | +### Users (`UserController`, `/api/v1`) |
| 161 | + |
| 162 | +- **GET `/api/v1/user/{id}`** — get user profile by ID. |
| 163 | +- **GET `/api/v1/user?ids=1,2,...`** — get short profiles by list of IDs. |
| 164 | +- **GET `/api/v1/user/role/{aliasRole}`** — get all users with the specified role. |
| 165 | +- **GET `/api/v1/users`** — get all FDM users (requires `@AccessControl` → `ADMINISTRATOR` role). |
| 166 | +- **POST `/api/v1/user/list`** — search user profiles by list of IDs. |
| 167 | + |
| 168 | +### User administration (`AdminUserController`, `/api/admin/v1/user`) |
| 169 | + |
| 170 | +- **GET `/api/admin/v1/user`** — list all user profiles. |
| 171 | +- **GET `/api/admin/v1/user/find?text=...&filter=...`** — search profiles (currently returns all, logic can be refined). |
| 172 | +- **GET `/api/admin/v1/user/{login}`** — get user profile by login. |
| 173 | +- **GET `/api/admin/v1/user/{login}/roles`** — get user roles. |
| 174 | +- **GET `/api/admin/v1/user/{login}/permissions`** — get user permissions. |
| 175 | +- **PUT `/api/admin/v1/user/{login}/roles`** — set user roles. |
| 176 | +- **GET `/api/admin/v1/user/{id}/existence`** — check user existence. |
| 177 | +- **GET `/api/admin/v1/user/{login}/info`** — extended user info. |
| 178 | + |
| 179 | +All controller endpoints (except a few) are protected by `@AccessControl` and require admin role. |
| 180 | + |
| 181 | +### Roles (`RoleController`, `/api/admin/v1/roles`) |
| 182 | + |
| 183 | +- **GET `/api/admin/v1/roles`** — get all non-deleted roles. |
| 184 | +- **POST `/api/admin/v1/roles`** — create a new role. |
| 185 | +- **PATCH `/api/admin/v1/roles`** — update a role. |
| 186 | +- **GET `/api/admin/v1/roles/{id}`** — get role by ID. |
| 187 | +- **DELETE `/api/admin/v1/roles/{id}`** — mark role as deleted (default roles cannot be deleted). |
| 188 | +- **GET `/api/admin/v1/roles/{id}/permissions`** — get role permissions. |
| 189 | +- **PUT `/api/admin/v1/roles/{id}/permissions`** — save role permissions (except for default roles). |
| 190 | + |
| 191 | +All operations require `@AccessControl` (admin role). |
| 192 | + |
| 193 | +### Permissions (`PermissionController`, `/api/admin/v1/permissions`) |
| 194 | + |
| 195 | +- **GET `/api/admin/v1/permissions`** — get full permissions directory (also protected with `@AccessControl`). |
| 196 | + |
| 197 | +### Products (`ProductController`, `/api`) |
| 198 | + |
| 199 | +- **GET `/api/product/{id}/existence`** — check product existence by ID. |
| 200 | +- **GET `/api/user/{id}/product`** — get list of products for user ID. |
| 201 | +- **GET `/api/admin/v1/product`** — get user products by `user-id` header (`@HeaderControl` annotation). |
| 202 | + |
| 203 | +### Profiles / BeeWorks integration (`ProfileController`, `/api/v1/profiles`) |
| 204 | + |
| 205 | +- **GET `/api/v1/profiles/{userId}/email`** — get user email by ID. |
| 206 | + |
| 207 | +### BeeWorks integration (`BeeWorksController`, `/api/bw`) |
| 208 | + |
| 209 | +- **GET `/api/bw/products/{login}`** — get employee products from BeeWorks by login. |
| 210 | + |
| 211 | +--- |
| 212 | + |
| 213 | +## Swagger documentation |
| 214 | + |
| 215 | +Swagger is configured via `SwaggerConfig` (`ru.beeline.fdmauth.config.SwaggerConfig`). |
| 216 | +After the service is started, the UI is usually available at one of (depending on Springfox/Spring Boot setup): |
| 217 | + |
| 218 | +- `http://localhost:8081/swagger-ui/` |
| 219 | +- or `http://localhost:8081/swagger-ui/index.html` |
| 220 | + |
| 221 | +Swagger uses **Bearer** security scheme: |
| 222 | + |
| 223 | +- Add `Authorization: Bearer <jwt>` header to call protected endpoints. |
| 224 | + |
| 225 | +--- |
| 226 | + |
| 227 | +## Database migrations |
| 228 | + |
| 229 | +Migrations are located under `src/main/resources/db/migration`: |
| 230 | + |
| 231 | +- **V0001__Create_tables.sql** — create core tables (users, roles, permissions, etc.). |
| 232 | +- **V0002__Add_Roles_And_Permissions.sql** — seed roles and permissions directories. |
| 233 | +- **V0003__Add_sequences.sql** — add sequences. |
| 234 | +- **V0004__Add_Default_Role_Permissions.sql** — default permissions for base roles. |
| 235 | +- **V0005__Add_Default_Product.sql** — add default product. |
| 236 | +- **V0006__Add_unique_user_product_constraint.sql** — unique constraints for user–product relations. |
| 237 | + |
| 238 | +Flyway is configured via `application.properties`: |
| 239 | + |
| 240 | +- `spring.flyway.default-schema=user_auth` |
| 241 | +- `spring.flyway.baseline-on-migrate=true` |
| 242 | +- `spring.flyway.clean-disabled=true` |
| 243 | + |
| 244 | +--- |
| 245 | + |
| 246 | +## Monitoring and healthcheck |
| 247 | + |
| 248 | +Spring Boot Actuator exposes the following useful endpoints: |
| 249 | + |
| 250 | +- **Health**: `GET /actuator/health` |
| 251 | +- **Info**: `GET /actuator/info` |
| 252 | +- **Metrics**: `GET /actuator/metrics` |
| 253 | +- **Prometheus**: `GET /actuator/prometheus` |
| 254 | + |
| 255 | +Some Actuator and Micrometer parameters are configured in `application.properties`: |
| 256 | + |
| 257 | +- `management.endpoints.web.exposure.include=health,info,metrics,prometheus` |
| 258 | +- `management.metrics.web.server.auto-time-requests=true` |
| 259 | + |
| 260 | +The container healthcheck in `docker-compose.yml` uses `http://localhost:8080/actuator/health`. |
| 261 | + |
| 262 | +--- |
| 263 | + |
| 264 | +## Versioning and build |
| 265 | + |
| 266 | +- Application version is taken from `pom.xml` (`<version>1.1.9</version>`). |
| 267 | +- Resulting artifact: `target/fdm-auth-<version>.jar`. |
| 268 | +- Docker image is built in two stages (`Dockerfile`): |
| 269 | + - Build stage: jar build via Maven. |
| 270 | + - Runtime stage: minimal JRE image (`eclipse-temurin:17-jre-jammy`) running `java -jar app.jar`. |
0 commit comments