Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85826375
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
Unknown
Size
11 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/config/config.exs b/config/config.exs
index 2b041b10f..18a2490a4 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -1,31 +1,35 @@
# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.
#
# This configuration file is loaded before any dependency and
# is restricted to this project.
use Mix.Config
# General application configuration
config :pleroma,
ecto_repos: [Pleroma.Repo]
config :pleroma, Pleroma.Upload,
uploads: "uploads"
# Configures the endpoint
config :pleroma, Pleroma.Web.Endpoint,
url: [host: "localhost"],
protocol: "https",
secret_key_base: "aK4Abxf29xU9TTDKre9coZPUgevcVCFQJe/5xP/7Lt4BEif6idBIbjupVbOrbKxl",
render_errors: [view: Pleroma.Web.ErrorView, accepts: ~w(json)],
pubsub: [name: Pleroma.PubSub,
adapter: Phoenix.PubSub.PG2]
# Configures Elixir's Logger
config :logger, :console,
format: "$time $metadata[$level] $message\n",
metadata: [:request_id]
+config :mime, :types, %{
+ "application/xrd+xml" => ["xrd+xml"]
+}
+
# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
import_config "#{Mix.env}.exs"
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 0446f622b..99d1f69c2 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -1,52 +1,63 @@
defmodule Pleroma.Web.Router do
use Pleroma.Web, :router
alias Pleroma.{Repo, User}
def user_fetcher(username) do
{:ok, Repo.get_by(User, %{nickname: username})}
end
pipeline :api do
plug :accepts, ["json"]
plug :fetch_session
plug Pleroma.Plugs.AuthenticationPlug, %{fetcher: &Pleroma.Web.Router.user_fetcher/1, optional: true}
end
pipeline :authenticated_api do
plug :accepts, ["json"]
plug :fetch_session
plug Pleroma.Plugs.AuthenticationPlug, %{fetcher: &Pleroma.Web.Router.user_fetcher/1}
end
+ pipeline :well_known do
+ plug :accepts, ["xml", "xrd+xml"]
+ end
+
scope "/api", Pleroma.Web do
pipe_through :api
get "/help/test", TwitterAPI.Controller, :help_test
get "/statuses/public_timeline", TwitterAPI.Controller, :public_timeline
get "/statuses/public_and_external_timeline", TwitterAPI.Controller, :public_timeline
get "/statuses/show/:id", TwitterAPI.Controller, :fetch_status
get "/statusnet/conversation/:id", TwitterAPI.Controller, :fetch_conversation
get "/statusnet/config", TwitterAPI.Controller, :config
post "/account/register", TwitterAPI.Controller, :register
end
scope "/api", Pleroma.Web do
pipe_through :authenticated_api
get "/account/verify_credentials", TwitterAPI.Controller, :verify_credentials
post "/account/verify_credentials", TwitterAPI.Controller, :verify_credentials
post "/statuses/update", TwitterAPI.Controller, :status_update
get "/statuses/home_timeline", TwitterAPI.Controller, :friends_timeline
get "/statuses/friends_timeline", TwitterAPI.Controller, :friends_timeline
post "/friendships/create", TwitterAPI.Controller, :follow
post "/friendships/destroy", TwitterAPI.Controller, :unfollow
post "/statusnet/media/upload", TwitterAPI.Controller, :upload
post "/media/upload", TwitterAPI.Controller, :upload_json
post "/favorites/create/:id", TwitterAPI.Controller, :favorite
post "/favorites/create", TwitterAPI.Controller, :favorite
post "/favorites/destroy/:id", TwitterAPI.Controller, :unfavorite
post "/statuses/retweet/:id", TwitterAPI.Controller, :retweet
post "/qvitter/update_avatar", TwitterAPI.Controller, :update_avatar
end
+
+ scope "/.well-known", Pleroma.Web do
+ pipe_through :well_known
+
+ get "/host-meta", WebFinger.WebFingerController, :host_meta
+ get "/webfinger", WebFinger.WebFingerController, :webfinger
+ end
end
diff --git a/lib/pleroma/web/web.ex b/lib/pleroma/web/web.ex
index d03db2231..a81e3e6e1 100644
--- a/lib/pleroma/web/web.ex
+++ b/lib/pleroma/web/web.ex
@@ -1,82 +1,87 @@
defmodule Pleroma.Web do
@moduledoc """
A module that keeps using definitions for controllers,
views and so on.
This can be used in your application as:
use Pleroma.Web, :controller
use Pleroma.Web, :view
The definitions below will be executed for every view,
controller, etc, so keep them short and clean, focused
on imports, uses and aliases.
Do NOT define functions inside the quoted expressions
below.
"""
def controller do
quote do
use Phoenix.Controller, namespace: Pleroma.Web
import Plug.Conn
import Pleroma.Web.Router.Helpers
import Pleroma.Web.Gettext
end
end
def view do
quote do
use Phoenix.View, root: "lib/pleroma/web/templates",
namespace: Pleroma.Web
# Import convenience functions from controllers
import Phoenix.Controller, only: [get_csrf_token: 0, get_flash: 2, view_module: 1]
import Pleroma.Web.Router.Helpers
import Pleroma.Web.ErrorHelpers
import Pleroma.Web.Gettext
end
end
def router do
quote do
use Phoenix.Router
import Plug.Conn
import Phoenix.Controller
end
end
def channel do
quote do
use Phoenix.Channel
import Pleroma.Web.Gettext
end
end
@doc """
When used, dispatch to the appropriate controller/view/etc.
"""
defmacro __using__(which) when is_atom(which) do
apply(__MODULE__, which, [])
end
+ def host do
+ settings = Application.get_env(:pleroma, Pleroma.Web.Endpoint)
+ settings
+ |> Keyword.fetch!(:url)
+ |> Keyword.fetch!(:host)
+ end
+
def base_url do
settings = Application.get_env(:pleroma, Pleroma.Web.Endpoint)
- host =
- settings
- |> Keyword.fetch!(:url)
- |> Keyword.fetch!(:host)
+
+ host = host()
protocol = settings |> Keyword.fetch!(:protocol)
port_fragment = with {:ok, protocol_info} <- settings |> Keyword.fetch(String.to_atom(protocol)),
{:ok, port} <- protocol_info |> Keyword.fetch(:port)
do
":#{port}"
else _e ->
""
end
"#{protocol}://#{host}#{port_fragment}"
end
end
diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex
new file mode 100644
index 000000000..258ff7671
--- /dev/null
+++ b/lib/pleroma/web/web_finger/web_finger.ex
@@ -0,0 +1,38 @@
+defmodule Pleroma.Web.WebFinger do
+ alias Pleroma.XmlBuilder
+ alias Pleroma.User
+
+ def host_meta() do
+ base_url = Pleroma.Web.base_url
+ {
+ :XRD, %{ xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0" },
+ {
+ :Link, %{ rel: "lrdd", type: "application/xrd+xml", template: "#{base_url}/.well-known/webfinger?resource={uri}" }
+ }
+ }
+ |> XmlBuilder.to_doc
+ end
+
+ def webfinger(resource) do
+ host = Pleroma.Web.host
+ regex = ~r/acct:(?<username>\w+)@#{host}/
+ case Regex.named_captures(regex, resource) do
+ %{"username" => username} ->
+ user = User.get_cached_by_nickname(username)
+ {:ok, represent_user(user)}
+ _ -> nil
+ end
+ end
+
+ def represent_user(user) do
+ {
+ :XRD, %{xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0"},
+ [
+ {:Subject, "acct:#{user.nickname}@#{Pleroma.Web.host}"},
+ {:Alias, user.ap_id},
+ {:Link, %{rel: "http://schemas.google.com/g/2010#updates-from", type: "application/atom+xml", href: "#{user.ap_id}.atom"}}
+ ]
+ }
+ |> XmlBuilder.to_doc
+ end
+end
diff --git a/lib/pleroma/web/web_finger/web_finger_controller.ex b/lib/pleroma/web/web_finger/web_finger_controller.ex
new file mode 100644
index 000000000..7c0fd3142
--- /dev/null
+++ b/lib/pleroma/web/web_finger/web_finger_controller.ex
@@ -0,0 +1,21 @@
+defmodule Pleroma.Web.WebFinger.WebFingerController do
+ use Pleroma.Web, :controller
+
+ alias Pleroma.Web.WebFinger
+
+ def host_meta(conn, _params) do
+ xml = WebFinger.host_meta
+
+ conn
+ |> put_resp_content_type("application/xrd+xml")
+ |> send_resp(200, xml)
+ end
+
+ def webfinger(conn, %{"resource" => resource}) do
+ {:ok, response} = Pleroma.Web.WebFinger.webfinger(resource)
+
+ conn
+ |> put_resp_content_type("application/xrd+xml")
+ |> send_resp(200, response)
+ end
+end
diff --git a/lib/xml_builder.ex b/lib/xml_builder.ex
new file mode 100644
index 000000000..ac1ac8a74
--- /dev/null
+++ b/lib/xml_builder.ex
@@ -0,0 +1,42 @@
+defmodule Pleroma.XmlBuilder do
+ def to_xml({tag, attributes, content}) do
+ open_tag = make_open_tag(tag, attributes)
+
+ content_xml = to_xml(content)
+
+ "<#{open_tag}>#{content_xml}</#{tag}>"
+ end
+
+ def to_xml({tag, %{} = attributes}) do
+ open_tag = make_open_tag(tag, attributes)
+
+ "<#{open_tag} />"
+ end
+
+ def to_xml({tag, content}), do: to_xml({tag, %{}, content})
+
+ def to_xml(content) when is_binary(content) do
+ to_string(content)
+ end
+
+ def to_xml(content) when is_list(content) do
+ for element <- content do
+ to_xml(element)
+ end
+ |> Enum.join
+ end
+
+ def to_xml(%NaiveDateTime{} = time) do
+ NaiveDateTime.to_iso8601(time)
+ end
+
+ def to_doc(content), do: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" <> to_xml(content)
+
+ defp make_open_tag(tag, attributes) do
+ attributes_string = for {attribute, value} <- attributes do
+ "#{attribute}=\"#{value}\""
+ end |> Enum.join(" ")
+
+ Enum.join([tag, attributes_string], " ") |> String.strip
+ end
+end
diff --git a/test/web/web_finger/web_finger_test.exs b/test/web/web_finger/web_finger_test.exs
new file mode 100644
index 000000000..8a3007ff9
--- /dev/null
+++ b/test/web/web_finger/web_finger_test.exs
@@ -0,0 +1,11 @@
+defmodule Pleroma.Web.WebFingerTest do
+ use Pleroma.DataCase
+
+ describe "host meta" do
+ test "returns a link to the xml lrdd" do
+ host_info = Pleroma.Web.WebFinger.host_meta
+
+ assert String.contains?(host_info, Pleroma.Web.base_url)
+ end
+ end
+end
diff --git a/test/xml_builder_test.exs b/test/xml_builder_test.exs
new file mode 100644
index 000000000..f502a0f0e
--- /dev/null
+++ b/test/xml_builder_test.exs
@@ -0,0 +1,59 @@
+defmodule Pleroma.XmlBuilderTest do
+ use Pleroma.DataCase
+ alias Pleroma.XmlBuilder
+
+ test "Build a basic xml string from a tuple" do
+ data = { :feed, %{ xmlns: "http://www.w3.org/2005/Atom"}, "Some content" }
+
+ expected_xml = "<feed xmlns=\"http://www.w3.org/2005/Atom\">Some content</feed>"
+
+ assert XmlBuilder.to_xml(data) == expected_xml
+ end
+
+ test "returns a complete document" do
+ data = { :feed, %{ xmlns: "http://www.w3.org/2005/Atom"}, "Some content" }
+
+ expected_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><feed xmlns=\"http://www.w3.org/2005/Atom\">Some content</feed>"
+
+ assert XmlBuilder.to_doc(data) == expected_xml
+ end
+
+ test "Works without attributes" do
+ data = {
+ :feed,
+ "Some content"
+ }
+
+ expected_xml = "<feed>Some content</feed>"
+
+ assert XmlBuilder.to_xml(data) == expected_xml
+ end
+
+ test "It works with nested tuples" do
+ data = {
+ :feed,
+ [
+ {:guy, "brush"},
+ {:lament, %{ configuration: "puzzle" }, "pinhead" }
+ ]
+ }
+
+ expected_xml = ~s[<feed><guy>brush</guy><lament configuration="puzzle">pinhead</lament></feed>]
+
+ assert XmlBuilder.to_xml(data) == expected_xml
+ end
+
+ test "Represents NaiveDateTime as iso8601" do
+ assert XmlBuilder.to_xml(~N[2000-01-01 13:13:33]) == "2000-01-01T13:13:33"
+ end
+
+ test "Uses self-closing tags when no content is giving" do
+ data = {
+ :link,
+ %{ rel: "self" }
+ }
+
+ expected_xml = ~s[<link rel="self" />]
+ assert XmlBuilder.to_xml(data) == expected_xml
+ end
+end
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Oct 30, 6:56 AM (20 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1799725
Default Alt Text
(11 KB)
Attached To
Mode
rPUBE pleroma-upstream
Attached
Detach File
Event Timeline