mirror of
https://github.com/azaion/admin.git
synced 2026-04-22 22:26:34 +00:00
d320d6dd59
Made-with: Cursor
4.3 KiB
4.3 KiB
Acceptance Criteria
Derived from validation rules, test assertions, configuration limits, and health check patterns found in the codebase.
Authentication
| # | Criterion | Threshold | Source |
|---|---|---|---|
| AC-1 | Login with valid credentials returns a JWT token | Token is non-empty string | Program.cs /login endpoint |
| AC-2 | Login with unknown email returns error code 10 | HTTP 409, ErrorCode: 10 |
UserService.ValidateUser throws NoEmailFound |
| AC-3 | Login with wrong password returns error code 30 | HTTP 409, ErrorCode: 30 |
UserService.ValidateUser throws WrongPassword |
| AC-4 | JWT token expires after configured hours | Token exp claim = now + TokenLifetimeHours |
AuthService.CreateToken, default 4 hours |
| AC-5 | JWT token contains user ID, email, and role claims | Claims: NameIdentifier, Name, Role |
AuthService.CreateToken |
User Management
| # | Criterion | Threshold | Source |
|---|---|---|---|
| AC-6 | Registration rejects email < 8 characters | Validation error, code EmailLengthIncorrect |
RegisterUserValidator |
| AC-7 | Registration rejects invalid email format | Validation error, code WrongEmail |
RegisterUserValidator |
| AC-8 | Registration rejects password < 8 characters | Validation error, code PasswordLengthIncorrect |
RegisterUserValidator |
| AC-9 | Registration rejects duplicate email | HTTP 409, ErrorCode: 20 (EmailExists) |
UserService.RegisterUser |
| AC-10 | Password is stored as SHA-384 hash, never plaintext | PasswordHash column contains Base64 of SHA-384 |
Security.ToHash() |
| AC-11 | User listing supports optional email and role filters | Filters applied via WhereIf |
UserService.GetUsers |
| AC-12 | Only ApiAdmin role can create, list, modify, or delete users | Endpoints require apiAdminPolicy |
Program.cs authorization |
Hardware Binding
| # | Criterion | Threshold | Source |
|---|---|---|---|
| AC-13 | First hardware check stores the hardware fingerprint | hardware column updated from null to provided string |
UserService.CheckHardwareHash |
| AC-14 | Subsequent hardware checks compare hash of provided hardware against stored | Hash comparison via Security.GetHWHash |
UserService.CheckHardwareHash |
| AC-15 | Hardware mismatch returns error code 40 | HTTP 409, ErrorCode: 40 (HardwareIdMismatch) |
UserService.CheckHardwareHash |
| AC-16 | Admin can reset hardware by setting it to null | PUT /users/hardware/set with null hardware |
UserService.UpdateHardware |
Resource Management
| # | Criterion | Threshold | Source |
|---|---|---|---|
| AC-17 | File upload supports up to 200 MB | Kestrel MaxRequestBodySize = 209715200 |
Program.cs |
| AC-18 | Uploaded file is saved to configured resource folder | File written to ResourcesConfig.ResourcesFolder |
ResourcesService.SaveResource |
| AC-19 | Resource download returns AES-256-CBC encrypted stream | Encryption via Security.EncryptTo |
ResourcesService.GetEncryptedResource |
| AC-20 | Encrypted resource can be decrypted with same key | Round-trip encrypt/decrypt preserves data | SecurityTest.EncryptDecryptTest ✓ |
| AC-21 | Large files (hundreds of MB) can be encrypted/decrypted | Round-trip works for ~400 MB files | SecurityTest.EncryptDecryptLargeFileTest ✓ |
| AC-22 | Missing file upload returns error code 60 | HTTP 409, ErrorCode: 60 (NoFileProvided) |
ResourcesService.SaveResource |
| AC-23 | Installer download returns latest AzaionSuite.Iterative* file |
Scans installer folder, returns first match | ResourcesService.GetInstaller |
| AC-24 | Only ApiAdmin can clear resource folders | POST /resources/clear requires apiAdminPolicy |
Program.cs |
API Behavior
| # | Criterion | Threshold | Source |
|---|---|---|---|
| AC-25 | Business errors return HTTP 409 with JSON {ErrorCode, Message} |
Handled by BusinessExceptionHandler |
BusinessExceptionHandler.TryHandleAsync |
| AC-26 | Swagger UI available in Development environment | app.UseSwagger() conditional on IsDevelopment |
Program.cs |
| AC-27 | Root URL redirects to /swagger | URL rewrite rule | Program.cs |
| AC-28 | CORS allows requests from admin.azaion.com | Origins: https://admin.azaion.com, http://admin.azaion.com |
Program.cs |