diff --git a/lib/nulla_web/controllers/activitypub/actor_controller.ex b/lib/nulla_web/controllers/activitypub/actor_controller.ex new file mode 100644 index 0000000..6012e78 --- /dev/null +++ b/lib/nulla_web/controllers/activitypub/actor_controller.ex @@ -0,0 +1,21 @@ +defmodule NullaWeb.ActivityPub.ActorController do + use NullaWeb, :controller + alias Nulla.ActivityPub + alias Nulla.Models.Actor + + def show(conn, %{"username" => username}) do + domain = NullaWeb.Endpoint.host() + + case Actor.get_actor(preferredUsername: username, domain: domain) do + nil -> + conn + |> put_status(:not_found) + |> json(%{error: "Not Found"}) + + %Actor{} = actor -> + conn + |> put_resp_content_type("application/activity+json") + |> send_resp(200, Jason.encode!(ActivityPub.actor(actor))) + end + end +end diff --git a/lib/nulla_web/controllers/follow_controller.ex b/lib/nulla_web/controllers/activitypub/follow_controller.ex similarity index 97% rename from lib/nulla_web/controllers/follow_controller.ex rename to lib/nulla_web/controllers/activitypub/follow_controller.ex index 22dc1c4..e12535d 100644 --- a/lib/nulla_web/controllers/follow_controller.ex +++ b/lib/nulla_web/controllers/activitypub/follow_controller.ex @@ -1,4 +1,4 @@ -defmodule NullaWeb.FollowController do +defmodule NullaWeb.ActivityPub.FollowController do use NullaWeb, :controller alias Nulla.ActivityPub alias Nulla.Models.Actor diff --git a/lib/nulla_web/controllers/hostmeta_controller.ex b/lib/nulla_web/controllers/activitypub/hostmeta_controller.ex similarity index 89% rename from lib/nulla_web/controllers/hostmeta_controller.ex rename to lib/nulla_web/controllers/activitypub/hostmeta_controller.ex index cee64ce..fb573e8 100644 --- a/lib/nulla_web/controllers/hostmeta_controller.ex +++ b/lib/nulla_web/controllers/activitypub/hostmeta_controller.ex @@ -1,4 +1,4 @@ -defmodule NullaWeb.HostmetaController do +defmodule NullaWeb.ActivityPub.HostmetaController do use NullaWeb, :controller def index(conn, _params) do diff --git a/lib/nulla_web/controllers/inbox_controller.ex b/lib/nulla_web/controllers/activitypub/inbox_controller.ex similarity index 99% rename from lib/nulla_web/controllers/inbox_controller.ex rename to lib/nulla_web/controllers/activitypub/inbox_controller.ex index 4cbbb44..d40170c 100644 --- a/lib/nulla_web/controllers/inbox_controller.ex +++ b/lib/nulla_web/controllers/activitypub/inbox_controller.ex @@ -1,4 +1,4 @@ -defmodule NullaWeb.InboxController do +defmodule NullaWeb.ActivityPub.InboxController do use NullaWeb, :controller alias Nulla.Snowflake alias Nulla.HTTPSignature diff --git a/lib/nulla_web/controllers/nodeinfo_controller.ex b/lib/nulla_web/controllers/activitypub/nodeinfo_controller.ex similarity index 92% rename from lib/nulla_web/controllers/nodeinfo_controller.ex rename to lib/nulla_web/controllers/activitypub/nodeinfo_controller.ex index f532473..aafc7f8 100644 --- a/lib/nulla_web/controllers/nodeinfo_controller.ex +++ b/lib/nulla_web/controllers/activitypub/nodeinfo_controller.ex @@ -1,4 +1,4 @@ -defmodule NullaWeb.NodeinfoController do +defmodule NullaWeb.ActivityPub.NodeinfoController do use NullaWeb, :controller alias Nulla.ActivityPub alias Nulla.Models.User diff --git a/lib/nulla_web/controllers/activitypub/note_controller.ex b/lib/nulla_web/controllers/activitypub/note_controller.ex new file mode 100644 index 0000000..48185b0 --- /dev/null +++ b/lib/nulla_web/controllers/activitypub/note_controller.ex @@ -0,0 +1,44 @@ +defmodule NullaWeb.ActivityPub.NoteController do + use NullaWeb, :controller + alias Nulla.Repo + alias Nulla.ActivityPub + alias Nulla.Models.Note + + def show(conn, %{"username" => username, "id" => id}) do + case Integer.parse(id) do + {int_id, ""} -> + note = Note.get_note(id: int_id) |> Repo.preload([:actor, :media_attachments]) + + cond do + is_nil(note) -> + conn + |> put_status(:not_found) + |> json(%{error: "Not Found"}) + |> halt() + + username != note.actor.preferredUsername -> + conn + |> put_status(:not_found) + |> json(%{error: "Not Found"}) + |> halt() + + true -> + format = Phoenix.Controller.get_format(conn) + + if format == "activity+json" do + conn + |> put_resp_content_type("application/activity+json") + |> json(ActivityPub.note(note)) + else + render(conn, :show, note: note, layout: false) + end + end + + _ -> + conn + |> put_status(:not_found) + |> json(%{error: "Not Found"}) + |> halt() + end + end +end diff --git a/lib/nulla_web/controllers/outbox_controller.ex b/lib/nulla_web/controllers/activitypub/outbox_controller.ex similarity index 96% rename from lib/nulla_web/controllers/outbox_controller.ex rename to lib/nulla_web/controllers/activitypub/outbox_controller.ex index d6b5791..7243ca2 100644 --- a/lib/nulla_web/controllers/outbox_controller.ex +++ b/lib/nulla_web/controllers/activitypub/outbox_controller.ex @@ -1,4 +1,4 @@ -defmodule NullaWeb.OutboxController do +defmodule NullaWeb.ActivityPub.OutboxController do use NullaWeb, :controller alias Nulla.ActivityPub alias Nulla.Models.Actor diff --git a/lib/nulla_web/controllers/webfinger_controller.ex b/lib/nulla_web/controllers/activitypub/webfinger_controller.ex similarity index 94% rename from lib/nulla_web/controllers/webfinger_controller.ex rename to lib/nulla_web/controllers/activitypub/webfinger_controller.ex index c837146..fd4459d 100644 --- a/lib/nulla_web/controllers/webfinger_controller.ex +++ b/lib/nulla_web/controllers/activitypub/webfinger_controller.ex @@ -1,4 +1,4 @@ -defmodule NullaWeb.WebfingerController do +defmodule NullaWeb.ActivityPub.WebfingerController do use NullaWeb, :controller alias Nulla.ActivityPub alias Nulla.Models.Actor diff --git a/lib/nulla_web/controllers/actor_controller.ex b/lib/nulla_web/controllers/actor_controller.ex deleted file mode 100644 index bedcc0f..0000000 --- a/lib/nulla_web/controllers/actor_controller.ex +++ /dev/null @@ -1,40 +0,0 @@ -defmodule NullaWeb.ActorController do - use NullaWeb, :controller - alias Nulla.ActivityPub - alias Nulla.Models.Actor - alias Nulla.Models.Relation - alias Nulla.Models.Note - - def show(conn, %{"username" => username}) do - format = Phoenix.Controller.get_format(conn) - domain = NullaWeb.Endpoint.host() - - case Actor.get_actor(preferredUsername: username, domain: domain) do - nil -> - conn - |> put_status(:not_found) - |> json(%{error: "Not Found"}) - - %Actor{} = actor -> - if format == "activity+json" do - conn - |> put_resp_content_type("application/activity+json") - |> send_resp(200, Jason.encode!(ActivityPub.actor(actor))) - else - following = Relation.count_following(actor.id) - followers = Relation.count_followers(actor.id) - notes = Note.get_latest_notes(actor.id) - - render( - conn, - :show, - actor: actor, - following: following, - followers: followers, - notes: notes, - layout: false - ) - end - end - end -end diff --git a/lib/nulla_web/controllers/api/note_controller.ex b/lib/nulla_web/controllers/api/note_controller.ex new file mode 100644 index 0000000..6a5b6f5 --- /dev/null +++ b/lib/nulla_web/controllers/api/note_controller.ex @@ -0,0 +1,33 @@ +defmodule NullaWeb.Api.NoteController do + use NullaWeb, :controller + alias Nulla.Models.Note + + def index(conn, _params) do + json(conn, []) + end + + def show(conn, %{"id" => id}) do + note = Note.get_note(id: id) + + case note do + nil -> + conn + |> put_status(:not_found) + |> json(%{error: "Not Found"}) + + %Note{} = note -> + IO.inspect note + + json(conn, %{}) + end + end + + def create(_conn, _params) do + end + + def update(_conn, _params) do + end + + def delete(_conn, _params) do + end +end diff --git a/lib/nulla_web/controllers/web/actor_controller.ex b/lib/nulla_web/controllers/web/actor_controller.ex new file mode 100644 index 0000000..e42a775 --- /dev/null +++ b/lib/nulla_web/controllers/web/actor_controller.ex @@ -0,0 +1,32 @@ +defmodule NullaWeb.Web.ActorController do + use NullaWeb, :controller + alias Nulla.Models.Actor + alias Nulla.Models.Relation + alias Nulla.Models.Note + + def show(conn, %{"username" => username}) do + domain = NullaWeb.Endpoint.host() + + case Actor.get_actor(preferredUsername: username, domain: domain) do + nil -> + conn + |> put_status(:not_found) + |> json(%{error: "Not Found"}) + + %Actor{} = actor -> + following = Relation.count_following(actor.id) + followers = Relation.count_followers(actor.id) + notes = Note.get_latest_notes(actor.id) + + render( + conn, + :show, + actor: actor, + following: following, + followers: followers, + notes: notes, + layout: false + ) + end + end +end diff --git a/lib/nulla_web/controllers/auth_controller.ex b/lib/nulla_web/controllers/web/auth_controller.ex similarity index 97% rename from lib/nulla_web/controllers/auth_controller.ex rename to lib/nulla_web/controllers/web/auth_controller.ex index 8a6017d..99e055c 100644 --- a/lib/nulla_web/controllers/auth_controller.ex +++ b/lib/nulla_web/controllers/web/auth_controller.ex @@ -1,4 +1,4 @@ -defmodule NullaWeb.AuthController do +defmodule NullaWeb.Web.AuthController do use NullaWeb, :controller alias Nulla.Models.User alias Nulla.Models.Actor diff --git a/lib/nulla_web/controllers/note_controller.ex b/lib/nulla_web/controllers/web/note_controller.ex similarity index 96% rename from lib/nulla_web/controllers/note_controller.ex rename to lib/nulla_web/controllers/web/note_controller.ex index f76a56a..ceb13e5 100644 --- a/lib/nulla_web/controllers/note_controller.ex +++ b/lib/nulla_web/controllers/web/note_controller.ex @@ -1,4 +1,4 @@ -defmodule NullaWeb.NoteController do +defmodule NullaWeb.Web.NoteController do use NullaWeb, :controller alias Nulla.Repo alias Nulla.ActivityPub diff --git a/lib/nulla_web/controllers/page_controller.ex b/lib/nulla_web/controllers/web/page_controller.ex similarity index 86% rename from lib/nulla_web/controllers/page_controller.ex rename to lib/nulla_web/controllers/web/page_controller.ex index 1212f3d..3649c08 100644 --- a/lib/nulla_web/controllers/page_controller.ex +++ b/lib/nulla_web/controllers/web/page_controller.ex @@ -1,4 +1,4 @@ -defmodule NullaWeb.PageController do +defmodule NullaWeb.Web.PageController do use NullaWeb, :controller def home(conn, _params) do diff --git a/lib/nulla_web/router.ex b/lib/nulla_web/router.ex index 31448b2..150e99b 100644 --- a/lib/nulla_web/router.ex +++ b/lib/nulla_web/router.ex @@ -6,8 +6,8 @@ defmodule NullaWeb.Router do plug :fetch_session plug :fetch_live_flash plug :put_root_layout, html: {NullaWeb.Layouts, :root} - # plug :protect_from_forgery - # plug :put_secure_browser_headers + plug :protect_from_forgery + plug :put_secure_browser_headers end pipeline :api do @@ -18,16 +18,11 @@ defmodule NullaWeb.Router do plug :accepts, ["activity+json"] end - scope "/", NullaWeb do + scope "/", NullaWeb.Web, as: :web do pipe_through :browser get "/", PageController, :home - get "/.well-known/host-meta", HostmetaController, :index - get "/.well-known/webfinger", WebfingerController, :index - get "/.well-known/nodeinfo", NodeinfoController, :index - get "/nodeinfo/2.0", NodeinfoController, :show - scope "/auth" do post "/", AuthController, :sign_up post "/sign_in", AuthController, :sign_in @@ -38,21 +33,24 @@ defmodule NullaWeb.Router do scope "/@:username" do get "/", ActorController, :show - get "/following", FollowController, :following - get "/followers", FollowController, :followers - post "/inbox", InboxController, :inbox - get "/outbox", OutboxController, :outbox get "/:id", NoteController, :show end end - scope "/api", NullaWeb do + scope "/api", NullaWeb.Api, as: :api do pipe_through :api + + resources "/notes", NoteController end - scope "/", NullaWeb do + scope "/", NullaWeb.ActivityPub, as: :activitypub do pipe_through :activitypub + get "/.well-known/host-meta", HostmetaController, :index + get "/.well-known/webfinger", WebfingerController, :index + get "/.well-known/nodeinfo", NodeinfoController, :index + get "/nodeinfo/2.0", NodeinfoController, :show + post "/inbox", InboxController, :inbox scope "/users/:username" do diff --git a/test/support/fixtures/data.ex b/test/support/fixtures/data.ex index d2944ab..11f26f5 100644 --- a/test/support/fixtures/data.ex +++ b/test/support/fixtures/data.ex @@ -45,11 +45,10 @@ defmodule Nulla.Fixtures.Data do }) Note.create_note(%{ - actor_url: actor.url, + visibility: "public", content: "Hello World from Nulla!", language: "en", - actor_id: actor.id, - visibility: "public" + actor_id: actor.id }) {publicKeyPem, privateKeyPem} = KeyGen.gen()