mirror of
https://github.com/azaion/admin.git
synced 2026-06-21 11:41:09 +00:00
refactor: remove obsolete resource download and installer endpoints
- Deleted the `POST /resources/get/{dataFolder?}` and `GET /resources/get-installer` endpoints as part of the architectural shift towards simplified resource management.
- Removed associated methods and configurations, including `ResourcesService.GetEncryptedResource`, `ResourcesService.GetInstaller`, and related properties in `ResourcesConfig`.
- Cleaned up environment variables and configuration files to reflect the removal of installer-related settings.
- Eliminated the `GetResourceRequest` DTO and its validator, along with the `WrongResourceName` error code.
- Updated documentation to clarify the changes in resource handling and the retirement of per-user file encryption.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,14 +1,16 @@
|
||||
# Resource Management
|
||||
|
||||
> **Cycle 1 (2026-05-13) note** — AZ-197 removed the `Hardware` field from `GetResourceRequest` and removed `CheckResourceRequest` and `POST /resources/check` entirely. AZ-183 introduced an OTA update path (`POST /get-update`, `POST /resources/publish`, `IResourceUpdateService`, `Resource` entity, `resources` table, `ResourcesConfig.EncryptionMasterKey`) but it was reverted later the same day after the security audit (finding F-1) — the OTA delivery model itself was deemed obsolete. The component is now back to filesystem-backed storage only.
|
||||
> **Cycle 1 (2026-05-13) note** — AZ-197 removed the `Hardware` field from `GetResourceRequest` and removed `CheckResourceRequest` and `POST /resources/check` entirely. AZ-183 introduced an OTA update path (`POST /get-update`, `POST /resources/publish`, `IResourceUpdateService`, `Resource` entity, `resources` table, `ResourcesConfig.EncryptionMasterKey`) but it was reverted later the same day after the security audit (finding F-1) — the OTA delivery model itself was deemed obsolete.
|
||||
>
|
||||
> **Cycle 2 (2026-05-14) note** — the encrypted-download endpoint (`POST /resources/get/{dataFolder?}`) and both installer endpoints (`GET /resources/get-installer[/stage]`) were removed as obsolete. With them went `ResourcesService.GetEncryptedResource` / `GetInstaller`, `GetResourceRequest` (and `WrongResourceName = 50`), and the `ResourcesConfig.SuiteInstallerFolder` / `SuiteStageInstallerFolder` properties + their env-var rows. The component is now upload + list + clear only and no longer depends on Authentication & Security for encryption primitives.
|
||||
|
||||
## 1. High-Level Overview
|
||||
|
||||
**Purpose**: filesystem-backed storage — upload, list, download (per-user AES-encrypted), folder clearing, installer distribution. Owned by `IResourcesService`.
|
||||
**Purpose**: filesystem-backed storage — upload, list, clear. Owned by `IResourcesService`.
|
||||
|
||||
**Architectural Pattern**: a single service over the local filesystem. No DB access, no cache.
|
||||
|
||||
**Upstream dependencies**: Data Layer (`ResourcesConfig`), Authentication & Security (encryption via `Security.EncryptTo`).
|
||||
**Upstream dependencies**: Data Layer (`ResourcesConfig`).
|
||||
|
||||
**Downstream consumers**: Admin API (resource endpoints).
|
||||
|
||||
@@ -18,22 +20,18 @@
|
||||
|
||||
| Method | Input | Output | Async | Error Types |
|
||||
|--------|-------|--------|-------|-------------|
|
||||
| `GetInstaller` | `bool isStage` | `(string?, Stream?)` | No | None (returns nulls if not found) |
|
||||
| `GetEncryptedResource` | `string? dataFolder, string fileName, string key, CancellationToken` | `Stream` | Yes | `FileNotFoundException` |
|
||||
| `SaveResource` | `string? dataFolder, IFormFile data, CancellationToken` | void | Yes | `BusinessException(NoFileProvided)` |
|
||||
| `ListResources` | `string? dataFolder, string? search, CancellationToken` | `IEnumerable<string>` | Yes | `DirectoryNotFoundException` |
|
||||
| `ClearFolder` | `string? dataFolder` | void | No | None |
|
||||
|
||||
**Input DTO**:
|
||||
```
|
||||
GetResourceRequest (post-AZ-197):
|
||||
Password: string (required, min 8 chars)
|
||||
FileName: string (required, not empty)
|
||||
// Hardware field removed by AZ-197.
|
||||
**Removed**:
|
||||
- `GetEncryptedResource` — removed in cycle 2 with the encrypted-download endpoint.
|
||||
- `GetInstaller` — removed in cycle 2 with the installer endpoints.
|
||||
|
||||
// CheckResourceRequest — REMOVED by AZ-197.
|
||||
// GetUpdateRequest, PublishResourceRequest — added by AZ-183, removed in the post-cycle-1 revert.
|
||||
```
|
||||
**Removed DTOs**:
|
||||
- `GetResourceRequest` — removed in cycle 2 (file deleted).
|
||||
- `CheckResourceRequest` — removed by AZ-197 (cycle 1).
|
||||
- `GetUpdateRequest`, `PublishResourceRequest` — removed in the post-cycle-1 AZ-183 revert.
|
||||
|
||||
## 3. External API Specification
|
||||
|
||||
@@ -49,7 +47,7 @@ N/A — exposed through Admin API.
|
||||
|
||||
### Storage Estimates
|
||||
|
||||
- **Filesystem**: AI models, DLLs, installers — potentially hundreds of MB per file.
|
||||
- **Filesystem**: AI models, DLLs, etc. — potentially hundreds of MB per file.
|
||||
|
||||
## 5. Implementation Details
|
||||
|
||||
@@ -61,32 +59,26 @@ N/A — exposed through Admin API.
|
||||
- `SaveResource` throws `BusinessException(NoFileProvided)` for null uploads.
|
||||
- Missing files/directories throw standard .NET I/O exceptions.
|
||||
- `ClearFolder` silently returns if directory doesn't exist.
|
||||
- `GetInstaller` returns `(null, null)` tuple if installer file is not found.
|
||||
|
||||
## 6. Extensions and Helpers
|
||||
|
||||
| Helper | Purpose | Used By |
|
||||
|--------|---------|---------|
|
||||
| `Security.EncryptTo` | AES stream encryption | `GetEncryptedResource` |
|
||||
| `Security.GetApiEncryptionKey(email, password)` | Per-user key derivation (post-AZ-197 — no hardware component) | Admin API (before calling `GetEncryptedResource`) |
|
||||
None remaining after the cycle-2 removal of `Security.EncryptTo` and `Security.GetApiEncryptionKey`.
|
||||
|
||||
## 7. Caveats & Edge Cases
|
||||
|
||||
**Known limitations** (security-audit findings):
|
||||
- **F-2 (High)** — no path traversal protection: `dataFolder` parameter is concatenated directly with `ResourcesFolder`. A malicious `dataFolder` like `../../etc` could access arbitrary filesystem paths. Filed as separate ticket.
|
||||
- `SaveResource` deletes existing file before writing — no versioning or backup.
|
||||
- `GetEncryptedResource` loads the entire encrypted file into a `MemoryStream` — memory-intensive for large files.
|
||||
- `ListResources` wraps a synchronous `DirectoryInfo.GetFiles` in `Task.FromResult` — not truly async.
|
||||
|
||||
**Performance bottlenecks**:
|
||||
- Full file encryption to memory before streaming response: memory usage scales with file size.
|
||||
- `ClearFolder` iterates and deletes files synchronously.
|
||||
|
||||
## 8. Dependency Graph
|
||||
|
||||
**Must be implemented after**: Data Layer (ResourcesConfig), Authentication & Security (encryption).
|
||||
**Must be implemented after**: Data Layer (ResourcesConfig).
|
||||
|
||||
**Can be implemented in parallel with**: User Management.
|
||||
**Can be implemented in parallel with**: User Management, Authentication & Security.
|
||||
|
||||
**Blocks**: Admin API.
|
||||
|
||||
@@ -101,6 +93,5 @@ N/A — exposed through Admin API.
|
||||
**Log storage**: console + rolling file (via Serilog configured in Program.cs).
|
||||
|
||||
## Modules Covered
|
||||
- `Services/ResourcesService`
|
||||
- `Common/Requests/GetResourceRequest` (post-AZ-197 — no `CheckResourceRequest`, no `Hardware` field)
|
||||
- `Common/Configs/ResourcesConfig` (the `EncryptionMasterKey` field added by AZ-183 was removed in the post-cycle-1 revert)
|
||||
- `Services/ResourcesService` (post-cycle-2 — only `SaveResource` / `ListResources` / `ClearFolder` remain)
|
||||
- `Common/Configs/ResourcesConfig` (post-cycle-2 — only `ResourcesFolder` remains)
|
||||
|
||||
Reference in New Issue
Block a user