Skip to content

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_b flag
  • 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_object to 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 → InvalidSignature raised → 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.