b29a268b1d
- Move completed plan files to .plans/done/ - Move 18 open plan files to .plans/open/ - Update .gitignore to exclude .verified_plans temp file - Verified all 18 open plans still describe unimplemented issues
76 lines
3.3 KiB
Markdown
76 lines
3.3 KiB
Markdown
# Plan: Issue #48 — Encrypted export (password-protected ZIP)
|
|
|
|
## Summary
|
|
Add encrypted export functionality that wraps sensitive CSV/PDF export files in AES-256 password-protected ZIP archives. The user provides a password at export time, and only users with banking visibility can export banking reports. All sensitive exports are audit-logged.
|
|
|
|
## Existing Code Context
|
|
- `EncryptionService.php` — field-level encryption (Issue #60), NOT file-level
|
|
- `CsvExportService.php` — generates CSV exports with UTF-8 BOM
|
|
- `ExportController.php` — REST endpoints for CSV downloads
|
|
- `AuditService.php` — audit logging with field-level diffs
|
|
- `PermissionService.php` — access control with `canSeeBanking()` method
|
|
- Routes in `appinfo/routes.php`
|
|
|
|
## Implementation Steps
|
|
|
|
### Step 1: Create EncryptedExportService
|
|
**File:** `lib/Service/EncryptedExportService.php`
|
|
|
|
Service that wraps any export content (CSV or PDF binary) in a password-protected ZIP.
|
|
|
|
```php
|
|
class EncryptedExportService {
|
|
// Dependencies: AuditService, PermissionService, IUserSession, LoggerInterface
|
|
|
|
// createEncryptedZip(string $content, string $filename, string $password): string
|
|
// - Creates temp ZipArchive
|
|
// - Sets encryption to AES-256 (ZipArchive::EM_AES_256)
|
|
// - Adds content as file inside ZIP
|
|
// - Returns ZIP binary
|
|
// - Cleanup: unlink temp files
|
|
|
|
// createEncryptedExport(string $content, string $innerFilename, string $password, string $userId, string $exportType): array
|
|
// - Permission check for sensitive exports
|
|
// - Calls createEncryptedZip
|
|
// - Audit logs the export
|
|
// - Returns {content: binary, filename: "Export_encrypted_<date>.zip"}
|
|
}
|
|
```
|
|
|
|
### Step 2: Add Encrypted Export Endpoints to ExportController
|
|
**File:** `lib/Controller/ExportController.php`
|
|
|
|
Add new endpoints that accept a `password` POST parameter and return encrypted ZIPs:
|
|
|
|
- `POST /api/v1/export/members/encrypted` — encrypted member list
|
|
- `POST /api/v1/export/fees/encrypted` — encrypted fee records
|
|
- `POST /api/v1/export/birthdays/encrypted` — encrypted birthday list
|
|
- `POST /api/v1/export/banking/encrypted` — encrypted banking data (requires canSeeBanking)
|
|
|
|
POST method used because password must not appear in URL/query string.
|
|
|
|
### Step 3: Add Banking Export to CsvExportService
|
|
**File:** `lib/Service/CsvExportService.php`
|
|
|
|
Add `exportBankingList()` method that exports IBAN/Kontoinhaber data (decrypted) for members. This is a sensitive export that requires banking permission.
|
|
|
|
### Step 4: Register New Routes
|
|
**File:** `appinfo/routes.php`
|
|
|
|
Add routes for the encrypted export endpoints.
|
|
|
|
### Step 5: Add Unit Test
|
|
**File:** `tests/Unit/EncryptedExportServiceTest.php`
|
|
|
|
Test ZIP creation, encryption flag usage, audit logging.
|
|
|
|
## Acceptance Criteria Checklist
|
|
1. [ ] Sensitive exports prompt for password and produce AES-256 encrypted ZIP
|
|
2. [ ] ZIP contains the original PDF or CSV file inside
|
|
3. [ ] ZipArchive with EM_AES_256 encryption is used
|
|
4. [ ] Fallback handling if ZipArchive encryption is not available
|
|
5. [ ] Audit log entry for every sensitive export (who exported what, when)
|
|
6. [ ] Permission check: only users with banking visibility can export banking reports
|
|
7. [ ] Clear separation of encrypted vs. plain export endpoints
|
|
8. [ ] POST method used for encrypted endpoints (password not in URL)
|