zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

commit 73a62160f3843551f11ca5a04043b0fde1840fb5
parent e1dcd39c615dfdbde284f1ebf9d7b0e5a195a913
Author: srfsh <dev@srf.sh>
Date:   Wed,  3 Aug 2022 10:21:04 +0300

Zenflows.{Web,GQL}: add authenticate_calls? context variable

This will allow us to skip authentication in tests.  It is set to true
by default in Zenflows.Web.Router, so there's no security hole.

Zenflows.GQL.MW's submodules can be inspected to see how it is used.

Diffstat:
Msrc/zenflows/gql/mw/admin.ex | 16++++++++++------
Msrc/zenflows/gql/mw/sign.ex | 14+++++++++-----
Msrc/zenflows/web/router.ex | 10+++++++---
3 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/src/zenflows/gql/mw/admin.ex b/src/zenflows/gql/mw/admin.ex @@ -26,13 +26,17 @@ alias Zenflows.Restroom @impl true def call(res, _opts) do - with %{gql_admin: key} <- res.context, - {:ok, key_given} <- Base.decode16(key, case: :lower), - key_want = Application.fetch_env!(:zenflows, Zenflows.Admin)[:admin_key], - true <- Restroom.byte_equal?(key_given, key_want) do + if res.context.authenticate_calls? do + with %{gql_admin: key} <- res.context, + {:ok, key_given} <- Base.decode16(key, case: :lower), + key_want = Application.fetch_env!(:zenflows, Zenflows.Admin)[:admin_key], + true <- Restroom.byte_equal?(key_given, key_want) do + res + else _ -> + Absinthe.Resolution.put_result(res, {:error, "you are not an admin"}) + end + else res - else _ -> - Absinthe.Resolution.put_result(res, {:error, "you are not an admin"}) end end end diff --git a/src/zenflows/gql/mw/sign.ex b/src/zenflows/gql/mw/sign.ex @@ -27,12 +27,16 @@ alias Zenflows.VF.Person @impl true def call(res, _opts) do - with %{gql_user: user, gql_sign: sign, gql_body: body} <- res.context, - per when not is_nil(per) <- Person.Domain.by_user(user), - true <- Restroom.verify_graphql?(body, sign, per.eddsa_public_key) do + if res.context.authenticate_calls? do + with %{gql_user: user, gql_sign: sign, gql_body: body} <- res.context, + per when not is_nil(per) <- Person.Domain.by_user(user), + true <- Restroom.verify_graphql?(body, sign, per.eddsa_public_key) do + put_in(res.context[:req_user], per) + else _ -> + Absinthe.Resolution.put_result(res, {:error, "you are not authenticated"}) + end + else res - else _ -> - Absinthe.Resolution.put_result(res, {:error, "you are not authenticated"}) end end end diff --git a/src/zenflows/web/router.ex b/src/zenflows/web/router.ex @@ -32,14 +32,18 @@ plug Plug.Parsers, plug MW.GQLContext plug :dispatch +@init_opts [ + schema: Zenflows.GQL.Schema, + context: %{authenticate_calls?: true}, +] + forward "/api", to: Absinthe.Plug, - schema: Zenflows.GQL.Schema + init_opts: @init_opts forward "/play", to: Absinthe.Plug.GraphiQL, - schema: Zenflows.GQL.Schema, - interface: :advanced + init_opts: [{:interface, :advanced} | @init_opts] match _ do conn