diff options
author | lain <lain@soykaf.club> | 2020-08-20 18:12:25 +0200 |
---|---|---|
committer | lain <lain@soykaf.club> | 2020-08-20 18:12:25 +0200 |
commit | 6a6548113d94018a235b6de7b01df11550c455f6 (patch) | |
tree | 97e2a233db9867914e8b6d9d481d3c0a767ad13f | |
parent | 8f882fd658843651c53d425d44c20d57aeef5f34 (diff) | |
download | pleroma-6a6548113d94018a235b6de7b01df11550c455f6.tar.gz |
.
-rw-r--r-- | lib/pleroma/application.ex | 3 | ||||
-rw-r--r-- | lib/pleroma/web/endpoint.ex | 6 | ||||
-rw-r--r-- | lib/pleroma/web/matrix_controller.ex | 236 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 13 |
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 |