From 02309e06aa8e6900c1f29b147f08994f19d0339f Mon Sep 17 00:00:00 2001 From: Pierre de Lacroix Date: Sun, 11 Oct 2020 03:59:41 +0200 Subject: docs --- .gitlab-ci.yml | 16 ++++++++ lib/matrix_app_service/adapter/room.ex | 2 +- lib/matrix_app_service/adapter/transaction.ex | 5 ++- lib/matrix_app_service/adapter/user.ex | 4 +- lib/matrix_app_service/client.ex | 46 ++++++++++++++++++++++ lib/matrix_app_service/event.ex | 4 ++ lib/matrix_app_service_web.ex | 18 +-------- lib/matrix_app_service_web/auth_plug.ex | 3 +- lib/matrix_app_service_web/channels/user_socket.ex | 35 ---------------- .../controllers/v1/room_controller.ex | 8 +++- .../controllers/v1/third_party_controller.ex | 2 + .../controllers/v1/transaction_controller.ex | 8 +++- .../controllers/v1/user_controller.ex | 8 +++- lib/matrix_app_service_web/router.ex | 25 ++++++++---- lib/matrix_app_service_web/telemetry.ex | 46 ---------------------- lib/matrix_app_service_web/views/error_view.ex | 10 +++++ 16 files changed, 124 insertions(+), 116 deletions(-) delete mode 100644 lib/matrix_app_service_web/channels/user_socket.ex delete mode 100644 lib/matrix_app_service_web/telemetry.ex diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1ebb025..ca7ec81 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,3 +1,7 @@ +stages: + - static_analysis + - deploy + image: elixir:latest before_script: @@ -6,6 +10,7 @@ before_script: - mix deps.get test: + stage: static_analysis script: - MIX_ENV=test mix compile - mix test --cover @@ -14,5 +19,16 @@ test: - cover format: + stage: static_analysis script: - mix format --check-formatted + +pages: + stage: deploy + script: + - mix docs -o public + artifacts: + paths: + - public + only: + - master diff --git a/lib/matrix_app_service/adapter/room.ex b/lib/matrix_app_service/adapter/room.ex index 4c1cafc..1601094 100644 --- a/lib/matrix_app_service/adapter/room.ex +++ b/lib/matrix_app_service/adapter/room.ex @@ -8,7 +8,7 @@ defmodule MatrixAppService.Adapter.Room do Responds to a room query by alias. If the room exists, implementations should create the room (for instance by using `MatrixAppService.Client.create_room/1`) then return `:ok`. If the room - doesn't exist, they sould return anything else. + doesn't exist, they should return anything else. """ @callback query_alias(String.t()) :: :ok | Any end diff --git a/lib/matrix_app_service/adapter/transaction.ex b/lib/matrix_app_service/adapter/transaction.ex index a6ff750..22a2fe4 100644 --- a/lib/matrix_app_service/adapter/transaction.ex +++ b/lib/matrix_app_service/adapter/transaction.ex @@ -1,10 +1,11 @@ defmodule MatrixAppService.Adapter.Transaction do @moduledoc """ - + Behaviour for a module that handles transactions involving registered users + and rooms. """ @doc """ - + Called when the application service receives an event. """ @callback new_event(MatrixAppService.Event.t()) :: any() end diff --git a/lib/matrix_app_service/adapter/user.ex b/lib/matrix_app_service/adapter/user.ex index 92b9d96..cd3c2aa 100644 --- a/lib/matrix_app_service/adapter/user.ex +++ b/lib/matrix_app_service/adapter/user.ex @@ -7,8 +7,8 @@ defmodule MatrixAppService.Adapter.User do @doc """ Responds to a user query by Matrix ID. If the user exists, implementations should create the user (for instance by using - `MatrixAppService.Client.register/1`) then return `:ok`. If the user - doesn't exist, they sould return anything else. + `MatrixAppService.Client.register/2`) then return `:ok`. If the user + doesn't exist, they should return anything else. """ @callback query_user(String.t()) :: :ok | Any end diff --git a/lib/matrix_app_service/client.ex b/lib/matrix_app_service/client.ex index 998b377..c32cf00 100644 --- a/lib/matrix_app_service/client.ex +++ b/lib/matrix_app_service/client.ex @@ -1,12 +1,25 @@ defmodule MatrixAppService.Client do @moduledoc """ + Convenience wrapper around `Polyjuice.Client.LowLevel`. + Library users can use the wrapped functions or call `user/1` and pass the + returned struct to Polyjuice functions. """ @type client_options :: {:base_url, String.t()} | MatrixAppService.Client.LowLevel.create_opts() @doc """ + Returns a client for the application service. + The client gets its homeserver URL and access token from configuration, by + default. + Different options can be provided to override the defaults, those are: + + * `:base_url`: homerver URL + * `:acces_token`: access token + * `:device_id`: device ID + * `:user_id`: user ID + * `:storage`: a `t:Polyjuice.Client.Storage.t/0` """ @spec client([client_options()]) :: Polyjuice.Client.LowLevel.t() @@ -25,7 +38,11 @@ defmodule MatrixAppService.Client do end @doc """ + Creates a Matrix room. + Arguments: + 1. `options`: see `Polyjuice.Client.Room.create_room/2` + 2. `client_options`: see `client/1` """ @spec create_room(Keyword.t()) :: {:ok, String.t()} | Any def create_room(options \\ [], client_options \\ []) do @@ -34,7 +51,12 @@ defmodule MatrixAppService.Client do end @doc """ + Creates a new alias for a Matrix room. + Arguments: + 1. `room_id`: room ID + 2. `room_alias`: room alias + 3. `client_options`: see `client/1` """ @spec create_alias(String.t(), String.t(), client_options()) :: {:ok, String.t()} | Any def create_alias(room_id, room_alias, client_options \\ []) do @@ -43,7 +65,31 @@ defmodule MatrixAppService.Client do end @doc """ + Sends a message to a Matrix room. + + Arguments: + 1. `room_id`: room ID + 2. `msg`: see `Polyjuice.Client.Room.send_message/3` + 3. `client_options`: see `client/1` + """ + @spec send_message(String.t(), String.t(), client_options()) :: {:ok, String.t()} | Any + def send_message(room_id, msg, client_options \\ []) do + client(client_options) + |> Polyjuice.Client.Room.send_message(room_id, msg) + end + + @doc """ + Registers a new Matrix user. + Arguments: + 1. `opts`: a keyword list that can contain these keys: + * `:inhibit_login`: true + * `:device_id`: device ID, defaults to `"APP_SERVICE"` + * `:initial_device_display_name`: device name, defaults to + `"ApplicationService"` + * `:kind`: kind of account to register, defaults to `"user"`, can also be + `"guest"` + 2. `client_options`: see `client/1` """ @spec register(Polyjuice.Client.LowLevel.register_opts(), client_options()) :: {:ok, String.t()} | Any diff --git a/lib/matrix_app_service/event.ex b/lib/matrix_app_service/event.ex index 06d26a1..23abc38 100644 --- a/lib/matrix_app_service/event.ex +++ b/lib/matrix_app_service/event.ex @@ -1,4 +1,8 @@ defmodule MatrixAppService.Event do + @moduledoc """ + Struct for a Matrix event. + """ + @type t :: %__MODULE__{ age: integer(), content: map(), diff --git a/lib/matrix_app_service_web.ex b/lib/matrix_app_service_web.ex index bf02126..8031d3b 100644 --- a/lib/matrix_app_service_web.ex +++ b/lib/matrix_app_service_web.ex @@ -1,21 +1,5 @@ defmodule MatrixAppServiceWeb do - @moduledoc """ - The entrypoint for defining your web interface, such - as controllers, views, channels and so on. - - This can be used in your application as: - - use MatrixAppServiceWeb, :controller - use MatrixAppServiceWeb, :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. Instead, define any helper function in modules - and import those modules here. - """ + @moduledoc false def controller do quote do diff --git a/lib/matrix_app_service_web/auth_plug.ex b/lib/matrix_app_service_web/auth_plug.ex index 2d2ae23..a06fd46 100644 --- a/lib/matrix_app_service_web/auth_plug.ex +++ b/lib/matrix_app_service_web/auth_plug.ex @@ -1,7 +1,6 @@ defmodule MatrixAppServiceWeb.AuthPlug do @moduledoc """ - This Plug implements the Application Service authorization, - as described here: + Implements the Application Service authorization as a Plug. https://matrix.org/docs/spec/application_service/r0.1.2#authorization """ diff --git a/lib/matrix_app_service_web/channels/user_socket.ex b/lib/matrix_app_service_web/channels/user_socket.ex deleted file mode 100644 index ec2e9fb..0000000 --- a/lib/matrix_app_service_web/channels/user_socket.ex +++ /dev/null @@ -1,35 +0,0 @@ -defmodule MatrixAppServiceWeb.UserSocket do - use Phoenix.Socket - - ## Channels - # channel "room:*", MatrixAppServiceWeb.RoomChannel - - # Socket params are passed from the client and can - # be used to verify and authenticate a user. After - # verification, you can put default assigns into - # the socket that will be set for all channels, ie - # - # {:ok, assign(socket, :user_id, verified_user_id)} - # - # To deny connection, return `:error`. - # - # See `Phoenix.Token` documentation for examples in - # performing token verification on connect. - @impl true - def connect(_params, socket, _connect_info) do - {:ok, socket} - end - - # Socket id's are topics that allow you to identify all sockets for a given user: - # - # def id(socket), do: "user_socket:#{socket.assigns.user_id}" - # - # Would allow you to broadcast a "disconnect" event and terminate - # all active sockets and channels for a given user: - # - # MatrixAppServiceWeb.Endpoint.broadcast("user_socket:#{user.id}", "disconnect", %{}) - # - # Returning `nil` makes this socket anonymous. - @impl true - def id(_socket), do: nil -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 b236dd2..460bcbf 100644 --- a/lib/matrix_app_service_web/controllers/v1/room_controller.ex +++ b/lib/matrix_app_service_web/controllers/v1/room_controller.ex @@ -1,7 +1,13 @@ defmodule MatrixAppServiceWeb.V1.RoomController do + @moduledoc """ + Controller for rooms. + """ use MatrixAppServiceWeb, :controller - def show(conn, %{"room_alias" => room_alias}) do + @doc """ + 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) with :ok <- adapter.query_alias(room_alias) do diff --git a/lib/matrix_app_service_web/controllers/v1/third_party_controller.ex b/lib/matrix_app_service_web/controllers/v1/third_party_controller.ex index 6ef00ee..f13d6ec 100644 --- a/lib/matrix_app_service_web/controllers/v1/third_party_controller.ex +++ b/lib/matrix_app_service_web/controllers/v1/third_party_controller.ex @@ -1,6 +1,8 @@ defmodule MatrixAppServiceWeb.V1.ThirdPartyController do use MatrixAppServiceWeb, :controller + # TODO + def show(conn, _params) do send_resp(conn, 200, "") end 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 c2a47e3..b6210ba 100644 --- a/lib/matrix_app_service_web/controllers/v1/transaction_controller.ex +++ b/lib/matrix_app_service_web/controllers/v1/transaction_controller.ex @@ -1,4 +1,7 @@ defmodule MatrixAppServiceWeb.V1.TransactionController do + @moduledoc """ + Controller for transactions. + """ use MatrixAppServiceWeb, :controller # %{"access_token" => access_token, @@ -75,7 +78,10 @@ defmodule MatrixAppServiceWeb.V1.TransactionController do adapter.new_event(event) end - def create(conn, %{"events" => events}) do + @doc """ + 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)) send_resp(conn, 200, "{}") 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 2f73ad7..9d00f63 100644 --- a/lib/matrix_app_service_web/controllers/v1/user_controller.ex +++ b/lib/matrix_app_service_web/controllers/v1/user_controller.ex @@ -1,7 +1,13 @@ defmodule MatrixAppServiceWeb.V1.UserController do + @moduledoc """ + Controller for users. + """ use MatrixAppServiceWeb, :controller - def show(conn, %{"user_id" => user_id}) do + @doc """ + 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) with :ok <- adapter.query_user(user_id) do diff --git a/lib/matrix_app_service_web/router.ex b/lib/matrix_app_service_web/router.ex index 21ccc39..ca37fe0 100644 --- a/lib/matrix_app_service_web/router.ex +++ b/lib/matrix_app_service_web/router.ex @@ -1,4 +1,13 @@ defmodule MatrixAppServiceWeb.Router do + @moduledoc """ + Provides the Matrix Application Service API routes. + + https://matrix.org/docs/spec/application_service/r0.1.2 + """ + + @doc """ + This macro injects the API routes in a Phoenix router. + """ defmacro routes() do quote do pipeline :matrix_api do @@ -11,16 +20,16 @@ defmodule MatrixAppServiceWeb.Router do scope path, MatrixAppServiceWeb.V1 do pipe_through :matrix_api - put "/transactions/:txn_id", TransactionController, :create + put "/transactions/:txn_id", TransactionController, :push - get "/users/:user_id", UserController, :show - get "/rooms/:room_alias", RoomController, :show + get "/users/:user_id", UserController, :query + get "/rooms/:room_alias", RoomController, :query - get "/thirdparty/protocol/:protocol", ThirdPartyController, :show - get "/thirdparty/user/:protocol", ThirdPartyController, :show - get "/thirdparty/location/:protocol", ThirdPartyController, :show - get "/thirdparty/location", ThirdPartyController, :show - get "/thirdparty/user", ThirdPartyController, :show + 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 diff --git a/lib/matrix_app_service_web/telemetry.ex b/lib/matrix_app_service_web/telemetry.ex deleted file mode 100644 index de3ec2d..0000000 --- a/lib/matrix_app_service_web/telemetry.ex +++ /dev/null @@ -1,46 +0,0 @@ -defmodule MatrixAppServiceWeb.Telemetry do - use Supervisor - import Telemetry.Metrics - - def start_link(arg) do - Supervisor.start_link(__MODULE__, arg, name: __MODULE__) - end - - @impl true - def init(_arg) do - children = [ - {:telemetry_poller, measurements: periodic_measurements(), period: 10_000} - # Add reporters as children of your supervision tree. - # {Telemetry.Metrics.ConsoleReporter, metrics: metrics()} - ] - - Supervisor.init(children, strategy: :one_for_one) - end - - def metrics do - [ - # Phoenix Metrics - summary("phoenix.endpoint.stop.duration", - unit: {:native, :millisecond} - ), - summary("phoenix.router_dispatch.stop.duration", - tags: [:route], - unit: {:native, :millisecond} - ), - - # VM Metrics - summary("vm.memory.total", unit: {:byte, :kilobyte}), - summary("vm.total_run_queue_lengths.total"), - summary("vm.total_run_queue_lengths.cpu"), - summary("vm.total_run_queue_lengths.io") - ] - end - - defp periodic_measurements do - [ - # A module, function and arguments to be invoked periodically. - # This function must call :telemetry.execute/3 and a metric must be added above. - # {MatrixAppServiceWeb, :count_users, []} - ] - end -end diff --git a/lib/matrix_app_service_web/views/error_view.ex b/lib/matrix_app_service_web/views/error_view.ex index ab705e1..024273f 100644 --- a/lib/matrix_app_service_web/views/error_view.ex +++ b/lib/matrix_app_service_web/views/error_view.ex @@ -1,10 +1,19 @@ defmodule MatrixAppServiceWeb.ErrorView do + @moduledoc """ + JSON views for errors. + """ use MatrixAppServiceWeb, :view + @doc """ + JSON view for a 401 response status. + """ def render("401.json", _assigns) do %{errcode: "EX.MAP.UNAUTHORIZED"} end + @doc """ + JSON view for a 403 response status. + """ def render("403.json", _assigns) do %{errcode: "EX.MAP.FORBIDDEN"} end @@ -12,6 +21,7 @@ defmodule MatrixAppServiceWeb.ErrorView do # By default, Phoenix returns the status message from # the template name. For example, "404.json" becomes # "Not Found". + @doc false def template_not_found(template, _assigns) do %{errors: %{detail: Phoenix.Controller.status_message_from_template(template)}} end -- cgit v1.2.3