From 46e0d23452df68f0b1d15c3cf566d934be29eb64 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Fri, 8 Nov 2024 09:17:46 +0100 Subject: [PATCH 01/40] example: generate phoenix boilerplate. --- examples/gatekeeper-auth/api/.formatter.exs | 5 + examples/gatekeeper-auth/api/.gitignore | 27 +++++ examples/gatekeeper-auth/api/README.md | 18 ++++ .../gatekeeper-auth/api/config/config.exs | 35 +++++++ examples/gatekeeper-auth/api/config/dev.exs | 63 +++++++++++ examples/gatekeeper-auth/api/config/prod.exs | 7 ++ .../gatekeeper-auth/api/config/runtime.exs | 99 ++++++++++++++++++ examples/gatekeeper-auth/api/config/test.exs | 27 +++++ examples/gatekeeper-auth/api/lib/api.ex | 9 ++ .../api/lib/api/application.ex | 34 ++++++ examples/gatekeeper-auth/api/lib/api/repo.ex | 5 + examples/gatekeeper-auth/api/lib/api_web.ex | 65 ++++++++++++ .../api/lib/api_web/controllers/error_json.ex | 21 ++++ .../api/lib/api_web/endpoint.ex | 47 +++++++++ .../gatekeeper-auth/api/lib/api_web/router.ex | 11 ++ .../api/lib/api_web/telemetry.ex | 92 ++++++++++++++++ examples/gatekeeper-auth/api/mix.exs | 61 +++++++++++ examples/gatekeeper-auth/api/mix.lock | 25 +++++ .../api/priv/repo/migrations/.formatter.exs | 4 + .../gatekeeper-auth/api/priv/repo/seeds.exs | 11 ++ .../api/priv/static/favicon.ico | Bin 0 -> 152 bytes .../api/priv/static/robots.txt | 5 + .../api_web/controllers/error_json_test.exs | 12 +++ .../api/test/support/conn_case.ex | 38 +++++++ .../api/test/support/data_case.ex | 58 ++++++++++ .../gatekeeper-auth/api/test/test_helper.exs | 2 + 26 files changed, 781 insertions(+) create mode 100644 examples/gatekeeper-auth/api/.formatter.exs create mode 100644 examples/gatekeeper-auth/api/.gitignore create mode 100644 examples/gatekeeper-auth/api/README.md create mode 100644 examples/gatekeeper-auth/api/config/config.exs create mode 100644 examples/gatekeeper-auth/api/config/dev.exs create mode 100644 examples/gatekeeper-auth/api/config/prod.exs create mode 100644 examples/gatekeeper-auth/api/config/runtime.exs create mode 100644 examples/gatekeeper-auth/api/config/test.exs create mode 100644 examples/gatekeeper-auth/api/lib/api.ex create mode 100644 examples/gatekeeper-auth/api/lib/api/application.ex create mode 100644 examples/gatekeeper-auth/api/lib/api/repo.ex create mode 100644 examples/gatekeeper-auth/api/lib/api_web.ex create mode 100644 examples/gatekeeper-auth/api/lib/api_web/controllers/error_json.ex create mode 100644 examples/gatekeeper-auth/api/lib/api_web/endpoint.ex create mode 100644 examples/gatekeeper-auth/api/lib/api_web/router.ex create mode 100644 examples/gatekeeper-auth/api/lib/api_web/telemetry.ex create mode 100644 examples/gatekeeper-auth/api/mix.exs create mode 100644 examples/gatekeeper-auth/api/mix.lock create mode 100644 examples/gatekeeper-auth/api/priv/repo/migrations/.formatter.exs create mode 100644 examples/gatekeeper-auth/api/priv/repo/seeds.exs create mode 100644 examples/gatekeeper-auth/api/priv/static/favicon.ico create mode 100644 examples/gatekeeper-auth/api/priv/static/robots.txt create mode 100644 examples/gatekeeper-auth/api/test/api_web/controllers/error_json_test.exs create mode 100644 examples/gatekeeper-auth/api/test/support/conn_case.ex create mode 100644 examples/gatekeeper-auth/api/test/support/data_case.ex create mode 100644 examples/gatekeeper-auth/api/test/test_helper.exs diff --git a/examples/gatekeeper-auth/api/.formatter.exs b/examples/gatekeeper-auth/api/.formatter.exs new file mode 100644 index 0000000000..5971023f6b --- /dev/null +++ b/examples/gatekeeper-auth/api/.formatter.exs @@ -0,0 +1,5 @@ +[ + import_deps: [:ecto, :ecto_sql, :phoenix], + subdirectories: ["priv/*/migrations"], + inputs: ["*.{ex,exs}", "{config,lib,test}/**/*.{ex,exs}", "priv/*/seeds.exs"] +] diff --git a/examples/gatekeeper-auth/api/.gitignore b/examples/gatekeeper-auth/api/.gitignore new file mode 100644 index 0000000000..74fcb6e6db --- /dev/null +++ b/examples/gatekeeper-auth/api/.gitignore @@ -0,0 +1,27 @@ +# The directory Mix will write compiled artifacts to. +/_build/ + +# If you run "mix test --cover", coverage assets end up here. +/cover/ + +# The directory Mix downloads your dependencies sources to. +/deps/ + +# Where 3rd-party dependencies like ExDoc output generated docs. +/doc/ + +# Ignore .fetch files in case you like to edit your project deps locally. +/.fetch + +# If the VM crashes, it generates a dump, let's ignore it too. +erl_crash.dump + +# Also ignore archive artifacts (built via "mix archive.build"). +*.ez + +# Temporary files, for example, from tests. +/tmp/ + +# Ignore package tarball (built via "mix hex.build"). +api-*.tar + diff --git a/examples/gatekeeper-auth/api/README.md b/examples/gatekeeper-auth/api/README.md new file mode 100644 index 0000000000..f8975f4af2 --- /dev/null +++ b/examples/gatekeeper-auth/api/README.md @@ -0,0 +1,18 @@ +# Api + +To start your Phoenix server: + + * Run `mix setup` to install and setup dependencies + * Start Phoenix endpoint with `mix phx.server` or inside IEx with `iex -S mix phx.server` + +Now you can visit [`localhost:4000`](http://localhost:4000) from your browser. + +Ready to run in production? Please [check our deployment guides](https://hexdocs.pm/phoenix/deployment.html). + +## Learn more + + * Official website: https://www.phoenixframework.org/ + * Guides: https://hexdocs.pm/phoenix/overview.html + * Docs: https://hexdocs.pm/phoenix + * Forum: https://elixirforum.com/c/phoenix-forum + * Source: https://github.com/phoenixframework/phoenix diff --git a/examples/gatekeeper-auth/api/config/config.exs b/examples/gatekeeper-auth/api/config/config.exs new file mode 100644 index 0000000000..5be3af4d06 --- /dev/null +++ b/examples/gatekeeper-auth/api/config/config.exs @@ -0,0 +1,35 @@ +# This file is responsible for configuring your application +# and its dependencies with the aid of the Config module. +# +# This configuration file is loaded before any dependency and +# is restricted to this project. + +# General application configuration +import Config + +config :api, + ecto_repos: [Api.Repo], + generators: [timestamp_type: :utc_datetime, binary_id: true] + +# Configures the endpoint +config :api, ApiWeb.Endpoint, + url: [host: "localhost"], + adapter: Bandit.PhoenixAdapter, + render_errors: [ + formats: [json: ApiWeb.ErrorJSON], + layout: false + ], + pubsub_server: Api.PubSub, + live_view: [signing_salt: "M9e8NmwP"] + +# Configures Elixir's Logger +config :logger, :console, + format: "$time $metadata[$level] $message\n", + metadata: [:request_id] + +# Use Jason for JSON parsing in Phoenix +config :phoenix, :json_library, Jason + +# Import environment specific config. This must remain at the bottom +# of this file so it overrides the configuration defined above. +import_config "#{config_env()}.exs" diff --git a/examples/gatekeeper-auth/api/config/dev.exs b/examples/gatekeeper-auth/api/config/dev.exs new file mode 100644 index 0000000000..5166168173 --- /dev/null +++ b/examples/gatekeeper-auth/api/config/dev.exs @@ -0,0 +1,63 @@ +import Config + +# Configure your database +config :api, Api.Repo, + username: "postgres", + password: "postgres", + hostname: "localhost", + database: "api_dev", + stacktrace: true, + show_sensitive_data_on_connection_error: true, + pool_size: 10 + +# For development, we disable any cache and enable +# debugging and code reloading. +# +# The watchers configuration can be used to run external +# watchers to your application. For example, we can use it +# to bundle .js and .css sources. +config :api, ApiWeb.Endpoint, + # Binding to loopback ipv4 address prevents access from other machines. + # Change to `ip: {0, 0, 0, 0}` to allow access from other machines. + http: [ip: {127, 0, 0, 1}, port: 4000], + check_origin: false, + code_reloader: true, + debug_errors: true, + secret_key_base: "pVvBh/U565dk0DteMtnoCjwLcoZnMDU9QeQNVr0gvVtYUrF8KqoJeyn5YJ0EQudX", + watchers: [] + +# ## SSL Support +# +# In order to use HTTPS in development, a self-signed +# certificate can be generated by running the following +# Mix task: +# +# mix phx.gen.cert +# +# Run `mix help phx.gen.cert` for more information. +# +# The `http:` config above can be replaced with: +# +# https: [ +# port: 4001, +# cipher_suite: :strong, +# keyfile: "priv/cert/selfsigned_key.pem", +# certfile: "priv/cert/selfsigned.pem" +# ], +# +# If desired, both `http:` and `https:` keys can be +# configured to run both http and https servers on +# different ports. + +# Enable dev routes for dashboard and mailbox +config :api, dev_routes: true + +# Do not include metadata nor timestamps in development logs +config :logger, :console, format: "[$level] $message\n" + +# Set a higher stacktrace during development. Avoid configuring such +# in production as building large stacktraces may be expensive. +config :phoenix, :stacktrace_depth, 20 + +# Initialize plugs at runtime for faster development compilation +config :phoenix, :plug_init_mode, :runtime diff --git a/examples/gatekeeper-auth/api/config/prod.exs b/examples/gatekeeper-auth/api/config/prod.exs new file mode 100644 index 0000000000..1fe2d9e854 --- /dev/null +++ b/examples/gatekeeper-auth/api/config/prod.exs @@ -0,0 +1,7 @@ +import Config + +# Do not print debug messages in production +config :logger, level: :info + +# Runtime production configuration, including reading +# of environment variables, is done on config/runtime.exs. diff --git a/examples/gatekeeper-auth/api/config/runtime.exs b/examples/gatekeeper-auth/api/config/runtime.exs new file mode 100644 index 0000000000..1e8292646e --- /dev/null +++ b/examples/gatekeeper-auth/api/config/runtime.exs @@ -0,0 +1,99 @@ +import Config + +# config/runtime.exs is executed for all environments, including +# during releases. It is executed after compilation and before the +# system starts, so it is typically used to load production configuration +# and secrets from environment variables or elsewhere. Do not define +# any compile-time configuration in here, as it won't be applied. +# The block below contains prod specific runtime configuration. + +# ## Using releases +# +# If you use `mix release`, you need to explicitly enable the server +# by passing the PHX_SERVER=true when you start it: +# +# PHX_SERVER=true bin/api start +# +# Alternatively, you can use `mix phx.gen.release` to generate a `bin/server` +# script that automatically sets the env var above. +if System.get_env("PHX_SERVER") do + config :api, ApiWeb.Endpoint, server: true +end + +if config_env() == :prod do + database_url = + System.get_env("DATABASE_URL") || + raise """ + environment variable DATABASE_URL is missing. + For example: ecto://USER:PASS@HOST/DATABASE + """ + + maybe_ipv6 = if System.get_env("ECTO_IPV6") in ~w(true 1), do: [:inet6], else: [] + + config :api, Api.Repo, + # ssl: true, + url: database_url, + pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"), + socket_options: maybe_ipv6 + + # The secret key base is used to sign/encrypt cookies and other secrets. + # A default value is used in config/dev.exs and config/test.exs but you + # want to use a different value for prod and you most likely don't want + # to check this value into version control, so we use an environment + # variable instead. + secret_key_base = + System.get_env("SECRET_KEY_BASE") || + raise """ + environment variable SECRET_KEY_BASE is missing. + You can generate one by calling: mix phx.gen.secret + """ + + host = System.get_env("PHX_HOST") || "example.com" + port = String.to_integer(System.get_env("PORT") || "4000") + + config :api, :dns_cluster_query, System.get_env("DNS_CLUSTER_QUERY") + + config :api, ApiWeb.Endpoint, + url: [host: host, port: 443, scheme: "https"], + http: [ + # Enable IPv6 and bind on all interfaces. + # Set it to {0, 0, 0, 0, 0, 0, 0, 1} for local network only access. + # See the documentation on https://hexdocs.pm/bandit/Bandit.html#t:options/0 + # for details about using IPv6 vs IPv4 and loopback vs public addresses. + ip: {0, 0, 0, 0, 0, 0, 0, 0}, + port: port + ], + secret_key_base: secret_key_base + + # ## SSL Support + # + # To get SSL working, you will need to add the `https` key + # to your endpoint configuration: + # + # config :api, ApiWeb.Endpoint, + # https: [ + # ..., + # port: 443, + # cipher_suite: :strong, + # keyfile: System.get_env("SOME_APP_SSL_KEY_PATH"), + # certfile: System.get_env("SOME_APP_SSL_CERT_PATH") + # ] + # + # The `cipher_suite` is set to `:strong` to support only the + # latest and more secure SSL ciphers. This means old browsers + # and clients may not be supported. You can set it to + # `:compatible` for wider support. + # + # `:keyfile` and `:certfile` expect an absolute path to the key + # and cert in disk or a relative path inside priv, for example + # "priv/ssl/server.key". For all supported SSL configuration + # options, see https://hexdocs.pm/plug/Plug.SSL.html#configure/1 + # + # We also recommend setting `force_ssl` in your config/prod.exs, + # ensuring no data is ever sent via http, always redirecting to https: + # + # config :api, ApiWeb.Endpoint, + # force_ssl: [hsts: true] + # + # Check `Plug.SSL` for all available options in `force_ssl`. +end diff --git a/examples/gatekeeper-auth/api/config/test.exs b/examples/gatekeeper-auth/api/config/test.exs new file mode 100644 index 0000000000..eff6f8273e --- /dev/null +++ b/examples/gatekeeper-auth/api/config/test.exs @@ -0,0 +1,27 @@ +import Config + +# Configure your database +# +# The MIX_TEST_PARTITION environment variable can be used +# to provide built-in test partitioning in CI environment. +# Run `mix help test` for more information. +config :api, Api.Repo, + username: "postgres", + password: "postgres", + hostname: "localhost", + database: "api_test#{System.get_env("MIX_TEST_PARTITION")}", + pool: Ecto.Adapters.SQL.Sandbox, + pool_size: System.schedulers_online() * 2 + +# We don't run a server during test. If one is required, +# you can enable the server option below. +config :api, ApiWeb.Endpoint, + http: [ip: {127, 0, 0, 1}, port: 4002], + secret_key_base: "FdsTo+z4sPEhsQNsUtBq26K9qn42nkn1OCH2cLURBZkPCvgJ4F3WiVNFo1NVjojw", + server: false + +# Print only warnings and errors during test +config :logger, level: :warning + +# Initialize plugs at runtime for faster test compilation +config :phoenix, :plug_init_mode, :runtime diff --git a/examples/gatekeeper-auth/api/lib/api.ex b/examples/gatekeeper-auth/api/lib/api.ex new file mode 100644 index 0000000000..d09be70aa6 --- /dev/null +++ b/examples/gatekeeper-auth/api/lib/api.ex @@ -0,0 +1,9 @@ +defmodule Api do + @moduledoc """ + Api keeps the contexts that define your domain + and business logic. + + Contexts are also responsible for managing your data, regardless + if it comes from the database, an external API or others. + """ +end diff --git a/examples/gatekeeper-auth/api/lib/api/application.ex b/examples/gatekeeper-auth/api/lib/api/application.ex new file mode 100644 index 0000000000..f1adfc4390 --- /dev/null +++ b/examples/gatekeeper-auth/api/lib/api/application.ex @@ -0,0 +1,34 @@ +defmodule Api.Application do + # See https://hexdocs.pm/elixir/Application.html + # for more information on OTP Applications + @moduledoc false + + use Application + + @impl true + def start(_type, _args) do + children = [ + ApiWeb.Telemetry, + Api.Repo, + {DNSCluster, query: Application.get_env(:api, :dns_cluster_query) || :ignore}, + {Phoenix.PubSub, name: Api.PubSub}, + # Start a worker by calling: Api.Worker.start_link(arg) + # {Api.Worker, arg}, + # Start to serve requests, typically the last entry + ApiWeb.Endpoint + ] + + # See https://hexdocs.pm/elixir/Supervisor.html + # for other strategies and supported options + opts = [strategy: :one_for_one, name: Api.Supervisor] + Supervisor.start_link(children, opts) + end + + # Tell Phoenix to update the endpoint configuration + # whenever the application is updated. + @impl true + def config_change(changed, _new, removed) do + ApiWeb.Endpoint.config_change(changed, removed) + :ok + end +end diff --git a/examples/gatekeeper-auth/api/lib/api/repo.ex b/examples/gatekeeper-auth/api/lib/api/repo.ex new file mode 100644 index 0000000000..87ced4ffe7 --- /dev/null +++ b/examples/gatekeeper-auth/api/lib/api/repo.ex @@ -0,0 +1,5 @@ +defmodule Api.Repo do + use Ecto.Repo, + otp_app: :api, + adapter: Ecto.Adapters.Postgres +end diff --git a/examples/gatekeeper-auth/api/lib/api_web.ex b/examples/gatekeeper-auth/api/lib/api_web.ex new file mode 100644 index 0000000000..2ed5a849d8 --- /dev/null +++ b/examples/gatekeeper-auth/api/lib/api_web.ex @@ -0,0 +1,65 @@ +defmodule ApiWeb do + @moduledoc """ + The entrypoint for defining your web interface, such + as controllers, components, channels, and so on. + + This can be used in your application as: + + use ApiWeb, :controller + use ApiWeb, :html + + The definitions below will be executed for every controller, + component, etc, so keep them short and clean, focused + on imports, uses and aliases. + + Do NOT define functions inside the quoted expressions + below. Instead, define additional modules and import + those modules here. + """ + + def static_paths, do: ~w(assets fonts images favicon.ico robots.txt) + + def router do + quote do + use Phoenix.Router, helpers: false + + # Import common connection and controller functions to use in pipelines + import Plug.Conn + import Phoenix.Controller + end + end + + def channel do + quote do + use Phoenix.Channel + end + end + + def controller do + quote do + use Phoenix.Controller, + formats: [:html, :json], + layouts: [html: ApiWeb.Layouts] + + import Plug.Conn + + unquote(verified_routes()) + end + end + + def verified_routes do + quote do + use Phoenix.VerifiedRoutes, + endpoint: ApiWeb.Endpoint, + router: ApiWeb.Router, + statics: ApiWeb.static_paths() + end + end + + @doc """ + When used, dispatch to the appropriate controller/live_view/etc. + """ + defmacro __using__(which) when is_atom(which) do + apply(__MODULE__, which, []) + end +end diff --git a/examples/gatekeeper-auth/api/lib/api_web/controllers/error_json.ex b/examples/gatekeeper-auth/api/lib/api_web/controllers/error_json.ex new file mode 100644 index 0000000000..00015e5b1c --- /dev/null +++ b/examples/gatekeeper-auth/api/lib/api_web/controllers/error_json.ex @@ -0,0 +1,21 @@ +defmodule ApiWeb.ErrorJSON do + @moduledoc """ + This module is invoked by your endpoint in case of errors on JSON requests. + + See config/config.exs. + """ + + # If you want to customize a particular status code, + # you may add your own clauses, such as: + # + # def render("500.json", _assigns) do + # %{errors: %{detail: "Internal Server Error"}} + # end + + # By default, Phoenix returns the status message from + # the template name. For example, "404.json" becomes + # "Not Found". + def render(template, _assigns) do + %{errors: %{detail: Phoenix.Controller.status_message_from_template(template)}} + end +end diff --git a/examples/gatekeeper-auth/api/lib/api_web/endpoint.ex b/examples/gatekeeper-auth/api/lib/api_web/endpoint.ex new file mode 100644 index 0000000000..d005df7198 --- /dev/null +++ b/examples/gatekeeper-auth/api/lib/api_web/endpoint.ex @@ -0,0 +1,47 @@ +defmodule ApiWeb.Endpoint do + use Phoenix.Endpoint, otp_app: :api + + # 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: "_api_key", + signing_salt: "wk5SPjwd", + same_site: "Lax" + ] + + # socket "/live", Phoenix.LiveView.Socket, + # websocket: [connect_info: [session: @session_options]], + # longpoll: [connect_info: [session: @session_options]] + + # Serve at "/" the static files from "priv/static" directory. + # + # You should set gzip to true if you are running phx.digest + # when deploying your static files in production. + plug Plug.Static, + at: "/", + from: :api, + gzip: false, + only: ApiWeb.static_paths() + + # Code reloading can be explicitly enabled under the + # :code_reloader configuration of your endpoint. + if code_reloading? do + plug Phoenix.CodeReloader + plug Phoenix.Ecto.CheckRepoStatus, otp_app: :api + end + + 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 ApiWeb.Router +end diff --git a/examples/gatekeeper-auth/api/lib/api_web/router.ex b/examples/gatekeeper-auth/api/lib/api_web/router.ex new file mode 100644 index 0000000000..75a469e235 --- /dev/null +++ b/examples/gatekeeper-auth/api/lib/api_web/router.ex @@ -0,0 +1,11 @@ +defmodule ApiWeb.Router do + use ApiWeb, :router + + pipeline :api do + plug :accepts, ["json"] + end + + scope "/api", ApiWeb do + pipe_through :api + end +end diff --git a/examples/gatekeeper-auth/api/lib/api_web/telemetry.ex b/examples/gatekeeper-auth/api/lib/api_web/telemetry.ex new file mode 100644 index 0000000000..e94763fa36 --- /dev/null +++ b/examples/gatekeeper-auth/api/lib/api_web/telemetry.ex @@ -0,0 +1,92 @@ +defmodule ApiWeb.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 will execute the given period measurements + # every 10_000ms. Learn more here: https://hexdocs.pm/telemetry_metrics + {: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.start.system_time", + unit: {:native, :millisecond} + ), + summary("phoenix.endpoint.stop.duration", + unit: {:native, :millisecond} + ), + summary("phoenix.router_dispatch.start.system_time", + tags: [:route], + unit: {:native, :millisecond} + ), + summary("phoenix.router_dispatch.exception.duration", + tags: [:route], + unit: {:native, :millisecond} + ), + summary("phoenix.router_dispatch.stop.duration", + tags: [:route], + unit: {:native, :millisecond} + ), + summary("phoenix.socket_connected.duration", + unit: {:native, :millisecond} + ), + summary("phoenix.channel_joined.duration", + unit: {:native, :millisecond} + ), + summary("phoenix.channel_handled_in.duration", + tags: [:event], + unit: {:native, :millisecond} + ), + + # Database Metrics + summary("api.repo.query.total_time", + unit: {:native, :millisecond}, + description: "The sum of the other measurements" + ), + summary("api.repo.query.decode_time", + unit: {:native, :millisecond}, + description: "The time spent decoding the data received from the database" + ), + summary("api.repo.query.query_time", + unit: {:native, :millisecond}, + description: "The time spent executing the query" + ), + summary("api.repo.query.queue_time", + unit: {:native, :millisecond}, + description: "The time spent waiting for a database connection" + ), + summary("api.repo.query.idle_time", + unit: {:native, :millisecond}, + description: + "The time the connection spent waiting before being checked out for the query" + ), + + # 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. + # {ApiWeb, :count_users, []} + ] + end +end diff --git a/examples/gatekeeper-auth/api/mix.exs b/examples/gatekeeper-auth/api/mix.exs new file mode 100644 index 0000000000..e0e101748b --- /dev/null +++ b/examples/gatekeeper-auth/api/mix.exs @@ -0,0 +1,61 @@ +defmodule Api.MixProject do + use Mix.Project + + def project do + [ + app: :api, + version: "0.1.0", + elixir: "~> 1.14", + elixirc_paths: elixirc_paths(Mix.env()), + start_permanent: Mix.env() == :prod, + aliases: aliases(), + deps: deps() + ] + end + + # Configuration for the OTP application. + # + # Type `mix help compile.app` for more information. + def application do + [ + mod: {Api.Application, []}, + extra_applications: [:logger, :runtime_tools] + ] + end + + # Specifies which paths to compile per environment. + defp elixirc_paths(:test), do: ["lib", "test/support"] + defp elixirc_paths(_), do: ["lib"] + + # Specifies your project dependencies. + # + # Type `mix help deps` for examples and options. + defp deps do + [ + {:phoenix, "~> 1.7.14"}, + {:phoenix_ecto, "~> 4.5"}, + {:ecto_sql, "~> 3.10"}, + {:postgrex, ">= 0.0.0"}, + {:telemetry_metrics, "~> 1.0"}, + {:telemetry_poller, "~> 1.0"}, + {:jason, "~> 1.2"}, + {:dns_cluster, "~> 0.1.1"}, + {:bandit, "~> 1.5"} + ] + end + + # Aliases are shortcuts or tasks specific to the current project. + # For example, to install project dependencies and perform other setup tasks, run: + # + # $ mix setup + # + # See the documentation for `Mix` for more info on aliases. + defp aliases do + [ + setup: ["deps.get", "ecto.setup"], + "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"], + "ecto.reset": ["ecto.drop", "ecto.setup"], + test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"] + ] + end +end diff --git a/examples/gatekeeper-auth/api/mix.lock b/examples/gatekeeper-auth/api/mix.lock new file mode 100644 index 0000000000..7ad3f35d77 --- /dev/null +++ b/examples/gatekeeper-auth/api/mix.lock @@ -0,0 +1,25 @@ +%{ + "bandit": {:hex, :bandit, "1.5.7", "6856b1e1df4f2b0cb3df1377eab7891bec2da6a7fd69dc78594ad3e152363a50", [:mix], [{:hpax, "~> 1.0.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "f2dd92ae87d2cbea2fa9aa1652db157b6cba6c405cb44d4f6dd87abba41371cd"}, + "castore": {:hex, :castore, "1.0.9", "5cc77474afadf02c7c017823f460a17daa7908e991b0cc917febc90e466a375c", [:mix], [], "hexpm", "5ea956504f1ba6f2b4eb707061d8e17870de2bee95fb59d512872c2ef06925e7"}, + "db_connection": {:hex, :db_connection, "2.7.0", "b99faa9291bb09892c7da373bb82cba59aefa9b36300f6145c5f201c7adf48ec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dcf08f31b2701f857dfc787fbad78223d61a32204f217f15e881dd93e4bdd3ff"}, + "decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"}, + "dns_cluster": {:hex, :dns_cluster, "0.1.3", "0bc20a2c88ed6cc494f2964075c359f8c2d00e1bf25518a6a6c7fd277c9b0c66", [:mix], [], "hexpm", "46cb7c4a1b3e52c7ad4cbe33ca5079fbde4840dedeafca2baf77996c2da1bc33"}, + "ecto": {:hex, :ecto, "3.12.4", "267c94d9f2969e6acc4dd5e3e3af5b05cdae89a4d549925f3008b2b7eb0b93c3", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ef04e4101688a67d061e1b10d7bc1fbf00d1d13c17eef08b71d070ff9188f747"}, + "ecto_sql": {:hex, :ecto_sql, "3.12.1", "c0d0d60e85d9ff4631f12bafa454bc392ce8b9ec83531a412c12a0d415a3a4d0", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.12", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "aff5b958a899762c5f09028c847569f7dfb9cc9d63bdb8133bff8a5546de6bf5"}, + "hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"}, + "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, + "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, + "phoenix": {:hex, :phoenix, "1.7.14", "a7d0b3f1bc95987044ddada111e77bd7f75646a08518942c72a8440278ae7825", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "c7859bc56cc5dfef19ecfc240775dae358cbaa530231118a9e014df392ace61a"}, + "phoenix_ecto": {:hex, :phoenix_ecto, "4.6.3", "f686701b0499a07f2e3b122d84d52ff8a31f5def386e03706c916f6feddf69ef", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.1", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "909502956916a657a197f94cc1206d9a65247538de8a5e186f7537c895d95764"}, + "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.3", "3168d78ba41835aecad272d5e8cd51aa87a7ac9eb836eabc42f6e57538e3731d", [:mix], [], "hexpm", "bba06bc1dcfd8cb086759f0edc94a8ba2bc8896d5331a1e2c2902bf8e36ee502"}, + "phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"}, + "plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"}, + "plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"}, + "postgrex": {:hex, :postgrex, "0.19.2", "34d6884a332c7bf1e367fc8b9a849d23b43f7da5c6e263def92784d03f9da468", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "618988886ab7ae8561ebed9a3c7469034bf6a88b8995785a3378746a4b9835ec"}, + "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, + "telemetry_metrics": {:hex, :telemetry_metrics, "1.0.0", "29f5f84991ca98b8eb02fc208b2e6de7c95f8bb2294ef244a176675adc7775df", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f23713b3847286a534e005126d4c959ebcca68ae9582118ce436b521d1d47d5d"}, + "telemetry_poller": {:hex, :telemetry_poller, "1.1.0", "58fa7c216257291caaf8d05678c8d01bd45f4bdbc1286838a28c4bb62ef32999", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9eb9d9cbfd81cbd7cdd24682f8711b6e2b691289a0de6826e58452f28c103c8f"}, + "thousand_island": {:hex, :thousand_island, "1.3.5", "6022b6338f1635b3d32406ff98d68b843ba73b3aa95cfc27154223244f3a6ca5", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2be6954916fdfe4756af3239fb6b6d75d0b8063b5df03ba76fd8a4c87849e180"}, + "websock": {:hex, :websock, "0.5.3", "2f69a6ebe810328555b6fe5c831a851f485e303a7c8ce6c5f675abeb20ebdadc", [:mix], [], "hexpm", "6105453d7fac22c712ad66fab1d45abdf049868f253cf719b625151460b8b453"}, + "websock_adapter": {:hex, :websock_adapter, "0.5.7", "65fa74042530064ef0570b75b43f5c49bb8b235d6515671b3d250022cb8a1f9e", [:mix], [{:bandit, ">= 0.6.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "d0f478ee64deddfec64b800673fd6e0c8888b079d9f3444dd96d2a98383bdbd1"}, +} diff --git a/examples/gatekeeper-auth/api/priv/repo/migrations/.formatter.exs b/examples/gatekeeper-auth/api/priv/repo/migrations/.formatter.exs new file mode 100644 index 0000000000..49f9151ed2 --- /dev/null +++ b/examples/gatekeeper-auth/api/priv/repo/migrations/.formatter.exs @@ -0,0 +1,4 @@ +[ + import_deps: [:ecto_sql], + inputs: ["*.exs"] +] diff --git a/examples/gatekeeper-auth/api/priv/repo/seeds.exs b/examples/gatekeeper-auth/api/priv/repo/seeds.exs new file mode 100644 index 0000000000..8e275e9319 --- /dev/null +++ b/examples/gatekeeper-auth/api/priv/repo/seeds.exs @@ -0,0 +1,11 @@ +# Script for populating the database. You can run it as: +# +# mix run priv/repo/seeds.exs +# +# Inside the script, you can read and write to any of your +# repositories directly: +# +# Api.Repo.insert!(%Api.SomeSchema{}) +# +# We recommend using the bang functions (`insert!`, `update!` +# and so on) as they will fail if something goes wrong. diff --git a/examples/gatekeeper-auth/api/priv/static/favicon.ico b/examples/gatekeeper-auth/api/priv/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7f372bfc21cdd8cb47585339d5fa4d9dd424402f GIT binary patch literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=@t!V@Ar*{oFEH`~d50E!_s``s q?{G*w(7?#d#v@^nKnY_HKaYb01EZMZjMqTJ89ZJ6T-G@yGywoKK_h|y literal 0 HcmV?d00001 diff --git a/examples/gatekeeper-auth/api/priv/static/robots.txt b/examples/gatekeeper-auth/api/priv/static/robots.txt new file mode 100644 index 0000000000..26e06b5f19 --- /dev/null +++ b/examples/gatekeeper-auth/api/priv/static/robots.txt @@ -0,0 +1,5 @@ +# See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file +# +# To ban all spiders from the entire site uncomment the next two lines: +# User-agent: * +# Disallow: / diff --git a/examples/gatekeeper-auth/api/test/api_web/controllers/error_json_test.exs b/examples/gatekeeper-auth/api/test/api_web/controllers/error_json_test.exs new file mode 100644 index 0000000000..48bff72e4e --- /dev/null +++ b/examples/gatekeeper-auth/api/test/api_web/controllers/error_json_test.exs @@ -0,0 +1,12 @@ +defmodule ApiWeb.ErrorJSONTest do + use ApiWeb.ConnCase, async: true + + test "renders 404" do + assert ApiWeb.ErrorJSON.render("404.json", %{}) == %{errors: %{detail: "Not Found"}} + end + + test "renders 500" do + assert ApiWeb.ErrorJSON.render("500.json", %{}) == + %{errors: %{detail: "Internal Server Error"}} + end +end diff --git a/examples/gatekeeper-auth/api/test/support/conn_case.ex b/examples/gatekeeper-auth/api/test/support/conn_case.ex new file mode 100644 index 0000000000..28a2bf3446 --- /dev/null +++ b/examples/gatekeeper-auth/api/test/support/conn_case.ex @@ -0,0 +1,38 @@ +defmodule ApiWeb.ConnCase do + @moduledoc """ + This module defines the test case to be used by + tests that require setting up a connection. + + Such tests rely on `Phoenix.ConnTest` and also + import other functionality to make it easier + to build common data structures and query the data layer. + + Finally, if the test case interacts with the database, + we enable the SQL sandbox, so changes done to the database + are reverted at the end of every test. If you are using + PostgreSQL, you can even run database tests asynchronously + by setting `use ApiWeb.ConnCase, async: true`, although + this option is not recommended for other databases. + """ + + use ExUnit.CaseTemplate + + using do + quote do + # The default endpoint for testing + @endpoint ApiWeb.Endpoint + + use ApiWeb, :verified_routes + + # Import conveniences for testing with connections + import Plug.Conn + import Phoenix.ConnTest + import ApiWeb.ConnCase + end + end + + setup tags do + Api.DataCase.setup_sandbox(tags) + {:ok, conn: Phoenix.ConnTest.build_conn()} + end +end diff --git a/examples/gatekeeper-auth/api/test/support/data_case.ex b/examples/gatekeeper-auth/api/test/support/data_case.ex new file mode 100644 index 0000000000..33c80f20a9 --- /dev/null +++ b/examples/gatekeeper-auth/api/test/support/data_case.ex @@ -0,0 +1,58 @@ +defmodule Api.DataCase do + @moduledoc """ + This module defines the setup for tests requiring + access to the application's data layer. + + You may define functions here to be used as helpers in + your tests. + + Finally, if the test case interacts with the database, + we enable the SQL sandbox, so changes done to the database + are reverted at the end of every test. If you are using + PostgreSQL, you can even run database tests asynchronously + by setting `use Api.DataCase, async: true`, although + this option is not recommended for other databases. + """ + + use ExUnit.CaseTemplate + + using do + quote do + alias Api.Repo + + import Ecto + import Ecto.Changeset + import Ecto.Query + import Api.DataCase + end + end + + setup tags do + Api.DataCase.setup_sandbox(tags) + :ok + end + + @doc """ + Sets up the sandbox based on the test tags. + """ + def setup_sandbox(tags) do + pid = Ecto.Adapters.SQL.Sandbox.start_owner!(Api.Repo, shared: not tags[:async]) + on_exit(fn -> Ecto.Adapters.SQL.Sandbox.stop_owner(pid) end) + end + + @doc """ + A helper that transforms changeset errors into a map of messages. + + assert {:error, changeset} = Accounts.create_user(%{password: "short"}) + assert "password is too short" in errors_on(changeset).password + assert %{password: ["password is too short"]} = errors_on(changeset) + + """ + def errors_on(changeset) do + Ecto.Changeset.traverse_errors(changeset, fn {message, opts} -> + Regex.replace(~r"%{(\w+)}", message, fn _, key -> + opts |> Keyword.get(String.to_existing_atom(key), key) |> to_string() + end) + end) + end +end diff --git a/examples/gatekeeper-auth/api/test/test_helper.exs b/examples/gatekeeper-auth/api/test/test_helper.exs new file mode 100644 index 0000000000..bba7843009 --- /dev/null +++ b/examples/gatekeeper-auth/api/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +Ecto.Adapters.SQL.Sandbox.mode(Api.Repo, :manual) From e132e87e3b3a0fc9b31caf74ee79b944525ba5ba Mon Sep 17 00:00:00 2001 From: James Arthur Date: Mon, 11 Nov 2024 14:01:27 +0100 Subject: [PATCH 02/40] api: Elixir/Phoenix-based gatekeeper and proxy example. --- .../gatekeeper-auth/api/config/config.exs | 14 +-- examples/gatekeeper-auth/api/config/dev.exs | 50 +++------- .../gatekeeper-auth/api/config/runtime.exs | 83 +++++----------- examples/gatekeeper-auth/api/config/test.exs | 23 +++-- examples/gatekeeper-auth/api/lib/api.ex | 6 +- .../api/lib/api/application.ex | 20 ---- examples/gatekeeper-auth/api/lib/api/item.ex | 19 ++++ examples/gatekeeper-auth/api/lib/api/shape.ex | 39 ++++++++ examples/gatekeeper-auth/api/lib/api/token.ex | 30 ++++++ examples/gatekeeper-auth/api/lib/api_web.ex | 45 +++------ .../api/lib/api_web/authenticator.ex | 50 ++++++++++ .../api/lib/api_web/controllers/error_json.ex | 12 --- .../api_web/controllers/proxy_controller.ex | 38 ++++++++ .../api/lib/api_web/endpoint.ex | 39 +------- .../api/lib/api_web/plugs/assign_shape.ex | 38 ++++++++ .../api_web/plugs/auth/authenticate_user.ex | 16 +++ .../plugs/auth/authorise_shape_access.ex | 30 ++++++ .../lib/api_web/plugs/auth/verify_token.ex | 27 +++++ .../gatekeeper-auth/api/lib/api_web/router.ex | 36 ++++++- .../api/lib/api_web/telemetry.ex | 92 ------------------ examples/gatekeeper-auth/api/mix.exs | 26 ++--- examples/gatekeeper-auth/api/mix.lock | 11 +++ .../20241108150947_create_items.exs | 12 +++ .../api/priv/static/favicon.ico | Bin 152 -> 0 bytes .../api/priv/static/robots.txt | 5 - .../api/test/api_web/authenticator_test.exs | 32 ++++++ .../controllers/proxy_controller_test.exs | 49 ++++++++++ .../api/test/api_web/gatekeeper_test.exs | 61 ++++++++++++ .../api/test/api_web/integration_test.exs | 51 ++++++++++ .../api/test/support/conn_case.ex | 3 +- .../api/test/support/data_case.ex | 1 + 31 files changed, 621 insertions(+), 337 deletions(-) create mode 100644 examples/gatekeeper-auth/api/lib/api/item.ex create mode 100644 examples/gatekeeper-auth/api/lib/api/shape.ex create mode 100644 examples/gatekeeper-auth/api/lib/api/token.ex create mode 100644 examples/gatekeeper-auth/api/lib/api_web/authenticator.ex create mode 100644 examples/gatekeeper-auth/api/lib/api_web/controllers/proxy_controller.ex create mode 100644 examples/gatekeeper-auth/api/lib/api_web/plugs/assign_shape.ex create mode 100644 examples/gatekeeper-auth/api/lib/api_web/plugs/auth/authenticate_user.ex create mode 100644 examples/gatekeeper-auth/api/lib/api_web/plugs/auth/authorise_shape_access.ex create mode 100644 examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex delete mode 100644 examples/gatekeeper-auth/api/lib/api_web/telemetry.ex create mode 100644 examples/gatekeeper-auth/api/priv/repo/migrations/20241108150947_create_items.exs delete mode 100644 examples/gatekeeper-auth/api/priv/static/favicon.ico delete mode 100644 examples/gatekeeper-auth/api/priv/static/robots.txt create mode 100644 examples/gatekeeper-auth/api/test/api_web/authenticator_test.exs create mode 100644 examples/gatekeeper-auth/api/test/api_web/controllers/proxy_controller_test.exs create mode 100644 examples/gatekeeper-auth/api/test/api_web/gatekeeper_test.exs create mode 100644 examples/gatekeeper-auth/api/test/api_web/integration_test.exs diff --git a/examples/gatekeeper-auth/api/config/config.exs b/examples/gatekeeper-auth/api/config/config.exs index 5be3af4d06..549f98014e 100644 --- a/examples/gatekeeper-auth/api/config/config.exs +++ b/examples/gatekeeper-auth/api/config/config.exs @@ -1,33 +1,21 @@ -# This file is responsible for configuring your application -# and its dependencies with the aid of the Config module. -# -# This configuration file is loaded before any dependency and -# is restricted to this project. - -# General application configuration import Config config :api, ecto_repos: [Api.Repo], generators: [timestamp_type: :utc_datetime, binary_id: true] -# Configures the endpoint config :api, ApiWeb.Endpoint, url: [host: "localhost"], adapter: Bandit.PhoenixAdapter, render_errors: [ formats: [json: ApiWeb.ErrorJSON], layout: false - ], - pubsub_server: Api.PubSub, - live_view: [signing_salt: "M9e8NmwP"] + ] -# Configures Elixir's Logger config :logger, :console, format: "$time $metadata[$level] $message\n", metadata: [:request_id] -# Use Jason for JSON parsing in Phoenix config :phoenix, :json_library, Jason # Import environment specific config. This must remain at the bottom diff --git a/examples/gatekeeper-auth/api/config/dev.exs b/examples/gatekeeper-auth/api/config/dev.exs index 5166168173..99643d107a 100644 --- a/examples/gatekeeper-auth/api/config/dev.exs +++ b/examples/gatekeeper-auth/api/config/dev.exs @@ -1,5 +1,11 @@ import Config +config :api, + auth_token_secret: "hxRgQliCC7Ceo/ocTcKOJCYrVxsB5HjcZd1WF9qnbbNdEoju/YMfqNim0RHRWV1B", + # Configure the proxy endpoint to route shape requests to the external Electric + # sync service, which we assume in development is running on `localhost:3000`. + electric_url: "http://localhost:3000" + # Configure your database config :api, Api.Repo, username: "postgres", @@ -10,47 +16,19 @@ config :api, Api.Repo, show_sensitive_data_on_connection_error: true, pool_size: 10 -# For development, we disable any cache and enable -# debugging and code reloading. -# -# The watchers configuration can be used to run external -# watchers to your application. For example, we can use it -# to bundle .js and .css sources. +port = 4000 + config :api, ApiWeb.Endpoint, # Binding to loopback ipv4 address prevents access from other machines. # Change to `ip: {0, 0, 0, 0}` to allow access from other machines. - http: [ip: {127, 0, 0, 1}, port: 4000], + http: [ip: {127, 0, 0, 1}, port: port], check_origin: false, - code_reloader: true, debug_errors: true, - secret_key_base: "pVvBh/U565dk0DteMtnoCjwLcoZnMDU9QeQNVr0gvVtYUrF8KqoJeyn5YJ0EQudX", - watchers: [] - -# ## SSL Support -# -# In order to use HTTPS in development, a self-signed -# certificate can be generated by running the following -# Mix task: -# -# mix phx.gen.cert -# -# Run `mix help phx.gen.cert` for more information. -# -# The `http:` config above can be replaced with: -# -# https: [ -# port: 4001, -# cipher_suite: :strong, -# keyfile: "priv/cert/selfsigned_key.pem", -# certfile: "priv/cert/selfsigned.pem" -# ], -# -# If desired, both `http:` and `https:` keys can be -# configured to run both http and https servers on -# different ports. - -# Enable dev routes for dashboard and mailbox -config :api, dev_routes: true + secret_key_base: "pVvBh/U565dk0DteMtnoCjwLcoZnMDU9QeQNVr0gvVtYUrF8KqoJeyn5YJ0EQudX" + +# Configure the Electric.Phoenix.Gateway.Plug to route electric client requests +# via this application's `GET /proxy/v1/shape` endpoint. +config :electric_phoenix, electric_url: "http://localhost:#{port}/proxy" # Do not include metadata nor timestamps in development logs config :logger, :console, format: "[$level] $message\n" diff --git a/examples/gatekeeper-auth/api/config/runtime.exs b/examples/gatekeeper-auth/api/config/runtime.exs index 1e8292646e..201e8f0945 100644 --- a/examples/gatekeeper-auth/api/config/runtime.exs +++ b/examples/gatekeeper-auth/api/config/runtime.exs @@ -1,26 +1,30 @@ import Config -# config/runtime.exs is executed for all environments, including -# during releases. It is executed after compilation and before the -# system starts, so it is typically used to load production configuration -# and secrets from environment variables or elsewhere. Do not define -# any compile-time configuration in here, as it won't be applied. -# The block below contains prod specific runtime configuration. - -# ## Using releases -# -# If you use `mix release`, you need to explicitly enable the server -# by passing the PHX_SERVER=true when you start it: -# -# PHX_SERVER=true bin/api start -# -# Alternatively, you can use `mix phx.gen.release` to generate a `bin/server` -# script that automatically sets the env var above. if System.get_env("PHX_SERVER") do config :api, ApiWeb.Endpoint, server: true end if config_env() == :prod do + auth_token_secret = + System.get_env("AUTH_TOKEN_SECRET") || + raise """ + environment variable AUTH_TOKEN_SECRET is missing. + It should be a long random string. + """ + + electric_url = + System.get_env("ELECTRIC_URL") || + raise """ + environment variable ELECTRIC_URL is missing. + For example: https://my-electric.example.com + """ + + # Configure the proxy endpoint to route shape requests to the external + # Electric sync service. + config :api, + auth_token_secret: auth_token_secret, + electric_url: electric_url + database_url = System.get_env("DATABASE_URL") || raise """ @@ -36,11 +40,6 @@ if config_env() == :prod do pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"), socket_options: maybe_ipv6 - # The secret key base is used to sign/encrypt cookies and other secrets. - # A default value is used in config/dev.exs and config/test.exs but you - # want to use a different value for prod and you most likely don't want - # to check this value into version control, so we use an environment - # variable instead. secret_key_base = System.get_env("SECRET_KEY_BASE") || raise """ @@ -49,12 +48,10 @@ if config_env() == :prod do """ host = System.get_env("PHX_HOST") || "example.com" - port = String.to_integer(System.get_env("PORT") || "4000") - - config :api, :dns_cluster_query, System.get_env("DNS_CLUSTER_QUERY") + port = System.get_env("PHX_PORT") || 443 config :api, ApiWeb.Endpoint, - url: [host: host, port: 443, scheme: "https"], + url: [host: host, port: port, scheme: "https"], http: [ # Enable IPv6 and bind on all interfaces. # Set it to {0, 0, 0, 0, 0, 0, 0, 1} for local network only access. @@ -65,35 +62,9 @@ if config_env() == :prod do ], secret_key_base: secret_key_base - # ## SSL Support - # - # To get SSL working, you will need to add the `https` key - # to your endpoint configuration: - # - # config :api, ApiWeb.Endpoint, - # https: [ - # ..., - # port: 443, - # cipher_suite: :strong, - # keyfile: System.get_env("SOME_APP_SSL_KEY_PATH"), - # certfile: System.get_env("SOME_APP_SSL_CERT_PATH") - # ] - # - # The `cipher_suite` is set to `:strong` to support only the - # latest and more secure SSL ciphers. This means old browsers - # and clients may not be supported. You can set it to - # `:compatible` for wider support. - # - # `:keyfile` and `:certfile` expect an absolute path to the key - # and cert in disk or a relative path inside priv, for example - # "priv/ssl/server.key". For all supported SSL configuration - # options, see https://hexdocs.pm/plug/Plug.SSL.html#configure/1 - # - # We also recommend setting `force_ssl` in your config/prod.exs, - # ensuring no data is ever sent via http, always redirecting to https: - # - # config :api, ApiWeb.Endpoint, - # force_ssl: [hsts: true] - # - # Check `Plug.SSL` for all available options in `force_ssl`. + # Configure Electric.Phoenix to route electric shape requests via + # this API, specifically the `/proxy` endpoint configured in + # `../lib/api_web/router.ex`. + config :electric_phoenix, + electric_url: URI.parse("https://#{host}:#{port}/proxy") |> URI.to_string() end diff --git a/examples/gatekeeper-auth/api/config/test.exs b/examples/gatekeeper-auth/api/config/test.exs index eff6f8273e..b33e7a4a4e 100644 --- a/examples/gatekeeper-auth/api/config/test.exs +++ b/examples/gatekeeper-auth/api/config/test.exs @@ -1,25 +1,34 @@ import Config +# Configure the proxy endpoint to route shape requests to the external Electric +# sync service, which we assume in test is running on `localhost:3002`. +config :api, + auth_token_secret: "DY1vSZb/BL1WgLyFq5A1d1FkmzoSMaRhXcBUL41mqciKLRSSSK6AO2hTCQmDyQj4", + electric_url: "http://localhost:3000" + # Configure your database -# -# The MIX_TEST_PARTITION environment variable can be used -# to provide built-in test partitioning in CI environment. -# Run `mix help test` for more information. config :api, Api.Repo, username: "postgres", - password: "postgres", + password: "password", hostname: "localhost", - database: "api_test#{System.get_env("MIX_TEST_PARTITION")}", + port: 54321, + database: "electric", pool: Ecto.Adapters.SQL.Sandbox, pool_size: System.schedulers_online() * 2 +port = 4002 + # We don't run a server during test. If one is required, # you can enable the server option below. config :api, ApiWeb.Endpoint, - http: [ip: {127, 0, 0, 1}, port: 4002], + http: [ip: {127, 0, 0, 1}, port: port], secret_key_base: "FdsTo+z4sPEhsQNsUtBq26K9qn42nkn1OCH2cLURBZkPCvgJ4F3WiVNFo1NVjojw", server: false +# Configure the Electric.Phoenix.Gateway.Plug to route electric client requests +# via this application's `GET /proxy/v1/shape` endpoint. +config :electric_phoenix, electric_url: "http://localhost:#{port}/proxy" + # Print only warnings and errors during test config :logger, level: :warning diff --git a/examples/gatekeeper-auth/api/lib/api.ex b/examples/gatekeeper-auth/api/lib/api.ex index d09be70aa6..64618a0e65 100644 --- a/examples/gatekeeper-auth/api/lib/api.ex +++ b/examples/gatekeeper-auth/api/lib/api.ex @@ -1,9 +1,5 @@ defmodule Api do @moduledoc """ - Api keeps the contexts that define your domain - and business logic. - - Contexts are also responsible for managing your data, regardless - if it comes from the database, an external API or others. + Api keeps the contexts that define your domain and business logic. """ end diff --git a/examples/gatekeeper-auth/api/lib/api/application.ex b/examples/gatekeeper-auth/api/lib/api/application.ex index f1adfc4390..4fb2dfa194 100644 --- a/examples/gatekeeper-auth/api/lib/api/application.ex +++ b/examples/gatekeeper-auth/api/lib/api/application.ex @@ -1,34 +1,14 @@ defmodule Api.Application do - # See https://hexdocs.pm/elixir/Application.html - # for more information on OTP Applications - @moduledoc false - use Application @impl true def start(_type, _args) do children = [ - ApiWeb.Telemetry, Api.Repo, - {DNSCluster, query: Application.get_env(:api, :dns_cluster_query) || :ignore}, - {Phoenix.PubSub, name: Api.PubSub}, - # Start a worker by calling: Api.Worker.start_link(arg) - # {Api.Worker, arg}, - # Start to serve requests, typically the last entry ApiWeb.Endpoint ] - # See https://hexdocs.pm/elixir/Supervisor.html - # for other strategies and supported options opts = [strategy: :one_for_one, name: Api.Supervisor] Supervisor.start_link(children, opts) end - - # Tell Phoenix to update the endpoint configuration - # whenever the application is updated. - @impl true - def config_change(changed, _new, removed) do - ApiWeb.Endpoint.config_change(changed, removed) - :ok - end end diff --git a/examples/gatekeeper-auth/api/lib/api/item.ex b/examples/gatekeeper-auth/api/lib/api/item.ex new file mode 100644 index 0000000000..7d9d5c3ff6 --- /dev/null +++ b/examples/gatekeeper-auth/api/lib/api/item.ex @@ -0,0 +1,19 @@ +defmodule Api.Item do + use Ecto.Schema + import Ecto.Changeset + + @primary_key {:id, :binary_id, autogenerate: true} + @foreign_key_type :binary_id + schema "items" do + field :value, :string + + timestamps(type: :utc_datetime) + end + + @doc false + def changeset(item, attrs) do + item + |> cast(attrs, [:value]) + |> validate_required([:value]) + end +end diff --git a/examples/gatekeeper-auth/api/lib/api/shape.ex b/examples/gatekeeper-auth/api/lib/api/shape.ex new file mode 100644 index 0000000000..96fe077b43 --- /dev/null +++ b/examples/gatekeeper-auth/api/lib/api/shape.ex @@ -0,0 +1,39 @@ +defmodule Api.Shape do + require Protocol + + alias Electric.Client.ShapeDefinition + + @public_fields [:namespace, :table, :where, :columns] + + Protocol.derive(Jason.Encoder, ShapeDefinition, only: @public_fields) + + # Compare the `shape` derived from the request params with the shape + # params signed in the auth token. Does the auth token allows access + # to this shape? + def matches(%ShapeDefinition{} = request_shape, %ShapeDefinition{} = token_shape) do + with ^token_shape <- request_shape do + true + else + _alt -> + false + end + end + + # Generate a `%ShapeDefinition{}` from a string keyed Map of `params`. + def from(params) do + with {table, other} when not is_nil(table) <- Map.pop(params, "table"), + options <- Enum.reduce(other, [], &put/2) do + ShapeDefinition.new(table, options) + end + end + + defp put({k, v}, opts) when is_binary(k) do + put({String.to_existing_atom(k), v}, opts) + end + + defp put({k, v}, opts) when k in @public_fields do + Keyword.put(opts, k, v) + end + + defp put(_, opts), do: opts +end diff --git a/examples/gatekeeper-auth/api/lib/api/token.ex b/examples/gatekeeper-auth/api/lib/api/token.ex new file mode 100644 index 0000000000..cc9d8a2a4d --- /dev/null +++ b/examples/gatekeeper-auth/api/lib/api/token.ex @@ -0,0 +1,30 @@ +defmodule Api.Token do + @moduledoc """ + Generate and validate JWT Tokens. + """ + alias Api.Shape + alias Electric.Client.ShapeDefinition + + defmodule JWT do + use Joken.Config + + def signer do + secret = Application.fetch_env!(:api, :auth_token_secret) + + Joken.Signer.create("HS256", secret) + end + end + + def generate(%ShapeDefinition{} = shape) do + {:ok, token, _claims} = JWT.generate_and_sign(%{shape: shape}, JWT.signer()) + + token + end + + def verify(%ShapeDefinition{} = request_shape, token) do + with {:ok, %{"shape" => token_params}} <- JWT.verify_and_validate(token, JWT.signer()), + {:ok, token_shape} <- Shape.from(token_params) do + Shape.matches(request_shape, token_shape) + end + end +end diff --git a/examples/gatekeeper-auth/api/lib/api_web.ex b/examples/gatekeeper-auth/api/lib/api_web.ex index 2ed5a849d8..bcb5d6ff1d 100644 --- a/examples/gatekeeper-auth/api/lib/api_web.ex +++ b/examples/gatekeeper-auth/api/lib/api_web.ex @@ -6,53 +6,38 @@ defmodule ApiWeb do This can be used in your application as: use ApiWeb, :controller - use ApiWeb, :html - - The definitions below will be executed for every controller, - component, etc, so keep them short and clean, focused - on imports, uses and aliases. - - Do NOT define functions inside the quoted expressions - below. Instead, define additional modules and import - those modules here. """ - def static_paths, do: ~w(assets fonts images favicon.ico robots.txt) - - def router do + def controller do quote do - use Phoenix.Router, helpers: false + use Phoenix.Controller, formats: [:json] - # Import common connection and controller functions to use in pipelines import Plug.Conn - import Phoenix.Controller end end - def channel do + def plug do quote do - use Phoenix.Channel + import Plug.Conn + + alias Api.Shape + alias ApiWeb.Authenticator + alias Electric.Client.ShapeDefinition end end - def controller do + def router do quote do - use Phoenix.Controller, - formats: [:html, :json], - layouts: [html: ApiWeb.Layouts] + use Phoenix.Router, helpers: false import Plug.Conn + import Phoenix.Controller - unquote(verified_routes()) - end - end + alias ApiWeb.Authenticator + alias ApiWeb.Plugs.AssignShape + alias ApiWeb.Plugs.Auth - def verified_routes do - quote do - use Phoenix.VerifiedRoutes, - endpoint: ApiWeb.Endpoint, - router: ApiWeb.Router, - statics: ApiWeb.static_paths() + alias Electric.Phoenix.Gateway end end diff --git a/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex b/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex new file mode 100644 index 0000000000..169164c5f5 --- /dev/null +++ b/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex @@ -0,0 +1,50 @@ +defmodule ApiWeb.Authenticator do + @moduledoc """ + `Electric.Client.Authenticator` implementation that generates + and validates tokens. + """ + alias Api.Token + alias Electric.Client + + @behaviour Client.Authenticator + @header "api-auth" + + def authenticate_shape(shape, _config) do + %{@header => Token.generate(shape)} + end + + def authenticate_request(request, _config) do + request + end + + def authorise(shape, headers) do + with {:ok, token} <- Map.fetch(headers, @header) do + Token.verify(shape, token) + end + end + + @doc """ + Provides an `Electric.Client` that uses our `Authenticator` + implementation to generate signed auth tokens. + + This is configured in `./router.ex` to work with the + `Electric.Phoenix.Gateway.Plug`: + + post "/:table", Gateway.Plug, client: &Gatekeeper.client/0 + + Because `client/0` returns a client that's configured to use our + `ApiWeb.Authenticator`, then `ApiWeb.Authenticator.authenticate_shape/2` + will be called to generate an auth header that's included in the + response data that the Gateway.Plug returns to the client. + + I.e.: we basically tie into the `Gateway.Plug` machinery to use our + `Authenticator` to generate and return a signed token to the client. + """ + def client do + base_url = Application.fetch_env!(:electric_phoenix, :electric_url) + + {:ok, client} = Client.new(base_url: base_url, authenticator: {__MODULE__, []}) + + client + end +end diff --git a/examples/gatekeeper-auth/api/lib/api_web/controllers/error_json.ex b/examples/gatekeeper-auth/api/lib/api_web/controllers/error_json.ex index 00015e5b1c..dcd97a7a5b 100644 --- a/examples/gatekeeper-auth/api/lib/api_web/controllers/error_json.ex +++ b/examples/gatekeeper-auth/api/lib/api_web/controllers/error_json.ex @@ -1,20 +1,8 @@ defmodule ApiWeb.ErrorJSON do @moduledoc """ This module is invoked by your endpoint in case of errors on JSON requests. - - See config/config.exs. """ - # If you want to customize a particular status code, - # you may add your own clauses, such as: - # - # def render("500.json", _assigns) do - # %{errors: %{detail: "Internal Server Error"}} - # end - - # By default, Phoenix returns the status message from - # the template name. For example, "404.json" becomes - # "Not Found". def render(template, _assigns) do %{errors: %{detail: Phoenix.Controller.status_message_from_template(template)}} end diff --git a/examples/gatekeeper-auth/api/lib/api_web/controllers/proxy_controller.ex b/examples/gatekeeper-auth/api/lib/api_web/controllers/proxy_controller.ex new file mode 100644 index 0000000000..b6ddfc2c5c --- /dev/null +++ b/examples/gatekeeper-auth/api/lib/api_web/controllers/proxy_controller.ex @@ -0,0 +1,38 @@ +defmodule ApiWeb.ProxyController do + use ApiWeb, :controller + + # Handles `GET /proxy/v1/shape` by proxying the request to Electric. + # Uses the `Req` HTTP client to stream the body through. + def show(conn, _params) do + %{status: status, headers: headers, body: stream} = proxy_request(conn) + + conn + |> clone_headers(headers) + |> stream_response(status, stream) + end + + defp proxy_request(%{req_headers: headers} = conn) do + conn + |> build_url() + |> Req.get!(headers: headers, into: :self) + end + + defp build_url(%{path_info: [_prefix | segments], query_string: query}) do + electric_url = Application.fetch_env!(:api, :electric_url) + + "#{electric_url}/#{Path.join(segments)}?#{query}" + end + + defp clone_headers(conn, headers) do + headers + |> Enum.reduce(conn, fn {k, [v]}, acc -> put_resp_header(acc, k, v) end) + end + + defp stream_response(conn, status, body) do + conn = send_chunked(conn, status) + + Enum.reduce(body, conn, fn chunk, conn -> + with {:ok, conn} <- chunk(conn, chunk), do: conn + end) + end +end diff --git a/examples/gatekeeper-auth/api/lib/api_web/endpoint.ex b/examples/gatekeeper-auth/api/lib/api_web/endpoint.ex index d005df7198..557926a2ff 100644 --- a/examples/gatekeeper-auth/api/lib/api_web/endpoint.ex +++ b/examples/gatekeeper-auth/api/lib/api_web/endpoint.ex @@ -1,47 +1,10 @@ defmodule ApiWeb.Endpoint do use Phoenix.Endpoint, otp_app: :api - # 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: "_api_key", - signing_salt: "wk5SPjwd", - same_site: "Lax" - ] - - # socket "/live", Phoenix.LiveView.Socket, - # websocket: [connect_info: [session: @session_options]], - # longpoll: [connect_info: [session: @session_options]] - - # Serve at "/" the static files from "priv/static" directory. - # - # You should set gzip to true if you are running phx.digest - # when deploying your static files in production. - plug Plug.Static, - at: "/", - from: :api, - gzip: false, - only: ApiWeb.static_paths() - - # Code reloading can be explicitly enabled under the - # :code_reloader configuration of your endpoint. - if code_reloading? do - plug Phoenix.CodeReloader - plug Phoenix.Ecto.CheckRepoStatus, otp_app: :api - end - - plug Plug.RequestId - plug Plug.Telemetry, event_prefix: [:phoenix, :endpoint] - plug Plug.Parsers, - parsers: [:urlencoded, :multipart, :json], + parsers: [:json], pass: ["*/*"], json_decoder: Phoenix.json_library() - plug Plug.MethodOverride - plug Plug.Head - plug Plug.Session, @session_options plug ApiWeb.Router end diff --git a/examples/gatekeeper-auth/api/lib/api_web/plugs/assign_shape.ex b/examples/gatekeeper-auth/api/lib/api_web/plugs/assign_shape.ex new file mode 100644 index 0000000000..f179ee0963 --- /dev/null +++ b/examples/gatekeeper-auth/api/lib/api_web/plugs/assign_shape.ex @@ -0,0 +1,38 @@ +defmodule ApiWeb.Plugs.AssignShape do + @moduledoc """ + This plug builds a shape definition from the request parameters and + assigns it to the conn. + """ + use ApiWeb, :plug + + def init(opts), do: opts + + # If you pass `table_from_path: true` as an option, then it reads the + # tablename from the path. This is useful for using hardcoded paths to + # specific shapes with `Gateway.Plug`, e.g.; + # + # post "/items", Gateway.Plug, shape: Electric.Client.shape!("items") + # + def call(%{params: params} = conn, [{:table_from_path, true} | opts]) do + table_name = Enum.at(conn.path_info, -1) + + params = Map.put(params, "table", table_name) + + conn + |> Map.put(:params, params) + |> call(opts) + end + + def call(%{params: params} = conn, _opts) do + case Shape.from(params) do + {:ok, shape} -> + conn + |> assign(:shape, shape) + + _alt -> + conn + |> send_resp(400, "Invalid") + |> halt() + end + end +end diff --git a/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/authenticate_user.ex b/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/authenticate_user.ex new file mode 100644 index 0000000000..6b3be189a9 --- /dev/null +++ b/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/authenticate_user.ex @@ -0,0 +1,16 @@ +defmodule ApiWeb.Plugs.Auth.AuthenticateUser do + @moduledoc """ + This plug is a no-op that just assigns a dummy user. + + In a real application, you would use this step to authenticate the user + based on some credentials and assign the real user to the conn. + """ + use ApiWeb, :plug + + def init(opts), do: opts + + def call(conn, _opts) do + conn + |> assign(:current_user, :dummy) + end +end diff --git a/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/authorise_shape_access.ex b/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/authorise_shape_access.ex new file mode 100644 index 0000000000..1297fe08bb --- /dev/null +++ b/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/authorise_shape_access.ex @@ -0,0 +1,30 @@ +defmodule ApiWeb.Plugs.Auth.AuthoriseShapeAccess do + @moduledoc """ + This plug allows the dummy user to access any shape. + + In a real application, you would use this step to validate that the + `user` has the right to access the `shape`. For example, you could + perform a database lookup or call out to an external auth service. + """ + use ApiWeb, :plug + + def init(opts), do: opts + + def call(%{assigns: %{current_user: user, shape: shape}} = conn, _opts) do + case is_authorised(user, shape) do + true -> + conn + + false -> + conn + |> send_resp(403, "Forbidden") + |> halt() + end + end + + defp is_authorised(:dummy, %ShapeDefinition{}) do + true + end + + defp is_authorised(_, _), do: false +end diff --git a/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex b/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex new file mode 100644 index 0000000000..1b47411089 --- /dev/null +++ b/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex @@ -0,0 +1,27 @@ +defmodule ApiWeb.Plugs.Auth.VerifyToken do + @moduledoc """ + Verify that the token matches the shape. We do this by comparing the + the shape defined in the request query params with the shape signed + into the auth token claims. + + So you can't proxy a shape request without having a signed token for that + exact shape definition. + """ + use ApiWeb, :plug + + def init(opts), do: opts + + def call(%{assigns: %{shape: shape}, req_headers: header_list} = conn, _opts) do + headers = Enum.into(header_list, %{}) + + case Authenticator.authorise(shape, headers) do + true -> + conn + + _alt -> + conn + |> send_resp(403, "Forbidden") + |> halt() + end + end +end diff --git a/examples/gatekeeper-auth/api/lib/api_web/router.ex b/examples/gatekeeper-auth/api/lib/api_web/router.ex index 75a469e235..7d6c62c8e2 100644 --- a/examples/gatekeeper-auth/api/lib/api_web/router.ex +++ b/examples/gatekeeper-auth/api/lib/api_web/router.ex @@ -5,7 +5,41 @@ defmodule ApiWeb.Router do plug :accepts, ["json"] end - scope "/api", ApiWeb do + pipeline :gatekeeper do + plug AssignShape + + plug Auth.AuthenticateUser + plug Auth.AuthoriseShapeAccess + end + + pipeline :proxy do + plug AssignShape + + plug Auth.VerifyToken + end + + scope "/" do pipe_through :api + + # The gatekeeper endpoint at `POST /gatekeeper/:table` authenticates the user, + # authorises the shape access, generates a shape-scoped auth token and returns + # this along with other config that the Electric client can use to stream the + # shape directly from Electric. + scope "/gatekeeper" do + pipe_through :gatekeeper + + post "/:table", Gateway.Plug, client: &Authenticator.client/0 + end + + # The proxy endpoint at `GET /proxy/v1/shape` proxies the request to the + # external Electric service. + # + # Access to this endpoint is protected by the `:proxy` pipeline, which verifies + # a shape signed token, generated by the gatekeeper endpoint above. + scope "/proxy", ApiWeb do + pipe_through :proxy + + get "/v1/shape", ProxyController, :show + end end end diff --git a/examples/gatekeeper-auth/api/lib/api_web/telemetry.ex b/examples/gatekeeper-auth/api/lib/api_web/telemetry.ex deleted file mode 100644 index e94763fa36..0000000000 --- a/examples/gatekeeper-auth/api/lib/api_web/telemetry.ex +++ /dev/null @@ -1,92 +0,0 @@ -defmodule ApiWeb.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 will execute the given period measurements - # every 10_000ms. Learn more here: https://hexdocs.pm/telemetry_metrics - {: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.start.system_time", - unit: {:native, :millisecond} - ), - summary("phoenix.endpoint.stop.duration", - unit: {:native, :millisecond} - ), - summary("phoenix.router_dispatch.start.system_time", - tags: [:route], - unit: {:native, :millisecond} - ), - summary("phoenix.router_dispatch.exception.duration", - tags: [:route], - unit: {:native, :millisecond} - ), - summary("phoenix.router_dispatch.stop.duration", - tags: [:route], - unit: {:native, :millisecond} - ), - summary("phoenix.socket_connected.duration", - unit: {:native, :millisecond} - ), - summary("phoenix.channel_joined.duration", - unit: {:native, :millisecond} - ), - summary("phoenix.channel_handled_in.duration", - tags: [:event], - unit: {:native, :millisecond} - ), - - # Database Metrics - summary("api.repo.query.total_time", - unit: {:native, :millisecond}, - description: "The sum of the other measurements" - ), - summary("api.repo.query.decode_time", - unit: {:native, :millisecond}, - description: "The time spent decoding the data received from the database" - ), - summary("api.repo.query.query_time", - unit: {:native, :millisecond}, - description: "The time spent executing the query" - ), - summary("api.repo.query.queue_time", - unit: {:native, :millisecond}, - description: "The time spent waiting for a database connection" - ), - summary("api.repo.query.idle_time", - unit: {:native, :millisecond}, - description: - "The time the connection spent waiting before being checked out for the query" - ), - - # 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. - # {ApiWeb, :count_users, []} - ] - end -end diff --git a/examples/gatekeeper-auth/api/mix.exs b/examples/gatekeeper-auth/api/mix.exs index e0e101748b..3ad6a18e8e 100644 --- a/examples/gatekeeper-auth/api/mix.exs +++ b/examples/gatekeeper-auth/api/mix.exs @@ -13,9 +13,6 @@ defmodule Api.MixProject do ] end - # Configuration for the OTP application. - # - # Type `mix help compile.app` for more information. def application do [ mod: {Api.Application, []}, @@ -23,33 +20,22 @@ defmodule Api.MixProject do ] end - # Specifies which paths to compile per environment. defp elixirc_paths(:test), do: ["lib", "test/support"] defp elixirc_paths(_), do: ["lib"] - # Specifies your project dependencies. - # - # Type `mix help deps` for examples and options. defp deps do [ + {:bandit, "~> 1.5"}, + {:electric_phoenix, "~> 0.1.2"}, + {:ecto_sql, "~> 3.10"}, + {:jason, "~> 1.4"}, + {:joken, "~> 2.6"}, {:phoenix, "~> 1.7.14"}, {:phoenix_ecto, "~> 4.5"}, - {:ecto_sql, "~> 3.10"}, - {:postgrex, ">= 0.0.0"}, - {:telemetry_metrics, "~> 1.0"}, - {:telemetry_poller, "~> 1.0"}, - {:jason, "~> 1.2"}, - {:dns_cluster, "~> 0.1.1"}, - {:bandit, "~> 1.5"} + {:postgrex, ">= 0.0.0"} ] end - # Aliases are shortcuts or tasks specific to the current project. - # For example, to install project dependencies and perform other setup tasks, run: - # - # $ mix setup - # - # See the documentation for `Mix` for more info on aliases. defp aliases do [ setup: ["deps.get", "ecto.setup"], diff --git a/examples/gatekeeper-auth/api/mix.lock b/examples/gatekeeper-auth/api/mix.lock index 7ad3f35d77..9cc68e5760 100644 --- a/examples/gatekeeper-auth/api/mix.lock +++ b/examples/gatekeeper-auth/api/mix.lock @@ -6,16 +6,27 @@ "dns_cluster": {:hex, :dns_cluster, "0.1.3", "0bc20a2c88ed6cc494f2964075c359f8c2d00e1bf25518a6a6c7fd277c9b0c66", [:mix], [], "hexpm", "46cb7c4a1b3e52c7ad4cbe33ca5079fbde4840dedeafca2baf77996c2da1bc33"}, "ecto": {:hex, :ecto, "3.12.4", "267c94d9f2969e6acc4dd5e3e3af5b05cdae89a4d549925f3008b2b7eb0b93c3", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ef04e4101688a67d061e1b10d7bc1fbf00d1d13c17eef08b71d070ff9188f747"}, "ecto_sql": {:hex, :ecto_sql, "3.12.1", "c0d0d60e85d9ff4631f12bafa454bc392ce8b9ec83531a412c12a0d415a3a4d0", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.12", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "aff5b958a899762c5f09028c847569f7dfb9cc9d63bdb8133bff8a5546de6bf5"}, + "electric_client": {:hex, :electric_client, "0.1.2", "1b4b2c3f53a44adaf98a648da21569325338a123ec8f00b7d26c6e3c3583ac94", [:mix], [{:ecto_sql, "~> 3.12", [hex: :ecto_sql, repo: "hexpm", optional: true]}, {:gen_stage, "~> 1.2", [hex: :gen_stage, repo: "hexpm", optional: true]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:nimble_options, "~> 1.1", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}], "hexpm", "fde191b8ce7c70c44ef12a821210699222ceba1951f73c3c4e7cff8c1d5c0294"}, + "electric_phoenix": {:hex, :electric_phoenix, "0.1.2", "a6228e95e6fa03591307dc34514ba9baf365878efbbfbd78d0312b3b6898bb06", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: true]}, {:electric_client, "~> 0.1.2", [hex: :electric_client, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:nimble_options, "~> 1.1", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.20", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "5d88ae053e8035335e6c6d779cc29c3228b71c02d4268e7e959cffff63debd04"}, + "finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"}, "hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, + "joken": {:hex, :joken, "2.6.2", "5daaf82259ca603af4f0b065475099ada1b2b849ff140ccd37f4b6828ca6892a", [:mix], [{:jose, "~> 1.11.10", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "5134b5b0a6e37494e46dbf9e4dad53808e5e787904b7c73972651b51cce3d72b"}, + "jose": {:hex, :jose, "1.11.10", "a903f5227417bd2a08c8a00a0cbcc458118be84480955e8d251297a425723f83", [:mix, :rebar3], [], "hexpm", "0d6cd36ff8ba174db29148fc112b5842186b68a90ce9fc2b3ec3afe76593e614"}, "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, + "mint": {:hex, :mint, "1.6.2", "af6d97a4051eee4f05b5500671d47c3a67dac7386045d87a904126fd4bbcea2e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5ee441dffc1892f1ae59127f74afe8fd82fda6587794278d924e4d90ea3d63f9"}, + "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, + "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "phoenix": {:hex, :phoenix, "1.7.14", "a7d0b3f1bc95987044ddada111e77bd7f75646a08518942c72a8440278ae7825", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "c7859bc56cc5dfef19ecfc240775dae358cbaa530231118a9e014df392ace61a"}, "phoenix_ecto": {:hex, :phoenix_ecto, "4.6.3", "f686701b0499a07f2e3b122d84d52ff8a31f5def386e03706c916f6feddf69ef", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.1", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "909502956916a657a197f94cc1206d9a65247538de8a5e186f7537c895d95764"}, + "phoenix_html": {:hex, :phoenix_html, "4.1.1", "4c064fd3873d12ebb1388425a8f2a19348cef56e7289e1998e2d2fa758aa982e", [:mix], [], "hexpm", "f2f2df5a72bc9a2f510b21497fd7d2b86d932ec0598f0210fed4114adc546c6f"}, + "phoenix_live_view": {:hex, :phoenix_live_view, "0.20.17", "f396bbdaf4ba227b82251eb75ac0afa6b3da5e509bc0d030206374237dfc9450", [:mix], [{:floki, "~> 0.36", [hex: :floki, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a61d741ffb78c85fdbca0de084da6a48f8ceb5261a79165b5a0b59e5f65ce98b"}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.3", "3168d78ba41835aecad272d5e8cd51aa87a7ac9eb836eabc42f6e57538e3731d", [:mix], [], "hexpm", "bba06bc1dcfd8cb086759f0edc94a8ba2bc8896d5331a1e2c2902bf8e36ee502"}, "phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"}, "plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"}, "plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"}, "postgrex": {:hex, :postgrex, "0.19.2", "34d6884a332c7bf1e367fc8b9a849d23b43f7da5c6e263def92784d03f9da468", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "618988886ab7ae8561ebed9a3c7469034bf6a88b8995785a3378746a4b9835ec"}, + "req": {:hex, :req, "0.5.7", "b722680e03d531a2947282adff474362a48a02aa54b131196fbf7acaff5e4cee", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "c6035374615120a8923e8089d0c21a3496cf9eda2d287b806081b8f323ceee29"}, "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, "telemetry_metrics": {:hex, :telemetry_metrics, "1.0.0", "29f5f84991ca98b8eb02fc208b2e6de7c95f8bb2294ef244a176675adc7775df", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f23713b3847286a534e005126d4c959ebcca68ae9582118ce436b521d1d47d5d"}, "telemetry_poller": {:hex, :telemetry_poller, "1.1.0", "58fa7c216257291caaf8d05678c8d01bd45f4bdbc1286838a28c4bb62ef32999", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9eb9d9cbfd81cbd7cdd24682f8711b6e2b691289a0de6826e58452f28c103c8f"}, diff --git a/examples/gatekeeper-auth/api/priv/repo/migrations/20241108150947_create_items.exs b/examples/gatekeeper-auth/api/priv/repo/migrations/20241108150947_create_items.exs new file mode 100644 index 0000000000..303f4b63d9 --- /dev/null +++ b/examples/gatekeeper-auth/api/priv/repo/migrations/20241108150947_create_items.exs @@ -0,0 +1,12 @@ +defmodule Api.Repo.Migrations.CreateItems do + use Ecto.Migration + + def change do + create table(:items, primary_key: false) do + add :id, :binary_id, primary_key: true + add :value, :string + + timestamps(type: :utc_datetime) + end + end +end diff --git a/examples/gatekeeper-auth/api/priv/static/favicon.ico b/examples/gatekeeper-auth/api/priv/static/favicon.ico deleted file mode 100644 index 7f372bfc21cdd8cb47585339d5fa4d9dd424402f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=@t!V@Ar*{oFEH`~d50E!_s``s q?{G*w(7?#d#v@^nKnY_HKaYb01EZMZjMqTJ89ZJ6T-G@yGywoKK_h|y diff --git a/examples/gatekeeper-auth/api/priv/static/robots.txt b/examples/gatekeeper-auth/api/priv/static/robots.txt deleted file mode 100644 index 26e06b5f19..0000000000 --- a/examples/gatekeeper-auth/api/priv/static/robots.txt +++ /dev/null @@ -1,5 +0,0 @@ -# See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file -# -# To ban all spiders from the entire site uncomment the next two lines: -# User-agent: * -# Disallow: / diff --git a/examples/gatekeeper-auth/api/test/api_web/authenticator_test.exs b/examples/gatekeeper-auth/api/test/api_web/authenticator_test.exs new file mode 100644 index 0000000000..aa03b98ec9 --- /dev/null +++ b/examples/gatekeeper-auth/api/test/api_web/authenticator_test.exs @@ -0,0 +1,32 @@ +defmodule ApiWeb.AuthenticatorTest do + use Api.DataCase + + alias Api.Shape + alias ApiWeb.Authenticator + + describe "authenticator" do + test "generate token" do + {:ok, shape} = Shape.from(%{"table" => "foo"}) + + assert %{"api-auth" => token} = Authenticator.authenticate_shape(shape, nil) + assert is_binary(token) + end + + test "validate token" do + {:ok, shape} = Shape.from(%{"table" => "foo"}) + + headers = Authenticator.authenticate_shape(shape, nil) + assert Authenticator.authorise(shape, headers) + end + + test "validate token with params" do + {:ok, shape} = Shape.from(%{ + "table" => "foo", + "where" => "value IS NOT NULL" + }) + + headers = Authenticator.authenticate_shape(shape, nil) + assert Authenticator.authorise(shape, headers) + end + end +end diff --git a/examples/gatekeeper-auth/api/test/api_web/controllers/proxy_controller_test.exs b/examples/gatekeeper-auth/api/test/api_web/controllers/proxy_controller_test.exs new file mode 100644 index 0000000000..98a6848ece --- /dev/null +++ b/examples/gatekeeper-auth/api/test/api_web/controllers/proxy_controller_test.exs @@ -0,0 +1,49 @@ +defmodule ApiWeb.ProxyControllerTest do + use ApiWeb.ConnCase + + alias Api.Token + alias Electric.Client.ShapeDefinition + + setup %{conn: conn} do + {:ok, conn: put_req_header(conn, "accept", "application/json")} + end + + describe "show" do + test "requires shape params", %{conn: conn} do + assert conn + |> get("/proxy/v1/shape") + |> response(400) + end + + test "requires auth", %{conn: conn} do + assert conn + |> get("/proxy/v1/shape", table: "items") + |> response(403) + end + + test "requires valid auth header", %{conn: conn} do + assert conn + |> put_req_header("api-auth", "invalid-token") + |> get("/proxy/v1/shape", table: "items") + |> response(403) + end + + test "requires matching shape definition", %{conn: conn} do + {:ok, shape} = ShapeDefinition.new("wrong", []) + + assert conn + |> put_req_header("api-auth", Token.generate(shape)) + |> get("/proxy/v1/shape", table: "items", offset: -1) + |> response(403) + end + + test "proxies request", %{conn: conn} do + {:ok, shape} = ShapeDefinition.new("items", []) + + assert conn + |> put_req_header("api-auth", Token.generate(shape)) + |> get("/proxy/v1/shape", table: "items", offset: -1) + |> json_response(200) + end + end +end diff --git a/examples/gatekeeper-auth/api/test/api_web/gatekeeper_test.exs b/examples/gatekeeper-auth/api/test/api_web/gatekeeper_test.exs new file mode 100644 index 0000000000..0e501cdb68 --- /dev/null +++ b/examples/gatekeeper-auth/api/test/api_web/gatekeeper_test.exs @@ -0,0 +1,61 @@ +defmodule ApiWeb.GatekeeperTest do + use ApiWeb.ConnCase + + alias Api.Shape + alias ApiWeb.Authenticator + + setup %{conn: conn} do + {:ok, conn: put_req_header(conn, "accept", "application/json")} + end + + describe "gatekeeper plug" do + test "does not support GET requests", %{conn: conn} do + assert conn + |> get("/gatekeeper/items") + |> response(404) + end + + test "generates valid config", %{conn: conn} do + data = + conn + |> post("/gatekeeper/items") + |> json_response(200) + + assert %{"table" => "items"} = data + end + + test "generates valid config with params", %{conn: conn} do + clause = "value is not None" + + data = + conn + |> post("/gatekeeper/items", where: clause) + |> json_response(200) + + assert %{"table" => "items", "where" => ^clause} = data + end + end + + describe "gatekeeper auth" do + test "generates an auth header", %{conn: conn} do + data = + conn + |> post("/gatekeeper/items") + |> json_response(200) + + assert %{"headers" => %{"api-auth" => auth_header}} = data + assert is_binary(auth_header) + end + + test "generates a valid auth header", %{conn: conn} do + assert %{"headers" => headers, "table" => table} = + conn + |> post("/gatekeeper/items") + |> json_response(200) + + {:ok, shape} = Shape.from(%{"table" => table}) + + assert Authenticator.authorise(shape, headers) + end + end +end diff --git a/examples/gatekeeper-auth/api/test/api_web/integration_test.exs b/examples/gatekeeper-auth/api/test/api_web/integration_test.exs new file mode 100644 index 0000000000..c6300c1cab --- /dev/null +++ b/examples/gatekeeper-auth/api/test/api_web/integration_test.exs @@ -0,0 +1,51 @@ +defmodule ApiWeb.IntegrationTest do + use ApiWeb.ConnCase + + setup %{conn: conn} do + {:ok, conn: put_req_header(conn, "accept", "application/json")} + end + + describe "integration" do + test "gatekeeper auth token works with the proxy", %{conn: conn} do + # Define a shape. Any shape. + table = "items" + where = "value IS NOT NULL" + + # Fetch the client config from the gatekeeper endpoint. + assert %{"headers" => %{"api-auth" => auth_token}} = + conn + |> post("/gatekeeper/#{table}", where: where) + |> json_response(200) + + # Make an authorised shape request. + assert [] = + conn + |> put_req_header("api-auth", auth_token) + |> get("/proxy/v1/shape", offset: -1, table: table, where: where) + |> json_response(200) + end + + test "using the gatekeeper config", %{conn: conn} do + # As above but this time dynamically construct the proxy request + # from the config returned by the gatekeeper endpoint. + assert data = + conn + |> post("/gatekeeper/items", where: "value IS NOT NULL") + |> json_response(200) + + assert {headers, data} = Map.pop(data, "headers") + assert {url, shape_params} = Map.pop(data, "url") + + # We use the path, not the full URL just because we're testing. + path = URI.parse(url).path + params = Map.put(shape_params, "offset", -1) + + conn = + headers + |> Enum.reduce(conn, fn {k, v}, acc -> put_req_header(acc, k, v) end) + |> get(path, params) + + assert [] = json_response(conn, 200) + end + end +end diff --git a/examples/gatekeeper-auth/api/test/support/conn_case.ex b/examples/gatekeeper-auth/api/test/support/conn_case.ex index 28a2bf3446..01fd8e0d35 100644 --- a/examples/gatekeeper-auth/api/test/support/conn_case.ex +++ b/examples/gatekeeper-auth/api/test/support/conn_case.ex @@ -22,8 +22,6 @@ defmodule ApiWeb.ConnCase do # The default endpoint for testing @endpoint ApiWeb.Endpoint - use ApiWeb, :verified_routes - # Import conveniences for testing with connections import Plug.Conn import Phoenix.ConnTest @@ -33,6 +31,7 @@ defmodule ApiWeb.ConnCase do setup tags do Api.DataCase.setup_sandbox(tags) + {:ok, conn: Phoenix.ConnTest.build_conn()} end end diff --git a/examples/gatekeeper-auth/api/test/support/data_case.ex b/examples/gatekeeper-auth/api/test/support/data_case.ex index 33c80f20a9..7a39af55f7 100644 --- a/examples/gatekeeper-auth/api/test/support/data_case.ex +++ b/examples/gatekeeper-auth/api/test/support/data_case.ex @@ -29,6 +29,7 @@ defmodule Api.DataCase do setup tags do Api.DataCase.setup_sandbox(tags) + :ok end From b3430ea7ebb510b10b60b8c83d131ffb037270fb Mon Sep 17 00:00:00 2001 From: James Arthur Date: Mon, 11 Nov 2024 14:13:14 +0100 Subject: [PATCH 03/40] docs: copy pass on docstrings. --- examples/gatekeeper-auth/api/lib/api/shape.ex | 5 ++- .../api/lib/api_web/authenticator.ex | 32 +++++++++---------- .../lib/api_web/plugs/auth/verify_token.ex | 8 ++--- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/examples/gatekeeper-auth/api/lib/api/shape.ex b/examples/gatekeeper-auth/api/lib/api/shape.ex index 96fe077b43..414fe6d87b 100644 --- a/examples/gatekeeper-auth/api/lib/api/shape.ex +++ b/examples/gatekeeper-auth/api/lib/api/shape.ex @@ -7,9 +7,8 @@ defmodule Api.Shape do Protocol.derive(Jason.Encoder, ShapeDefinition, only: @public_fields) - # Compare the `shape` derived from the request params with the shape - # params signed in the auth token. Does the auth token allows access - # to this shape? + # Compare the `shape` derived from the request params with the shape params + # signed in the auth token. Does the auth token grant access to this shape? def matches(%ShapeDefinition{} = request_shape, %ShapeDefinition{} = token_shape) do with ^token_shape <- request_shape do true diff --git a/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex b/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex index 169164c5f5..5d8d83a1d9 100644 --- a/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex +++ b/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex @@ -23,23 +23,21 @@ defmodule ApiWeb.Authenticator do end end - @doc """ - Provides an `Electric.Client` that uses our `Authenticator` - implementation to generate signed auth tokens. - - This is configured in `./router.ex` to work with the - `Electric.Phoenix.Gateway.Plug`: - - post "/:table", Gateway.Plug, client: &Gatekeeper.client/0 - - Because `client/0` returns a client that's configured to use our - `ApiWeb.Authenticator`, then `ApiWeb.Authenticator.authenticate_shape/2` - will be called to generate an auth header that's included in the - response data that the Gateway.Plug returns to the client. - - I.e.: we basically tie into the `Gateway.Plug` machinery to use our - `Authenticator` to generate and return a signed token to the client. - """ + # Provides an `Electric.Client` that uses our `Authenticator` + # implementation to generate signed auth tokens. + # + # This is configured in `./router.ex` to work with the + # `Electric.Phoenix.Gateway.Plug`: + # + # post "/:table", Electric.Phoenix.Gateway.Plug, client: &Authenticator.client/0 + # + # Because `client/0` returns a client that's configured to use our + # `ApiWeb.Authenticator`, then `ApiWeb.Authenticator.authenticate_shape/2` + # will be called to generate an auth header that's included in the + # response data that the Gateway.Plug returns to the client. + # + # I.e.: we basically tie into the `Gateway.Plug` machinery to use our + # `Authenticator` to generate and return a signed token to the client. def client do base_url = Application.fetch_env!(:electric_phoenix, :electric_url) diff --git a/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex b/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex index 1b47411089..7d139191c4 100644 --- a/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex +++ b/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex @@ -1,11 +1,11 @@ defmodule ApiWeb.Plugs.Auth.VerifyToken do @moduledoc """ Verify that the token matches the shape. We do this by comparing the - the shape defined in the request query params with the shape signed - into the auth token claims. + shape defined in the request query params with the shape signed into + the auth token claims. - So you can't proxy a shape request without having a signed token for that - exact shape definition. + So you can't proxy a shape request without having a signed token for + that exact shape definition. """ use ApiWeb, :plug From c18446865e9316bf3abcfd66a6679000858038b5 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Mon, 11 Nov 2024 14:13:37 +0100 Subject: [PATCH 04/40] api: tweak imports for readability. --- examples/gatekeeper-auth/api/lib/api_web.ex | 11 +++-------- .../api/lib/api_web/plugs/assign_shape.ex | 2 ++ .../lib/api_web/plugs/auth/authorise_shape_access.ex | 2 +- .../api/lib/api_web/plugs/auth/verify_token.ex | 2 ++ examples/gatekeeper-auth/api/lib/api_web/router.ex | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/examples/gatekeeper-auth/api/lib/api_web.ex b/examples/gatekeeper-auth/api/lib/api_web.ex index bcb5d6ff1d..60b2b8dacd 100644 --- a/examples/gatekeeper-auth/api/lib/api_web.ex +++ b/examples/gatekeeper-auth/api/lib/api_web.ex @@ -20,9 +20,10 @@ defmodule ApiWeb do quote do import Plug.Conn - alias Api.Shape alias ApiWeb.Authenticator - alias Electric.Client.ShapeDefinition + + alias ApiWeb.Plugs.AssignShape + alias ApiWeb.Plugs.Auth end end @@ -32,12 +33,6 @@ defmodule ApiWeb do import Plug.Conn import Phoenix.Controller - - alias ApiWeb.Authenticator - alias ApiWeb.Plugs.AssignShape - alias ApiWeb.Plugs.Auth - - alias Electric.Phoenix.Gateway end end diff --git a/examples/gatekeeper-auth/api/lib/api_web/plugs/assign_shape.ex b/examples/gatekeeper-auth/api/lib/api_web/plugs/assign_shape.ex index f179ee0963..dface8fc45 100644 --- a/examples/gatekeeper-auth/api/lib/api_web/plugs/assign_shape.ex +++ b/examples/gatekeeper-auth/api/lib/api_web/plugs/assign_shape.ex @@ -5,6 +5,8 @@ defmodule ApiWeb.Plugs.AssignShape do """ use ApiWeb, :plug + alias Api.Shape + def init(opts), do: opts # If you pass `table_from_path: true` as an option, then it reads the diff --git a/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/authorise_shape_access.ex b/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/authorise_shape_access.ex index 1297fe08bb..c42e0d441c 100644 --- a/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/authorise_shape_access.ex +++ b/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/authorise_shape_access.ex @@ -22,7 +22,7 @@ defmodule ApiWeb.Plugs.Auth.AuthoriseShapeAccess do end end - defp is_authorised(:dummy, %ShapeDefinition{}) do + defp is_authorised(:dummy, _) do true end diff --git a/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex b/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex index 7d139191c4..3f481e3950 100644 --- a/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex +++ b/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex @@ -9,6 +9,8 @@ defmodule ApiWeb.Plugs.Auth.VerifyToken do """ use ApiWeb, :plug + alias ApiWeb.Authenticator + def init(opts), do: opts def call(%{assigns: %{shape: shape}, req_headers: header_list} = conn, _opts) do diff --git a/examples/gatekeeper-auth/api/lib/api_web/router.ex b/examples/gatekeeper-auth/api/lib/api_web/router.ex index 7d6c62c8e2..e737d7e36c 100644 --- a/examples/gatekeeper-auth/api/lib/api_web/router.ex +++ b/examples/gatekeeper-auth/api/lib/api_web/router.ex @@ -28,7 +28,7 @@ defmodule ApiWeb.Router do scope "/gatekeeper" do pipe_through :gatekeeper - post "/:table", Gateway.Plug, client: &Authenticator.client/0 + post "/:table", Electric.Phoenix.Gateway.Plug, client: &Authenticator.client/0 end # The proxy endpoint at `GET /proxy/v1/shape` proxies the request to the From 4360a018ed1a2429aef96673d3f2151eb8c82877 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Mon, 11 Nov 2024 14:13:52 +0100 Subject: [PATCH 05/40] tests: remove non-essential test file. --- .../api/test/api_web/controllers/error_json_test.exs | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 examples/gatekeeper-auth/api/test/api_web/controllers/error_json_test.exs diff --git a/examples/gatekeeper-auth/api/test/api_web/controllers/error_json_test.exs b/examples/gatekeeper-auth/api/test/api_web/controllers/error_json_test.exs deleted file mode 100644 index 48bff72e4e..0000000000 --- a/examples/gatekeeper-auth/api/test/api_web/controllers/error_json_test.exs +++ /dev/null @@ -1,12 +0,0 @@ -defmodule ApiWeb.ErrorJSONTest do - use ApiWeb.ConnCase, async: true - - test "renders 404" do - assert ApiWeb.ErrorJSON.render("404.json", %{}) == %{errors: %{detail: "Not Found"}} - end - - test "renders 500" do - assert ApiWeb.ErrorJSON.render("500.json", %{}) == - %{errors: %{detail: "Internal Server Error"}} - end -end From 475269e2990f005512a125c683724de48b7a0a4e Mon Sep 17 00:00:00 2001 From: James Arthur Date: Mon, 11 Nov 2024 17:55:43 +0100 Subject: [PATCH 06/40] router: fix imports. --- examples/gatekeeper-auth/api/lib/api_web.ex | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/gatekeeper-auth/api/lib/api_web.ex b/examples/gatekeeper-auth/api/lib/api_web.ex index 60b2b8dacd..5ceafe1421 100644 --- a/examples/gatekeeper-auth/api/lib/api_web.ex +++ b/examples/gatekeeper-auth/api/lib/api_web.ex @@ -19,11 +19,6 @@ defmodule ApiWeb do def plug do quote do import Plug.Conn - - alias ApiWeb.Authenticator - - alias ApiWeb.Plugs.AssignShape - alias ApiWeb.Plugs.Auth end end @@ -33,6 +28,11 @@ defmodule ApiWeb do import Plug.Conn import Phoenix.Controller + + alias ApiWeb.Authenticator + + alias ApiWeb.Plugs.AssignShape + alias ApiWeb.Plugs.Auth end end From 009298d221ccea31e302f4280dc1fab263f5c48f Mon Sep 17 00:00:00 2001 From: James Arthur Date: Mon, 11 Nov 2024 17:56:21 +0100 Subject: [PATCH 07/40] auth: use standard `Authorization: Bearer ...` header. --- .../api/lib/api_web/authenticator.ex | 6 +++--- .../api/test/api_web/authenticator_test.exs | 4 ++-- .../controllers/proxy_controller_test.exs | 18 +++++++++--------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex b/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex index 5d8d83a1d9..76e52a5208 100644 --- a/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex +++ b/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex @@ -7,10 +7,10 @@ defmodule ApiWeb.Authenticator do alias Electric.Client @behaviour Client.Authenticator - @header "api-auth" + @header "authorization" def authenticate_shape(shape, _config) do - %{@header => Token.generate(shape)} + %{@header => "Bearer #{Token.generate(shape)}"} end def authenticate_request(request, _config) do @@ -18,7 +18,7 @@ defmodule ApiWeb.Authenticator do end def authorise(shape, headers) do - with {:ok, token} <- Map.fetch(headers, @header) do + with {:ok, "Bearer " <> token} <- Map.fetch(headers, @header) do Token.verify(shape, token) end end diff --git a/examples/gatekeeper-auth/api/test/api_web/authenticator_test.exs b/examples/gatekeeper-auth/api/test/api_web/authenticator_test.exs index aa03b98ec9..bd2c0ecc71 100644 --- a/examples/gatekeeper-auth/api/test/api_web/authenticator_test.exs +++ b/examples/gatekeeper-auth/api/test/api_web/authenticator_test.exs @@ -8,8 +8,8 @@ defmodule ApiWeb.AuthenticatorTest do test "generate token" do {:ok, shape} = Shape.from(%{"table" => "foo"}) - assert %{"api-auth" => token} = Authenticator.authenticate_shape(shape, nil) - assert is_binary(token) + assert %{"authorization" => "Bearer " <> _token} = + Authenticator.authenticate_shape(shape, nil) end test "validate token" do diff --git a/examples/gatekeeper-auth/api/test/api_web/controllers/proxy_controller_test.exs b/examples/gatekeeper-auth/api/test/api_web/controllers/proxy_controller_test.exs index 98a6848ece..f1646b56f4 100644 --- a/examples/gatekeeper-auth/api/test/api_web/controllers/proxy_controller_test.exs +++ b/examples/gatekeeper-auth/api/test/api_web/controllers/proxy_controller_test.exs @@ -23,27 +23,27 @@ defmodule ApiWeb.ProxyControllerTest do test "requires valid auth header", %{conn: conn} do assert conn - |> put_req_header("api-auth", "invalid-token") - |> get("/proxy/v1/shape", table: "items") - |> response(403) + |> put_req_header("authorization", "Bearer invalid-token") + |> get("/proxy/v1/shape", table: "items") + |> response(403) end test "requires matching shape definition", %{conn: conn} do {:ok, shape} = ShapeDefinition.new("wrong", []) assert conn - |> put_req_header("api-auth", Token.generate(shape)) - |> get("/proxy/v1/shape", table: "items", offset: -1) - |> response(403) + |> put_req_header("authorization", "Bearer #{Token.generate(shape)}") + |> get("/proxy/v1/shape", table: "items", offset: -1) + |> response(403) end test "proxies request", %{conn: conn} do {:ok, shape} = ShapeDefinition.new("items", []) assert conn - |> put_req_header("api-auth", Token.generate(shape)) - |> get("/proxy/v1/shape", table: "items", offset: -1) - |> json_response(200) + |> put_req_header("authorization", "Bearer #{Token.generate(shape)}") + |> get("/proxy/v1/shape", table: "items", offset: -1) + |> json_response(200) end end end From 383f38470160c1a42fb391ef7384f25691e66a38 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Mon, 11 Nov 2024 17:56:41 +0100 Subject: [PATCH 08/40] api: mix format. --- .../api/test/api_web/authenticator_test.exs | 9 ++++---- .../controllers/proxy_controller_test.exs | 8 +++---- .../api/test/api_web/gatekeeper_test.exs | 13 +++++------ .../api/test/api_web/integration_test.exs | 22 +++++++++---------- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/examples/gatekeeper-auth/api/test/api_web/authenticator_test.exs b/examples/gatekeeper-auth/api/test/api_web/authenticator_test.exs index bd2c0ecc71..ac86af2b5a 100644 --- a/examples/gatekeeper-auth/api/test/api_web/authenticator_test.exs +++ b/examples/gatekeeper-auth/api/test/api_web/authenticator_test.exs @@ -20,10 +20,11 @@ defmodule ApiWeb.AuthenticatorTest do end test "validate token with params" do - {:ok, shape} = Shape.from(%{ - "table" => "foo", - "where" => "value IS NOT NULL" - }) + {:ok, shape} = + Shape.from(%{ + "table" => "foo", + "where" => "value IS NOT NULL" + }) headers = Authenticator.authenticate_shape(shape, nil) assert Authenticator.authorise(shape, headers) diff --git a/examples/gatekeeper-auth/api/test/api_web/controllers/proxy_controller_test.exs b/examples/gatekeeper-auth/api/test/api_web/controllers/proxy_controller_test.exs index f1646b56f4..f1f6a5696a 100644 --- a/examples/gatekeeper-auth/api/test/api_web/controllers/proxy_controller_test.exs +++ b/examples/gatekeeper-auth/api/test/api_web/controllers/proxy_controller_test.exs @@ -11,14 +11,14 @@ defmodule ApiWeb.ProxyControllerTest do describe "show" do test "requires shape params", %{conn: conn} do assert conn - |> get("/proxy/v1/shape") - |> response(400) + |> get("/proxy/v1/shape") + |> response(400) end test "requires auth", %{conn: conn} do assert conn - |> get("/proxy/v1/shape", table: "items") - |> response(403) + |> get("/proxy/v1/shape", table: "items") + |> response(403) end test "requires valid auth header", %{conn: conn} do diff --git a/examples/gatekeeper-auth/api/test/api_web/gatekeeper_test.exs b/examples/gatekeeper-auth/api/test/api_web/gatekeeper_test.exs index 0e501cdb68..e0afe72814 100644 --- a/examples/gatekeeper-auth/api/test/api_web/gatekeeper_test.exs +++ b/examples/gatekeeper-auth/api/test/api_web/gatekeeper_test.exs @@ -11,8 +11,8 @@ defmodule ApiWeb.GatekeeperTest do describe "gatekeeper plug" do test "does not support GET requests", %{conn: conn} do assert conn - |> get("/gatekeeper/items") - |> response(404) + |> get("/gatekeeper/items") + |> response(404) end test "generates valid config", %{conn: conn} do @@ -43,15 +43,14 @@ defmodule ApiWeb.GatekeeperTest do |> post("/gatekeeper/items") |> json_response(200) - assert %{"headers" => %{"api-auth" => auth_header}} = data - assert is_binary(auth_header) + assert %{"headers" => %{"authorization" => "Bearer " <> _token}} = data end test "generates a valid auth header", %{conn: conn} do assert %{"headers" => headers, "table" => table} = - conn - |> post("/gatekeeper/items") - |> json_response(200) + conn + |> post("/gatekeeper/items") + |> json_response(200) {:ok, shape} = Shape.from(%{"table" => table}) diff --git a/examples/gatekeeper-auth/api/test/api_web/integration_test.exs b/examples/gatekeeper-auth/api/test/api_web/integration_test.exs index c6300c1cab..6f28d80177 100644 --- a/examples/gatekeeper-auth/api/test/api_web/integration_test.exs +++ b/examples/gatekeeper-auth/api/test/api_web/integration_test.exs @@ -12,26 +12,26 @@ defmodule ApiWeb.IntegrationTest do where = "value IS NOT NULL" # Fetch the client config from the gatekeeper endpoint. - assert %{"headers" => %{"api-auth" => auth_token}} = - conn - |> post("/gatekeeper/#{table}", where: where) - |> json_response(200) + assert %{"headers" => %{"authorization" => auth_header}} = + conn + |> post("/gatekeeper/#{table}", where: where) + |> json_response(200) # Make an authorised shape request. assert [] = - conn - |> put_req_header("api-auth", auth_token) - |> get("/proxy/v1/shape", offset: -1, table: table, where: where) - |> json_response(200) + conn + |> put_req_header("authorization", auth_header) + |> get("/proxy/v1/shape", offset: -1, table: table, where: where) + |> json_response(200) end test "using the gatekeeper config", %{conn: conn} do # As above but this time dynamically construct the proxy request # from the config returned by the gatekeeper endpoint. assert data = - conn - |> post("/gatekeeper/items", where: "value IS NOT NULL") - |> json_response(200) + conn + |> post("/gatekeeper/items", where: "value IS NOT NULL") + |> json_response(200) assert {headers, data} = Map.pop(data, "headers") assert {url, shape_params} = Map.pop(data, "url") From 68449106d65124df5355461493a02df7317e423b Mon Sep 17 00:00:00 2001 From: James Arthur Date: Wed, 13 Nov 2024 13:07:01 +0100 Subject: [PATCH 09/40] api: prepare docker release. --- examples/gatekeeper-auth/api/.dockerignore | 45 +++++++++ examples/gatekeeper-auth/api/Dockerfile | 92 +++++++++++++++++++ examples/gatekeeper-auth/api/README.md | 34 ++++--- examples/gatekeeper-auth/api/config/dev.exs | 7 +- .../gatekeeper-auth/api/config/runtime.exs | 15 +-- examples/gatekeeper-auth/api/config/test.exs | 2 +- .../gatekeeper-auth/api/lib/api/release.ex | 28 ++++++ examples/gatekeeper-auth/api/lib/api/token.ex | 2 +- .../api/rel/overlays/bin/migrate | 5 + .../api/rel/overlays/bin/migrate.bat | 1 + .../api/rel/overlays/bin/server | 5 + .../api/rel/overlays/bin/server.bat | 2 + 12 files changed, 215 insertions(+), 23 deletions(-) create mode 100644 examples/gatekeeper-auth/api/.dockerignore create mode 100644 examples/gatekeeper-auth/api/Dockerfile create mode 100644 examples/gatekeeper-auth/api/lib/api/release.ex create mode 100755 examples/gatekeeper-auth/api/rel/overlays/bin/migrate create mode 100755 examples/gatekeeper-auth/api/rel/overlays/bin/migrate.bat create mode 100755 examples/gatekeeper-auth/api/rel/overlays/bin/server create mode 100755 examples/gatekeeper-auth/api/rel/overlays/bin/server.bat diff --git a/examples/gatekeeper-auth/api/.dockerignore b/examples/gatekeeper-auth/api/.dockerignore new file mode 100644 index 0000000000..61a73933c8 --- /dev/null +++ b/examples/gatekeeper-auth/api/.dockerignore @@ -0,0 +1,45 @@ +# This file excludes paths from the Docker build context. +# +# By default, Docker's build context includes all files (and folders) in the +# current directory. Even if a file isn't copied into the container it is still sent to +# the Docker daemon. +# +# There are multiple reasons to exclude files from the build context: +# +# 1. Prevent nested folders from being copied into the container (ex: exclude +# /assets/node_modules when copying /assets) +# 2. Reduce the size of the build context and improve build time (ex. /build, /deps, /doc) +# 3. Avoid sending files containing sensitive information +# +# More information on using .dockerignore is available here: +# https://docs.docker.com/engine/reference/builder/#dockerignore-file + +.dockerignore + +# Ignore git, but keep git HEAD and refs to access current commit hash if needed: +# +# $ cat .git/HEAD | awk '{print ".git/"$2}' | xargs cat +# d0b8727759e1e0e7aa3d41707d12376e373d5ecc +.git +!.git/HEAD +!.git/refs + +# Common development/test artifacts +/cover/ +/doc/ +/test/ +/tmp/ +.elixir_ls + +# Mix artifacts +/_build/ +/deps/ +*.ez + +# Generated on crash by the VM +erl_crash.dump + +# Static artifacts - These should be fetched and built inside the Docker image +/assets/node_modules/ +/priv/static/assets/ +/priv/static/cache_manifest.json diff --git a/examples/gatekeeper-auth/api/Dockerfile b/examples/gatekeeper-auth/api/Dockerfile new file mode 100644 index 0000000000..4579074c44 --- /dev/null +++ b/examples/gatekeeper-auth/api/Dockerfile @@ -0,0 +1,92 @@ +# Find eligible builder and runner images on Docker Hub. We use Ubuntu/Debian +# instead of Alpine to avoid DNS resolution issues in production. +# +# https://hub.docker.com/r/hexpm/elixir/tags?page=1&name=ubuntu +# https://hub.docker.com/_/ubuntu?tab=tags +# +# This file is based on these images: +# +# - https://hub.docker.com/r/hexpm/elixir/tags - for the build image +# - https://hub.docker.com/_/debian?tab=tags&page=1&name=bullseye-20240904-slim - for the release image +# - https://pkgs.org/ - resource for finding needed packages +# - Ex: hexpm/elixir:1.17.2-erlang-27.0.1-debian-bullseye-20240904-slim +# +ARG ELIXIR_VERSION=1.17.2 +ARG OTP_VERSION=27.0.1 +ARG DEBIAN_VERSION=bullseye-20240904-slim + +ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}" +ARG RUNNER_IMAGE="debian:${DEBIAN_VERSION}" + +FROM ${BUILDER_IMAGE} as builder + +# install build dependencies +RUN apt-get update -y && apt-get install -y build-essential git \ + && apt-get clean && rm -f /var/lib/apt/lists/*_* + +# prepare build dir +WORKDIR /app + +# install hex + rebar +RUN mix local.hex --force && \ + mix local.rebar --force + +# set build ENV +ENV MIX_ENV="prod" + +# install mix dependencies +COPY mix.exs mix.lock ./ +RUN mix deps.get --only $MIX_ENV +RUN mkdir config + +# copy compile-time config files before we compile dependencies +# to ensure any relevant config change will trigger the dependencies +# to be re-compiled. +COPY config/config.exs config/${MIX_ENV}.exs config/ +RUN mix deps.compile + +COPY priv priv + +COPY lib lib + +# Compile the release +RUN mix compile + +# Changes to config/runtime.exs don't require recompiling the code +COPY config/runtime.exs config/ + +COPY rel rel +RUN mix release + +# start a new build stage so that the final image will only contain +# the compiled release and other runtime necessities +FROM ${RUNNER_IMAGE} + +RUN apt-get update -y && \ + apt-get install -y libstdc++6 openssl libncurses5 locales ca-certificates \ + && apt-get clean && rm -f /var/lib/apt/lists/*_* + +# Set the locale +RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && locale-gen + +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 + +WORKDIR "/app" +RUN chown nobody /app + +# set runner ENV +ENV MIX_ENV="prod" + +# Only copy the final release from the build stage +COPY --from=builder --chown=nobody:root /app/_build/${MIX_ENV}/rel/api ./ + +USER nobody + +# If using an environment that doesn't automatically reap zombie processes, it is +# advised to add an init process such as tini via `apt-get install` +# above and adding an entrypoint. See https://github.com/krallin/tini for details +# ENTRYPOINT ["/tini", "--"] + +CMD ["sh", "-c", "/app/bin/migrate && /app/bin/server"] diff --git a/examples/gatekeeper-auth/api/README.md b/examples/gatekeeper-auth/api/README.md index f8975f4af2..711126efa1 100644 --- a/examples/gatekeeper-auth/api/README.md +++ b/examples/gatekeeper-auth/api/README.md @@ -1,18 +1,28 @@ -# Api -To start your Phoenix server: +# API gatekeeper and proxy - * Run `mix setup` to install and setup dependencies - * Start Phoenix endpoint with `mix phx.server` or inside IEx with `iex -S mix phx.server` +This is a [Phoenix](https://www.phoenixframework.org) web application written in [Elixir](https://elixir-lang.org). -Now you can visit [`localhost:4000`](http://localhost:4000) from your browser. +See the [Implementation](../README.md#implementation) section of the README in the root folder of this example for context and instructions on how to run using Docker Compose. -Ready to run in production? Please [check our deployment guides](https://hexdocs.pm/phoenix/deployment.html). +## Locally without Docker -## Learn more +Alternatively you can run locally without Docker. See the [Phoenix Installation](https://hexdocs.pm/phoenix/installation.html) for pre-reqs. - * Official website: https://www.phoenixframework.org/ - * Guides: https://hexdocs.pm/phoenix/overview.html - * Docs: https://hexdocs.pm/phoenix - * Forum: https://elixirforum.com/c/phoenix-forum - * Source: https://github.com/phoenixframework/phoenix +Install and setup dependencies: + +```shell +mix setup +``` + +Run the tests: + +```shell +mix test +``` + +Run locally: + +``` +mix phx.server +``` diff --git a/examples/gatekeeper-auth/api/config/dev.exs b/examples/gatekeeper-auth/api/config/dev.exs index 99643d107a..5b5438c453 100644 --- a/examples/gatekeeper-auth/api/config/dev.exs +++ b/examples/gatekeeper-auth/api/config/dev.exs @@ -1,7 +1,7 @@ import Config config :api, - auth_token_secret: "hxRgQliCC7Ceo/ocTcKOJCYrVxsB5HjcZd1WF9qnbbNdEoju/YMfqNim0RHRWV1B", + auth_token_secret: "NFL5*0Bc#9U6E@tnmC&E7SUN6GwHfLmY", # Configure the proxy endpoint to route shape requests to the external Electric # sync service, which we assume in development is running on `localhost:3000`. electric_url: "http://localhost:3000" @@ -9,9 +9,10 @@ config :api, # Configure your database config :api, Api.Repo, username: "postgres", - password: "postgres", + password: "password", hostname: "localhost", - database: "api_dev", + port: 54321, + database: "electric", stacktrace: true, show_sensitive_data_on_connection_error: true, pool_size: 10 diff --git a/examples/gatekeeper-auth/api/config/runtime.exs b/examples/gatekeeper-auth/api/config/runtime.exs index 201e8f0945..0645a0d2ac 100644 --- a/examples/gatekeeper-auth/api/config/runtime.exs +++ b/examples/gatekeeper-auth/api/config/runtime.exs @@ -49,9 +49,10 @@ if config_env() == :prod do host = System.get_env("PHX_HOST") || "example.com" port = System.get_env("PHX_PORT") || 443 + scheme = System.get_env("PHX_SCHEME") || "https" config :api, ApiWeb.Endpoint, - url: [host: host, port: port, scheme: "https"], + url: [host: host, port: port, scheme: scheme], http: [ # Enable IPv6 and bind on all interfaces. # Set it to {0, 0, 0, 0, 0, 0, 0, 1} for local network only access. @@ -62,9 +63,11 @@ if config_env() == :prod do ], secret_key_base: secret_key_base - # Configure Electric.Phoenix to route electric shape requests via - # this API, specifically the `/proxy` endpoint configured in - # `../lib/api_web/router.ex`. - config :electric_phoenix, - electric_url: URI.parse("https://#{host}:#{port}/proxy") |> URI.to_string() + # Configure the URL that the Electric.Phoenix.Gateway.Plug uses when returning + # shape config to the client. Defaults to this API, specifically the `/proxy` + # endpoint configured in `../lib/api_web/router.ex`. + default_proxy_url = URI.parse("https://#{host}:#{port}/proxy") |> URI.to_string() + proxy_url = System.get_env("ELECTRIC_PROXY_URL") || default_proxy_url + + config :electric_phoenix, electric_url: proxy_url end diff --git a/examples/gatekeeper-auth/api/config/test.exs b/examples/gatekeeper-auth/api/config/test.exs index b33e7a4a4e..886c89a4b3 100644 --- a/examples/gatekeeper-auth/api/config/test.exs +++ b/examples/gatekeeper-auth/api/config/test.exs @@ -3,7 +3,7 @@ import Config # Configure the proxy endpoint to route shape requests to the external Electric # sync service, which we assume in test is running on `localhost:3002`. config :api, - auth_token_secret: "DY1vSZb/BL1WgLyFq5A1d1FkmzoSMaRhXcBUL41mqciKLRSSSK6AO2hTCQmDyQj4", + auth_token_secret: "NFL5*0Bc#9U6E@tnmC&E7SUN6GwHfLmY", electric_url: "http://localhost:3000" # Configure your database diff --git a/examples/gatekeeper-auth/api/lib/api/release.ex b/examples/gatekeeper-auth/api/lib/api/release.ex new file mode 100644 index 0000000000..2da6c27e8a --- /dev/null +++ b/examples/gatekeeper-auth/api/lib/api/release.ex @@ -0,0 +1,28 @@ +defmodule Api.Release do + @moduledoc """ + Used for executing DB release tasks when run in production without Mix + installed. + """ + @app :api + + def migrate do + load_app() + + for repo <- repos() do + {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true)) + end + end + + def rollback(repo, version) do + load_app() + {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version)) + end + + defp repos do + Application.fetch_env!(@app, :ecto_repos) + end + + defp load_app do + Application.load(@app) + end +end diff --git a/examples/gatekeeper-auth/api/lib/api/token.ex b/examples/gatekeeper-auth/api/lib/api/token.ex index cc9d8a2a4d..e14dc0c340 100644 --- a/examples/gatekeeper-auth/api/lib/api/token.ex +++ b/examples/gatekeeper-auth/api/lib/api/token.ex @@ -16,7 +16,7 @@ defmodule Api.Token do end def generate(%ShapeDefinition{} = shape) do - {:ok, token, _claims} = JWT.generate_and_sign(%{shape: shape}, JWT.signer()) + {:ok, token, _claims} = JWT.generate_and_sign(%{"shape" => shape}, JWT.signer()) token end diff --git a/examples/gatekeeper-auth/api/rel/overlays/bin/migrate b/examples/gatekeeper-auth/api/rel/overlays/bin/migrate new file mode 100755 index 0000000000..f093404c52 --- /dev/null +++ b/examples/gatekeeper-auth/api/rel/overlays/bin/migrate @@ -0,0 +1,5 @@ +#!/bin/sh +set -eu + +cd -P -- "$(dirname -- "$0")" +exec ./api eval Api.Release.migrate diff --git a/examples/gatekeeper-auth/api/rel/overlays/bin/migrate.bat b/examples/gatekeeper-auth/api/rel/overlays/bin/migrate.bat new file mode 100755 index 0000000000..d8003e83d8 --- /dev/null +++ b/examples/gatekeeper-auth/api/rel/overlays/bin/migrate.bat @@ -0,0 +1 @@ +call "%~dp0\api" eval Api.Release.migrate diff --git a/examples/gatekeeper-auth/api/rel/overlays/bin/server b/examples/gatekeeper-auth/api/rel/overlays/bin/server new file mode 100755 index 0000000000..de9c7d9ca7 --- /dev/null +++ b/examples/gatekeeper-auth/api/rel/overlays/bin/server @@ -0,0 +1,5 @@ +#!/bin/sh +set -eu + +cd -P -- "$(dirname -- "$0")" +PHX_SERVER=true exec ./api start diff --git a/examples/gatekeeper-auth/api/rel/overlays/bin/server.bat b/examples/gatekeeper-auth/api/rel/overlays/bin/server.bat new file mode 100755 index 0000000000..4cf5d1e061 --- /dev/null +++ b/examples/gatekeeper-auth/api/rel/overlays/bin/server.bat @@ -0,0 +1,2 @@ +set PHX_SERVER=true +call "%~dp0\api" start From d3f8a8e89477172b0a56031c529b7fae530093c0 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Wed, 13 Nov 2024 13:07:19 +0100 Subject: [PATCH 10/40] api: simplify the `Item` schema. --- examples/gatekeeper-auth/api/lib/api/item.ex | 3 --- .../api/priv/repo/migrations/20241108150947_create_items.exs | 4 +--- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/examples/gatekeeper-auth/api/lib/api/item.ex b/examples/gatekeeper-auth/api/lib/api/item.ex index 7d9d5c3ff6..4539e1569e 100644 --- a/examples/gatekeeper-auth/api/lib/api/item.ex +++ b/examples/gatekeeper-auth/api/lib/api/item.ex @@ -6,14 +6,11 @@ defmodule Api.Item do @foreign_key_type :binary_id schema "items" do field :value, :string - - timestamps(type: :utc_datetime) end @doc false def changeset(item, attrs) do item |> cast(attrs, [:value]) - |> validate_required([:value]) end end diff --git a/examples/gatekeeper-auth/api/priv/repo/migrations/20241108150947_create_items.exs b/examples/gatekeeper-auth/api/priv/repo/migrations/20241108150947_create_items.exs index 303f4b63d9..68c31a585d 100644 --- a/examples/gatekeeper-auth/api/priv/repo/migrations/20241108150947_create_items.exs +++ b/examples/gatekeeper-auth/api/priv/repo/migrations/20241108150947_create_items.exs @@ -4,9 +4,7 @@ defmodule Api.Repo.Migrations.CreateItems do def change do create table(:items, primary_key: false) do add :id, :binary_id, primary_key: true - add :value, :string - - timestamps(type: :utc_datetime) + add :value, :string, null: true end end end From 0047f21245de59212c66273afaf7c4c42d56c574 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Wed, 13 Nov 2024 13:07:52 +0100 Subject: [PATCH 11/40] caddy: add Caddy reverse proxy option. --- examples/gatekeeper-auth/caddy/Caddyfile | 82 ++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 examples/gatekeeper-auth/caddy/Caddyfile diff --git a/examples/gatekeeper-auth/caddy/Caddyfile b/examples/gatekeeper-auth/caddy/Caddyfile new file mode 100644 index 0000000000..ff1af03e8d --- /dev/null +++ b/examples/gatekeeper-auth/caddy/Caddyfile @@ -0,0 +1,82 @@ +{ + order jwtauth before basicauth +} + +:8080 { + jwtauth { + # You can sign and validate JWT tokens however you prefer. Here we + # expect tokens to have been signed with the `HS256` algorithm and + # a shared symmetric signing key to match the configuration in + # `../api/lib/api/token.ex`, so that this example config validates + # tokens generated by the example Api service. + # + # Note that the signing key should be base64 encoded: + # + # sign_key "" + # + # See https://caddyserver.com/docs/modules/http.authentication.providers.jwt + # for more details. + sign_key {$JWT_AUTH_SIGNING_KEY:"TkZMNSowQmMjOVU2RUB0bm1DJkU3U1VONkd3SGZMbVk="} + sign_alg HS256 + + # The jwtauth module requires a user claim but we don't actually use + # it here, so we just set it to the token issuer. + user_claims iss + + # Extract the shape definition from the JWT `shape` claim and write + # into {http.auth.user.*} variables, so e.g.: the `shape.table` + # becomes {http.auth.user.table} and is used below to match against + # the request parameters. + meta_claims \ + "shape.namespace -> namespace" \ + "shape.table -> table" \ + "shape.where -> where" \ + "shape.columns -> columns" + } + + # Match `GET /v1/shape` requests. + @get_shape { + method GET + + path /v1/shape + } + + # Match requests whose JWT shape definition matches the shape definition + # in the request parameters. + # + # So, for example, a claim of `{"shape": {"table": "items"}}` will match + # a query parameter of `?table=items`. + # + # Note that the first expression matches the request table param against + # either the shape `table` or `namespace.table` depending on whether the + # shape `namespace` is empty or not. + @definition_matches { + expression < Date: Wed, 13 Nov 2024 13:08:47 +0100 Subject: [PATCH 12/40] docs: README and docker-compose with options. --- examples/gatekeeper-auth/.env.caddy | 1 + examples/gatekeeper-auth/README.md | 254 ++++++++++++++++++ examples/gatekeeper-auth/caddy/README.md | 20 ++ examples/gatekeeper-auth/docker-compose.yaml | 61 +++++ examples/gatekeeper-auth/docs/NOTES.md | 12 + .../docs/img/gatekeeper-flow.dark.png | Bin 0 -> 80391 bytes .../docs/img/gatekeeper-flow.jpg | Bin 0 -> 204374 bytes .../docs/img/gatekeeper-flow.png | Bin 0 -> 66167 bytes 8 files changed, 348 insertions(+) create mode 100644 examples/gatekeeper-auth/.env.caddy create mode 100644 examples/gatekeeper-auth/README.md create mode 100644 examples/gatekeeper-auth/caddy/README.md create mode 100644 examples/gatekeeper-auth/docker-compose.yaml create mode 100644 examples/gatekeeper-auth/docs/NOTES.md create mode 100644 examples/gatekeeper-auth/docs/img/gatekeeper-flow.dark.png create mode 100644 examples/gatekeeper-auth/docs/img/gatekeeper-flow.jpg create mode 100644 examples/gatekeeper-auth/docs/img/gatekeeper-flow.png diff --git a/examples/gatekeeper-auth/.env.caddy b/examples/gatekeeper-auth/.env.caddy new file mode 100644 index 0000000000..3009186960 --- /dev/null +++ b/examples/gatekeeper-auth/.env.caddy @@ -0,0 +1 @@ +ELECTRIC_PROXY_URL=http://localhost:8080 \ No newline at end of file diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md new file mode 100644 index 0000000000..97a51d366c --- /dev/null +++ b/examples/gatekeeper-auth/README.md @@ -0,0 +1,254 @@ + +# Electric Gatekeeper Auth Example + +This example demonstrates a number of ways of implementing the [Gatekeeper auth pattern](https://electric-sql.com/docs/guides/auth#gatekeeper) for securing access to the [Electric sync service](https://electric-sql.com/product/sync). + +It includes: + +- an [`./api`](./api) service for generating auth tokens +- three options for validating those auth tokens when proxying requests to Electric: + - [`./api`](./api) the API itself + - [`./caddy`](./caddy) a Caddy web server as a reverse proxy + - [`./edge`](./edge) an edge function that you can run in front of a CDN + + +## How it works + +There are two steps to the gatekeeper pattern: + +1. first a client posts authentication credentials to a gatekeeper endpoint to generate an auth token +2. the client then makes requests to Electric via an authorising proxy that validates the auth token against the shape request + +The auth token can be *shape-scoped* (i.e.: can sign a specific shape definition). This allows the proxy to authorise a shape request by comparing the shape signed into the token with the [shape defined in the request parameters](https://electric-sql.com/docs/quickstart#http-api). This allows you to: + +- keep your main authorisation logic in your API (in the gatekeeper endpoint) where it's natural to do things like query the database and call external authorisation services; and to +- run your authorisation logic *once* when generating a token, rather than on the "hot path" of every shape request in your authorising proxy + +### Implementation + +The core of this example is an [Elixir/Phoenix](https://www.phoenixframework.org) web application in [`./api`](./api). This exposes (in [`api_web/router.ex`](./api/lib/api_web/router.ex)): + +1. a gatekeeper endpoint at `POST /gatekeeper/:table` +2. a proxy endpoint at `GET /proxy/v1/shape` + + + + + + Gatekeeper flow diagramme + + + +#### Gatekeeper endpoint + +1. the user makes a `POST` request to `POST /gatekeeper/:table` with some authentication credentials and a shape definition in the request parameters; the gatekeeper is then responsible for authorising the user's access to the shape +2. if access is granted, the gatekeeper generates a shape-scoped auth token and returns it to the client +3. the client can then use the auth token when connecting to the Electric HTTP API, via the proxy endpoint + +#### Proxy endpoint + +4. the proxy validates the JWT auth token and verifies that the shape definition in the token matches the shape being requested; if so it reverse-proxies the request onto Electric +5. Electric then handles the request as normal, sending a response back through the proxy to the client +6. the client can then process the data and make additional requests using the same auth token (step 3); if the auth token expires or is rejected, the client starts again (step 1). + + +## How to run + +There are three ways to run this example: + +1. with the [API as both gatekeeper and proxy](#1-api-as-gatekeeper-and-proxy) +2. with the [API as gatekeeper and Caddy as the proxy](#2-caddy-as-proxy) +3. with the [API as gatekeeper and an edge function as the proxy](#3-edge-function-as-proxy) + +It makes sense to run through these in order. + +### Pre-reqs + +You need [Docker Compose](https://docs.docker.com/compose/) and [curl](https://curl.se). We also (optionally) pipe into `jq` for JSON formatting. + +The instructions below all use the same [`./docker-compose.yaml`](./docker-compose.yaml) file in the root of this repo. With a different set of services and environment variables. + +> [!Tip] Running Postgres and Electric +> All of the configurations are based on running Postgres and Electric. This is handled for you by the `./docker-compose.yaml`. However, if you're unfamiliar with how Electric works, it may be useful to go through the [Quickstart](https://electric-sql.com/docs/quickstart) and [Installation](https://electric-sql.com/docs/guides/installation) guides. + +### 1. API as gatekeeper and proxy + +Build the local API image: + +```shell +docker compose build api +``` + +Run `postgres`, `electric` and the `api` services: + +```console +$ docker compose up postgres electric api +... +gatekeeper-api-1 | 10:22:20.951 [info] == Migrated 20241108150947 in 0.0s +gatekeeper-api-1 | 10:22:21.453 [info] Running ApiWeb.Endpoint with Bandit 1.5.7 at :::4000 (http) +gatekeeper-api-1 | 10:22:21.455 [info] Access ApiWeb.Endpoint at http://localhost:4000 +``` + +In a new terminal, make a `POST` request to the gatekeeper endpoint: + +```console +$ curl -sX POST "http://localhost:4000/gatekeeper/items" | jq +{ + "headers": { + "authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJKb2tlbiIsImV4cCI6MTczMTUwMjM2OSwiaWF0IjoxNzMxNDk1MTY5LCJpc3MiOiJKb2tlbiIsImp0aSI6IjMwM28zYmx0czN2aHYydXNiazAwMDJrMiIsIm5iZiI6MTczMTQ5NTE2OSwic2hhcGUiOnsibmFtZXNwYWNlIjpudWxsLCJ0YWJsZSI6Iml0ZW1zIiwid2hlcmUiOm51bGwsImNvbHVtbnMiOm51bGx9fQ.8UZehIWk1EDQ3dJ4ggCBNkx9vGudfrD9appqs8r6zRI" + }, + "url": "http://localhost:3000/proxy/v1/shape", + "table": "items" +} +``` + +You'll see that the response contains: + +- the proxy `url` to make shape requests to (`http://localhost:4000/proxy/v1/shape`) +- the request parameters for the shape we're requesting, in this case `"table": "items"` +- an `authorization` header, containing a `Bearer ` + +Copy the auth token and set it to an env var: + +```shell +export AUTH_TOKEN="" +``` + +First let's make a `GET` request to the proxy endpoint *without* the auth token: + +```console +$ curl "http://localhost:4000/proxy/v1/shape?table=items&offset=-1" +Forbidden +``` + +Now let's add the authorization header: + +```console +$ curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ + "http://localhost:4000/proxy/v1/shape?table=items&offset=-1" +[] +``` + +Success! We got an empty response because there are no `items` in the database. If you like, +you can create some, e.g. using `psql`: + +```console +~ psql "postgresql://postgres:password@localhost:54321/electric?sslmode=disable" +psql (16.4) +Type "help" for help. + +electric=# \d + List of relations + Schema | Name | Type | Owner +--------+-------------------+-------+---------- + public | items | table | postgres + public | schema_migrations | table | postgres +(2 rows) + +electric=# select * from items; + id | value | inserted_at | updated_at +----+-------+-------------+------------ +(0 rows) + +electric=# insert into items (id, inserted_at, updated_at) values (gen_random_uuid(), now(), now()); +INSERT 0 1 +electric=# \q +``` + +Now re-run the same request and you'll get data: + +```console +$ curl -s --header "Authorization: Bearer ${AUTH_TOKEN}" \ + "http://localhost:3000/v1/shape?table=items&offset=-1" | jq +[ + { + "key": "\"public\".\"items\"/\"b702e58e-9364-4d54-9360-8dda20cb4405\"", + "value": { + "id": "b702e58e-9364-4d54-9360-8dda20cb4405", + "value": null, + "inserted_at": "2024-11-13 10:45:33", + "updated_at": "2024-11-13 10:45:33" + }, + "headers": { + "operation": "insert", + "relation": [ + "public", + "items" + ] + }, + "offset": "0_0" + } +] +``` + +So far we've shown things working with Electric's lower-level [HTTP API](https://electric-sql.com/docs/api/http). You can also setup the [higher level clients](https://electric-sql.com/docs/api/clients/typescript) to use an auth token. See the [auth guide](https://electric-sql.com/docs/guides/auth) for more details. + +### 2. Caddy as proxy + +Run `postgres`, `electric`, `api` and `caddy` services with the `.env.caddy` env file: + +```shell +docker compose --env-file .env.caddy up postgres electric api caddy +``` + +As above, use the gatekeeper endpoint to generate an auth token. Note that the `url` has changed to point to Caddy: + +```console +$ curl -sX POST "http://localhost:4000/gatekeeper/items" | jq +{ + "headers": { + "authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJKb2tlbiIsImV4cCI6MTczMTUwNDUxNCwiaWF0IjoxNzMxNDk3MzE0LCJpc3MiOiJKb2tlbiIsImp0aSI6IjMwM283OGd1cWIxZ240ODhmazAwMDJnNCIsIm5iZiI6MTczMTQ5NzMxNCwic2hhcGUiOnsibmFtZXNwYWNlIjpudWxsLCJ0YWJsZSI6Iml0ZW1zIiwid2hlcmUiOm51bGwsImNvbHVtbnMiOm51bGx9fQ.EkSj-ro9-3chGyuxlAglOjo0Ln8t4HLVLQ4vCCNjMCY" + }, + "url": "http://localhost:8080/v1/shape", + "table": "items" +} +``` + +Copy the auth token and set it to an env var: + +```shell +export AUTH_TOKEN="" +``` + +Make an unauthorised shape request to Caddy: + +```console +$ curl -v "http://localhost:8080/v1/shape?table=items&offset=-1" +* Trying 127.0.0.1:8080... +* Connected to localhost (127.0.0.1) port 8080 (#0) +> GET /v1/shape?table=items&offset=-1 HTTP/1.1 +> Host: localhost:8080 +> User-Agent: curl/8.1.2 +> Accept: */* +> +< HTTP/1.1 401 Unauthorized +< Server: Caddy +< Date: Wed, 13 Nov 2024 11:30:22 GMT +< Content-Length: 0 +< +* Connection #0 to host localhost left intact +``` + +Make an authorised request to Caddy with the auth token: + +```console +$ curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ + "http://localhost:8080/v1/shape?table=items&offset=-1" +[] +``` + +Try making a request for a different shape: + +```console +$ curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ + "http://localhost:4000/proxy/v1/shape?table=items&offset=-1&where=true" +Forbidden +``` + +As you can see, Caddy is validating the shape request against the shape definition signed into the auth token. Take a look at the [`./caddy/Caddyfile`](./caddy/Caddyfile) for more details. + +### 3. Edge function as proxy + + diff --git a/examples/gatekeeper-auth/caddy/README.md b/examples/gatekeeper-auth/caddy/README.md new file mode 100644 index 0000000000..e26aa1ad38 --- /dev/null +++ b/examples/gatekeeper-auth/caddy/README.md @@ -0,0 +1,20 @@ + +# Caddy as authorising proxy + +This folder contains example configuration (the [`./Caddyfile`](./Caddyfile)) to run the [Caddy](https://caddyserver.com) web server as a authorising proxy for Electric. + +It uses the [ggicci/caddy-jwt](https://github.com/ggicci/caddy-jwt) module to validate and parse the shape definition out of a shape-scoped JWT auth token. It then uses Caddy's [request matchers](https://caddyserver.com/docs/caddyfile/matchers) to validate that the shape definition derived from the token matches the shape definition in the request. + +## How to run + +See the [2. Caddy as proxy](../README.md#2-caddy-as-proxy) section of the README in the root folder of this example. + +## Locally without Docker + +Alternatively, to run locally without Docker, you can open https://caddyserver.com/download?package=github.com%2Fggicci%2Fcaddy-jwt and click "Download" to download a pre-build Caddy binary for your environment with the `caddy-jwt` module installed. + +Copy the binary to this folder and run with e.g.: + +```shell +caddy run --config ./Caddyfile +``` diff --git a/examples/gatekeeper-auth/docker-compose.yaml b/examples/gatekeeper-auth/docker-compose.yaml new file mode 100644 index 0000000000..e392db30d9 --- /dev/null +++ b/examples/gatekeeper-auth/docker-compose.yaml @@ -0,0 +1,61 @@ +name: "gatekeeper" + +services: + postgres: + image: postgres:16-alpine + environment: + POSTGRES_DB: "electric" + POSTGRES_USER: "postgres" + POSTGRES_PASSWORD: "password" + ports: + - 54321:5432 + tmpfs: + - /var/lib/postgresql/data + - /tmp + command: + - -c + - listen_addresses=* + - -c + - wal_level=logical + + electric: + image: electricsql/electric:latest + environment: + DATABASE_URL: "postgresql://postgres:password@postgres:5432/electric?sslmode=disable" + ports: + - 3000:3000 + depends_on: + - postgres + + api: + image: gatekeeper-api:local-build + build: ./api + environment: + AUTH_TOKEN_SECRET: "NFL5*0Bc#9U6E@tnmC&E7SUN6GwHfLmY" + DATABASE_URL: "postgresql://postgres:password@postgres:5432/electric?sslmode=disable" + ELECTRIC_URL: "http://electric:3000" + ELECTRIC_PROXY_URL: "${ELECTRIC_PROXY_URL:-http://localhost:3000/proxy}" + PHX_HOST: "localhost" + PHX_PORT: 4000 + PHX_SCHEME: "http" + PHX_SERVER: true + SECRET_KEY_BASE: "pVvBh/U565dk0DteMtnoCjwLcoZnMDU9QeQNVr0gvVtYUrF8KqoJeyn5YJ0EQudX" + ports: + - 4000:4000 + depends_on: + - electric + + caddy: + image: mdirkse/caddy-jwt:2.7.5-0.9.2 + restart: unless-stopped + cap_add: + - NET_ADMIN + environment: + ELECTRIC_URL: http://electric:3000 + JWT_AUTH_SIGNING_KEY: "TkZMNSowQmMjOVU2RUB0bm1DJkU3U1VONkd3SGZMbVk=" + ports: + - 8080:8080 + volumes: + - $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile + depends_on: + - electric diff --git a/examples/gatekeeper-auth/docs/NOTES.md b/examples/gatekeeper-auth/docs/NOTES.md new file mode 100644 index 0000000000..39da05e4ae --- /dev/null +++ b/examples/gatekeeper-auth/docs/NOTES.md @@ -0,0 +1,12 @@ +### Seperating the concerns + +With the [proxy auth pattern](https://electric-sql.com/docs/guides/auth#proxy), the proxy performs authorisation logic on the shape request path. Performing this logic can be expensive. You may not want to query the database or call an external service every time you make a shape request [1]. It can also be a security concern. Do you want your database exposed to your edge worker? + +The gatekeeper pattern avoids these concerns by separating the steps of: + +1. running authorisation logic to determine whether a user should be able to access a shape +2. authorising a shape request to Electric + +Specifically, the gatekeeper endpoint is designed to perform authorisation logic *once* when generating the shape-scoped token. The proxy endpoint can then authorise multiple shape requests by validating the token against the shape definition in the request, without needing to know or do anything else. + +[1] Proxies can mitigate this in a number of ways, for example with some kind of local cache of client credentials against authorisation state. diff --git a/examples/gatekeeper-auth/docs/img/gatekeeper-flow.dark.png b/examples/gatekeeper-auth/docs/img/gatekeeper-flow.dark.png new file mode 100644 index 0000000000000000000000000000000000000000..355c86ceb65ac215a05b4161a75aaded9b6a61d2 GIT binary patch literal 80391 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ɶ%h#`-2`Y*!BTjqqJ0lA&!&}^g1Dshi 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�Mg3%@LXlrPq8V&^}bx~*+}ICQ-)XCHVL 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ⅅLqBDp7qLa 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 literal 0 HcmV?d00001 diff --git a/examples/gatekeeper-auth/docs/img/gatekeeper-flow.png b/examples/gatekeeper-auth/docs/img/gatekeeper-flow.png new file mode 100644 index 0000000000000000000000000000000000000000..a027a5492e4b562ad6b3eb1aeda2f70bf6a0bc28 GIT binary patch literal 66167 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 Date: Wed, 13 Nov 2024 13:13:07 +0100 Subject: [PATCH 13/40] docs: make the dark flow diagramme less neon. --- .../docs/img/gatekeeper-flow.dark.png | Bin 80391 -> 75259 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/examples/gatekeeper-auth/docs/img/gatekeeper-flow.dark.png b/examples/gatekeeper-auth/docs/img/gatekeeper-flow.dark.png index 355c86ceb65ac215a05b4161a75aaded9b6a61d2..21c8c8156b68db5c994e8e9d82dd518460b652bf 100644 GIT binary patch literal 75259 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%0DS}s{K@wlfUTjNiSKD9t)J5?W${D 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 literal 80391 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ɶ%h#`-2`Y*!BTjqqJ0lA&!&}^g1Dshi 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 Date: Wed, 13 Nov 2024 13:14:10 +0100 Subject: [PATCH 14/40] docs: fix link. --- examples/gatekeeper-auth/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md index 97a51d366c..0c03a5a893 100644 --- a/examples/gatekeeper-auth/README.md +++ b/examples/gatekeeper-auth/README.md @@ -31,7 +31,7 @@ The core of this example is an [Elixir/Phoenix](https://www.phoenixframework.org 1. a gatekeeper endpoint at `POST /gatekeeper/:table` 2. a proxy endpoint at `GET /proxy/v1/shape` - + From 025c6bb8973e43dbc673f4a26151b87ab05e0798 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Wed, 13 Nov 2024 13:20:54 +0100 Subject: [PATCH 15/40] docs: tidy up README. --- examples/gatekeeper-auth/README.md | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md index 0c03a5a893..7467baee0f 100644 --- a/examples/gatekeeper-auth/README.md +++ b/examples/gatekeeper-auth/README.md @@ -135,7 +135,7 @@ Success! We got an empty response because there are no `items` in the database. you can create some, e.g. using `psql`: ```console -~ psql "postgresql://postgres:password@localhost:54321/electric?sslmode=disable" +$ psql "postgresql://postgres:password@localhost:54321/electric?sslmode=disable" psql (16.4) Type "help" for help. @@ -212,26 +212,17 @@ Copy the auth token and set it to an env var: export AUTH_TOKEN="" ``` -Make an unauthorised shape request to Caddy: +An unauthorised request to Caddy will get a 401: ```console $ curl -v "http://localhost:8080/v1/shape?table=items&offset=-1" -* Trying 127.0.0.1:8080... -* Connected to localhost (127.0.0.1) port 8080 (#0) -> GET /v1/shape?table=items&offset=-1 HTTP/1.1 -> Host: localhost:8080 -> User-Agent: curl/8.1.2 -> Accept: */* -> +... < HTTP/1.1 401 Unauthorized < Server: Caddy -< Date: Wed, 13 Nov 2024 11:30:22 GMT -< Content-Length: 0 -< -* Connection #0 to host localhost left intact +... ``` -Make an authorised request to Caddy with the auth token: +An authorised request for the correct shape will succeed: ```console $ curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ @@ -239,7 +230,7 @@ $ curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ [] ``` -Try making a request for a different shape: +Caddy validates the shape request against the shape definition signed into the auth token. So an authorised request *for the wrong shape* will fail: ```console $ curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ @@ -247,7 +238,7 @@ $ curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ Forbidden ``` -As you can see, Caddy is validating the shape request against the shape definition signed into the auth token. Take a look at the [`./caddy/Caddyfile`](./caddy/Caddyfile) for more details. +Take a look at the [`./caddy/Caddyfile`](./caddy/Caddyfile) for more details. ### 3. Edge function as proxy From bc45f43d2e5635d22c3d6489cd8edb53ce7a9615 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Wed, 13 Nov 2024 13:22:58 +0100 Subject: [PATCH 16/40] caddy: tabs and spaces o_O. --- examples/gatekeeper-auth/caddy/Caddyfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/gatekeeper-auth/caddy/Caddyfile b/examples/gatekeeper-auth/caddy/Caddyfile index ff1af03e8d..286c3052ac 100644 --- a/examples/gatekeeper-auth/caddy/Caddyfile +++ b/examples/gatekeeper-auth/caddy/Caddyfile @@ -1,10 +1,10 @@ { - order jwtauth before basicauth + order jwtauth before basicauth } :8080 { jwtauth { - # You can sign and validate JWT tokens however you prefer. Here we + # You can sign and validate JWT tokens however you prefer. Here we # expect tokens to have been signed with the `HS256` algorithm and # a shared symmetric signing key to match the configuration in # `../api/lib/api/token.ex`, so that this example config validates @@ -63,7 +63,7 @@ expression {http.auth.user.where} == {http.request.uri.query.where} expression {http.auth.user.columns} == {http.request.uri.query.columns} - } + } # Route the request according to the matchers. handle @get_shape { From db6a02c89ca1b91d76e010cefe4137b227be6496 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Wed, 13 Nov 2024 13:57:09 +0100 Subject: [PATCH 17/40] caddy: use a local docker build. --- examples/gatekeeper-auth/README.md | 6 ++++++ examples/gatekeeper-auth/caddy/Dockerfile | 7 +++++++ examples/gatekeeper-auth/docker-compose.yaml | 6 ++---- 3 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 examples/gatekeeper-auth/caddy/Dockerfile diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md index 7467baee0f..ea576895c1 100644 --- a/examples/gatekeeper-auth/README.md +++ b/examples/gatekeeper-auth/README.md @@ -187,6 +187,12 @@ So far we've shown things working with Electric's lower-level [HTTP API](https:/ ### 2. Caddy as proxy +Build the local docker images: + +```shell +docker compose build api caddy +``` + Run `postgres`, `electric`, `api` and `caddy` services with the `.env.caddy` env file: ```shell diff --git a/examples/gatekeeper-auth/caddy/Dockerfile b/examples/gatekeeper-auth/caddy/Dockerfile new file mode 100644 index 0000000000..1d3a5d2d6e --- /dev/null +++ b/examples/gatekeeper-auth/caddy/Dockerfile @@ -0,0 +1,7 @@ +FROM caddy:2.8.4-builder-alpine AS builder + +RUN xcaddy build --with github.com/ggicci/caddy-jwt@v0.12.0 + +FROM caddy:2.8.4-alpine + +COPY --from=builder /usr/bin/caddy /usr/bin/caddy diff --git a/examples/gatekeeper-auth/docker-compose.yaml b/examples/gatekeeper-auth/docker-compose.yaml index e392db30d9..a596d61c7c 100644 --- a/examples/gatekeeper-auth/docker-compose.yaml +++ b/examples/gatekeeper-auth/docker-compose.yaml @@ -46,10 +46,8 @@ services: - electric caddy: - image: mdirkse/caddy-jwt:2.7.5-0.9.2 - restart: unless-stopped - cap_add: - - NET_ADMIN + image: caddy:local-build + build: ./caddy environment: ELECTRIC_URL: http://electric:3000 JWT_AUTH_SIGNING_KEY: "TkZMNSowQmMjOVU2RUB0bm1DJkU3U1VONkd3SGZMbVk=" From 68810c4aaed2d26013ccc568caa314dc71da8231 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Wed, 13 Nov 2024 13:57:59 +0100 Subject: [PATCH 18/40] caddy: fix and simplify the definition match expression. --- examples/gatekeeper-auth/caddy/Caddyfile | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/examples/gatekeeper-auth/caddy/Caddyfile b/examples/gatekeeper-auth/caddy/Caddyfile index 286c3052ac..72e1d890df 100644 --- a/examples/gatekeeper-auth/caddy/Caddyfile +++ b/examples/gatekeeper-auth/caddy/Caddyfile @@ -47,22 +47,19 @@ # So, for example, a claim of `{"shape": {"table": "items"}}` will match # a query parameter of `?table=items`. # - # Note that the first expression matches the request table param against - # either the shape `table` or `namespace.table` depending on whether the - # shape `namespace` is empty or not. + # Note that the first part of the expression matches the request table + # param against either the shape `table` or `namespace.table` depending + # on whether the shape `namespace` is empty or not. @definition_matches { expression < Date: Wed, 13 Nov 2024 22:54:43 +0100 Subject: [PATCH 19/40] docs: fix Caddy port in example usage. --- examples/gatekeeper-auth/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md index ea576895c1..84ca53bbe0 100644 --- a/examples/gatekeeper-auth/README.md +++ b/examples/gatekeeper-auth/README.md @@ -240,7 +240,7 @@ Caddy validates the shape request against the shape definition signed into the a ```console $ curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ - "http://localhost:4000/proxy/v1/shape?table=items&offset=-1&where=true" + "http://localhost:8080/v1/shape?table=items&offset=-1&where=true" Forbidden ``` From be2112f8d0f9e5facd60176da5314dd0b483e53a Mon Sep 17 00:00:00 2001 From: James Arthur Date: Wed, 13 Nov 2024 22:56:02 +0100 Subject: [PATCH 20/40] config: rename the auth secret to `AUTH_SECRET`. --- examples/gatekeeper-auth/api/config/dev.exs | 2 +- examples/gatekeeper-auth/api/config/runtime.exs | 8 ++++---- examples/gatekeeper-auth/api/config/test.exs | 2 +- examples/gatekeeper-auth/api/lib/api/token.ex | 2 +- examples/gatekeeper-auth/caddy/Caddyfile | 3 +-- examples/gatekeeper-auth/docker-compose.yaml | 6 ++++-- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/examples/gatekeeper-auth/api/config/dev.exs b/examples/gatekeeper-auth/api/config/dev.exs index 5b5438c453..782898a6fd 100644 --- a/examples/gatekeeper-auth/api/config/dev.exs +++ b/examples/gatekeeper-auth/api/config/dev.exs @@ -1,7 +1,7 @@ import Config config :api, - auth_token_secret: "NFL5*0Bc#9U6E@tnmC&E7SUN6GwHfLmY", + auth_secret: "NFL5*0Bc#9U6E@tnmC&E7SUN6GwHfLmY", # Configure the proxy endpoint to route shape requests to the external Electric # sync service, which we assume in development is running on `localhost:3000`. electric_url: "http://localhost:3000" diff --git a/examples/gatekeeper-auth/api/config/runtime.exs b/examples/gatekeeper-auth/api/config/runtime.exs index 0645a0d2ac..b62a145588 100644 --- a/examples/gatekeeper-auth/api/config/runtime.exs +++ b/examples/gatekeeper-auth/api/config/runtime.exs @@ -5,10 +5,10 @@ if System.get_env("PHX_SERVER") do end if config_env() == :prod do - auth_token_secret = - System.get_env("AUTH_TOKEN_SECRET") || + auth_secret = + System.get_env("AUTH_SECRET") || raise """ - environment variable AUTH_TOKEN_SECRET is missing. + environment variable AUTH_SECRET is missing. It should be a long random string. """ @@ -22,7 +22,7 @@ if config_env() == :prod do # Configure the proxy endpoint to route shape requests to the external # Electric sync service. config :api, - auth_token_secret: auth_token_secret, + auth_secret: auth_secret, electric_url: electric_url database_url = diff --git a/examples/gatekeeper-auth/api/config/test.exs b/examples/gatekeeper-auth/api/config/test.exs index 886c89a4b3..4b538ac2eb 100644 --- a/examples/gatekeeper-auth/api/config/test.exs +++ b/examples/gatekeeper-auth/api/config/test.exs @@ -3,7 +3,7 @@ import Config # Configure the proxy endpoint to route shape requests to the external Electric # sync service, which we assume in test is running on `localhost:3002`. config :api, - auth_token_secret: "NFL5*0Bc#9U6E@tnmC&E7SUN6GwHfLmY", + auth_secret: "NFL5*0Bc#9U6E@tnmC&E7SUN6GwHfLmY", electric_url: "http://localhost:3000" # Configure your database diff --git a/examples/gatekeeper-auth/api/lib/api/token.ex b/examples/gatekeeper-auth/api/lib/api/token.ex index e14dc0c340..723a2471c0 100644 --- a/examples/gatekeeper-auth/api/lib/api/token.ex +++ b/examples/gatekeeper-auth/api/lib/api/token.ex @@ -9,7 +9,7 @@ defmodule Api.Token do use Joken.Config def signer do - secret = Application.fetch_env!(:api, :auth_token_secret) + secret = Application.fetch_env!(:api, :auth_secret) Joken.Signer.create("HS256", secret) end diff --git a/examples/gatekeeper-auth/caddy/Caddyfile b/examples/gatekeeper-auth/caddy/Caddyfile index 72e1d890df..c3aa1f46bc 100644 --- a/examples/gatekeeper-auth/caddy/Caddyfile +++ b/examples/gatekeeper-auth/caddy/Caddyfile @@ -15,8 +15,7 @@ # sign_key "" # # See https://caddyserver.com/docs/modules/http.authentication.providers.jwt - # for more details. - sign_key {$JWT_AUTH_SIGNING_KEY:"TkZMNSowQmMjOVU2RUB0bm1DJkU3U1VONkd3SGZMbVk="} + sign_key {$AUTH_SECRET:"TkZMNSowQmMjOVU2RUB0bm1DJkU3U1VONkd3SGZMbVk="} sign_alg HS256 # The jwtauth module requires a user claim but we don't actually use diff --git a/examples/gatekeeper-auth/docker-compose.yaml b/examples/gatekeeper-auth/docker-compose.yaml index a596d61c7c..4ca672617e 100644 --- a/examples/gatekeeper-auth/docker-compose.yaml +++ b/examples/gatekeeper-auth/docker-compose.yaml @@ -31,7 +31,7 @@ services: image: gatekeeper-api:local-build build: ./api environment: - AUTH_TOKEN_SECRET: "NFL5*0Bc#9U6E@tnmC&E7SUN6GwHfLmY" + AUTH_SECRET: "NFL5*0Bc#9U6E@tnmC&E7SUN6GwHfLmY" DATABASE_URL: "postgresql://postgres:password@postgres:5432/electric?sslmode=disable" ELECTRIC_URL: "http://electric:3000" ELECTRIC_PROXY_URL: "${ELECTRIC_PROXY_URL:-http://localhost:3000/proxy}" @@ -49,8 +49,10 @@ services: image: caddy:local-build build: ./caddy environment: + # Caddy needs this key to be base64 encoded. So this is actually the same + # key as the "NFL5*0Bc#9U6E@tnmC&E7SUN6GwHfLmY" used by the other services. + AUTH_SECRET: "TkZMNSowQmMjOVU2RUB0bm1DJkU3U1VONkd3SGZMbVk=" ELECTRIC_URL: http://electric:3000 - JWT_AUTH_SIGNING_KEY: "TkZMNSowQmMjOVU2RUB0bm1DJkU3U1VONkd3SGZMbVk=" ports: - 8080:8080 volumes: From 68de2f1a5ae07f1a8f92dc6f5394b2f16fb0a7a9 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Wed, 13 Nov 2024 22:56:38 +0100 Subject: [PATCH 21/40] edge: add Supabase Edge Function proxy. --- examples/gatekeeper-auth/.env.edge | 1 + examples/gatekeeper-auth/README.md | 60 ++++++++++++++ examples/gatekeeper-auth/docker-compose.yaml | 13 +++ examples/gatekeeper-auth/edge/.gitignore | 2 + examples/gatekeeper-auth/edge/README.md | 81 +++++++++++++++++++ examples/gatekeeper-auth/edge/deno.json | 5 ++ examples/gatekeeper-auth/edge/index.ts | 83 ++++++++++++++++++++ 7 files changed, 245 insertions(+) create mode 100644 examples/gatekeeper-auth/.env.edge create mode 100644 examples/gatekeeper-auth/edge/.gitignore create mode 100644 examples/gatekeeper-auth/edge/README.md create mode 100644 examples/gatekeeper-auth/edge/deno.json create mode 100644 examples/gatekeeper-auth/edge/index.ts diff --git a/examples/gatekeeper-auth/.env.edge b/examples/gatekeeper-auth/.env.edge new file mode 100644 index 0000000000..0f1e51362f --- /dev/null +++ b/examples/gatekeeper-auth/.env.edge @@ -0,0 +1 @@ +ELECTRIC_PROXY_URL=http://localhost:8000 \ No newline at end of file diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md index 84ca53bbe0..67354c34ed 100644 --- a/examples/gatekeeper-auth/README.md +++ b/examples/gatekeeper-auth/README.md @@ -248,4 +248,64 @@ Take a look at the [`./caddy/Caddyfile`](./caddy/Caddyfile) for more details. ### 3. Edge function as proxy +Electric is [designed to run behind a CDN](https://electric-sql.com/docs/api/http#caching). This makes sync faster and more scalable. However, it means that if you want to authorise access to the Electric API using a proxy, you need to run that proxy in-front-of the CDN. +You can do this with a centralised proxy, like your API, or a reverse-proxy like Caddy. However, running these in front of a CDN from a central location reduces the benefit of the CDN — adding latency and introducing a bottleneck / single point of failure. + +So, it's often better (faster, more scalable and a more natural topology) to run your authorising proxy at the edge, between your CDN and your user. The gatekeeper pattern works well for this because it minimises both the logic that your edge proxy needs to perform and the network access and credentials that it needs to be granted. + +The example in the [`./edge`](./edge) folder shows a Deno server that's designed to match the code you would deploy to a [Supabase Edge Function](https://supabase.com/docs/guides/functions/quickstart). See the README in the folder for more information about deploying to Supabase. + +Here, we'll run it locally using Docker in order to demonstrate it working with the other services: + +```shell +docker compose --env-file .env.edge up postgres electric api edge +``` + +As above, first hit the gatekeeper endpoint to get an auth token: + +```console +$ curl -sX POST "http://localhost:4000/gatekeeper/items" | jq +{ + "headers": { + "authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJKb2tlbiIsImV4cCI6MTczMTUyNDQ1OSwiaWF0IjoxNzMxNTE3MjU5LCJpc3MiOiJKb2tlbiIsImp0aSI6IjMwM3BiaGdob2phcW5pYnE4YzAwMDAwMiIsIm5iZiI6MTczMTUxNzI1OSwic2hhcGUiOnsibmFtZXNwYWNlIjpudWxsLCJ0YWJsZSI6Iml0ZW1zIiwid2hlcmUiOm51bGwsImNvbHVtbnMiOm51bGx9fQ.dNAhTVEUtWGjAoX7IbwX1ccpwZP5sUYTIiTaJnSmaTU" + }, + "url": "http://localhost:8000/v1/shape", + "table": "items" +} +``` + +Copy the auth token and set it to an env var: + +```shell +export AUTH_TOKEN="" +``` + +An unauthorised request to the edge-function proxy will get a 401: + +```console +$ curl -v "http://localhost:8000/v1/shape?table=items&offset=-1" +... +< HTTP/1.1 401 Unauthorized +... +``` + +An authorised request for the correct shape will succeed: + +```console +$ curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ + "http://localhost:8000/v1/shape?table=items&offset=-1" +[] +``` + +An authorised request for the wrong shape will fail: + +```console +$ curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ + "http://localhost:8000/v1/shape?table=items&offset=-1&where=true" +Forbidden +``` + +## More information + +See the [Auth guide](https://electric-sql.com/docs/guides/auth). If you have any questions about this example please feel free to [ask on Discord](https://discord.electric-sql.com). diff --git a/examples/gatekeeper-auth/docker-compose.yaml b/examples/gatekeeper-auth/docker-compose.yaml index 4ca672617e..d5346baa35 100644 --- a/examples/gatekeeper-auth/docker-compose.yaml +++ b/examples/gatekeeper-auth/docker-compose.yaml @@ -59,3 +59,16 @@ services: - $PWD/caddy/Caddyfile:/etc/caddy/Caddyfile depends_on: - electric + + edge: + image: denoland/deno:2.0.6 + command: run --allow-env --allow-net /app/index.ts + environment: + ELECTRIC_URL: http://electric:3000 + AUTH_SECRET: "NFL5*0Bc#9U6E@tnmC&E7SUN6GwHfLmY" + ports: + - 8000:8000 + volumes: + - $PWD/edge:/app + depends_on: + - electric diff --git a/examples/gatekeeper-auth/edge/.gitignore b/examples/gatekeeper-auth/edge/.gitignore new file mode 100644 index 0000000000..e80bbba6e1 --- /dev/null +++ b/examples/gatekeeper-auth/edge/.gitignore @@ -0,0 +1,2 @@ +deno.lock +supabase/ diff --git a/examples/gatekeeper-auth/edge/README.md b/examples/gatekeeper-auth/edge/README.md new file mode 100644 index 0000000000..6f7f4a23cb --- /dev/null +++ b/examples/gatekeeper-auth/edge/README.md @@ -0,0 +1,81 @@ + +# Edge function as an authorising proxy + +This folder contains example edge function ([`./index.ts`](./index.ts)) which you can run as a authorising proxy for Electric. + +It uses the [jsonwebtoken](https://www.npmjs.com/package/jsonwebtoken) NPM package to validate and parse the shape definition out of a shape-scoped JWT auth token. It then uses standard Javascript functions to validate that the shape definition derived from the token matches the shape definition in the request parameters. + +## How to run + +See the [3. Edge function as proxy](../README.md#2-edge-function-as-proxy) section of the README in the root folder of this example to run using Docker. + +### Locally without Docker + +It's just a [Deno server](https://docs.deno.com/runtime/fundamentals/http_server/). Make sure you have [Deno installed](https://docs.deno.com/runtime/getting_started/installation/) and then run: + +```shell +deno run --allow-env --allow-net index.ts +``` + +### As a Supabase Edge Function + +One of the key things about using an edge function as an authorising proxy is that it can run close to your users, in front of a CDN. This example is designed to match the code you would deploy to a [Supabase Edge Function](https://supabase.com/docs/guides/functions). + +Follow their [Quickstart guide](https://supabase.com/docs/guides/functions/quickstart) for instructions and their docs on [setting secrets](https://supabase.com/docs/guides/functions/secrets) as environment variables. + +In short you run: + +```shell +supabase init +supabase functions new $YOUR_FUNCTION_NAME +``` + +Copy `./index.ts` and `./deno.json` into the `./supabase/functions/$YOUR_FUNCTION_NAME` folder. You can then run locally with: + +```shell +supabase start +supabase functions server +``` + +And then hit it at `http://localhost:54321/functions/v1/$YOUR_FUNCTION_NAME`, e.g.: + +```shell +export FUNCTION_URL="http://localhost:54321/functions/v1/${YOUR_FUNCTION_NAME}" + +curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ + "${FUNCTION_URL}/v1/shape?table=items&offset=-1" +``` + +To deploy, you login using + +```shell +supabase login +``` + +Link a project using: + +```shell +supabase link --project-ref $YOUR_PROJECT_ID +``` + +Deploy using the `--no-verify-jwt` flag to disable Supabase's built-in JWT validation: + +```shell +supabase functions deploy --no-verify-jwt +``` + +Set your env vars using `supabase secrets set`: + +```shell +# ngrok http 3000 +supabase secrets set ELECTRIC_URL=https://example.ngrok.app +``` + +Hit the deployed function at `https://$YOUR_PROJECT_ID.supabase.co/functions/v1/$YOUR_FUNCTION_NAME`: + +```shell +export FUNCTION_URL="https://${YOUR_PROJECT_ID}.supabase.co/functions/v1/${YOUR_FUNCTION_NAME}" + +curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ + "${FUNCTION_URL}/v1/shape?table=items&offset=-1" +``` \ No newline at end of file diff --git a/examples/gatekeeper-auth/edge/deno.json b/examples/gatekeeper-auth/edge/deno.json new file mode 100644 index 0000000000..1720d4c203 --- /dev/null +++ b/examples/gatekeeper-auth/edge/deno.json @@ -0,0 +1,5 @@ +{ + "imports": { + "jsonwebtoken": "npm:jsonwebtoken" + } +} \ No newline at end of file diff --git a/examples/gatekeeper-auth/edge/index.ts b/examples/gatekeeper-auth/edge/index.ts new file mode 100644 index 0000000000..25e7e5ee02 --- /dev/null +++ b/examples/gatekeeper-auth/edge/index.ts @@ -0,0 +1,83 @@ +import jwt from 'jsonwebtoken' + +const AUTH_SECRET = Deno.env.get("AUTH_SECRET") || "NFL5*0Bc#9U6E@tnmC&E7SUN6GwHfLmY" +const ELECTRIC_URL = Deno.env.get("ELECTRIC_URL") || "http://localhost:3000" + +/** + * Match `GET /v1/shape` requests. + */ +function isGetShapeRequest(method, path) { + return method === 'GET' && path.endsWith('/v1/shape') +} + +/** + * Allow requests with a valid JWT in the auth header. + */ +function verifyAuthHeader(headers) { + const auth_header = headers.get("Authorization") + + if (auth_header === null) { + return [false, null] + } + + const token = auth_header.split("Bearer ")[1] + + try { + const claims = jwt.verify(token, AUTH_SECRET, {algorithms: ["HS256"]}) + + return [true, claims] + } + catch (err) { + console.warn(err) + + return [false, null] + } +} + +/** + * Allow requests where the signed `shape` definition in the JWT claims + * matches the shape definition in the request `params`. + */ +function matchesDefinition(shape, params) { + if (shape === null || !shape.hasOwnProperty('table')) { + return false + } + + const table = shape.namespace !== null + ? `${shape.namespace}.${shape.table}` + : shape.table + + if (table === null || table !== params.get('table')) { + return false + } + + if (shape.where !== params.get('where')) { + return false + } + + if (shape.columns !== params.get('columns')) { + return false + } + + return true +} + +// Handle requests to the server / edge function. +Deno.serve((req) => { + const url = new URL(req.url) + if (!isGetShapeRequest(req.method, url.pathname)) { + return new Response("Not found", {status: 404}) + } + + const [isValidJWT, claims] = verifyAuthHeader(req.headers) + if (!isValidJWT) { + return new Response("Unauthorized", {status: 401}) + } + + if (!matchesDefinition(claims.shape, url.searchParams)) { + return new Response("Forbidden", {status: 403}) + } + + // Reverse-proxy the request on to the Electric sync service. + return fetch(`${ELECTRIC_URL}/v1/shape${url.search}`, {headers: req.headers}) +}) From 09decf5b32f0c20e4435e1a0f25a69986f1c9747 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Wed, 13 Nov 2024 22:59:54 +0100 Subject: [PATCH 22/40] docs: fix tip syntax. --- examples/gatekeeper-auth/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md index 67354c34ed..a6ecd8eab1 100644 --- a/examples/gatekeeper-auth/README.md +++ b/examples/gatekeeper-auth/README.md @@ -70,7 +70,7 @@ You need [Docker Compose](https://docs.docker.com/compose/) and [curl](https://c The instructions below all use the same [`./docker-compose.yaml`](./docker-compose.yaml) file in the root of this repo. With a different set of services and environment variables. -> [!Tip] Running Postgres and Electric +> [!TIP] Running Postgres and Electric > All of the configurations are based on running Postgres and Electric. This is handled for you by the `./docker-compose.yaml`. However, if you're unfamiliar with how Electric works, it may be useful to go through the [Quickstart](https://electric-sql.com/docs/quickstart) and [Installation](https://electric-sql.com/docs/guides/installation) guides. ### 1. API as gatekeeper and proxy From 00c85d5ee917caa7ac8719cc92793c2799e516b2 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Wed, 13 Nov 2024 23:01:01 +0100 Subject: [PATCH 23/40] docs: try that again. --- examples/gatekeeper-auth/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md index a6ecd8eab1..dbe51bffff 100644 --- a/examples/gatekeeper-auth/README.md +++ b/examples/gatekeeper-auth/README.md @@ -70,7 +70,7 @@ You need [Docker Compose](https://docs.docker.com/compose/) and [curl](https://c The instructions below all use the same [`./docker-compose.yaml`](./docker-compose.yaml) file in the root of this repo. With a different set of services and environment variables. -> [!TIP] Running Postgres and Electric +> [!TIP] > All of the configurations are based on running Postgres and Electric. This is handled for you by the `./docker-compose.yaml`. However, if you're unfamiliar with how Electric works, it may be useful to go through the [Quickstart](https://electric-sql.com/docs/quickstart) and [Installation](https://electric-sql.com/docs/guides/installation) guides. ### 1. API as gatekeeper and proxy From 07a48d4086e2bcdc5b4b9f2c92c846aaa801e116 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Wed, 13 Nov 2024 23:08:09 +0100 Subject: [PATCH 24/40] docs: tidy up the api README. --- examples/gatekeeper-auth/api/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/gatekeeper-auth/api/README.md b/examples/gatekeeper-auth/api/README.md index 711126efa1..e8122f8150 100644 --- a/examples/gatekeeper-auth/api/README.md +++ b/examples/gatekeeper-auth/api/README.md @@ -1,15 +1,15 @@ -# API gatekeeper and proxy +# API gatekeeper (and proxy) application This is a [Phoenix](https://www.phoenixframework.org) web application written in [Elixir](https://elixir-lang.org). -See the [Implementation](../README.md#implementation) section of the README in the root folder of this example for context and instructions on how to run using Docker Compose. +See the [Implementation](../README.md#implementation) and [How to run](../README.md#how-to-run) sections of the README in the root folder of this example for more context about the application and instructions on how to run it using Docker Compose. -## Locally without Docker +## Run/develop locally without Docker -Alternatively you can run locally without Docker. See the [Phoenix Installation](https://hexdocs.pm/phoenix/installation.html) for pre-reqs. +See the [Phoenix Installation](https://hexdocs.pm/phoenix/installation.html) page for pre-reqs. -Install and setup dependencies: +Install and setup the dependencies: ```shell mix setup @@ -23,6 +23,6 @@ mix test Run locally: -``` +```shell mix phx.server ``` From 7c1ed83e9954b7ba9b4d5c6e64db99cb90dccf90 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Wed, 13 Nov 2024 23:16:47 +0100 Subject: [PATCH 25/40] docs: add code pointers to api README. --- examples/gatekeeper-auth/api/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/examples/gatekeeper-auth/api/README.md b/examples/gatekeeper-auth/api/README.md index e8122f8150..0c40a1b5d8 100644 --- a/examples/gatekeeper-auth/api/README.md +++ b/examples/gatekeeper-auth/api/README.md @@ -5,6 +5,12 @@ This is a [Phoenix](https://www.phoenixframework.org) web application written in See the [Implementation](../README.md#implementation) and [How to run](../README.md#how-to-run) sections of the README in the root folder of this example for more context about the application and instructions on how to run it using Docker Compose. +## Understanding the code + +Take a look at [`./lib/api_web/router.ex`](./lib/api_web/router.ex) to see what's exposed and read through the [`./lib/api_web/plugs`](./lib/api_web/plugs) and [`./lib/api_web/authenticator.ex`](./lib/api_web/authenticator.ex) to see how auth is implemented and could be extended. + +The gatekeeper endpoint is based on an [`Electric.Phoenix.Gateway.Plug`](https://hexdocs.pm/electric_phoenix/Electric.Phoenix.Gateway.Plug.html). + ## Run/develop locally without Docker See the [Phoenix Installation](https://hexdocs.pm/phoenix/installation.html) page for pre-reqs. From 4ab286c5fc08c5855a8bcea388224da238f10b81 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Wed, 13 Nov 2024 23:35:33 +0100 Subject: [PATCH 26/40] docs: api comment tweaks. --- .../api/lib/api_web/plugs/auth/verify_token.ex | 7 ++++--- examples/gatekeeper-auth/api/lib/api_web/router.ex | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex b/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex index 3f481e3950..518c1ed5d5 100644 --- a/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex +++ b/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex @@ -1,8 +1,9 @@ defmodule ApiWeb.Plugs.Auth.VerifyToken do @moduledoc """ - Verify that the token matches the shape. We do this by comparing the - shape defined in the request query params with the shape signed into - the auth token claims. + Verify that the auth token in the Authorization header matches the shape. + + We do this by comparing the shape defined in the request query params with + the shape signed into the auth token claims. So you can't proxy a shape request without having a signed token for that exact shape definition. diff --git a/examples/gatekeeper-auth/api/lib/api_web/router.ex b/examples/gatekeeper-auth/api/lib/api_web/router.ex index e737d7e36c..7aecf1a3f0 100644 --- a/examples/gatekeeper-auth/api/lib/api_web/router.ex +++ b/examples/gatekeeper-auth/api/lib/api_web/router.ex @@ -23,7 +23,7 @@ defmodule ApiWeb.Router do # The gatekeeper endpoint at `POST /gatekeeper/:table` authenticates the user, # authorises the shape access, generates a shape-scoped auth token and returns - # this along with other config that the Electric client can use to stream the + # this along with other config that an Electric client can use to stream the # shape directly from Electric. scope "/gatekeeper" do pipe_through :gatekeeper @@ -31,8 +31,8 @@ defmodule ApiWeb.Router do post "/:table", Electric.Phoenix.Gateway.Plug, client: &Authenticator.client/0 end - # The proxy endpoint at `GET /proxy/v1/shape` proxies the request to the - # external Electric service. + # The proxy endpoint at `GET /proxy/v1/shape` proxies the request to an + # upstream Electric service. # # Access to this endpoint is protected by the `:proxy` pipeline, which verifies # a shape signed token, generated by the gatekeeper endpoint above. From 02c00a2499980f8a410992baba5ce34c57f0270b Mon Sep 17 00:00:00 2001 From: James Arthur Date: Wed, 13 Nov 2024 23:43:43 +0100 Subject: [PATCH 27/40] api: capitalise `Authorization`. --- examples/gatekeeper-auth/README.md | 8 ++++---- .../gatekeeper-auth/api/lib/api_web/authenticator.ex | 9 ++++++--- .../api/lib/api_web/plugs/auth/verify_token.ex | 4 +--- .../api/test/api_web/authenticator_test.exs | 2 +- .../gatekeeper-auth/api/test/api_web/gatekeeper_test.exs | 2 +- .../api/test/api_web/integration_test.exs | 4 ++-- 6 files changed, 15 insertions(+), 14 deletions(-) diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md index dbe51bffff..9c167bcdcc 100644 --- a/examples/gatekeeper-auth/README.md +++ b/examples/gatekeeper-auth/README.md @@ -97,7 +97,7 @@ In a new terminal, make a `POST` request to the gatekeeper endpoint: $ curl -sX POST "http://localhost:4000/gatekeeper/items" | jq { "headers": { - "authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJKb2tlbiIsImV4cCI6MTczMTUwMjM2OSwiaWF0IjoxNzMxNDk1MTY5LCJpc3MiOiJKb2tlbiIsImp0aSI6IjMwM28zYmx0czN2aHYydXNiazAwMDJrMiIsIm5iZiI6MTczMTQ5NTE2OSwic2hhcGUiOnsibmFtZXNwYWNlIjpudWxsLCJ0YWJsZSI6Iml0ZW1zIiwid2hlcmUiOm51bGwsImNvbHVtbnMiOm51bGx9fQ.8UZehIWk1EDQ3dJ4ggCBNkx9vGudfrD9appqs8r6zRI" + "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJKb2tlbiIsImV4cCI6MTczMTUwMjM2OSwiaWF0IjoxNzMxNDk1MTY5LCJpc3MiOiJKb2tlbiIsImp0aSI6IjMwM28zYmx0czN2aHYydXNiazAwMDJrMiIsIm5iZiI6MTczMTQ5NTE2OSwic2hhcGUiOnsibmFtZXNwYWNlIjpudWxsLCJ0YWJsZSI6Iml0ZW1zIiwid2hlcmUiOm51bGwsImNvbHVtbnMiOm51bGx9fQ.8UZehIWk1EDQ3dJ4ggCBNkx9vGudfrD9appqs8r6zRI" }, "url": "http://localhost:3000/proxy/v1/shape", "table": "items" @@ -108,7 +108,7 @@ You'll see that the response contains: - the proxy `url` to make shape requests to (`http://localhost:4000/proxy/v1/shape`) - the request parameters for the shape we're requesting, in this case `"table": "items"` -- an `authorization` header, containing a `Bearer ` +- an `Authorization` header, containing a `Bearer ` Copy the auth token and set it to an env var: @@ -205,7 +205,7 @@ As above, use the gatekeeper endpoint to generate an auth token. Note that the ` $ curl -sX POST "http://localhost:4000/gatekeeper/items" | jq { "headers": { - "authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJKb2tlbiIsImV4cCI6MTczMTUwNDUxNCwiaWF0IjoxNzMxNDk3MzE0LCJpc3MiOiJKb2tlbiIsImp0aSI6IjMwM283OGd1cWIxZ240ODhmazAwMDJnNCIsIm5iZiI6MTczMTQ5NzMxNCwic2hhcGUiOnsibmFtZXNwYWNlIjpudWxsLCJ0YWJsZSI6Iml0ZW1zIiwid2hlcmUiOm51bGwsImNvbHVtbnMiOm51bGx9fQ.EkSj-ro9-3chGyuxlAglOjo0Ln8t4HLVLQ4vCCNjMCY" + "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJKb2tlbiIsImV4cCI6MTczMTUwNDUxNCwiaWF0IjoxNzMxNDk3MzE0LCJpc3MiOiJKb2tlbiIsImp0aSI6IjMwM283OGd1cWIxZ240ODhmazAwMDJnNCIsIm5iZiI6MTczMTQ5NzMxNCwic2hhcGUiOnsibmFtZXNwYWNlIjpudWxsLCJ0YWJsZSI6Iml0ZW1zIiwid2hlcmUiOm51bGwsImNvbHVtbnMiOm51bGx9fQ.EkSj-ro9-3chGyuxlAglOjo0Ln8t4HLVLQ4vCCNjMCY" }, "url": "http://localhost:8080/v1/shape", "table": "items" @@ -268,7 +268,7 @@ As above, first hit the gatekeeper endpoint to get an auth token: $ curl -sX POST "http://localhost:4000/gatekeeper/items" | jq { "headers": { - "authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJKb2tlbiIsImV4cCI6MTczMTUyNDQ1OSwiaWF0IjoxNzMxNTE3MjU5LCJpc3MiOiJKb2tlbiIsImp0aSI6IjMwM3BiaGdob2phcW5pYnE4YzAwMDAwMiIsIm5iZiI6MTczMTUxNzI1OSwic2hhcGUiOnsibmFtZXNwYWNlIjpudWxsLCJ0YWJsZSI6Iml0ZW1zIiwid2hlcmUiOm51bGwsImNvbHVtbnMiOm51bGx9fQ.dNAhTVEUtWGjAoX7IbwX1ccpwZP5sUYTIiTaJnSmaTU" + "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJKb2tlbiIsImV4cCI6MTczMTUyNDQ1OSwiaWF0IjoxNzMxNTE3MjU5LCJpc3MiOiJKb2tlbiIsImp0aSI6IjMwM3BiaGdob2phcW5pYnE4YzAwMDAwMiIsIm5iZiI6MTczMTUxNzI1OSwic2hhcGUiOnsibmFtZXNwYWNlIjpudWxsLCJ0YWJsZSI6Iml0ZW1zIiwid2hlcmUiOm51bGwsImNvbHVtbnMiOm51bGx9fQ.dNAhTVEUtWGjAoX7IbwX1ccpwZP5sUYTIiTaJnSmaTU" }, "url": "http://localhost:8000/v1/shape", "table": "items" diff --git a/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex b/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex index 76e52a5208..24a328251e 100644 --- a/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex +++ b/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex @@ -7,7 +7,7 @@ defmodule ApiWeb.Authenticator do alias Electric.Client @behaviour Client.Authenticator - @header "authorization" + @header "Authorization" def authenticate_shape(shape, _config) do %{@header => "Bearer #{Token.generate(shape)}"} @@ -17,8 +17,11 @@ defmodule ApiWeb.Authenticator do request end - def authorise(shape, headers) do - with {:ok, "Bearer " <> token} <- Map.fetch(headers, @header) do + def authorise(shape, header_list) do + headers = Enum.into(header_list, %{}) + header_name = String.downcase(@header) + + with {:ok, "Bearer " <> token} <- Map.fetch(headers, header_name) do Token.verify(shape, token) end end diff --git a/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex b/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex index 518c1ed5d5..8544d3bedf 100644 --- a/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex +++ b/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex @@ -14,9 +14,7 @@ defmodule ApiWeb.Plugs.Auth.VerifyToken do def init(opts), do: opts - def call(%{assigns: %{shape: shape}, req_headers: header_list} = conn, _opts) do - headers = Enum.into(header_list, %{}) - + def call(%{assigns: %{shape: shape}, req_headers: headers} = conn, _opts) do case Authenticator.authorise(shape, headers) do true -> conn diff --git a/examples/gatekeeper-auth/api/test/api_web/authenticator_test.exs b/examples/gatekeeper-auth/api/test/api_web/authenticator_test.exs index ac86af2b5a..4f19a2a3dd 100644 --- a/examples/gatekeeper-auth/api/test/api_web/authenticator_test.exs +++ b/examples/gatekeeper-auth/api/test/api_web/authenticator_test.exs @@ -8,7 +8,7 @@ defmodule ApiWeb.AuthenticatorTest do test "generate token" do {:ok, shape} = Shape.from(%{"table" => "foo"}) - assert %{"authorization" => "Bearer " <> _token} = + assert %{"Authorization" => "Bearer " <> _token} = Authenticator.authenticate_shape(shape, nil) end diff --git a/examples/gatekeeper-auth/api/test/api_web/gatekeeper_test.exs b/examples/gatekeeper-auth/api/test/api_web/gatekeeper_test.exs index e0afe72814..67df0fdfe0 100644 --- a/examples/gatekeeper-auth/api/test/api_web/gatekeeper_test.exs +++ b/examples/gatekeeper-auth/api/test/api_web/gatekeeper_test.exs @@ -43,7 +43,7 @@ defmodule ApiWeb.GatekeeperTest do |> post("/gatekeeper/items") |> json_response(200) - assert %{"headers" => %{"authorization" => "Bearer " <> _token}} = data + assert %{"headers" => %{"Authorization" => "Bearer " <> _token}} = data end test "generates a valid auth header", %{conn: conn} do diff --git a/examples/gatekeeper-auth/api/test/api_web/integration_test.exs b/examples/gatekeeper-auth/api/test/api_web/integration_test.exs index 6f28d80177..59fa7237e0 100644 --- a/examples/gatekeeper-auth/api/test/api_web/integration_test.exs +++ b/examples/gatekeeper-auth/api/test/api_web/integration_test.exs @@ -12,7 +12,7 @@ defmodule ApiWeb.IntegrationTest do where = "value IS NOT NULL" # Fetch the client config from the gatekeeper endpoint. - assert %{"headers" => %{"authorization" => auth_header}} = + assert %{"headers" => %{"Authorization" => auth_header}} = conn |> post("/gatekeeper/#{table}", where: where) |> json_response(200) @@ -42,7 +42,7 @@ defmodule ApiWeb.IntegrationTest do conn = headers - |> Enum.reduce(conn, fn {k, v}, acc -> put_req_header(acc, k, v) end) + |> Enum.reduce(conn, fn {k, v}, acc -> put_req_header(acc, String.downcase(k), v) end) |> get(path, params) assert [] = json_response(conn, 200) From bf66b6f7e8c998907df3f0d14c0f88401aca801a Mon Sep 17 00:00:00 2001 From: James Arthur Date: Wed, 13 Nov 2024 23:45:43 +0100 Subject: [PATCH 28/40] api: slightly clearer variable names. --- .../gatekeeper-auth/api/lib/api_web/authenticator.ex | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex b/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex index 24a328251e..907b8069f4 100644 --- a/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex +++ b/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex @@ -7,21 +7,21 @@ defmodule ApiWeb.Authenticator do alias Electric.Client @behaviour Client.Authenticator - @header "Authorization" + @header_name "Authorization" def authenticate_shape(shape, _config) do - %{@header => "Bearer #{Token.generate(shape)}"} + %{@header_name => "Bearer #{Token.generate(shape)}"} end def authenticate_request(request, _config) do request end - def authorise(shape, header_list) do - headers = Enum.into(header_list, %{}) - header_name = String.downcase(@header) + def authorise(shape, request_header_list) do + header_map = Enum.into(request_header_list, %{}) + header_key = String.downcase(@header_name) - with {:ok, "Bearer " <> token} <- Map.fetch(headers, header_name) do + with {:ok, "Bearer " <> token} <- Map.fetch(header_map, header_key) do Token.verify(shape, token) end end From a4e5159f31af9bad84f12a9c3cb3e450122c734c Mon Sep 17 00:00:00 2001 From: James Arthur Date: Thu, 14 Nov 2024 00:01:40 +0100 Subject: [PATCH 29/40] docs: hyperlink `jq`. --- examples/gatekeeper-auth/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md index 9c167bcdcc..2da74a8578 100644 --- a/examples/gatekeeper-auth/README.md +++ b/examples/gatekeeper-auth/README.md @@ -66,7 +66,7 @@ It makes sense to run through these in order. ### Pre-reqs -You need [Docker Compose](https://docs.docker.com/compose/) and [curl](https://curl.se). We also (optionally) pipe into `jq` for JSON formatting. +You need [Docker Compose](https://docs.docker.com/compose/) and [curl](https://curl.se). We also (optionally) pipe into [`jq`](https://jqlang.github.io/jq/) for JSON formatting. The instructions below all use the same [`./docker-compose.yaml`](./docker-compose.yaml) file in the root of this repo. With a different set of services and environment variables. From 8431ce92f0f4fb93362db66a76309cfc2599e03a Mon Sep 17 00:00:00 2001 From: James Arthur Date: Thu, 14 Nov 2024 00:02:00 +0100 Subject: [PATCH 30/40] docs: fix example SQL insert to use simplified schema. --- examples/gatekeeper-auth/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md index 2da74a8578..9b37439c2f 100644 --- a/examples/gatekeeper-auth/README.md +++ b/examples/gatekeeper-auth/README.md @@ -152,7 +152,7 @@ electric=# select * from items; ----+-------+-------------+------------ (0 rows) -electric=# insert into items (id, inserted_at, updated_at) values (gen_random_uuid(), now(), now()); +electric=# insert into items (id) values (gen_random_uuid()); INSERT 0 1 electric=# \q ``` From 46140f881a4c077e7296b0dadfd20deb4716b3a7 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Thu, 14 Nov 2024 00:02:22 +0100 Subject: [PATCH 31/40] docs: tweak edge function intro copy. --- examples/gatekeeper-auth/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md index 9b37439c2f..c1b47177fe 100644 --- a/examples/gatekeeper-auth/README.md +++ b/examples/gatekeeper-auth/README.md @@ -250,9 +250,9 @@ Take a look at the [`./caddy/Caddyfile`](./caddy/Caddyfile) for more details. Electric is [designed to run behind a CDN](https://electric-sql.com/docs/api/http#caching). This makes sync faster and more scalable. However, it means that if you want to authorise access to the Electric API using a proxy, you need to run that proxy in-front-of the CDN. -You can do this with a centralised proxy, like your API, or a reverse-proxy like Caddy. However, running these in front of a CDN from a central location reduces the benefit of the CDN — adding latency and introducing a bottleneck / single point of failure. +You can do this with a centralised cloud proxy, such as an API endpoint deployed as part of a backend web service. Or a reverse-proxy like Caddy that's deployed next to your Electric service. However, running these in front of a CDN from a central location reduces the benefit of the CDN — adding latency and introducing a bottleneck. -So, it's often better (faster, more scalable and a more natural topology) to run your authorising proxy at the edge, between your CDN and your user. The gatekeeper pattern works well for this because it minimises both the logic that your edge proxy needs to perform and the network access and credentials that it needs to be granted. +It's often better (faster, more scalable and a more natural topology) to run your authorising proxy at the edge, between your CDN and your user. The gatekeeper pattern works well for this because it minimises both the logic that your edge proxy needs to perform and the network access and credentials that it needs to be granted. The example in the [`./edge`](./edge) folder shows a Deno server that's designed to match the code you would deploy to a [Supabase Edge Function](https://supabase.com/docs/guides/functions/quickstart). See the README in the folder for more information about deploying to Supabase. From ae83170c67e178a467c59a68050ad9e44a6c8f5e Mon Sep 17 00:00:00 2001 From: James Arthur Date: Thu, 14 Nov 2024 00:26:47 +0100 Subject: [PATCH 32/40] docs: add package.json. --- examples/gatekeeper-auth/package.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 examples/gatekeeper-auth/package.json diff --git a/examples/gatekeeper-auth/package.json b/examples/gatekeeper-auth/package.json new file mode 100644 index 0000000000..74811f78f6 --- /dev/null +++ b/examples/gatekeeper-auth/package.json @@ -0,0 +1,5 @@ +{ + "name": "@electric-examples/gatekeeper-auth-example", + "private": true, + "version": "0.0.1" +} From 478dae97f5c86eb44a27cf1dc19c82ab82def8e5 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Thu, 14 Nov 2024 00:56:13 +0100 Subject: [PATCH 33/40] pnpm: update lock file. --- pnpm-lock.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 17f610ab50..7c8f7d00c4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -112,6 +112,8 @@ importers: specifier: ^5.3.4 version: 5.3.4(@types/node@20.14.11) + examples/gatekeeper-auth: {} + examples/linearlite: dependencies: '@electric-sql/client': @@ -644,6 +646,8 @@ importers: specifier: ^0.0.9 version: 0.0.9 + packages/elixir-client: {} + packages/react-hooks: dependencies: '@electric-sql/client': From 69ff01ca39ac585ce622f9d1cfbf9140ac3cebb8 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Thu, 14 Nov 2024 00:58:04 +0100 Subject: [PATCH 34/40] docs: clearer curl examples. --- examples/gatekeeper-auth/README.md | 69 ++++++++++++++++--------- examples/gatekeeper-auth/edge/README.md | 10 +++- 2 files changed, 54 insertions(+), 25 deletions(-) diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md index c1b47177fe..ff5f7dedc6 100644 --- a/examples/gatekeeper-auth/README.md +++ b/examples/gatekeeper-auth/README.md @@ -116,23 +116,36 @@ Copy the auth token and set it to an env var: export AUTH_TOKEN="" ``` -First let's make a `GET` request to the proxy endpoint *without* the auth token: +First let's make a `GET` request to the proxy endpoint *without* the auth token. It will be rejected with a `403` status: ```console -$ curl "http://localhost:4000/proxy/v1/shape?table=items&offset=-1" -Forbidden +$ curl -sv "http://localhost:4000/proxy/v1/shape?table=items&offset=-1" +... +< HTTP/1.1 403 Forbidden +... ``` -Now let's add the authorization header: +Now let's add the authorization header. The request will be successfully proxied through to Electric: ```console -$ curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ +$ curl -sv --header "Authorization: Bearer ${AUTH_TOKEN}" \ "http://localhost:4000/proxy/v1/shape?table=items&offset=-1" -[] +... +< HTTP/1.1 200 OK +... +``` + +However if we try to request a different shape (i.e.: using different request parameters), the request will not match the shape signed into the auth token claims and will be rejected: + +```console +$ curl -sv --header "Authorization: Bearer ${AUTH_TOKEN}" \ + "http://localhost:4000/proxy/v1/shape?table=items&offset=-1&where=true" +... +< HTTP/1.1 403 Forbidden +... ``` -Success! We got an empty response because there are no `items` in the database. If you like, -you can create some, e.g. using `psql`: +Note that we got an empty response when successfully proxied through to Electric above because there are no `items` in the database. If you like, you can create some, e.g. using `psql`: ```console $ psql "postgresql://postgres:password@localhost:54321/electric?sslmode=disable" @@ -157,7 +170,7 @@ INSERT 0 1 electric=# \q ``` -Now re-run the same request and you'll get data: +Now re-run the successful request and you'll get data: ```console $ curl -s --header "Authorization: Bearer ${AUTH_TOKEN}" \ @@ -199,7 +212,7 @@ Run `postgres`, `electric`, `api` and `caddy` services with the `.env.caddy` env docker compose --env-file .env.caddy up postgres electric api caddy ``` -As above, use the gatekeeper endpoint to generate an auth token. Note that the `url` has changed to point to Caddy: +As above, use the gatekeeper endpoint to generate an auth token. Note that the `url` in the response data has changed to point to Caddy: ```console $ curl -sX POST "http://localhost:4000/gatekeeper/items" | jq @@ -221,7 +234,7 @@ export AUTH_TOKEN="" An unauthorised request to Caddy will get a 401: ```console -$ curl -v "http://localhost:8080/v1/shape?table=items&offset=-1" +$ curl -sv "http://localhost:8080/v1/shape?table=items&offset=-1" ... < HTTP/1.1 401 Unauthorized < Server: Caddy @@ -231,17 +244,21 @@ $ curl -v "http://localhost:8080/v1/shape?table=items&offset=-1" An authorised request for the correct shape will succeed: ```console -$ curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ +$ curl -sv --header "Authorization: Bearer ${AUTH_TOKEN}" \ "http://localhost:8080/v1/shape?table=items&offset=-1" -[] +... +< HTTP/1.1 200 OK +... ``` Caddy validates the shape request against the shape definition signed into the auth token. So an authorised request *for the wrong shape* will fail: ```console -$ curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ +$ curl -sv --header "Authorization: Bearer ${AUTH_TOKEN}" \ "http://localhost:8080/v1/shape?table=items&offset=-1&where=true" -Forbidden +... +< HTTP/1.1 403 Forbidden +... ``` Take a look at the [`./caddy/Caddyfile`](./caddy/Caddyfile) for more details. @@ -254,7 +271,7 @@ You can do this with a centralised cloud proxy, such as an API endpoint deployed It's often better (faster, more scalable and a more natural topology) to run your authorising proxy at the edge, between your CDN and your user. The gatekeeper pattern works well for this because it minimises both the logic that your edge proxy needs to perform and the network access and credentials that it needs to be granted. -The example in the [`./edge`](./edge) folder shows a Deno server that's designed to match the code you would deploy to a [Supabase Edge Function](https://supabase.com/docs/guides/functions/quickstart). See the README in the folder for more information about deploying to Supabase. +The example in the [`./edge`](./edge) folder contains a small [Deno HTTP server](https://docs.deno.com/runtime/fundamentals/http_server/) in the [`index.ts`](./edge/index.ts) file that's designed to work as a [Supabase Edge Function](https://supabase.com/docs/guides/functions/quickstart). See the README in the folder for more information about deploying to Supabase. Here, we'll run it locally using Docker in order to demonstrate it working with the other services: @@ -262,7 +279,7 @@ Here, we'll run it locally using Docker in order to demonstrate it working with docker compose --env-file .env.edge up postgres electric api edge ``` -As above, first hit the gatekeeper endpoint to get an auth token: +Hit the gatekeeper endpoint to get an auth token: ```console $ curl -sX POST "http://localhost:4000/gatekeeper/items" | jq @@ -284,7 +301,7 @@ export AUTH_TOKEN="" An unauthorised request to the edge-function proxy will get a 401: ```console -$ curl -v "http://localhost:8000/v1/shape?table=items&offset=-1" +$ curl -sv "http://localhost:8000/v1/shape?table=items&offset=-1" ... < HTTP/1.1 401 Unauthorized ... @@ -293,19 +310,25 @@ $ curl -v "http://localhost:8000/v1/shape?table=items&offset=-1" An authorised request for the correct shape will succeed: ```console -$ curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ +$ curl -sv --header "Authorization: Bearer ${AUTH_TOKEN}" \ "http://localhost:8000/v1/shape?table=items&offset=-1" -[] +... +< HTTP/1.1 200 OK +... ``` An authorised request for the wrong shape will fail: ```console -$ curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ +$ curl -sv --header "Authorization: Bearer ${AUTH_TOKEN}" \ "http://localhost:8000/v1/shape?table=items&offset=-1&where=true" -Forbidden +... +< HTTP/1.1 403 Forbidden +... ``` ## More information -See the [Auth guide](https://electric-sql.com/docs/guides/auth). If you have any questions about this example please feel free to [ask on Discord](https://discord.electric-sql.com). +See the [Auth guide](https://electric-sql.com/docs/guides/auth). + +If you have any questions about this example please feel free to [ask on Discord](https://discord.electric-sql.com). diff --git a/examples/gatekeeper-auth/edge/README.md b/examples/gatekeeper-auth/edge/README.md index 6f7f4a23cb..872b37244c 100644 --- a/examples/gatekeeper-auth/edge/README.md +++ b/examples/gatekeeper-auth/edge/README.md @@ -42,8 +42,11 @@ And then hit it at `http://localhost:54321/functions/v1/$YOUR_FUNCTION_NAME`, e. ```shell export FUNCTION_URL="http://localhost:54321/functions/v1/${YOUR_FUNCTION_NAME}" -curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ +curl -sv --header "Authorization: Bearer ${AUTH_TOKEN}" \ "${FUNCTION_URL}/v1/shape?table=items&offset=-1" +... +< HTTP/1.1 200 OK +... ``` To deploy, you login using @@ -76,6 +79,9 @@ Hit the deployed function at `https://$YOUR_PROJECT_ID.supabase.co/functions/v1/ ```shell export FUNCTION_URL="https://${YOUR_PROJECT_ID}.supabase.co/functions/v1/${YOUR_FUNCTION_NAME}" -curl --header "Authorization: Bearer ${AUTH_TOKEN}" \ +curl -sv --header "Authorization: Bearer ${AUTH_TOKEN}" \ "${FUNCTION_URL}/v1/shape?table=items&offset=-1" +... +< HTTP/1.1 200 OK +... ``` \ No newline at end of file From ff8f1925ed9588ff988cfb58c27053fe1fc0395d Mon Sep 17 00:00:00 2001 From: James Arthur Date: Thu, 14 Nov 2024 17:17:06 +0100 Subject: [PATCH 35/40] docs: clarify shape claim wording. --- examples/gatekeeper-auth/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md index ff5f7dedc6..1badd2be3b 100644 --- a/examples/gatekeeper-auth/README.md +++ b/examples/gatekeeper-auth/README.md @@ -19,7 +19,7 @@ There are two steps to the gatekeeper pattern: 1. first a client posts authentication credentials to a gatekeeper endpoint to generate an auth token 2. the client then makes requests to Electric via an authorising proxy that validates the auth token against the shape request -The auth token can be *shape-scoped* (i.e.: can sign a specific shape definition). This allows the proxy to authorise a shape request by comparing the shape signed into the token with the [shape defined in the request parameters](https://electric-sql.com/docs/quickstart#http-api). This allows you to: +The auth token can be *shape-scoped* (i.e.: can include a claim containing the shape definition). This allows the proxy to authorise a shape request by comparing the shape claim signed into the token with the [shape defined in the request parameters](https://electric-sql.com/docs/quickstart#http-api). This allows you to: - keep your main authorisation logic in your API (in the gatekeeper endpoint) where it's natural to do things like query the database and call external authorisation services; and to - run your authorisation logic *once* when generating a token, rather than on the "hot path" of every shape request in your authorising proxy From 594deb3036354c35310286a9cf1f492cb5918f2f Mon Sep 17 00:00:00 2001 From: James Arthur Date: Thu, 14 Nov 2024 17:17:48 +0100 Subject: [PATCH 36/40] docs: clarify that the response goes through the proxy. --- examples/gatekeeper-auth/README.md | 5 +++-- .../docs/img/gatekeeper-flow.dark.png | Bin 75259 -> 76138 bytes .../docs/img/gatekeeper-flow.jpg | Bin 204374 -> 216435 bytes .../docs/img/gatekeeper-flow.png | Bin 66167 -> 67196 bytes 4 files changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md index 1badd2be3b..ea2849eed2 100644 --- a/examples/gatekeeper-auth/README.md +++ b/examples/gatekeeper-auth/README.md @@ -50,8 +50,9 @@ The core of this example is an [Elixir/Phoenix](https://www.phoenixframework.org #### Proxy endpoint 4. the proxy validates the JWT auth token and verifies that the shape definition in the token matches the shape being requested; if so it reverse-proxies the request onto Electric -5. Electric then handles the request as normal, sending a response back through the proxy to the client -6. the client can then process the data and make additional requests using the same auth token (step 3); if the auth token expires or is rejected, the client starts again (step 1). +5. Electric then handles the request as normal +6. sending a response back *through the proxy* to the client +7. the client can then process the data and make additional requests using the same auth token (step 3); if the auth token expires or is rejected, the client starts again (step 1). ## How to run diff --git a/examples/gatekeeper-auth/docs/img/gatekeeper-flow.dark.png b/examples/gatekeeper-auth/docs/img/gatekeeper-flow.dark.png index 21c8c8156b68db5c994e8e9d82dd518460b652bf..6dd42d8854db5f446260c822af78d33eba5c6ef6 100644 GIT binary patch literal 76138 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 literal 75259 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%0DS}s{K@wlfUTjNiSKD9t)J5?W${D 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 diff --git a/examples/gatekeeper-auth/docs/img/gatekeeper-flow.jpg b/examples/gatekeeper-auth/docs/img/gatekeeper-flow.jpg index 8c9754954d8912cc01be0ce326d01ceba6bbc69e..c8b730d80c437257974d9d3cad0e9edf0ee32969 100644 GIT binary patch delta 26364 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 delta 12304 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
    N5r34O>`DGYBrQMN}XyI3*(h zS_VeeiUJ-Z2X^xHc6I^fJ)v6it58?&XxL;LXAMk;!9E^nP_7R(>XW$tb1 zZYZ!BM^bER`)tCshw->2>>kX3zM+PIBsTCbDXHl6tgPcka%CTHZk%O(=IYFLVxa9| zJp-4nPohVHL)?n?YBGjkjvDv27&Vs$ZNQ*N6M=S(atZZ1ZB5jXrtc!XTt3zy4`GM- zmWBcECd1|w=fvU$&3TC1!G#;=72uH2hDV7*yZ6BN^?VE{oWKEt9(UKcvn5pU&vWsC zOz=)1t8NhZ70N9!Tbze($D*NR+!MmmGE9fI=%Q(D#oS{wZ;;9=h|OJ8V@$$gDd|_g zGjzwNbCLoYim-yJba)7%s5bALpcpxzmma#ZIq?Zdt53Aw=4 z*|dZ2Llp~?vn>+vK@MQe4D!Ws6l>+0W!T7qeK9fIsyWK^Q+CB9WdUGoV3lE>HR;OP x$CyjR66(0mUJs9iwiRVdUL>UnyoyH{e9fNpYRdL3)q`E)2ww$Jpg{;Z{9hF$noa-! diff --git a/examples/gatekeeper-auth/docs/img/gatekeeper-flow.png b/examples/gatekeeper-auth/docs/img/gatekeeper-flow.png index a027a5492e4b562ad6b3eb1aeda2f70bf6a0bc28..2470a7512d52a28722d7a4447869f7fb9ea3a6d0 100644 GIT binary patch delta 15019 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 From 684ecba614a2c00ed586d0010f1c26248032e06e Mon Sep 17 00:00:00 2001 From: James Arthur Date: Thu, 14 Nov 2024 17:19:29 +0100 Subject: [PATCH 37/40] docs: add psql to (optional) pre-reqs. --- examples/gatekeeper-auth/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md index ea2849eed2..5419ec1fd1 100644 --- a/examples/gatekeeper-auth/README.md +++ b/examples/gatekeeper-auth/README.md @@ -67,7 +67,7 @@ It makes sense to run through these in order. ### Pre-reqs -You need [Docker Compose](https://docs.docker.com/compose/) and [curl](https://curl.se). We also (optionally) pipe into [`jq`](https://jqlang.github.io/jq/) for JSON formatting. +You need [Docker Compose](https://docs.docker.com/compose/) and [curl](https://curl.se). We also (optionally) use [`psql`](https://www.postgresql.org/docs/current/app-psql.html) and pipe into [`jq`](https://jqlang.github.io/jq/) for JSON formatting. The instructions below all use the same [`./docker-compose.yaml`](./docker-compose.yaml) file in the root of this repo. With a different set of services and environment variables. From bccb1e4d61fd5e1c928c266d92fed27b60364f22 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Thu, 14 Nov 2024 17:37:56 +0100 Subject: [PATCH 38/40] api: return 401 when auth header is missing or invalid. --- examples/gatekeeper-auth/README.md | 2 +- examples/gatekeeper-auth/api/lib/api/token.ex | 21 +++++++++++++++++-- .../api/lib/api_web/authenticator.ex | 7 +++++-- .../lib/api_web/plugs/auth/verify_token.ex | 9 ++++++-- .../controllers/proxy_controller_test.exs | 4 ++-- 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md index 5419ec1fd1..789560cc3f 100644 --- a/examples/gatekeeper-auth/README.md +++ b/examples/gatekeeper-auth/README.md @@ -122,7 +122,7 @@ First let's make a `GET` request to the proxy endpoint *without* the auth token. ```console $ curl -sv "http://localhost:4000/proxy/v1/shape?table=items&offset=-1" ... -< HTTP/1.1 403 Forbidden +< HTTP/1.1 401 Unauthorized ... ``` diff --git a/examples/gatekeeper-auth/api/lib/api/token.ex b/examples/gatekeeper-auth/api/lib/api/token.ex index 723a2471c0..c0d636f56a 100644 --- a/examples/gatekeeper-auth/api/lib/api/token.ex +++ b/examples/gatekeeper-auth/api/lib/api/token.ex @@ -22,9 +22,26 @@ defmodule Api.Token do end def verify(%ShapeDefinition{} = request_shape, token) do - with {:ok, %{"shape" => token_params}} <- JWT.verify_and_validate(token, JWT.signer()), - {:ok, token_shape} <- Shape.from(token_params) do + with {:ok, shape_claim} <- validate(token) do + matches(request_shape, shape_claim) + end + end + + defp validate(token) do + with {:ok, %{"shape" => shape_claim}} <- JWT.verify_and_validate(token, JWT.signer()) do + {:ok, shape_claim} + else + _alt -> + {:error, :invalid} + end + end + + defp matches(%ShapeDefinition{} = request_shape, %{} = shape_claim) do + with {:ok, token_shape} <- Shape.from(shape_claim) do Shape.matches(request_shape, token_shape) + else + _alt -> + false end end end diff --git a/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex b/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex index 907b8069f4..a0dacc1ecd 100644 --- a/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex +++ b/examples/gatekeeper-auth/api/lib/api_web/authenticator.ex @@ -17,12 +17,15 @@ defmodule ApiWeb.Authenticator do request end - def authorise(shape, request_header_list) do - header_map = Enum.into(request_header_list, %{}) + def authorise(shape, request_headers) do + header_map = Enum.into(request_headers, %{}) header_key = String.downcase(@header_name) with {:ok, "Bearer " <> token} <- Map.fetch(header_map, header_key) do Token.verify(shape, token) + else + _alt -> + {:error, :missing} end end diff --git a/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex b/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex index 8544d3bedf..2760efc005 100644 --- a/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex +++ b/examples/gatekeeper-auth/api/lib/api_web/plugs/auth/verify_token.ex @@ -16,13 +16,18 @@ defmodule ApiWeb.Plugs.Auth.VerifyToken do def call(%{assigns: %{shape: shape}, req_headers: headers} = conn, _opts) do case Authenticator.authorise(shape, headers) do - true -> + {:error, message} when message in [:invalid, :missing] -> conn + |> send_resp(401, "Unauthorized") + |> halt() - _alt -> + false -> conn |> send_resp(403, "Forbidden") |> halt() + + true -> + conn end end end diff --git a/examples/gatekeeper-auth/api/test/api_web/controllers/proxy_controller_test.exs b/examples/gatekeeper-auth/api/test/api_web/controllers/proxy_controller_test.exs index f1f6a5696a..6bc2190f56 100644 --- a/examples/gatekeeper-auth/api/test/api_web/controllers/proxy_controller_test.exs +++ b/examples/gatekeeper-auth/api/test/api_web/controllers/proxy_controller_test.exs @@ -18,14 +18,14 @@ defmodule ApiWeb.ProxyControllerTest do test "requires auth", %{conn: conn} do assert conn |> get("/proxy/v1/shape", table: "items") - |> response(403) + |> response(401) end test "requires valid auth header", %{conn: conn} do assert conn |> put_req_header("authorization", "Bearer invalid-token") |> get("/proxy/v1/shape", table: "items") - |> response(403) + |> response(401) end test "requires matching shape definition", %{conn: conn} do From 8c20344d34b5e782af8e0a36eee8394812b6638e Mon Sep 17 00:00:00 2001 From: James Arthur Date: Thu, 14 Nov 2024 17:38:26 +0100 Subject: [PATCH 39/40] docs: higher-level. --- examples/gatekeeper-auth/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md index 789560cc3f..d752589e36 100644 --- a/examples/gatekeeper-auth/README.md +++ b/examples/gatekeeper-auth/README.md @@ -197,7 +197,7 @@ $ curl -s --header "Authorization: Bearer ${AUTH_TOKEN}" \ ] ``` -So far we've shown things working with Electric's lower-level [HTTP API](https://electric-sql.com/docs/api/http). You can also setup the [higher level clients](https://electric-sql.com/docs/api/clients/typescript) to use an auth token. See the [auth guide](https://electric-sql.com/docs/guides/auth) for more details. +So far we've shown things working with Electric's lower-level [HTTP API](https://electric-sql.com/docs/api/http). You can also setup the [higher-level clients](https://electric-sql.com/docs/api/clients/typescript) to use an auth token. See the [auth guide](https://electric-sql.com/docs/guides/auth) for more details. ### 2. Caddy as proxy From 2f0c92437aa8d15ceea49291db3dc9d37b76fed6 Mon Sep 17 00:00:00 2001 From: James Arthur Date: Mon, 18 Nov 2024 17:22:50 +0100 Subject: [PATCH 40/40] docs: address review comments. --- examples/gatekeeper-auth/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/gatekeeper-auth/README.md b/examples/gatekeeper-auth/README.md index d752589e36..2b94c4c5b3 100644 --- a/examples/gatekeeper-auth/README.md +++ b/examples/gatekeeper-auth/README.md @@ -69,7 +69,7 @@ It makes sense to run through these in order. You need [Docker Compose](https://docs.docker.com/compose/) and [curl](https://curl.se). We also (optionally) use [`psql`](https://www.postgresql.org/docs/current/app-psql.html) and pipe into [`jq`](https://jqlang.github.io/jq/) for JSON formatting. -The instructions below all use the same [`./docker-compose.yaml`](./docker-compose.yaml) file in the root of this repo. With a different set of services and environment variables. +The instructions below all use the same [`./docker-compose.yaml`](./docker-compose.yaml) file in this folder. With a different set of services and environment variables. > [!TIP] > All of the configurations are based on running Postgres and Electric. This is handled for you by the `./docker-compose.yaml`. However, if you're unfamiliar with how Electric works, it may be useful to go through the [Quickstart](https://electric-sql.com/docs/quickstart) and [Installation](https://electric-sql.com/docs/guides/installation) guides. @@ -100,7 +100,7 @@ $ curl -sX POST "http://localhost:4000/gatekeeper/items" | jq "headers": { "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJKb2tlbiIsImV4cCI6MTczMTUwMjM2OSwiaWF0IjoxNzMxNDk1MTY5LCJpc3MiOiJKb2tlbiIsImp0aSI6IjMwM28zYmx0czN2aHYydXNiazAwMDJrMiIsIm5iZiI6MTczMTQ5NTE2OSwic2hhcGUiOnsibmFtZXNwYWNlIjpudWxsLCJ0YWJsZSI6Iml0ZW1zIiwid2hlcmUiOm51bGwsImNvbHVtbnMiOm51bGx9fQ.8UZehIWk1EDQ3dJ4ggCBNkx9vGudfrD9appqs8r6zRI" }, - "url": "http://localhost:3000/proxy/v1/shape", + "url": "http://localhost:4000/proxy/v1/shape", "table": "items" } ```