summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuanjo Rodriguez <jjrodrig@gmail.com>2020-03-17 23:51:40 +0100
committerGitHub <noreply@github.com>2020-03-17 23:51:40 +0100
commit3bf47de19232ef076e843d05c626beeebd051bd7 (patch)
tree05071744ac66428c610aa37c99f05d531e019762
parent8acb4d59c99646786c82ed5a37f8023ec8d78e5a (diff)
downloadcouchdb-3bf47de19232ef076e843d05c626beeebd051bd7.tar.gz
3.x merge - Port elixir proxyauth tests from js to elixir (#2660)
* Port elixir proxyauth tests from js to elixir (#2660) * Add support for specify a custom config file for CouchDB startup during testing
-rw-r--r--Makefile5
-rwxr-xr-xdev/run27
-rw-r--r--test/elixir/README.md2
-rw-r--r--test/elixir/lib/couch.ex4
-rw-r--r--test/elixir/test/config/test-config.ini2
-rw-r--r--test/elixir/test/proxyauth_test.exs163
-rw-r--r--test/elixir/test/users_db_test.exs3
-rw-r--r--test/javascript/tests/proxyauth.js4
8 files changed, 203 insertions, 7 deletions
diff --git a/Makefile b/Makefile
index e229ee55b..7d56dd1ab 100644
--- a/Makefile
+++ b/Makefile
@@ -223,7 +223,10 @@ python-black-update: .venv/bin/black
elixir: export MIX_ENV=integration
elixir: export COUCHDB_TEST_ADMIN_PARTY_OVERRIDE=1
elixir: elixir-init elixir-check-formatted elixir-credo devclean
- @dev/run "$(TEST_OPTS)" -a adm:pass -n 1 --enable-erlang-views --no-eval 'mix test --trace --exclude without_quorum_test --exclude with_quorum_test $(EXUNIT_OPTS)'
+ @dev/run "$(TEST_OPTS)" -a adm:pass -n 1 \
+ --enable-erlang-views \
+ --locald-config test/elixir/test/config/test-config.ini \
+ --no-eval 'mix test --trace --exclude without_quorum_test --exclude with_quorum_test $(EXUNIT_OPTS)'
.PHONY: elixir-init
elixir-init: MIX_ENV=test
diff --git a/dev/run b/dev/run
index a96817d83..573c80c9b 100755
--- a/dev/run
+++ b/dev/run
@@ -211,6 +211,14 @@ def get_args_parser():
default=None,
help="Extra arguments to pass to beam process",
)
+ parser.add_option(
+ "-l",
+ "--locald-config",
+ dest="locald_configs",
+ action="append",
+ default=[],
+ help="Path to config to place in 'local.d'. Can be repeated",
+ )
return parser
@@ -238,6 +246,7 @@ def setup_context(opts, args):
"reset_logs": True,
"procs": [],
"auto_ports": opts.auto_ports,
+ "locald_configs": opts.locald_configs,
}
@@ -279,9 +288,24 @@ def setup_configs(ctx):
"_default": "",
}
write_config(ctx, node, env)
+ write_locald_configs(ctx, node, env)
generate_haproxy_config(ctx)
+def write_locald_configs(ctx, node, env):
+ for locald_config in ctx["locald_configs"]:
+ config_src = os.path.join(ctx["rootdir"], locald_config)
+ if os.path.exists(config_src):
+ config_filename = os.path.basename(config_src)
+ config_tgt = os.path.join(
+ ctx["devdir"], "lib", node, "etc", "local.d", config_filename
+ )
+ with open(config_src) as handle:
+ content = handle.read()
+ with open(config_tgt, "w") as handle:
+ handle.write(content)
+
+
def generate_haproxy_config(ctx):
haproxy_config = os.path.join(ctx["devdir"], "lib", "haproxy.cfg")
template = os.path.join(ctx["rootdir"], "rel", "haproxy.cfg")
@@ -382,6 +406,8 @@ def write_config(ctx, node, env):
with open(tgt, "w") as handle:
handle.write(content)
+ ensure_dir_exists(etc_tgt, "local.d")
+
def boot_haproxy(ctx):
if not ctx["with_haproxy"]:
@@ -580,6 +606,7 @@ def boot_node(ctx, node):
"-couch_ini",
os.path.join(node_etcdir, "default.ini"),
os.path.join(node_etcdir, "local.ini"),
+ os.path.join(node_etcdir, "local.d"),
"-reltool_config",
os.path.join(reldir, "reltool.config"),
"-parent_pid",
diff --git a/test/elixir/README.md b/test/elixir/README.md
index 6a19c246d..f163dd029 100644
--- a/test/elixir/README.md
+++ b/test/elixir/README.md
@@ -60,7 +60,7 @@ X means done, - means partially
- [X] Port lots_of_docs.js
- [ ] Port method_override.js
- [X] Port multiple_rows.js
- - [ ] Port proxyauth.js
+ - [X] Port proxyauth.js
- [ ] Port purge.js
- [ ] Port reader_acl.js
- [ ] Port recreate_doc.js
diff --git a/test/elixir/lib/couch.ex b/test/elixir/lib/couch.ex
index 3aef07f01..7819299cc 100644
--- a/test/elixir/lib/couch.ex
+++ b/test/elixir/lib/couch.ex
@@ -127,8 +127,8 @@ defmodule Couch do
def set_auth_options(options) do
if Keyword.get(options, :cookie) == nil do
headers = Keyword.get(options, :headers, [])
-
- if headers[:basic_auth] != nil or headers[:authorization] != nil do
+ if headers[:basic_auth] != nil or headers[:authorization] != nil
+ or List.keymember?(headers, :"X-Auth-CouchDB-UserName", 0) do
options
else
username = System.get_env("EX_USERNAME") || "adm"
diff --git a/test/elixir/test/config/test-config.ini b/test/elixir/test/config/test-config.ini
new file mode 100644
index 000000000..72a13a707
--- /dev/null
+++ b/test/elixir/test/config/test-config.ini
@@ -0,0 +1,2 @@
+[chttpd]
+authentication_handlers = {chttpd_auth, proxy_authentication_handler}, {chttpd_auth, cookie_authentication_handler}, {chttpd_auth, default_authentication_handler}
diff --git a/test/elixir/test/proxyauth_test.exs b/test/elixir/test/proxyauth_test.exs
new file mode 100644
index 000000000..6f2d49a53
--- /dev/null
+++ b/test/elixir/test/proxyauth_test.exs
@@ -0,0 +1,163 @@
+defmodule ProxyAuthTest do
+ use CouchTestCase
+
+ @moduletag :authentication
+
+ @tag :with_db
+ test "proxy auth with secret", context do
+ db_name = context[:db_name]
+
+ design_doc = %{
+ _id: "_design/test",
+ language: "javascript",
+ shows: %{
+ welcome: """
+ function(doc,req) {
+ return "Welcome " + req.userCtx["name"];
+ }
+ """,
+ role: """
+ function(doc, req) {
+ return req.userCtx['roles'][0];
+ }
+ """
+ }
+ }
+
+ {:ok, _} = create_doc(db_name, design_doc)
+
+ users_db_name = random_db_name()
+ create_db(users_db_name)
+
+ secret = generate_secret(64)
+
+ server_config = [
+ %{
+ :section => "chttpd_auth",
+ :key => "authentication_db",
+ :value => users_db_name
+ },
+ %{
+ :section => "couch_httpd_auth",
+ :key => "proxy_use_secret",
+ :value => "true"
+ },
+ %{
+ :section => "couch_httpd_auth",
+ :key => "secret",
+ :value => secret
+ }
+ ]
+
+ run_on_modified_server(server_config, fn ->
+ test_fun(db_name, users_db_name, secret)
+ end)
+ delete_db(users_db_name)
+ end
+
+ defp generate_secret(len) do
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
+ |> String.splitter("", trim: true)
+ |> Enum.take_random(len)
+ |> Enum.join("")
+ end
+
+ defp hex_hmac_sha1(secret, message) do
+ signature = :crypto.hmac(:sha, secret, message)
+ Base.encode16(signature, case: :lower)
+ end
+
+ def test_fun(db_name, users_db_name, secret) do
+ user = prepare_user_doc(name: "couch@apache.org", password: "test")
+ create_doc(users_db_name, user)
+
+ resp =
+ Couch.get("/_session",
+ headers: [authorization: "Basic Y291Y2hAYXBhY2hlLm9yZzp0ZXN0"]
+ )
+
+ assert resp.body["userCtx"]["name"] == "couch@apache.org"
+ assert resp.body["info"]["authenticated"] == "default"
+
+ headers = [
+ "X-Auth-CouchDB-UserName": "couch@apache.org",
+ "X-Auth-CouchDB-Roles": "test",
+ "X-Auth-CouchDB-Token": hex_hmac_sha1(secret, "couch@apache.org")
+ ]
+ resp = Couch.get("/#{db_name}/_design/test/_show/welcome", headers: headers)
+ assert resp.body == "Welcome couch@apache.org"
+
+ resp = Couch.get("/#{db_name}/_design/test/_show/role", headers: headers)
+ assert resp.body == "test"
+ end
+
+ @tag :with_db
+ test "proxy auth without secret", context do
+ db_name = context[:db_name]
+
+ design_doc = %{
+ _id: "_design/test",
+ language: "javascript",
+ shows: %{
+ welcome: """
+ function(doc,req) {
+ return "Welcome " + req.userCtx["name"];
+ }
+ """,
+ role: """
+ function(doc, req) {
+ return req.userCtx['roles'][0];
+ }
+ """
+ }
+ }
+
+ {:ok, _} = create_doc(db_name, design_doc)
+
+ users_db_name = random_db_name()
+ create_db(users_db_name)
+
+ server_config = [
+ %{
+ :section => "chttpd_auth",
+ :key => "authentication_db",
+ :value => users_db_name
+ },
+ %{
+ :section => "couch_httpd_auth",
+ :key => "proxy_use_secret",
+ :value => "false"
+ }
+ ]
+
+ run_on_modified_server(server_config, fn ->
+ test_fun_no_secret(db_name, users_db_name)
+ end)
+
+ delete_db(users_db_name)
+ end
+
+ def test_fun_no_secret(db_name, users_db_name) do
+ user = prepare_user_doc(name: "couch@apache.org", password: "test")
+ create_doc(users_db_name, user)
+
+ resp =
+ Couch.get("/_session",
+ headers: [authorization: "Basic Y291Y2hAYXBhY2hlLm9yZzp0ZXN0"]
+ )
+
+ assert resp.body["userCtx"]["name"] == "couch@apache.org"
+ assert resp.body["info"]["authenticated"] == "default"
+
+ headers = [
+ "X-Auth-CouchDB-UserName": "couch@apache.org",
+ "X-Auth-CouchDB-Roles": "test"
+ ]
+
+ resp = Couch.get("/#{db_name}/_design/test/_show/welcome", headers: headers)
+ assert resp.body == "Welcome couch@apache.org"
+
+ resp = Couch.get("/#{db_name}/_design/test/_show/role", headers: headers)
+ assert resp.body == "test"
+ end
+end
diff --git a/test/elixir/test/users_db_test.exs b/test/elixir/test/users_db_test.exs
index 71ab2f7e7..1d34d8c9e 100644
--- a/test/elixir/test/users_db_test.exs
+++ b/test/elixir/test/users_db_test.exs
@@ -147,7 +147,8 @@ defmodule UsersDbTest do
assert resp.body["userCtx"]["name"] == "jchris@apache.org"
assert resp.body["info"]["authenticated"] == "default"
assert resp.body["info"]["authentication_db"] == @users_db_name
- assert resp.body["info"]["authentication_handlers"] == ["cookie", "default"]
+ assert Enum.member?(resp.body["info"]["authentication_handlers"], "cookie")
+ assert Enum.member?(resp.body["info"]["authentication_handlers"], "default")
resp =
Couch.get(
diff --git a/test/javascript/tests/proxyauth.js b/test/javascript/tests/proxyauth.js
index cc75faaf3..7f2e097e8 100644
--- a/test/javascript/tests/proxyauth.js
+++ b/test/javascript/tests/proxyauth.js
@@ -11,10 +11,10 @@
// the License.
-
+couchTests.elixir = true;
couchTests.proxyauth = function(debug) {
// this test proxy authentification handler
-
+ return console.log('done in test/elixir/test/proxyauth_test.exs');
var users_db_name = get_random_db_name();
var usersDb = new CouchDB(users_db_name, {"X-Couch-Full-Commit":"false"});
usersDb.createDb();