summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Lehnardt <jan@apache.org>2017-06-03 15:49:21 +0200
committerJan Lehnardt <jan@apache.org>2017-06-03 15:49:24 +0200
commitdecd71b396720d896f2d2d504dac5ab6976b4a70 (patch)
tree07b0a72a9c57b72ccc127b2406559c8655efc900
parente9cc63fc9c524c6f1f0b736a45cb8b060f59929d (diff)
downloadcouchdb-fix/peruser-3/2.0.tar.gz
feat: update for 2.0 patch by @guillettfix/peruser-3/2.0
https://github.com/apache/couchdb-peruser/pull/3
-rw-r--r--src/couch_peruser/.travis.yml24
-rw-r--r--src/couch_peruser/src/couch_peruser.erl44
-rw-r--r--src/couch_peruser/test/couch_peruser_test.erl28
3 files changed, 57 insertions, 39 deletions
diff --git a/src/couch_peruser/.travis.yml b/src/couch_peruser/.travis.yml
deleted file mode 100644
index 26cfdc1ed..000000000
--- a/src/couch_peruser/.travis.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-language: erlang
-
-otp_release:
- - 18.0
- - 17.5
- - R16B03-1
- - R14B04
-
-before_install:
- - sudo apt-get update -qq
- - sudo apt-get -y install libmozjs-dev
- - git clone https://github.com/apache/couchdb
-
-before_script:
- - cd couchdb
- - ./configure --disable-docs --disable-fauxton
- - cp -r ../!(couchdb) ./src/couch_peruser
- - make
-
-script:
- - rebar setup_eunit
- - BUILDDIR=`pwd` rebar -r eunit apps=couch_peruser
-
-cache: apt
diff --git a/src/couch_peruser/src/couch_peruser.erl b/src/couch_peruser/src/couch_peruser.erl
index d38a86db3..63ef084ce 100644
--- a/src/couch_peruser/src/couch_peruser.erl
+++ b/src/couch_peruser/src/couch_peruser.erl
@@ -14,6 +14,7 @@
-behaviour(gen_server).
-include_lib("couch/include/couch_db.hrl").
+-include_lib("mem3/include/mem3.hrl").
-define(USERDB_PREFIX, "userdb-").
@@ -24,6 +25,7 @@
-export([init_changes_handler/1, changes_handler/3]).
-record(state, {parent, db_name, delete_dbs, changes_pid, changes_ref}).
+-record(clusterState, {parent, db_name, delete_dbs, states}).
-define(RELISTEN_DELAY, 5000).
@@ -34,17 +36,32 @@ start_link() ->
init() ->
case config:get_boolean("couch_peruser", "enable", false) of
false ->
- #state{};
+ #clusterState{};
true ->
DbName = ?l2b(config:get(
"couch_httpd_auth", "authentication_db", "_users")),
DeleteDbs = config:get_boolean("couch_peruser", "delete_dbs", false),
- State = #state{parent = self(),
- db_name = DbName,
- delete_dbs = DeleteDbs},
- {Pid, Ref} = spawn_opt(
- ?MODULE, init_changes_handler, [State], [link, monitor]),
- State#state{changes_pid=Pid, changes_ref=Ref}
+
+ ClusterState = #clusterState{
+ parent = self(),
+ db_name = DbName,
+ delete_dbs = DeleteDbs
+ },
+ try
+ States = lists:map(fun (A) ->
+ S = #state{parent = ClusterState#clusterState.parent,
+ db_name = A#shard.name,
+ delete_dbs = DeleteDbs},
+ {Pid, Ref} = spawn_opt(
+ ?MODULE, init_changes_handler, [S], [link, monitor]),
+ S#state{changes_pid=Pid, changes_ref=Ref}
+ end, mem3:local_shards(DbName)),
+
+ ClusterState#clusterState{states = States}
+ catch error:database_does_not_exist ->
+ couch_log:warning("couch_peruser can't proceed as underlying database (~s) is missing, disables itself.", [DbName]),
+ config:set("couch_peruser", "enable", "false", lists:concat([binary_to_list(DbName), " is missing"]))
+ end
end.
init_changes_handler(#state{db_name=DbName} = State) ->
@@ -172,12 +189,15 @@ init([]) ->
handle_call(_Msg, _From, State) ->
{reply, error, State}.
-handle_cast(update_config, State) when State#state.changes_pid =/= undefined ->
- % we don't want to have multiple changes handler at the same time
- demonitor(State#state.changes_ref, [flush]),
- exit(State#state.changes_pid, kill),
+
+handle_cast(update_config, ClusterState) when ClusterState#clusterState.states =/= undefined ->
+ lists:foreach(fun (State) ->
+ demonitor(State#state.changes_ref, [flush]),
+ exit(State#state.changes_pid, kill)
+ end, ClusterState#clusterState.states),
+
{noreply, init()};
-handle_cast(update_config, _State) ->
+handle_cast(update_config, _) ->
{noreply, init()};
handle_cast(stop, State) ->
{stop, normal, State};
diff --git a/src/couch_peruser/test/couch_peruser_test.erl b/src/couch_peruser/test/couch_peruser_test.erl
index 55308e6d7..73eff7f64 100644
--- a/src/couch_peruser/test/couch_peruser_test.erl
+++ b/src/couch_peruser/test/couch_peruser_test.erl
@@ -31,14 +31,16 @@ teardown_all(TestCtx) ->
setup() ->
TestAuthDb = ?tempdb(),
do_request(put, get_base_url() ++ "/" ++ ?b2l(TestAuthDb)),
+ do_request(put, get_cluster_base_url() ++ "/" ++ ?b2l(TestAuthDb)),
set_config("couch_httpd_auth", "authentication_db", ?b2l(TestAuthDb)),
set_config("couch_peruser", "enable", "true"),
TestAuthDb.
teardown(TestAuthDb) ->
- set_config("couch_httpd_auth", "authentication_db", "_users"),
set_config("couch_peruser", "enable", "false"),
set_config("couch_peruser", "delete_dbs", "false"),
+ set_config("couch_httpd_auth", "authentication_db", "_users"),
+ do_request(delete, get_cluster_base_url() ++ "/" ++ ?b2l(TestAuthDb)),
do_request(delete, get_base_url() ++ "/" ++ ?b2l(TestAuthDb)),
lists:foreach(fun (DbName) ->
case DbName of
@@ -62,6 +64,11 @@ do_request(Method, Url, Body) ->
{"Content-Type", "application/json"}],
{ok, _, _, _} = test_request:request(Method, Url, Headers, Body).
+do_anon_request(Method, Url, Body) ->
+ Headers = [
+ {"Content-Type", "application/json"}],
+ {ok, _, _, _} = test_request:request(Method, Url, Headers, Body).
+
create_db(DbName) ->
{ok, _, _, _} = do_request(put, get_cluster_base_url() ++ "/" ++ ?b2l(DbName)).
@@ -72,13 +79,22 @@ create_user(AuthDb, Name) ->
Body = "{\"name\":\"" ++ Name ++
"\",\"type\":\"user\",\"roles\":[],\"password\":\"secret\"}",
Url = lists:concat([
- get_base_url(), "/", ?b2l(AuthDb), "/org.couchdb.user:", Name]),
+ get_cluster_base_url(), "/", ?b2l(AuthDb), "/org.couchdb.user:", Name]),
{ok, 201, _, _} = do_request(put, Url, Body),
% let's proceed after giving couch_peruser some time to create the user db
timer:sleep(2000).
+create_anon_user(AuthDb, Name) ->
+ Body = "{\"name\":\"" ++ Name ++
+ "\",\"type\":\"user\",\"roles\":[],\"password\":\"secret\"}",
+ Url = lists:concat([
+ get_cluster_base_url(), "/", ?b2l(AuthDb), "/org.couchdb.user:", Name]),
+ {ok, 201, _, _} = do_anon_request(put, Url, Body),
+ % let's proceed after giving couch_peruser some time to create the user db
+ timer:sleep(2000).
+
delete_user(AuthDb, Name) ->
- Url = lists:concat([get_base_url(), "/", ?b2l(AuthDb),
+ Url = lists:concat([get_cluster_base_url(), "/", ?b2l(AuthDb),
"/org.couchdb.user:", Name]),
{ok, 200, _, Body} = do_request(get, Url),
{DocProps} = jiffy:decode(Body),
@@ -118,6 +134,11 @@ should_create_user_db(TestAuthDb) ->
create_user(TestAuthDb, "foo"),
?_assert(lists:member(<<"userdb-666f6f">>, all_dbs())).
+should_create_anon_user_db(TestAuthDb) ->
+ create_anon_user(TestAuthDb, "fooo"),
+ io:fwrite("HELLO: " ++ ?b2l(TestAuthDb) ++ "~n", []),
+ ?_assert(lists:member(<<"userdb-666f6f6f">>, all_dbs())).
+
should_not_delete_user_db(TestAuthDb) ->
User = "foo",
UserDbName = <<"userdb-666f6f">>,
@@ -264,6 +285,7 @@ couch_peruser_test_() ->
foreach,
fun setup/0, fun teardown/1,
[
+ fun should_create_anon_user_db/1,
fun should_create_user_db/1,
fun should_not_delete_user_db/1,
fun should_delete_user_db/1,