Add inbox_controller_test.exs

This commit is contained in:
Mirai Kumiko 2025-06-29 08:35:12 +02:00
parent c30541830f
commit 748baff8f3
Signed by: miraikumiko
GPG key ID: 3F178B1B5E0CB278
2 changed files with 99 additions and 22 deletions

View file

@ -0,0 +1,71 @@
defmodule NullaWeb.InboxControllerTest do
use NullaWeb.ConnCase
alias Nulla.Snowflake
alias Nulla.Models.User
alias Nulla.Models.Actor
setup do
Nulla.Fixtures.Data.create()
:ok
end
describe "POST /users/username/inbox" do
test "Validate follow request", %{conn: conn} do
actor = Actor.get_actor(preferredUsername: "test")
target_actor = Actor.get_actor(preferredUsername: "test2")
user = User.get_user(id: actor.id)
follow_activity = %{
"@context" => "https://www.w3.org/ns/activitystreams",
"id" => Snowflake.next_id(),
"type" => "Follow",
"actor" => actor.ap_id,
"object" => target_actor.ap_id
}
body = Jason.encode!(follow_activity)
digest = "SHA-256=" <> (:crypto.hash(:sha256, body) |> Base.encode64())
date = Calendar.strftime(DateTime.utc_now(), "%a, %d %b %Y %H:%M:%S GMT")
uri = URI.parse("/users/test2/inbox")
signature_string = """
(request-target): post #{uri.path}
host: localhost
date: #{date}
digest: #{digest}
"""
private_key =
case :public_key.pem_decode(user.privateKeyPem) do
[entry] -> :public_key.pem_entry_decode(entry)
_ -> raise "Invalid PEM format"
end
signature =
:public_key.sign(signature_string, :sha256, private_key)
|> Base.encode64()
signature_header =
"""
keyId="#{actor.publicKey["id"]}",
algorithm="rsa-sha256",
headers="(request-target) host date digest",
signature="#{signature}"
"""
|> String.replace("\n", "")
|> String.trim()
conn =
conn
|> put_req_header("content-type", "application/activity+json")
|> put_req_header("accept", "application/activity+json")
|> put_req_header("date", date)
|> put_req_header("digest", digest)
|> put_req_header("signature", signature_header)
|> post("/users/test2/inbox", body)
assert conn.status == 200
end
end
end

View file

@ -5,23 +5,29 @@ defmodule Nulla.Fixtures.Data do
alias Nulla.Models.Note alias Nulla.Models.Note
def create do def create do
endpoint_config = Application.fetch_env!(:nulla, NullaWeb.Endpoint)
ip = endpoint_config[:http][:ip]
host = :inet_parse.ntoa(ip) |> to_string()
port = endpoint_config[:http][:port]
base_url = "http://#{host}:#{port}"
{publicKeyPem, privateKeyPem} = KeyGen.gen() {publicKeyPem, privateKeyPem} = KeyGen.gen()
{:ok, actor} = {:ok, actor} =
Actor.create_actor(%{ Actor.create_actor(%{
domain: "localhost", domain: "localhost",
ap_id: "http://localhost/users/test", ap_id: "#{base_url}/users/test",
type: "Person", type: "Person",
following: "http://localhost/users/test/following", following: "#{base_url}/users/test/following",
followers: "http://localhost/users/test/followers", followers: "#{base_url}/users/test/followers",
inbox: "http://localhost/users/test/inbox", inbox: "#{base_url}/users/test/inbox",
outbox: "http://localhost/users/test/outbox", outbox: "#{base_url}/users/test/outbox",
featured: "http://localhost/users/test/collections/featured", featured: "#{base_url}/users/test/collections/featured",
featuredTags: "http://localhost/users/test/collections/tags", featuredTags: "#{base_url}/users/test/collections/tags",
preferredUsername: "test", preferredUsername: "test",
name: "Test", name: "Test",
summary: "Test User", summary: "Test User",
url: "http://localhost/@test", url: "#{base_url}/@test",
manuallyApprovesFollowers: false, manuallyApprovesFollowers: false,
discoverable: true, discoverable: true,
indexable: true, indexable: true,
@ -29,11 +35,11 @@ defmodule Nulla.Fixtures.Data do
memorial: false, memorial: false,
publicKey: publicKey:
Jason.OrderedObject.new( Jason.OrderedObject.new(
id: "http://localhost/users/test#main-key", id: "#{base_url}/users/test#main-key",
owner: "http://localhost/users/test", owner: "#{base_url}/users/test",
publicKeyPem: publicKeyPem publicKeyPem: publicKeyPem
), ),
endpoints: Jason.OrderedObject.new(sharedInbox: "http://localhost/inbox") endpoints: Jason.OrderedObject.new(sharedInbox: "#{base_url}/inbox")
}) })
User.create_user(%{ User.create_user(%{
@ -56,18 +62,18 @@ defmodule Nulla.Fixtures.Data do
{:ok, actor} = {:ok, actor} =
Actor.create_actor(%{ Actor.create_actor(%{
domain: "localhost", domain: "localhost",
ap_id: "http://localhost/users/test2", ap_id: "#{base_url}/users/test2",
type: "Person", type: "Person",
following: "http://localhost/users/test2/following", following: "#{base_url}/users/test2/following",
followers: "http://localhost/users/test2/followers", followers: "#{base_url}/users/test2/followers",
inbox: "http://localhost/users/test2/inbox", inbox: "#{base_url}/users/test2/inbox",
outbox: "http://localhost/users/test2/outbox", outbox: "#{base_url}/users/test2/outbox",
featured: "http://localhost/users/test2/collections/featured", featured: "#{base_url}/users/test2/collections/featured",
featuredTags: "http://localhost/users/test2/collections/tags", featuredTags: "#{base_url}/users/test2/collections/tags",
preferredUsername: "test2", preferredUsername: "test2",
name: "Test", name: "Test",
summary: "Test User", summary: "Test User",
url: "http://localhost/@test2", url: "#{base_url}/@test2",
manuallyApprovesFollowers: false, manuallyApprovesFollowers: false,
discoverable: true, discoverable: true,
indexable: true, indexable: true,
@ -75,11 +81,11 @@ defmodule Nulla.Fixtures.Data do
memorial: false, memorial: false,
publicKey: publicKey:
Jason.OrderedObject.new( Jason.OrderedObject.new(
id: "http://localhost/users/test2#main-key", id: "#{base_url}/users/test2#main-key",
owner: "http://localhost/users/test2", owner: "#{base_url}/users/test2",
publicKeyPem: publicKeyPem publicKeyPem: publicKeyPem
), ),
endpoints: Jason.OrderedObject.new(sharedInbox: "http://localhost/inbox") endpoints: Jason.OrderedObject.new(sharedInbox: "#{base_url}/inbox")
}) })
User.create_user(%{ User.create_user(%{