commit 4f45ef1f13f628961ae77cfec980ada03e7398a6
parent 55c26fc551c5e7b17255ea6d7f596ca0ed53a7f4
Author: sir fish <dev@srf.sh>
Date: Wed, 5 Oct 2022 09:27:08 +0000
Merge pull request #19 from dyne/not-mandatory-auth
Auhenticated calls are not mandatory
Diffstat:
8 files changed, 55 insertions(+), 10 deletions(-)
diff --git a/conf/.env.templ b/conf/.env.templ
@@ -35,5 +35,6 @@ export ROOM_SALT=@ROOM_SALT
export ADMIN_KEY=@ADMIN_KEY
## gql
+export GQL_AUTH_CALLS=true
export GQL_DEF_PAGE_SIZE=50
export GQL_MAX_PAGE_SIZE=100
diff --git a/conf/runtime.exs b/conf/runtime.exs
@@ -91,6 +91,8 @@ if def_page_size < 1,
max_page_size = get_env_int.("GQL_MAX_PAGE_SIZE", 100)
if max_page_size < def_page_size,
do: raise "GQL_MAX_PAGE_SIZE can't be less than GQL_DEF_PAGE_SIZE"
+auth? = get_env("GQL_AUTH_CALLS", "true") != "false"
config :zenflows, Zenflows.GQL,
def_page_size: def_page_size,
- max_page_size: max_page_size
+ max_page_size: max_page_size,
+ authenticate_calls?: auth?
diff --git a/devop/.docker-compose.templ b/devop/.docker-compose.templ
@@ -40,6 +40,7 @@ services:
ROOM_PORT: &room_port 3000
ROOM_SALT: @ROOM_SALT
+ GQL_AUTH_CALLS: true
GQL_DEF_PAGE_SIZE: 50
GQL_MAX_PAGE_SIZE: 100
depends_on:
diff --git a/docs/configuration-guide.md b/docs/configuration-guide.md
@@ -47,6 +47,8 @@ also see the [Required Options](#required-options).
`openssl rand -hex 64`. It is automatically generated when you run
`mann env.setup`.
+* `GQL_AUTH_CALLS`: Boolean value. It enables the authentication with
+ restroom (each gql request has to be signed). Defaults to `true`.
* `GQL_DEF_PAGE_SIZE`: A non-negative integer. It is used for the
default GraphQL page size if the client doesn't provide one.
* `GQL_MAX_PAGE_SIZE`: A non-negative integer. It is used for the
diff --git a/src/zenflows/gql/mw/debug.ex b/src/zenflows/gql/mw/debug.ex
@@ -0,0 +1,38 @@
+# Zenflows is designed to implement the Valueflows vocabulary,
+# written and maintained by srfsh <info@dyne.org>.
+# Copyright (C) 2021-2022 Dyne.org foundation <foundation@dyne.org>.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+defmodule Zenflows.GQL.MW.Debug do
+@moduledoc """
+Absinthe middleware to verify GraphQL calls.
+"""
+
+@behaviour Absinthe.Middleware
+
+@impl true
+def call(res, _opts) do
+ if Map.has_key?(res.context, :authenticate_calls?) do
+ res
+ else
+ put_in(res.context[:authenticate_calls?], conf()[:authenticate_calls?])
+ end
+end
+
+@spec conf() :: Keyword.t()
+defp conf() do
+ Application.fetch_env!(:zenflows, Zenflows.GQL)
+end
+end
diff --git a/src/zenflows/gql/mw/sign.ex b/src/zenflows/gql/mw/sign.ex
@@ -25,6 +25,8 @@ Absinthe middleware to verify GraphQL calls.
alias Zenflows.Restroom
alias Zenflows.VF.Person
+@missing_headers_auth_call "couldn't aunthenticate: zenflows-user and/or zenflows-sign headers are missing"
+
@impl true
def call(res, _opts) do
if res.context.authenticate_calls? do
@@ -44,7 +46,7 @@ defp fetch_ctx(res) do
case res.context do
%{gql_user: username, gql_sign: sign, gql_body: body} ->
{:ok, username, sign, body}
- _ -> {:error, "some headers are missing"}
+ _ -> {:error, @missing_headers_auth_call}
end
end
diff --git a/src/zenflows/gql/schema.ex b/src/zenflows/gql/schema.ex
@@ -169,19 +169,21 @@ def middleware(mw, field, %{identifier: id})
when id in ~w[query mutation subscription]a do
alias Absinthe.Type
- cond do
+ mw = cond do
# require nothing to be provided
Type.meta(field, :only_guest?) ->
- mw ++ [MW.Errors]
+ mw
# require the admin key to be provided
Type.meta(field, :only_admin?) ->
- [MW.Admin | mw] ++ [MW.Errors]
+ [MW.Admin | mw]
# require every call to be signed
true ->
- [MW.Sign | mw] ++ [MW.Errors]
+ [MW.Sign | mw]
end
+ [MW.Debug | mw] ++ [MW.Errors]
+
end
def middleware(mw, _, _), do: mw
diff --git a/src/zenflows/web/router.ex b/src/zenflows/web/router.ex
@@ -32,10 +32,7 @@ plug Plug.Parsers,
plug MW.GQLContext
plug :dispatch
-@init_opts [
- schema: Zenflows.GQL.Schema,
- context: %{authenticate_calls?: true},
-]
+@init_opts [schema: Zenflows.GQL.Schema]
forward "/api/file",
to: Zenflows.Web.File