feat: Add basic actor and webfinger setup
This commit is contained in:
parent
3b385a6a1c
commit
5529d5f979
8 changed files with 103 additions and 4 deletions
|
|
@ -13,11 +13,30 @@ defmodule Postland do
|
|||
:crypto.strong_rand_bytes(12) |> Base.encode64()
|
||||
end
|
||||
|
||||
def generate_keys(bits \\ 4096) do
|
||||
{:RSAPrivateKey, _, modulus, publicExponent, _, _, _, _exponent1, _, _, _otherPrimeInfos} =
|
||||
rsa_private_key = :public_key.generate_key({:rsa, bits, 65537})
|
||||
|
||||
rsa_public_key = {:RSAPublicKey, modulus, publicExponent}
|
||||
|
||||
pem_entry = :public_key.pem_entry_encode(:RSAPrivateKey, rsa_private_key)
|
||||
private_key = :public_key.pem_encode([pem_entry])
|
||||
|
||||
pem_entry = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, rsa_public_key)
|
||||
public_key = :public_key.pem_encode([pem_entry])
|
||||
|
||||
%{public: public_key, private: private_key}
|
||||
end
|
||||
|
||||
def on_boot_setup() do
|
||||
if !setup?() do
|
||||
%{public: public_key, private: private_key} = generate_keys()
|
||||
|
||||
attrs = %{
|
||||
username: "welcome",
|
||||
password: temporary_password()
|
||||
password: temporary_password(),
|
||||
private_key: private_key,
|
||||
public_key: public_key
|
||||
}
|
||||
|
||||
{:ok, _user} = Accounts.register_user(attrs)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ defmodule Postland.Accounts.User do
|
|||
field :hashed_password, :string, redact: true
|
||||
field :current_password, :string, virtual: true, redact: true
|
||||
field :confirmed_at, :utc_datetime
|
||||
field :private_key, :string
|
||||
field :public_key, :string
|
||||
|
||||
timestamps(type: :utc_datetime)
|
||||
end
|
||||
|
|
@ -31,7 +33,7 @@ defmodule Postland.Accounts.User do
|
|||
"""
|
||||
def registration_changeset(user, attrs, opts \\ []) do
|
||||
user
|
||||
|> cast(attrs, [:username, :password])
|
||||
|> cast(attrs, [:username, :password, :public_key, :private_key])
|
||||
|> validate_username()
|
||||
|> validate_password(opts)
|
||||
end
|
||||
|
|
|
|||
7
lib/postland_web/controllers/actor_controller.ex
Normal file
7
lib/postland_web/controllers/actor_controller.ex
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
defmodule PostlandWeb.ActorController do
|
||||
use PostlandWeb, :controller
|
||||
|
||||
def get(conn, _params) do
|
||||
render(conn, :actor, %{})
|
||||
end
|
||||
end
|
||||
25
lib/postland_web/controllers/actor_json.ex
Normal file
25
lib/postland_web/controllers/actor_json.ex
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
defmodule PostlandWeb.ActorJSON do
|
||||
use Phoenix.VerifiedRoutes, endpoint: PostlandWeb.Endpoint, router: PostlandWeb.Router
|
||||
|
||||
alias Postland.Accounts
|
||||
|
||||
def render("actor.json", _assigns) do
|
||||
user = Accounts.solo_user()
|
||||
|
||||
%{
|
||||
"@context" => [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1"
|
||||
],
|
||||
"id" => url(~p"/actor"),
|
||||
"type" => "Person",
|
||||
"preferredUsername" => user.username,
|
||||
"inbox" => url(~p"/inbox"),
|
||||
"publicKey" => %{
|
||||
"id" => url(~p"/actor#main-key"),
|
||||
"owner" => url(~p"/actor"),
|
||||
"publicKeyPem" => user.public_key
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
9
lib/postland_web/controllers/webfinger_controller.ex
Normal file
9
lib/postland_web/controllers/webfinger_controller.ex
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
defmodule PostlandWeb.WebfingerController do
|
||||
use PostlandWeb, :controller
|
||||
|
||||
alias Postland.Accounts
|
||||
|
||||
def get(conn, _params) do
|
||||
render(conn, :webfinger, %{})
|
||||
end
|
||||
end
|
||||
21
lib/postland_web/controllers/webfinger_json.ex
Normal file
21
lib/postland_web/controllers/webfinger_json.ex
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
defmodule PostlandWeb.WebfingerJSON do
|
||||
use Phoenix.VerifiedRoutes, endpoint: PostlandWeb.Endpoint, router: PostlandWeb.Router
|
||||
|
||||
alias Postland.Accounts
|
||||
|
||||
def render("webfinger.json", _assigns) do
|
||||
user = Accounts.solo_user()
|
||||
|
||||
# TODO: Check that the host here is correct after deploy
|
||||
%{
|
||||
subject: "acct:#{user.username}@#{PostlandWeb.Endpoint.host()}",
|
||||
links: [
|
||||
%{
|
||||
"rel" => "self",
|
||||
"type" => "application/activity+json",
|
||||
"href" => url(~p"/actor")
|
||||
}
|
||||
]
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
@ -21,6 +21,14 @@ defmodule PostlandWeb.Router do
|
|||
plug PostlandWeb.Plugs.RedirectIfNotSetup
|
||||
end
|
||||
|
||||
scope "/", PostlandWeb do
|
||||
pipe_through [:api]
|
||||
|
||||
get "/.well-known/webfinger", WebfingerController, :get
|
||||
|
||||
get "/actor", ActorController, :get
|
||||
end
|
||||
|
||||
scope "/", PostlandWeb do
|
||||
pipe_through [:browser, :redirect_if_not_set_up]
|
||||
|
||||
|
|
@ -55,9 +63,7 @@ defmodule PostlandWeb.Router do
|
|||
|
||||
live_session :redirect_if_user_is_authenticated,
|
||||
on_mount: [{PostlandWeb.UserAuth, :redirect_if_user_is_authenticated}] do
|
||||
live "/users/register", UserRegistrationLive, :new
|
||||
live "/users/log_in", UserLoginLive, :new
|
||||
live "/users/reset_password/:token", UserResetPasswordLive, :edit
|
||||
end
|
||||
|
||||
post "/users/log_in", UserSessionController, :create
|
||||
|
|
|
|||
10
priv/repo/migrations/20240921235213_add_keys_to_user.exs
Normal file
10
priv/repo/migrations/20240921235213_add_keys_to_user.exs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
defmodule Postland.Repo.Migrations.AddKeysToUser do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
alter table("users") do
|
||||
add :private_key, :text, null: false
|
||||
add :public_key, :text, null: false
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue