aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlain <lain@soykaf.club>2020-08-20 18:12:25 +0200
committerlain <lain@soykaf.club>2020-08-20 18:12:25 +0200
commit6a6548113d94018a235b6de7b01df11550c455f6 (patch)
tree97e2a233db9867914e8b6d9d481d3c0a767ad13f
parent8f882fd658843651c53d425d44c20d57aeef5f34 (diff)
downloadpleroma-6a6548113d94018a235b6de7b01df11550c455f6.tar.gz
.
-rw-r--r--lib/pleroma/application.ex3
-rw-r--r--lib/pleroma/web/endpoint.ex6
-rw-r--r--lib/pleroma/web/matrix_controller.ex236
-rw-r--r--lib/pleroma/web/router.ex13
4 files changed, 251 insertions, 7 deletions
diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex
index c0b5db9f1..db493ef22 100644
--- a/lib/pleroma/application.ex
+++ b/lib/pleroma/application.ex
@@ -156,7 +156,8 @@ defmodule Pleroma.Application do
build_cachex("web_resp", limit: 2500),
build_cachex("emoji_packs", expiration: emoji_packs_expiration(), limit: 10),
build_cachex("failed_proxy_url", limit: 2500),
- build_cachex("banned_urls", default_ttl: :timer.hours(24 * 30), limit: 5_000)
+ build_cachex("banned_urls", default_ttl: :timer.hours(24 * 30), limit: 5_000),
+ build_cachex("matrix_compat", default_ttl: :timer.hours(120), limit: 5000)
]
end
diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex
index 527fb288d..1d9c3acec 100644
--- a/lib/pleroma/web/endpoint.ex
+++ b/lib/pleroma/web/endpoint.ex
@@ -20,7 +20,7 @@ defmodule Pleroma.Web.Endpoint do
# If you're adding new paths to `only:` you'll need to configure them in InstanceStatic as well
# Cache-control headers are duplicated in case we turn off etags in the future
plug(Pleroma.Plugs.InstanceStatic,
- at: "/",
+ at: "/s",
gzip: true,
cache_control_for_etags: @static_cache_control,
headers: %{
@@ -30,7 +30,7 @@ defmodule Pleroma.Web.Endpoint do
# Careful! No `only` restriction here, as we don't know what frontends contain.
plug(Pleroma.Plugs.FrontendStatic,
- at: "/",
+ at: "/s",
frontend_type: :primary,
gzip: true,
cache_control_for_etags: @static_cache_control,
@@ -45,7 +45,7 @@ defmodule Pleroma.Web.Endpoint do
# when deploying your static files in production.
plug(
Plug.Static,
- at: "/",
+ at: "/s",
from: :pleroma,
only: Pleroma.Constants.static_only_files(),
# credo:disable-for-previous-line Credo.Check.Readability.MaxLineLength
diff --git a/lib/pleroma/web/matrix_controller.ex b/lib/pleroma/web/matrix_controller.ex
index 86d58bfa5..b67b6d90a 100644
--- a/lib/pleroma/web/matrix_controller.ex
+++ b/lib/pleroma/web/matrix_controller.ex
@@ -5,9 +5,34 @@
defmodule Pleroma.Web.MatrixController do
use Pleroma.Web, :controller
+ alias Pleroma.User
+ # alias Pleroma.Web.MediaProxy
+ alias Pleroma.Plugs.AuthenticationPlug
+ alias Pleroma.Plugs.OAuthScopesPlug
+ alias Pleroma.Web.OAuth.App
+ alias Pleroma.Web.OAuth.Token
+ alias Pleroma.Chat
+ alias Pleroma.Chat.MessageReference
+ alias Pleroma.Repo
+ alias Pleroma.HTML
+ import Ecto.Query
+
+ plug(
+ OAuthScopesPlug,
+ %{scopes: ["write"]}
+ when action in [:set_presence_status, :set_filter]
+ )
+
+ plug(
+ OAuthScopesPlug,
+ %{scopes: ["read"]}
+ when action in [:pushrules, :sync, :filter, :key_query, :profile]
+ )
+
def client_versions(conn, _) do
data = %{
versions: ["r0.0.1", "r0.1.0", "r0.2.0", "r0.3.0", "r0.4.0", "r0.5.0"]
+ # versions: ["r0.0.1", "r0.1.0"]
}
conn
@@ -26,15 +51,220 @@ defmodule Pleroma.Web.MatrixController do
end
def login(conn, params) do
+ username = params["identifier"]["user"]
+ password = params["password"]
+
+ dn = params["initial_device_display_name"]
+
+ with %User{} = user <- User.get_by_nickname(username),
+ true <- AuthenticationPlug.checkpw(password, user.password_hash),
+ {:ok, app} <-
+ App.create(%{client_name: dn, scopes: ~w(read write), redirect_uris: "nowhere"}),
+ {:ok, token} <- Token.create_token(app, user) do
+ data = %{
+ user_id: "@#{user.nickname}:#{Pleroma.Web.Endpoint.host()}",
+ access_token: token.token,
+ device_id: app.client_id
+ }
+
+ conn
+ |> put_status(200)
+ |> json(data)
+ else
+ _ ->
+ data = %{
+ errcode: "M_FORBIDDEN",
+ error: "Invalid password"
+ }
+
+ conn
+ |> put_status(403)
+ |> json(data)
+ end
+ end
+
+ def presence_status(conn, _) do
+ data = %{
+ presence: "online"
+ }
+
+ conn
+ |> json(data)
+ end
+
+ def set_presence_status(conn, params) do
+ IO.inspect(params)
+
+ conn
+ |> json(%{})
+ end
+
+ def pushrules(conn, _) do
+ data = %{
+ global: %{}
+ }
+
+ conn
+ |> json(data)
+ end
+
+ def set_filter(conn, params) do
+ IO.inspect(params)
+
+ filter_id = :crypto.strong_rand_bytes(32) |> Base.url_encode64(padding: false)
+ Cachex.put(:matrix_compat, "filter:#{filter_id}", params)
+
+ data = %{
+ filter_id: filter_id
+ }
+
+ conn
+ |> json(data)
+ end
+
+ def filter(conn, params) do
+ result = Cachex.get(:matrix_compat, "filter:#{params["filter_id"]}")
+ IO.inspect(result)
+
+ conn
+ |> put_status(200)
+ |> json(result)
+ end
+
+ defp matrix_name(%{local: true, nickname: nick}) do
+ "@#{nick}:#{Pleroma.Web.Endpoint.host()}"
+ end
+
+ defp matrix_name(%{nickname: nick}) do
+ nick =
+ nick
+ |> String.replace("@", ":")
+
+ "@" <> nick
+ end
+
+ def sync(%{assigns: %{user: user}} = conn, params) do
+ with {:ok, timeout} <- Ecto.Type.cast(:integer, params["timeout"]) do
+ :timer.sleep(timeout)
+ end
+
+ blocked_ap_ids = User.blocked_users_ap_ids(user)
+
+ user_id = user.id
+
+ chats =
+ from(c in Chat,
+ where: c.user_id == ^user_id,
+ where: c.recipient not in ^blocked_ap_ids,
+ order_by: [desc: c.updated_at]
+ )
+ |> Repo.all()
+ |> Enum.reduce(%{}, fn chat, acc ->
+ recipient = User.get_by_ap_id(chat.recipient)
+
+ messages =
+ chat
+ |> MessageReference.for_chat_query()
+ |> Repo.all()
+ |> Enum.map(fn message ->
+ chat_data = message.object.data
+ author = User.get_cached_by_ap_id(chat_data["actor"])
+
+ {:ok, date, _} = DateTime.from_iso8601(chat_data["published"])
+
+ %{
+ content: %{
+ body: chat_data["content"] |> HTML.strip_tags(),
+ msgtype: "m.text",
+ format: "org.matrix.custom.html",
+ formatted_body: chat_data["content"]
+ },
+ type: "m.room.message",
+ event_id: message.id,
+ room_id: chat.id,
+ sender: matrix_name(author),
+ origin_ts: date |> DateTime.to_unix(),
+ unsigned: %{
+ age: 0
+ }
+ }
+ end)
+
+ room = %{
+ chat.id => %{
+ summary: %{
+ "m.heroes" => [matrix_name(recipient)],
+ "m.joined_member_count" => 2,
+ "m.invited_member_count" => 0
+ },
+ state: %{events: []},
+ ephemeral: %{events: []},
+ timeline: %{
+ events: messages,
+ limited: false,
+ prev_batch: "prev"
+ },
+ account_data: %{events: []},
+ unread_notifications: %{
+ highlight_count: 0,
+ notification_count: 0
+ }
+ }
+ }
+
+ Map.merge(acc, room)
+ end)
+
+ data = %{
+ next_batch: "next",
+ rooms: %{
+ join: chats,
+ invite: %{},
+ leave: %{}
+ },
+ account_data: %{
+ events: []
+ },
+ presence: %{
+ events: []
+ },
+ to_device: %{
+ events: []
+ },
+ device_one_time_keys_count: %{},
+ device_lists: %{
+ left: [],
+ changed: []
+ }
+ }
+
+ conn
+ |> json(data)
+ end
+
+ def key_query(conn, params) do
+ IO.inspect(params)
+
+ conn
+ |> json(params)
+ end
+
+ def profile(conn, params) do
IO.inspect(params)
+ nickname =
+ params["user_id"]
+ |> String.trim_leading("@")
+ |> String.replace(":", "@")
+ |> String.trim_trailing("@#{Pleroma.Web.Endpoint.host()}")
+
+ user = User.get_by_nickname(nickname)
+
data = %{
- errcode: "M_FORBIDDEN",
- error: "Invalid password"
+ displayname: user.name
}
conn
- |> put_status(403)
|> json(data)
end
end
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index dc0641881..89aef5164 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -711,9 +711,22 @@ defmodule Pleroma.Web.Router do
end
scope "/_matrix", Pleroma.Web do
+ pipe_through(:api)
get("/client/versions", MatrixController, :client_versions)
get("/client/r0/login", MatrixController, :login_info)
post("/client/r0/login", MatrixController, :login)
+ get("/client/r0/presence/:user_id/status", MatrixController, :presence_status)
+ get("/client/r0/user/:user_id/filter/:filter_id", MatrixController, :filter)
+ end
+
+ scope "/_matrix", Pleroma.Web do
+ pipe_through(:authenticated_api)
+ put("/client/r0/presence/:user_id/status", MatrixController, :set_presence_status)
+ get("/client/r0/pushrules", MatrixController, :pushrules)
+ post("/client/r0/user/:user_id/filter", MatrixController, :set_filter)
+ get("/client/r0/sync", MatrixController, :sync)
+ post("/client/r0/keys/query", MatrixController, :key_query)
+ get("/client/r0/profile/:user_id", MatrixController, :profile)
end
scope "/", Pleroma.Web.MongooseIM do