Persona separation is tested, the API is smoke-checked on deploy, OAuth rows are pruned
- PersonaSeparationTests: two personas of one login follow the same account and post; nothing the API maps for one contains the other's id, username or the root id. - tools/smoke/mastodon-api.sh checks what a client meets first (instance v1/v2, discovery, app registration, client credentials, an app token refused by a user endpoint, the public timeline, revocation) and, given a persona token, verify_credentials, home and notifications. deploy.yml runs it after every deploy. - OAuthPruner removes invalid tokens and authorizations older than two weeks, every six hours. - The consent page no longer sets form-action, which browsers apply to the redirect back to the client after the form is posted. CLAUDE.md gains the Mastodon API layout and invariants. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012CzABvBkbcFqoHdmi8b9WB
This commit is contained in:
1 parent
70b4c45eb0
commit
d8f163b5ce
7 files changed
+157
-3
No files matched your search
Executable
+27
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
# Checks the Mastodon client API the way a client first meets it.
|
||||
# usage: tools/smoke/mastodon-api.sh https://privapub.thepra.dev [ACCESS_TOKEN]
|
||||
set -euo pipefail
|
||||
BASE="${1:?base url}"; TOKEN="${2:-}"
|
||||
fail() { echo "::error::$*"; exit 1; }
|
||||
json() { python3 -c "import sys,json; d=json.load(sys.stdin); $1"; }
|
||||
|
||||
version=$(curl -fsS "$BASE/api/v1/instance" | json "print(d['version'])") || fail "instance v1"
|
||||
curl -fsS "$BASE/api/v2/instance" | json "assert d['configuration']['statuses']['max_characters'] > 0" || fail "instance v2"
|
||||
curl -fsS "$BASE/.well-known/oauth-authorization-server" | json "assert d['token_endpoint'].endswith('/oauth/token')" || fail "oauth discovery"
|
||||
|
||||
app=$(curl -fsS -X POST "$BASE/api/v1/apps" -d 'client_name=privapub-smoke&redirect_uris=urn:ietf:wg:oauth:2.0:oob&scopes=read') || fail "app registration"
|
||||
id=$(echo "$app" | json "print(d['client_id'])"); secret=$(echo "$app" | json "print(d['client_secret'])")
|
||||
app_token=$(curl -fsS -X POST "$BASE/oauth/token" -d "grant_type=client_credentials&client_id=$id&client_secret=$secret&scope=read" | json "print(d['access_token'])") || fail "client credentials"
|
||||
curl -fsS -H "Authorization: Bearer $app_token" "$BASE/api/v1/apps/verify_credentials" | json "assert d['name'] == 'privapub-smoke'" || fail "app verify_credentials"
|
||||
code=$(curl -s -o /dev/null -w '%{http_code}' -H "Authorization: Bearer $app_token" "$BASE/api/v1/accounts/verify_credentials")
|
||||
[ "$code" = "401" ] || fail "an app token reached a user endpoint ($code)"
|
||||
curl -fsS "$BASE/api/v1/timelines/public?limit=2" | json "assert isinstance(d, list)" || fail "public timeline"
|
||||
curl -fsS -X POST "$BASE/oauth/revoke" -d "token=$app_token&client_id=$id&client_secret=$secret" -o /dev/null || fail "revoke"
|
||||
|
||||
if [ -n "$TOKEN" ]; then
|
||||
curl -fsS -H "Authorization: Bearer $TOKEN" "$BASE/api/v1/accounts/verify_credentials" | json "assert d['source'] is not None" || fail "verify_credentials"
|
||||
curl -fsS -H "Authorization: Bearer $TOKEN" "$BASE/api/v1/timelines/home?limit=5" | json "assert isinstance(d, list)" || fail "home"
|
||||
curl -fsS -H "Authorization: Bearer $TOKEN" "$BASE/api/v1/notifications?limit=5" | json "assert isinstance(d, list)" || fail "notifications"
|
||||
fi
|
||||
echo "mastodon api ok: $version"
|
||||
Reference in new issue
Block a user