refactor: remove obsolete resource download and installer endpoints
ci/woodpecker/push/01-test Pipeline failed
ci/woodpecker/push/02-build-push unknown status

- 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:
Oleksandr Bezdieniezhnykh
2026-05-14 04:17:55 +03:00
parent c7b297de83
commit 3a925b9b0f
60 changed files with 1202 additions and 982 deletions
@@ -1,23 +1,21 @@
# Module: Azaion.Services.ResourcesService
## Purpose
File-based resource management: upload, list, download (encrypted), clear, and installer retrieval from the server's filesystem.
File-based resource management: upload, list, and clear files in the server's filesystem.
> **Cycle 2 (2026-05-14) note** — `GetInstaller` and `GetEncryptedResource` were removed along with the `POST /resources/get/{dataFolder?}` and `GET /resources/get-installer[/stage]` endpoints; the corresponding interface methods, the `Security.EncryptTo` dependency, and the `ResourcesConfig.SuiteInstallerFolder` / `SuiteStageInstallerFolder` properties went with them. The service is now upload + list + clear only.
## Public Interface
### IResourcesService
| Method | Signature | Description |
|--------|-----------|-------------|
| `GetInstaller` | `(string?, Stream?) GetInstaller(bool isStage)` | Returns the latest installer file (prod or stage) |
| `GetEncryptedResource` | `Task<Stream> GetEncryptedResource(string? dataFolder, string fileName, string key, CancellationToken ct)` | Reads a file and returns it AES-encrypted |
| `SaveResource` | `Task SaveResource(string? dataFolder, IFormFile data, CancellationToken ct)` | Saves an uploaded file to the resource folder |
| `ListResources` | `Task<IEnumerable<string>> ListResources(string? dataFolder, string? search, CancellationToken ct)` | Lists file names in a resource folder, optionally filtered |
| `ClearFolder` | `void ClearFolder(string? dataFolder)` | Deletes all files and subdirectories in the specified folder |
## Internal Logic
- **GetResourceFolder**: resolves the target directory. If `dataFolder` is null/empty, uses `ResourcesConfig.ResourcesFolder` directly; otherwise, appends it as a subdirectory.
- **GetInstaller**: scans the installer folder for files matching `"AzaionSuite.Iterative*"`, returns the first match as a `FileStream`.
- **GetEncryptedResource**: opens the file, encrypts via `Security.EncryptTo` extension into a `MemoryStream`, returns the encrypted stream.
- **SaveResource**: creates the folder if needed, deletes any existing file with the same name, then copies the uploaded file.
- **ListResources**: uses `DirectoryInfo.GetFiles` with optional search pattern.
- **ClearFolder**: iterates and deletes all files and subdirectories.
@@ -26,24 +24,22 @@ File-based resource management: upload, list, download (encrypted), clear, and i
- `IOptions<ResourcesConfig>` — folder paths
- `ILogger<ResourcesService>` — logs successful saves
- `BusinessException` — thrown for null file uploads
- `Security.EncryptTo` — stream encryption extension
## Consumers
- `Program.cs`all `/resources/*` endpoints
- `Program.cs``POST /resources/{dataFolder?}` (upload), `GET /resources/list/{dataFolder?}`, `POST /resources/clear/{dataFolder?}`
## Data Models
None.
## Configuration
Uses `ResourcesConfig` (ResourcesFolder, SuiteInstallerFolder, SuiteStageInstallerFolder).
Uses `ResourcesConfig.ResourcesFolder`.
## External Integrations
Local filesystem for resource storage.
## Security
- Resources are encrypted per-user using a key derived from `email + password` (the hardware-hash component was removed by AZ-197 — see `services_security.md`).
- File deletion overwrites existing files before writing new ones.
- No path traversal protection on `dataFolder` parameter.
- No path traversal protection on `dataFolder` parameter (security audit F-2 — open).
## Tests
None at the module level. End-to-end coverage lives in `e2e/Azaion.E2E/Tests/ResourceTests.cs` (encrypted download / round-trip / 200 MB upload limit) — updated by AZ-197 to stop sending the `Hardware` field.
End-to-end coverage in `e2e/Azaion.E2E/Tests/ResourceTests.cs` `File_upload_succeeds` and `Upload_without_file_is_rejected_with_400_or_409_and_60_on_conflict`.