forked from claw/flaskpaste
docs: update for tiered expiry, admin features, batch delete
This commit is contained in:
38
README.md
38
README.md
@@ -92,6 +92,12 @@ curl -X DELETE \
|
|||||||
http://localhost:5000/abc12345
|
http://localhost:5000/abc12345
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### List user's pastes (requires authentication)
|
||||||
|
```bash
|
||||||
|
curl -H "X-SSL-Client-SHA1: <your-cert-fingerprint>" \
|
||||||
|
http://localhost:5000/pastes
|
||||||
|
```
|
||||||
|
|
||||||
## CLI Client
|
## CLI Client
|
||||||
|
|
||||||
A standalone command-line client `fpaste` is included. For E2E encryption, install the optional `cryptography` package.
|
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
|
# Get paste metadata
|
||||||
./fpaste get -m abc12345
|
./fpaste get -m abc12345
|
||||||
|
|
||||||
|
# List your pastes (requires auth)
|
||||||
|
./fpaste list
|
||||||
|
|
||||||
|
# List all pastes (admin only)
|
||||||
|
./fpaste list --all
|
||||||
|
|
||||||
# Delete paste (requires auth)
|
# Delete paste (requires auth)
|
||||||
./fpaste delete abc12345
|
./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
|
# Show server info
|
||||||
./fpaste info
|
./fpaste info
|
||||||
|
|
||||||
@@ -237,7 +255,10 @@ Configuration via environment variables:
|
|||||||
| `FLASKPASTE_ID_LENGTH` | `12` | Paste ID length (hex characters) |
|
| `FLASKPASTE_ID_LENGTH` | `12` | Paste ID length (hex characters) |
|
||||||
| `FLASKPASTE_MAX_ANON` | `3145728` (3 MiB) | Max paste size for anonymous users |
|
| `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_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_WINDOW` | `3600` (1 hour) | Dedup throttle window in seconds |
|
||||||
| `FLASKPASTE_DEDUP_MAX` | `3` | Max identical submissions per window |
|
| `FLASKPASTE_DEDUP_MAX` | `3` | Max identical submissions per window |
|
||||||
| `FLASKPASTE_PROXY_SECRET` | (empty) | Shared secret for proxy trust validation |
|
| `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:
|
Authenticated users can:
|
||||||
- Upload larger pastes (50 MiB vs 3 MiB)
|
- Upload larger pastes (50 MiB vs 3 MiB)
|
||||||
- Delete their own pastes
|
- 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
|
## Production Deployment
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ Prioritized, actionable tasks. Each task is small and completable in one session
|
|||||||
|
|
||||||
| Date | Task
|
| 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 public certificate registration endpoint
|
||||||
| 2024-12 | Add CLI register command
|
| 2024-12 | Add CLI register command
|
||||||
| 2024-12 | Implement anti-flood (dynamic PoW difficulty)
|
| 2024-12 | Implement anti-flood (dynamic PoW difficulty)
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ X-SSL-Client-SHA1: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
|
|||||||
| `type` | string | Filter by MIME type (glob pattern, e.g., `image/*`) |
|
| `type` | string | Filter by MIME type (glob pattern, e.g., `image/*`) |
|
||||||
| `after` | int | Created after timestamp (Unix epoch) |
|
| `after` | int | Created after timestamp (Unix epoch) |
|
||||||
| `before` | int | Created before timestamp (Unix epoch) |
|
| `before` | int | Created before timestamp (Unix epoch) |
|
||||||
|
| `all` | int | List all pastes (admin only, set to 1) |
|
||||||
|
|
||||||
**Response (200 OK):**
|
**Response (200 OK):**
|
||||||
```json
|
```json
|
||||||
@@ -171,7 +172,8 @@ X-SSL-Client-SHA1: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
|
|||||||
"created_at": "2024-12-20T10:30:00Z",
|
"created_at": "2024-12-20T10:30:00Z",
|
||||||
"expires_at": "2024-12-25T10:30:00Z",
|
"expires_at": "2024-12-25T10:30:00Z",
|
||||||
"burn_after_read": false,
|
"burn_after_read": false,
|
||||||
"password_protected": false
|
"password_protected": false,
|
||||||
|
"owner": "a1b2c3d4..."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"total": 42,
|
"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 /
|
### POST /
|
||||||
@@ -382,7 +396,7 @@ Content-Disposition: inline
|
|||||||
```http
|
```http
|
||||||
DELETE /abc12345 HTTP/1.1
|
DELETE /abc12345 HTTP/1.1
|
||||||
Host: localhost:5000
|
Host: localhost:5000
|
||||||
X-SSL-Client-SHA1: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
|
X-SSL-Client-SHA1: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
|
||||||
```
|
```
|
||||||
|
|
||||||
**Response (200 OK):**
|
**Response (200 OK):**
|
||||||
@@ -403,9 +417,13 @@ X-SSL-Client-SHA1: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
|
|||||||
**Notes:**
|
**Notes:**
|
||||||
- Admin users can delete any paste, not just their own
|
- Admin users can delete any paste, not just their own
|
||||||
- First user to register via PKI becomes admin
|
- First user to register via PKI becomes admin
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## MIME Type Detection
|
||||||
|
|
||||||
|
FlaskPaste automatically detects MIME types using:
|
||||||
|
|
||||||
1. **Magic byte signatures** (highest priority)
|
1. **Magic byte signatures** (highest priority)
|
||||||
- PNG: `\x89PNG\r\n\x1a\n`
|
- PNG: `\x89PNG\r\n\x1a\n`
|
||||||
- JPEG: `\xff\xd8\xff`
|
- JPEG: `\xff\xd8\xff`
|
||||||
@@ -431,11 +449,16 @@ FlaskPaste automatically detects MIME types using:
|
|||||||
|-------------|----------------|-------------|
|
|-------------|----------------|-------------|
|
||||||
| Anonymous | 1 day | No certificate provided |
|
| Anonymous | 1 day | No certificate provided |
|
||||||
| Untrusted | 7 days | Certificate not registered via PKI |
|
| Untrusted | 7 days | Certificate not registered via PKI |
|
||||||
**Custom Expiry:**
|
| Trusted | 30 days | Certificate registered via `/register` |
|
||||||
|
|
||||||
|
- Every `GET /{id}` or `GET /{id}/raw` updates the last access timestamp
|
||||||
|
- Cleanup runs automatically (hourly, throttled)
|
||||||
|
|
||||||
|
**Custom Expiry:**
|
||||||
|
|
||||||
Pastes can have custom expiry times using the `X-Expiry` header:
|
Pastes can have custom expiry times using the `X-Expiry` header:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
```bash
|
|
||||||
# Paste expires in 1 hour
|
# Paste expires in 1 hour
|
||||||
curl -H "X-Expiry: 3600" --data-binary @file.txt http://host/
|
curl -H "X-Expiry: 3600" --data-binary @file.txt http://host/
|
||||||
```
|
```
|
||||||
@@ -448,14 +471,16 @@ curl -H "X-Expiry: 3600" --data-binary @file.txt http://host/
|
|||||||
export FLASKPASTE_MAX_EXPIRY=7776000 # Max custom expiry: 90 days
|
export FLASKPASTE_MAX_EXPIRY=7776000 # Max custom expiry: 90 days
|
||||||
```
|
```
|
||||||
|
|
||||||
- Invalid or negative values are ignored (uses default)
|
**Notes:**
|
||||||
- Response includes `expires_at` timestamp when custom expiry is set
|
- Custom expiry is capped at `FLASKPASTE_MAX_EXPIRY`
|
||||||
|
- Invalid or negative values use the default for the user's trust level
|
||||||
|
- All pastes now include `expires_at` timestamp in responses
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Burn-After-Read
|
## Burn-After-Read
|
||||||
|
|
||||||
Single-access pastes that delete themselves after first retrieval.
|
Single-access pastes that delete themselves after first retrieval.
|
||||||
|
|
||||||
**How it works:**
|
**How it works:**
|
||||||
- Set `X-Burn-After-Read: true` header on creation
|
- Set `X-Burn-After-Read: true` header on creation
|
||||||
|
|||||||
Reference in New Issue
Block a user