From decd71b396720d896f2d2d504dac5ab6976b4a70 Mon Sep 17 00:00:00 2001 From: Jan Lehnardt Date: Sat, 3 Jun 2017 15:49:21 +0200 Subject: feat: update for 2.0 patch by @guillett https://github.com/apache/couchdb-peruser/pull/3 --- src/couch_peruser/.travis.yml | 24 --------------- src/couch_peruser/src/couch_peruser.erl | 44 +++++++++++++++++++-------- src/couch_peruser/test/couch_peruser_test.erl | 28 +++++++++++++++-- 3 files changed, 57 insertions(+), 39 deletions(-) delete mode 100644 src/couch_peruser/.travis.yml 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, -- cgit v1.2.1