# Azaion Admin API — System Flows ## Flow Inventory | # | Flow Name | Trigger | Primary Components | Criticality | |---|-----------|---------|-------------------|-------------| | F1 | User Login | POST /login | Admin API, User Mgmt, Auth & Security | High | | F2 | User Registration | POST /users | Admin API, User Mgmt | High | | F3 | Encrypted Resource Download | POST /resources/get | Admin API, Auth, User Mgmt, Resource Mgmt | High | | F4 | Hardware Check | POST /resources/check | Admin API, Auth, User Mgmt | High | | F5 | Resource Upload | POST /resources | Admin API, Resource Mgmt | Medium | | F6 | Installer Download | GET /resources/get-installer | Admin API, Auth, Resource Mgmt | Medium | | F7 | User Management (CRUD) | Various /users/* | Admin API, User Mgmt | Medium | ## Flow Dependencies | Flow | Depends On | Shares Data With | |------|-----------|-----------------| | F1 | — | All other flows (produces JWT token) | | F2 | — | F1, F3, F4 (creates user records) | | F3 | F1 (requires JWT), F4 (hardware must be bound) | F4 (via hardware hash) | | F4 | F1 (requires JWT) | F3 (hardware binding) | | F5 | F1 (requires JWT) | F3 (uploaded resources are later downloaded) | | F6 | F1 (requires JWT) | — | | F7 | F1 (requires JWT, ApiAdmin role) | F3, F4 (user data) | --- ## Flow F1: User Login ### Description A user submits email/password credentials. The system validates them against the database and returns a signed JWT token for subsequent authenticated requests. ### Preconditions - User account exists in the database - User knows correct password ### Sequence Diagram ```mermaid sequenceDiagram participant Client participant API as Admin API participant US as UserService participant DB as PostgreSQL participant Auth as AuthService Client->>API: POST /login {email, password} API->>US: ValidateUser(request) US->>DB: SELECT user WHERE email = ? DB-->>US: User record US->>US: Compare password hash US-->>API: User entity API->>Auth: CreateToken(user) Auth-->>API: JWT string API-->>Client: 200 OK {token} ``` ### Error Scenarios | Error | Where | Detection | Recovery | |-------|-------|-----------|----------| | Email not found | UserService.ValidateUser | No DB record | 409: NoEmailFound (code 10) | | Wrong password | UserService.ValidateUser | Hash mismatch | 409: WrongPassword (code 30) | --- ## Flow F2: User Registration ### Description An admin creates a new user account with email, password, and role. ### Preconditions - Caller has ApiAdmin role - Email is not already registered ### Sequence Diagram ```mermaid sequenceDiagram participant Admin participant API as Admin API participant VAL as FluentValidation participant US as UserService participant DB as PostgreSQL Admin->>API: POST /users {email, password, role} API->>VAL: Validate RegisterUserRequest VAL-->>API: OK API->>US: RegisterUser(request) US->>DB: SELECT user WHERE email = ? DB-->>US: null (no duplicate) US->>US: Hash password (SHA-384) US->>DB: INSERT user (admin connection) DB-->>US: OK US-->>API: void API-->>Admin: 200 OK ``` ### Error Scenarios | Error | Where | Detection | Recovery | |-------|-------|-----------|----------| | Validation failure | FluentValidation | Email < 8 chars, bad format, password < 8 chars | 400 Bad Request | | Duplicate email | UserService.RegisterUser | Existing user found | 409: EmailExists (code 20) | --- ## Flow F3: Encrypted Resource Download ### Description An authenticated user requests a resource file. The system validates hardware binding, derives a per-user encryption key, encrypts the file with AES-256-CBC, and streams the encrypted content. ### Preconditions - User is authenticated (JWT) - User's hardware is bound (via prior F4 call) - Resource file exists on server ### Sequence Diagram ```mermaid sequenceDiagram participant Client participant API as Admin API participant Auth as AuthService participant US as UserService participant Sec as Security participant RS as ResourcesService participant FS as Filesystem Client->>API: POST /resources/get {password, hardware, fileName} API->>Auth: GetCurrentUser() Auth-->>API: User API->>US: CheckHardwareHash(user, hardware) US->>Sec: GetHWHash(hardware) Sec-->>US: hash US-->>API: hwHash API->>Sec: GetApiEncryptionKey(email, password, hwHash) Sec-->>API: AES key API->>RS: GetEncryptedResource(folder, fileName, key) RS->>FS: Read file FS-->>RS: FileStream RS->>Sec: EncryptTo(stream, key) Sec-->>RS: Encrypted MemoryStream RS-->>API: Stream API-->>Client: 200 OK (application/octet-stream) ``` ### Error Scenarios | Error | Where | Detection | Recovery | |-------|-------|-----------|----------| | Not authenticated | API | No/invalid JWT | 401 Unauthorized | | Hardware mismatch | UserService.CheckHardwareHash | Hash comparison fails | 409: HardwareIdMismatch (code 40) | | File not found | ResourcesService | FileStream throws | 500 Internal Server Error | --- ## Flow F4: Hardware Check (First Login / Validation) ### Description Client submits its hardware fingerprint. On first call, the hardware is stored for the user. On subsequent calls, the stored hash is compared against the provided hardware. ### Preconditions - User is authenticated (JWT) ### Sequence Diagram ```mermaid sequenceDiagram participant Client participant API as Admin API participant Auth as AuthService participant US as UserService participant DB as PostgreSQL Client->>API: POST /resources/check {hardware} API->>Auth: GetCurrentUser() Auth-->>API: User API->>US: CheckHardwareHash(user, hardware) alt First time (no stored hardware) US->>DB: UPDATE user SET hardware = ? (admin conn) US->>DB: UPDATE user SET last_login = now() US-->>API: hwHash else Hardware already bound US->>US: Compare hashes alt Match US->>DB: UPDATE user SET last_login = now() US-->>API: hwHash else Mismatch US-->>API: throw HardwareIdMismatch end end API-->>Client: 200 OK (true) / 409 ``` --- ## Flow F5: Resource Upload ### Description An authenticated user uploads a file to a specified resource folder on the server. ### Preconditions - User is authenticated (JWT) - File size <= 200 MB ### Sequence Diagram ```mermaid sequenceDiagram participant User participant API as Admin API participant RS as ResourcesService participant FS as Filesystem User->>API: POST /resources/{folder} (multipart/form-data) API->>RS: SaveResource(folder, file) RS->>FS: Create directory (if needed) RS->>FS: Delete existing file (same name) RS->>FS: Write file FS-->>RS: OK RS-->>API: void API-->>User: 200 OK ``` --- ## Flow F6: Installer Download ### Description An authenticated user downloads the latest Azaion Suite installer (production or staging). ### Preconditions - User is authenticated (JWT) - Installer file exists on server ### Sequence Diagram ```mermaid sequenceDiagram participant Client participant API as Admin API participant Auth as AuthService participant RS as ResourcesService participant FS as Filesystem Client->>API: GET /resources/get-installer API->>Auth: GetCurrentUser() Auth-->>API: User (not null) API->>RS: GetInstaller(isStage: false) RS->>FS: Scan for AzaionSuite.Iterative* FS-->>RS: FileInfo RS-->>API: (name, FileStream) API-->>Client: 200 OK (application/octet-stream) ``` --- ## Flow F7: User Management (CRUD) ### Description Admin operations: list users, change role, enable/disable, set hardware, update queue offsets, delete user. ### Preconditions - Caller has ApiAdmin role (for most operations) All operations follow the same pattern: API endpoint → UserService method → DbFactory.RunAdmin → PostgreSQL UPDATE/DELETE. Cache is invalidated for affected user keys after writes.