Skip to content

Commit

Permalink
Added script to populate DB with 5k followers
Browse files Browse the repository at this point in the history
  • Loading branch information
allouis committed Sep 20, 2024
1 parent df358ab commit 67086c2
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 0 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ This has only been tested on MacOS using [Docker for Mac](https://docs.docker.co
- Run `yarn test` to execute tests within a Docker Compose stack.


## Populating the DB

The below command will populate the DB with ~5000 followers for the `activitypub` host

- Run `docker compose run scripts populate-activitypub-db`

 

![Leaderboard](https://github.com/TryGhost/ActivityPub/assets/115641230/371e8f36-8293-43d2-912a-772e56517e1d)
Expand Down
6 changes: 6 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ services:
mysql:
condition: service_healthy

scripts:
build: scripts
depends_on:
- activitypub
- fake-mastodon

nginx:
build: nginx
ports:
Expand Down
6 changes: 6 additions & 0 deletions scripts/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM debian:latest

RUN apt-get update -y
RUN apt-get install -y curl openssl jq

COPY bin /usr/local/bin
160 changes: 160 additions & 0 deletions scripts/bin/populate-activitypub-db
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#!/usr/bin/env bash

activitypub_url="http://activitypub:8080"
user_count=5000
wiremock_only=false

while getopts "u:n:w" opt; do
case ${opt} in
u )
activitypub_url=$OPTARG
;;
n )
user_count=$OPTARG
;;
w )
wiremock_only=true
;;
\? )
echo "Usage: cmd [-u activitypub_url] [-n user_count] [-w]"
exit 1
;;
esac
done

curl -X DELETE http://fake-mastodon:8080/__admin/mappings

curl "${activitypub_url}/.ghost/activitypub/users/index"

if [ ! -f "private.pem" ] || [ ! -f "public.pem" ]; then
openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in private.pem -out public.pem
openssl pkcs8 -topk8 -inform PEM -outform PEM -in private.pem -out private-pkcs8.pem -nocrypt
fi

PUBLIC_PEM=$(cat public.pem)

PUBLIC_PEM_JSON=$(printf '%s' "$PUBLIC_PEM" | jq -aRs .)

curl -X POST http://fake-mastodon:8080/__admin/mappings \
-H "Content-Type: application/json" \
-d '{
"request": {
"method": "POST",
"urlPattern": "/inbox/.*"
},
"response": {
"status": 200
}
}'

curl -X POST http://fake-mastodon:8080/__admin/mappings \
-H "Content-Type: application/json" \
-d '{
"request": {
"method": "GET",
"urlPattern": "/user/.*"
},
"response": {
"status": 200,
"jsonBody": {
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
"https://w3id.org/security/data-integrity/v1",
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/multikey/v1",
{
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
"toot": "http://joinmastodon.org/ns#",
"featured": {
"@id": "toot:featured",
"@type": "@id"
},
"featuredTags": {
"@id": "toot:featuredTags",
"@type": "@id"
},
"discoverable": "toot:discoverable",
"suspended": "toot:suspended",
"memorial": "toot:memorial",
"indexable": "toot:indexable",
"schema": "http://schema.org#",
"PropertyValue": "schema:PropertyValue",
"value": "schema:value"
}
],
"id": "http://fake-mastodon:8080/user/{{request.pathSegments.[1]}}",
"type": "Person",
"inbox": "http://fake-mastodon:8080/inbox/{{request.pathSegments.[1]}}",
"publicKey": {
"id": "http://fake-mastodon:8080/user/{{request.pathSegments.[1]}}#main-key",
"type": "CryptographicKey",
"owner": "http://fake-mastodon:8080/user/{{request.pathSegments.[1]}}",
"publicKeyPem": '"$PUBLIC_PEM_JSON"'
},
"followers": "http://fake-mastodon:8080/followers/{{request.pathSegments.[1]}}",
"following": "http://fake-mastodon:8080/following/{{request.pathSegments.[1]}}",
"icon": {
"type": "Image",
"url": "https://ghost.org/favicon.ico"
},
"liked": "http://fake-mastodon:8080/liked/{{request.pathSegments.[1]}}",
"name": "User {{request.pathSegments.[1]}}",
"outbox": "http://fake-mastodon:8080/outbox/{{request.pathSegments.[1]}}",
"preferredUsername": "{{request.pathSegments.[1]}}",
"summary": "This is a dynamically generated summary for {{request.pathSegments.[1]}}",
"url": "http://fake-mastodon:8080/user/{{request.pathSegments.[1]}}"
},
"headers": {
"Content-Type": "application/activity+json"
}
}
}'

if [ "$wiremock_only" = true ]; then
echo "Wiremock setup only, skipping user creation."
exit 0
fi

# Define variables
PRIVATE_KEY="private.pem"

for i in $(seq 1 $user_count); do
NAME="user$i"
echo "Processing user: $NAME"

KEY_ID="http://fake-mastodon:8080/user/$NAME#main-key"

BODY=$(jq -n --arg name "$NAME" --arg randomId "$RANDOM" '{
"@context": "https://www.w3.org/ns/activitystreams",
"id": "http://fake-mastodon:8080/activity/\($randomId)",
"type": "Follow",
"actor": "http://fake-mastodon:8080/user/\($name)",
"object": "'"${activitypub_url}/.ghost/activitypub/users/index"'",
"to": ["'"${activitypub_url}/.ghost/activitypub/users/index"'"],
"cc": ["http://fake-mastodon:8080/user/\($name)/following"]
}')

DIGEST=$(echo -n "$BODY" | openssl dgst -sha256 -binary | openssl base64)
REQUEST_TARGET="post /.ghost/activitypub/inbox/index"
HOST=$(echo "$activitypub_url" | awk -F/ '{print $3}')
DATE=$(date -R)
SIGN_STRING="(request-target): $REQUEST_TARGET\nhost: $HOST\ndate: $DATE\ndigest: SHA-256=$DIGEST"

SIGNATURE=$(echo -n "$SIGN_STRING" | openssl dgst -sha256 -sign "$PRIVATE_KEY" | openssl base64 -A)

AUTH_HEADER="keyId=\"$KEY_ID\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date digest\",signature=\"$SIGNATURE\""

curl -v -X POST "${activitypub_url}/.ghost/activitypub/inbox/index" \
-H "Host: $HOST" \
-H "Date: $DATE" \
-H "Digest: SHA-256=$DIGEST" \
-H "Signature: $AUTH_HEADER" \
-d "$BODY"

echo "Request sent for user: $NAME"
echo "---------------------------------------------"
done

exit 0

0 comments on commit 67086c2

Please sign in to comment.