diff options
Diffstat (limited to 'lib/matrix_app_service_web')
-rw-r--r-- | lib/matrix_app_service_web/auth_plug.ex | 20 | ||||
-rw-r--r-- | lib/matrix_app_service_web/controllers/v1/room_controller.ex | 5 | ||||
-rw-r--r-- | lib/matrix_app_service_web/controllers/v1/transaction_controller.ex | 64 | ||||
-rw-r--r-- | lib/matrix_app_service_web/controllers/v1/user_controller.ex | 5 | ||||
-rw-r--r-- | lib/matrix_app_service_web/endpoint.ex | 31 | ||||
-rw-r--r-- | lib/matrix_app_service_web/router.ex | 39 | ||||
-rw-r--r-- | lib/matrix_app_service_web/routes.ex | 77 | ||||
-rw-r--r-- | lib/matrix_app_service_web/set_config_plug.ex | 27 |
8 files changed, 196 insertions, 72 deletions
diff --git a/lib/matrix_app_service_web/auth_plug.ex b/lib/matrix_app_service_web/auth_plug.ex index a06fd46..19f8c21 100644 --- a/lib/matrix_app_service_web/auth_plug.ex +++ b/lib/matrix_app_service_web/auth_plug.ex @@ -17,20 +17,20 @@ defmodule MatrixAppServiceWeb.AuthPlug do @doc false @impl Plug - def call(%Plug.Conn{params: %{"access_token" => hs_token}} = conn, _opts) do - config_hs_token = Application.fetch_env!(:matrix_app_service, :homeserver_token) - - with ^config_hs_token <- hs_token do - conn - else - _ -> - Logger.warn("Received invalid homeserver token") - respond_error(conn, 403) - end + def call(%Plug.Conn{params: %{"access_token" => access_token}} = conn, homeserver_token) + when access_token == homeserver_token do + conn + end + + def call(%Plug.Conn{params: %{"access_token" => _access_token}} = conn, _homeserver_token) do + Logger.warn("Received invalid homeserver token") + + respond_error(conn, 403) end def call(conn, _opts) do Logger.warn("No homeserver token provided") + respond_error(conn, 401) end diff --git a/lib/matrix_app_service_web/controllers/v1/room_controller.ex b/lib/matrix_app_service_web/controllers/v1/room_controller.ex index cc84c48..e7af00d 100644 --- a/lib/matrix_app_service_web/controllers/v1/room_controller.ex +++ b/lib/matrix_app_service_web/controllers/v1/room_controller.ex @@ -8,7 +8,10 @@ defmodule MatrixAppServiceWeb.V1.RoomController do https://matrix.org/docs/spec/application_service/r0.1.2#get-matrix-app-v1-rooms-roomalias """ def query(conn, %{"room_alias" => room_alias}) do - adapter = Application.fetch_env!(:matrix_app_service, :room_adapter) + adapter = + conn.private[:room_adapter] || + MatrixAppServiceWeb.Endpoint.config(:room_adapter) || + raise "MatrixAppService: config key room_adapter missing" with :ok <- adapter.query_alias(room_alias) do conn diff --git a/lib/matrix_app_service_web/controllers/v1/transaction_controller.ex b/lib/matrix_app_service_web/controllers/v1/transaction_controller.ex index b6210ba..4d45819 100644 --- a/lib/matrix_app_service_web/controllers/v1/transaction_controller.ex +++ b/lib/matrix_app_service_web/controllers/v1/transaction_controller.ex @@ -19,20 +19,21 @@ defmodule MatrixAppServiceWeb.V1.TransactionController do # "user_id" => "@alice:matrix.imago.local"}], # "txn_id" => "269"} - defp create_event(%{ - "age" => age, - "content" => content, - "event_id" => event_id, - "origin_server_ts" => origin_server_ts, - "room_id" => room_id, - "sender" => sender, - "state_key" => state_key, - "type" => type, - "unsigned" => unsigned, - "user_id" => user_id - }) do - adapter = Application.fetch_env!(:matrix_app_service, :transaction_adapter) - + defp create_event( + %{ + "age" => age, + "content" => content, + "event_id" => event_id, + "origin_server_ts" => origin_server_ts, + "room_id" => room_id, + "sender" => sender, + "state_key" => state_key, + "type" => type, + "unsigned" => unsigned, + "user_id" => user_id + }, + adapter + ) do event = %MatrixAppService.Event{ age: age, content: content, @@ -49,19 +50,20 @@ defmodule MatrixAppServiceWeb.V1.TransactionController do adapter.new_event(event) end - defp create_event(%{ - "age" => age, - "content" => content, - "event_id" => event_id, - "origin_server_ts" => origin_server_ts, - "room_id" => room_id, - "sender" => sender, - "type" => type, - "unsigned" => unsigned, - "user_id" => user_id - }) do - adapter = Application.fetch_env!(:matrix_app_service, :transaction_adapter) - + defp create_event( + %{ + "age" => age, + "content" => content, + "event_id" => event_id, + "origin_server_ts" => origin_server_ts, + "room_id" => room_id, + "sender" => sender, + "type" => type, + "unsigned" => unsigned, + "user_id" => user_id + }, + adapter + ) do event = %MatrixAppService.Event{ age: age, content: content, @@ -82,7 +84,13 @@ defmodule MatrixAppServiceWeb.V1.TransactionController do https://matrix.org/docs/spec/application_service/r0.1.2#put-matrix-app-v1-transactions-txnid """ def push(conn, %{"events" => events}) do - Enum.each(events, &create_event(&1)) + adapter = + conn.private[:transaction_adapter] || + MatrixAppServiceWeb.Endpoint.config(:transaction_adapter) || + raise "MatrixAppService: config key room_adapter missing" + + Enum.each(events, &create_event(&1, adapter)) + send_resp(conn, 200, "{}") end end diff --git a/lib/matrix_app_service_web/controllers/v1/user_controller.ex b/lib/matrix_app_service_web/controllers/v1/user_controller.ex index bf3aa1e..a6e84c0 100644 --- a/lib/matrix_app_service_web/controllers/v1/user_controller.ex +++ b/lib/matrix_app_service_web/controllers/v1/user_controller.ex @@ -8,7 +8,10 @@ defmodule MatrixAppServiceWeb.V1.UserController do https://matrix.org/docs/spec/application_service/r0.1.2#get-matrix-app-v1-users-userid """ def query(conn, %{"user_id" => user_id}) do - adapter = Application.fetch_env!(:matrix_app_service, :user_adapter) + adapter = + conn.private[:user_adapter] || + MatrixAppServiceWeb.Endpoint.config(:user_adapter) || + raise "MatrixAppService: config key user_adapter missing" with :ok <- adapter.query_user(user_id) do conn diff --git a/lib/matrix_app_service_web/endpoint.ex b/lib/matrix_app_service_web/endpoint.ex new file mode 100644 index 0000000..4519ead --- /dev/null +++ b/lib/matrix_app_service_web/endpoint.ex @@ -0,0 +1,31 @@ +defmodule MatrixAppServiceWeb.Endpoint do + use Phoenix.Endpoint, otp_app: :matrix_app_service + require Logger + + def init(:supervisor, config) do + Logger.error(inspect(config)) + {:ok, config} + end + + # The session will be stored in the cookie and signed, + # this means its contents can be read but not tampered with. + # Set :encryption_salt if you would also like to encrypt it. + # @session_options [ + # store: :cookie, + # key: "_matrix_app_service_key", + # signing_salt: "zE7AHynD" + # ] + + plug Plug.RequestId + # plug Plug.Telemetry, event_prefix: [:phoenix, :endpoint] + + plug Plug.Parsers, + parsers: [:urlencoded, :multipart, :json], + pass: ["*/*"], + json_decoder: Phoenix.json_library() + + plug Plug.MethodOverride + plug Plug.Head + # plug Plug.Session, @session_options + plug MatrixAppServiceWeb.Router +end diff --git a/lib/matrix_app_service_web/router.ex b/lib/matrix_app_service_web/router.ex index 2c2f0ca..f254bdc 100644 --- a/lib/matrix_app_service_web/router.ex +++ b/lib/matrix_app_service_web/router.ex @@ -1,36 +1,11 @@ defmodule MatrixAppServiceWeb.Router do - @moduledoc """ - Provides the Matrix Application Service API routes. + use Phoenix.Router + use MatrixAppServiceWeb.Routes - https://matrix.org/docs/spec/application_service/r0.1.2 - """ + import Plug.Conn + import Phoenix.Controller - @doc """ - This macro injects the API routes in a Phoenix router. - """ - defmacro routes() do - quote do - pipeline :matrix_api do - plug :accepts, ["json"] - plug MatrixAppServiceWeb.AuthPlug - end - - path = Application.compile_env(:matrix_app_service, :path, "/") - - scope path, MatrixAppServiceWeb.V1, as: :matrix do - pipe_through :matrix_api - - put "/transactions/:txn_id", TransactionController, :push - - get "/users/:user_id", UserController, :query - get "/rooms/:room_alias", RoomController, :query - - get "/thirdparty/protocol/:protocol", ThirdPartyController, :query_protocol - get "/thirdparty/user/:protocol", ThirdPartyController, :query_users - get "/thirdparty/location/:protocol", ThirdPartyController, :query_locations - get "/thirdparty/location", ThirdPartyController, :query_location_by_alias - get "/thirdparty/user", ThirdPartyController, :query_user_by_id - end - end - end + # if MatrixAppService.Application.start_endpoint?() do + MatrixAppServiceWeb.Routes.routes(:no_config) + # end end diff --git a/lib/matrix_app_service_web/routes.ex b/lib/matrix_app_service_web/routes.ex new file mode 100644 index 0000000..54f5c83 --- /dev/null +++ b/lib/matrix_app_service_web/routes.ex @@ -0,0 +1,77 @@ +defmodule MatrixAppServiceWeb.Routes do + @moduledoc """ + Provides the Matrix Application Service API routes. + + https://matrix.org/docs/spec/application_service/r0.1.2 + """ + + @doc """ + + """ + defmacro __using__(_env) do + quote do + require unquote(__MODULE__) + + @matrix_app_services 0 + end + end + + @doc """ + This macro injects the API routes in a Phoenix router. + """ + # defmacro routes(opts \\ []) + defmacro routes(:no_config) do + quote do + pipeline :matrix_app_service do + plug :accepts, ["json"] + end + + scope "/", MatrixAppServiceWeb.V1, as: :matrix do + pipe_through :matrix_app_service + + put "/transactions/:txn_id", TransactionController, :push + + get "/users/:user_id", UserController, :query + get "/rooms/:room_alias", RoomController, :query + + get "/thirdparty/protocol/:protocol", ThirdPartyController, :query_protocol + get "/thirdparty/user/:protocol", ThirdPartyController, :query_users + get "/thirdparty/location/:protocol", ThirdPartyController, :query_locations + get "/thirdparty/location", ThirdPartyController, :query_location_by_alias + get "/thirdparty/user", ThirdPartyController, :query_user_by_id + end + end + end + + defmacro routes(opts) do + quote bind_quoted: [opts: opts] do + path = Keyword.get(opts, :path, "/") + namespace = Keyword.get(opts, :namespace, :matrix) + homeserver_token = Keyword.fetch!(opts, :homeserver_token) + pipeline_name = String.to_atom("matrix_api_#{@matrix_app_services}") + + pipeline pipeline_name do + plug :accepts, ["json"] + plug MatrixAppServiceWeb.SetConfigPlug, opts + plug MatrixAppServiceWeb.AuthPlug, homeserver_token + end + + scope path, MatrixAppServiceWeb.V1, as: namespace do + pipe_through pipeline_name + + put "/transactions/:txn_id", TransactionController, :push + + get "/users/:user_id", UserController, :query + get "/rooms/:room_alias", RoomController, :query + + get "/thirdparty/protocol/:protocol", ThirdPartyController, :query_protocol + get "/thirdparty/user/:protocol", ThirdPartyController, :query_users + get "/thirdparty/location/:protocol", ThirdPartyController, :query_locations + get "/thirdparty/location", ThirdPartyController, :query_location_by_alias + get "/thirdparty/user", ThirdPartyController, :query_user_by_id + end + + @matrix_app_services @matrix_app_services + 1 + end + end +end diff --git a/lib/matrix_app_service_web/set_config_plug.ex b/lib/matrix_app_service_web/set_config_plug.ex new file mode 100644 index 0000000..10296e2 --- /dev/null +++ b/lib/matrix_app_service_web/set_config_plug.ex @@ -0,0 +1,27 @@ +defmodule MatrixAppServiceWeb.SetConfigPlug do + @moduledoc """ + """ + + @behaviour Plug + import Plug.Conn + require Logger + + @doc false + @impl Plug + def init(opts) do + opts + end + + @doc false + @impl Plug + def call(conn, opts) do + conn + |> put_private(:transaction_adapter, Keyword.fetch!(opts, :transaction_adapter)) + |> put_private(:room_adapter, Keyword.fetch!(opts, :room_adapter)) + |> put_private(:user_adapter, Keyword.fetch!(opts, :user_adapter)) + |> put_private(:homeserver_token, Keyword.fetch!(opts, :homeserver_token)) + |> put_private(:access_token, Keyword.fetch!(opts, :access_token)) + |> put_private(:base_url, Keyword.fetch!(opts, :base_url)) + |> put_private(:path, Keyword.fetch!(opts, :path)) + end +end |