From e2e2039903dbb76f45b30b5277e69c41949519c1 Mon Sep 17 00:00:00 2001 From: Username Date: Sun, 21 Dec 2025 22:16:51 +0100 Subject: [PATCH] docs: update for tiered expiry, admin features, batch delete --- README.md | 38 +++++++++++++++++++++++++++++++++++++- TASKLIST.md | 4 ++++ documentation/api.md | 43 ++++++++++++++++++++++++++++++++++--------- 3 files changed, 75 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 4ccbcd9..caea0c8 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,12 @@ curl -X DELETE \ http://localhost:5000/abc12345 ``` +### List user's pastes (requires authentication) +```bash +curl -H "X-SSL-Client-SHA1: " \ + http://localhost:5000/pastes +``` + ## CLI Client A standalone command-line client `fpaste` is included. For E2E encryption, install the optional `cryptography` package. @@ -138,9 +144,21 @@ echo "Hello" | ./fpaste # Get paste metadata ./fpaste get -m abc12345 +# List your pastes (requires auth) +./fpaste list + +# List all pastes (admin only) +./fpaste list --all + # Delete paste (requires auth) ./fpaste delete abc12345 +# Delete multiple pastes +./fpaste delete abc12345 def67890 + +# Delete all pastes (admin only, requires confirmation) +./fpaste delete --all --confirm 42 # where 42 is expected count + # Show server info ./fpaste info @@ -237,7 +255,10 @@ Configuration via environment variables: | `FLASKPASTE_ID_LENGTH` | `12` | Paste ID length (hex characters) | | `FLASKPASTE_MAX_ANON` | `3145728` (3 MiB) | Max paste size for anonymous users | | `FLASKPASTE_MAX_AUTH` | `52428800` (50 MiB) | Max paste size for authenticated users | -| `FLASKPASTE_EXPIRY` | `432000` (5 days) | Paste expiry in seconds | +| `FLASKPASTE_EXPIRY_ANON` | `86400` (1 day) | Default expiry for anonymous users | +| `FLASKPASTE_EXPIRY_UNTRUSTED` | `604800` (7 days) | Default expiry for untrusted cert users | +| `FLASKPASTE_EXPIRY_TRUSTED` | `2592000` (30 days) | Default expiry for trusted (PKI) cert users | +| `FLASKPASTE_MAX_EXPIRY` | `7776000` (90 days) | Maximum custom expiry allowed | | `FLASKPASTE_DEDUP_WINDOW` | `3600` (1 hour) | Dedup throttle window in seconds | | `FLASKPASTE_DEDUP_MAX` | `3` | Max identical submissions per window | | `FLASKPASTE_PROXY_SECRET` | (empty) | Shared secret for proxy trust validation | @@ -276,9 +297,24 @@ location / { } ``` +### Trust Levels + +FlaskPaste distinguishes three trust levels: + +| Level | Description | Default Expiry | +|-------|-------------|----------------| +| Anonymous | No certificate | 1 day | +| Untrusted | Valid certificate, not registered via PKI | 7 days | +| Trusted | Certificate registered via `/register` endpoint | 30 days | + Authenticated users can: - Upload larger pastes (50 MiB vs 3 MiB) - Delete their own pastes +- List their own pastes + +**Admin users** (first user to register via PKI) can additionally: +- List all pastes (`GET /pastes?all=1`) +- Delete any paste ## Production Deployment diff --git a/TASKLIST.md b/TASKLIST.md index 05ceab0..e931bac 100644 --- a/TASKLIST.md +++ b/TASKLIST.md @@ -37,6 +37,10 @@ Prioritized, actionable tasks. Each task is small and completable in one session | Date | Task |------------|-------------------------------------------------------------- +| 2024-12 | Add tiered auto-expiry (anon/untrusted/trusted) +| 2024-12 | Add admin list all pastes (`--all` flag) +| 2024-12 | Add batch delete with confirmation (`--confirm N`) +| 2024-12 | Add admin rights for first PKI user | 2024-12 | Add public certificate registration endpoint | 2024-12 | Add CLI register command | 2024-12 | Implement anti-flood (dynamic PoW difficulty) diff --git a/documentation/api.md b/documentation/api.md index 39cdca7..62a24d6 100644 --- a/documentation/api.md +++ b/documentation/api.md @@ -159,6 +159,7 @@ X-SSL-Client-SHA1: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2 | `type` | string | Filter by MIME type (glob pattern, e.g., `image/*`) | | `after` | int | Created after timestamp (Unix epoch) | | `before` | int | Created before timestamp (Unix epoch) | +| `all` | int | List all pastes (admin only, set to 1) | **Response (200 OK):** ```json @@ -171,7 +172,8 @@ X-SSL-Client-SHA1: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2 "created_at": "2024-12-20T10:30:00Z", "expires_at": "2024-12-25T10:30:00Z", "burn_after_read": false, - "password_protected": false + "password_protected": false, + "owner": "a1b2c3d4..." } ], "total": 42, @@ -187,6 +189,18 @@ X-SSL-Client-SHA1: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2 } ``` +**Response (403 Forbidden - non-admin using `all=1`):** +```json +{ + "error": "Admin access required" +} +``` + +**Notes:** +- Only admin users can use `all=1` to list all pastes +- The `owner` field shows the certificate fingerprint (truncated) +- First user to register via PKI becomes admin + --- ### POST / @@ -382,7 +396,7 @@ Content-Disposition: inline ### DELETE /{id} -Delete a paste. Requires authentication and ownership. +Delete a paste. Requires authentication and ownership (or admin rights). **Request:** ```http @@ -403,9 +417,13 @@ X-SSL-Client-SHA1: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2 |------|-------------| | 400 | Invalid paste ID format | | 401 | Authentication required | -| 403 | Permission denied (not owner) | +| 403 | Permission denied (not owner or admin) | | 404 | Paste not found | +**Notes:** +- Admin users can delete any paste, not just their own +- First user to register via PKI becomes admin + --- ## MIME Type Detection @@ -431,11 +449,16 @@ FlaskPaste automatically detects MIME types using: ## Paste Expiry -Pastes expire based on last access time (default: 5 days). +Pastes automatically expire based on authentication level: + +| Trust Level | Default Expiry | Description | +|-------------|----------------|-------------| +| Anonymous | 1 day | No certificate provided | +| Untrusted | 7 days | Certificate not registered via PKI | +| Trusted | 30 days | Certificate registered via `/register` | - Every `GET /{id}` or `GET /{id}/raw` updates the last access timestamp - Cleanup runs automatically (hourly, throttled) -- Configurable via `FLASKPASTE_EXPIRY` environment variable **Custom Expiry:** @@ -448,14 +471,16 @@ curl -H "X-Expiry: 3600" --data-binary @file.txt http://host/ **Configuration:** ```bash -export FLASKPASTE_EXPIRY=432000 # Default expiry: 5 days -export FLASKPASTE_MAX_EXPIRY=2592000 # Max custom expiry: 30 days +export FLASKPASTE_EXPIRY_ANON=86400 # Anonymous: 1 day +export FLASKPASTE_EXPIRY_UNTRUSTED=604800 # Untrusted cert: 7 days +export FLASKPASTE_EXPIRY_TRUSTED=2592000 # Trusted cert: 30 days +export FLASKPASTE_MAX_EXPIRY=7776000 # Max custom expiry: 90 days ``` **Notes:** - Custom expiry is capped at `FLASKPASTE_MAX_EXPIRY` -- Invalid or negative values are ignored (uses default) -- Response includes `expires_at` timestamp when custom expiry is set +- Invalid or negative values use the default for the user's trust level +- All pastes now include `expires_at` timestamp in responses ---