Secure Storage Module¶
Files: Features/SecureStorage/secure_storage_new_routes.py, Features/SecureStorage/upload_wasabi_home.py, Features/SecureStorage/DecideWheretoUpload.py, Features/SecureStorage/multifile_upload_routes.py
What This Module Covers¶
This module handles file upload and download for registered users (as opposed to guest_upload_routes.py which handles external senders). It includes:
- Direct multipart upload to Wasabi S3 (plain path)
- Server-side encrypted upload (encrypted path)
- Download (plain + encrypted streaming)
- Upload path routing decision
- Multi-file upload handling
Upload Decision Router¶
File: DecideWheretoUpload.py
flowchart TD
A[Upload request] --> B{User has
encryption?}
B -- Yes --> C[Encrypted
upload path]
B -- No --> D[Plain
presigned URL path]
- Checks
user.encrypt_data_bflag - Routes to encrypted or plain upload accordingly
- Acts as a gateway before actual upload initiates
Plain Upload Path (upload_wasabi_home.py)¶
Same multipart protocol as guest upload, but for registered users:
| Route | Method | Action |
|---|---|---|
/upload/initiate |
POST | create_multipart_upload on S3 |
/upload/presigned-url |
GET | Generate presigned URL for browser → S3 direct PUT |
/upload/complete |
POST | complete_multipart_upload on S3 |
The BoundedSemaphore(4) is shared between upload_wasabi_home.py and guest_upload_routes.py — total concurrent encrypt+upload ops across all users is capped at 4, not 4 per route.
Encrypted Upload Path¶
Same structure as the guest encrypted path but for registered users:
| Route | Method | Action |
|---|---|---|
/upload/encrypted/initiate |
POST | Create session token, create_multipart_upload |
/upload/encrypted/upload-part |
POST | Decrypt token, AES-256-CTR encrypt, upload_part |
/upload/encrypted/complete |
POST | Finalize HMAC, complete_multipart_upload, update S3 metadata |
Download (secure_storage_new_routes.py)¶
Plain Download¶
- Server generates presigned URL for the S3 object
- Browser redirected to Wasabi directly
- No server RAM usage for file data
Encrypted Download¶
- Server calls
s3.get_objectto stream ciphertext - HMAC is read from S3 metadata
- Stream is decrypted chunk-by-chunk with
AES-256-CTR - HMAC verified against accumulated value after full stream
- If HMAC fails →
InvalidSignatureraised → stream aborted - Plaintext yielded as Flask streaming response
Multi-File Upload (multifile_upload_routes.py)¶
- Handles batch upload of multiple files in a single session
- Each file is individually initiated, uploaded in parts, and completed
- Progress tracking per file
- Supports both plain and encrypted paths per file
TL;DR¶
What it does: Upload and download for registered users. Plain path = browser → S3 direct via presigned URLs. Encrypted path = browser → server (AES-256-CTR) → S3. Download = S3 stream → server decrypt → browser.
Key constraints: Same BoundedSemaphore(4) shared with guest upload. HMAC registry requires single Gunicorn worker. Streaming decryption keeps server RAM bounded.