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()
|
:crypto.strong_rand_bytes(12) |> Base.encode64()
|
||||||
end
|
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
|
def on_boot_setup() do
|
||||||
if !setup?() do
|
if !setup?() do
|
||||||
|
%{public: public_key, private: private_key} = generate_keys()
|
||||||
|
|
||||||
attrs = %{
|
attrs = %{
|
||||||
username: "welcome",
|
username: "welcome",
|
||||||
password: temporary_password()
|
password: temporary_password(),
|
||||||
|
private_key: private_key,
|
||||||
|
public_key: public_key
|
||||||
}
|
}
|
||||||
|
|
||||||
{:ok, _user} = Accounts.register_user(attrs)
|
{:ok, _user} = Accounts.register_user(attrs)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ defmodule Postland.Accounts.User do
|
||||||
field :hashed_password, :string, redact: true
|
field :hashed_password, :string, redact: true
|
||||||
field :current_password, :string, virtual: true, redact: true
|
field :current_password, :string, virtual: true, redact: true
|
||||||
field :confirmed_at, :utc_datetime
|
field :confirmed_at, :utc_datetime
|
||||||
|
field :private_key, :string
|
||||||
|
field :public_key, :string
|
||||||
|
|
||||||
timestamps(type: :utc_datetime)
|
timestamps(type: :utc_datetime)
|
||||||
end
|
end
|
||||||
|
|
@ -31,7 +33,7 @@ defmodule Postland.Accounts.User do
|
||||||
"""
|
"""
|
||||||
def registration_changeset(user, attrs, opts \\ []) do
|
def registration_changeset(user, attrs, opts \\ []) do
|
||||||
user
|
user
|
||||||
|> cast(attrs, [:username, :password])
|
|> cast(attrs, [:username, :password, :public_key, :private_key])
|
||||||
|> validate_username()
|
|> validate_username()
|
||||||
|> validate_password(opts)
|
|> validate_password(opts)
|
||||||
end
|
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
|
plug PostlandWeb.Plugs.RedirectIfNotSetup
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scope "/", PostlandWeb do
|
||||||
|
pipe_through [:api]
|
||||||
|
|
||||||
|
get "/.well-known/webfinger", WebfingerController, :get
|
||||||
|
|
||||||
|
get "/actor", ActorController, :get
|
||||||
|
end
|
||||||
|
|
||||||
scope "/", PostlandWeb do
|
scope "/", PostlandWeb do
|
||||||
pipe_through [:browser, :redirect_if_not_set_up]
|
pipe_through [:browser, :redirect_if_not_set_up]
|
||||||
|
|
||||||
|
|
@ -55,9 +63,7 @@ defmodule PostlandWeb.Router do
|
||||||
|
|
||||||
live_session :redirect_if_user_is_authenticated,
|
live_session :redirect_if_user_is_authenticated,
|
||||||
on_mount: [{PostlandWeb.UserAuth, :redirect_if_user_is_authenticated}] do
|
on_mount: [{PostlandWeb.UserAuth, :redirect_if_user_is_authenticated}] do
|
||||||
live "/users/register", UserRegistrationLive, :new
|
|
||||||
live "/users/log_in", UserLoginLive, :new
|
live "/users/log_in", UserLoginLive, :new
|
||||||
live "/users/reset_password/:token", UserResetPasswordLive, :edit
|
|
||||||
end
|
end
|
||||||
|
|
||||||
post "/users/log_in", UserSessionController, :create
|
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