couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From klaus_trai...@apache.org
Subject [2/2] couchdb-peruser git commit: Update security object after a user is deleted
Date Tue, 18 Aug 2015 15:12:16 GMT
Update security object after a user is deleted

If the `delete_dbs` configuration value is `false`, we now remove the
user name from each the security object's `members` and `admins`
element's `names` list, respectively.


Project: http://git-wip-us.apache.org/repos/asf/couchdb-peruser/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-peruser/commit/47347190
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-peruser/tree/47347190
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-peruser/diff/47347190

Branch: refs/heads/master
Commit: 473471907c1835f1877805023cfd13ecd3e2ac3a
Parents: 124480e
Author: Klaus Trainer <klaus_trainer@posteo.de>
Authored: Tue Aug 18 16:45:49 2015 +0200
Committer: Klaus Trainer <klaus_trainer@posteo.de>
Committed: Tue Aug 18 17:01:32 2015 +0200

----------------------------------------------------------------------
 src/couchdb_peruser.erl       | 25 +++++++++++++++---
 test/couchdb_peruser_test.erl | 52 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 72 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-peruser/blob/47347190/src/couchdb_peruser.erl
----------------------------------------------------------------------
diff --git a/src/couchdb_peruser.erl b/src/couchdb_peruser.erl
index e6598da..992ac47 100644
--- a/src/couchdb_peruser.erl
+++ b/src/couchdb_peruser.erl
@@ -67,7 +67,7 @@ changes_handler({change, {Doc}, _Prepend}, _ResType, State=#state{}) ->
         case couch_util:get_value(<<"deleted">>, Doc, false) of
         false ->
             UserDb = ensure_user_db(User),
-            ensure_security(User, UserDb),
+            ensure_security(User, UserDb, fun add_user/3),
             State;
         true ->
             case State#state.delete_dbs of
@@ -75,6 +75,7 @@ changes_handler({change, {Doc}, _Prepend}, _ResType, State=#state{}) ->
                 _UserDb = delete_user_db(User),
                 State;
             false ->
+                ensure_security(User, user_db_name(User), fun remove_user/3),
                 State
             end
         end;
@@ -118,15 +119,31 @@ add_user(User, Prop, {Modified, SecProps}) ->
                    {<<"names">>, [User | Names]})}})}
     end.
 
-ensure_security(User, UserDb) ->
+remove_user(User, Prop, {Modified, SecProps}) ->
+    {PropValue} = couch_util:get_value(Prop, SecProps, {[]}),
+    Names = couch_util:get_value(<<"names">>, PropValue, []),
+    case lists:member(User, Names) of
+    false ->
+        {Modified, SecProps};
+    true ->
+        {true,
+         lists:keystore(
+             Prop, 1, SecProps,
+             {Prop,
+              {lists:keystore(
+                   <<"names">>, 1, PropValue,
+                   {<<"names">>, lists:delete(User, Names)})}})}
+    end.
+
+ensure_security(User, UserDb, TransformFun) ->
     {ok, Shards} = fabric:get_all_security(UserDb, [?ADMIN_CTX]),
     {_ShardInfo, {SecProps}} = hd(Shards),
     % assert that shards have the same security object
-    true = lists:all(fun({_, {SecProps1}}) ->
+    true = lists:all(fun ({_, {SecProps1}}) ->
         SecProps =:= SecProps1
     end, Shards),
     case lists:foldl(
-           fun(Prop, SAcc) -> add_user(User, Prop, SAcc) end,
+           fun (Prop, SAcc) -> TransformFun(User, Prop, SAcc) end,
            {false, SecProps},
            [<<"admins">>, <<"members">>]) of
     {false, _} ->

http://git-wip-us.apache.org/repos/asf/couchdb-peruser/blob/47347190/test/couchdb_peruser_test.erl
----------------------------------------------------------------------
diff --git a/test/couchdb_peruser_test.erl b/test/couchdb_peruser_test.erl
index 243c8fd..9bf756d 100644
--- a/test/couchdb_peruser_test.erl
+++ b/test/couchdb_peruser_test.erl
@@ -201,6 +201,54 @@ should_not_remove_existing_db_members(TestAuthDb) ->
     ?_assert(lists:member(<<"wow">>, MemberNames)),
     ?_assert(lists:member(<<"qux">>, MemberNames)).
 
+should_remove_user_from_db_admins(TestAuthDb) ->
+    User = "qux",
+    UserDbName = <<"userdb-717578">>,
+    SecurityProperties = [
+        {<<"admins">>,{[{<<"names">>,[<<"foo">>,<<"bar">>]}]}},
+        {<<"members">>,{[{<<"names">>,[<<"baz">>,<<"pow">>]}]}}
+    ],
+    create_db(UserDbName),
+    set_security(UserDbName, SecurityProperties),
+    create_user(TestAuthDb, User),
+    {AdminProperties} = proplists:get_value(<<"admins">>,
+        get_security(UserDbName)),
+    AdminNames = proplists:get_value(<<"names">>, AdminProperties),
+    ?assert(lists:member(<<"foo">>, AdminNames)),
+    ?assert(lists:member(<<"bar">>, AdminNames)),
+    ?assert(lists:member(<<"qux">>, AdminNames)),
+    delete_user(TestAuthDb, User),
+    {NewAdminProperties} = proplists:get_value(<<"admins">>,
+        get_security(UserDbName)),
+    NewAdminNames = proplists:get_value(<<"names">>, NewAdminProperties),
+    ?_assert(lists:member(<<"foo">>, NewAdminNames)),
+    ?_assert(lists:member(<<"bar">>, NewAdminNames)),
+    ?_assert(not lists:member(<<"qux">>, NewAdminNames)).
+
+should_remove_user_from_db_members(TestAuthDb) ->
+    User = "qux",
+    UserDbName = <<"userdb-717578">>,
+    SecurityProperties = [
+        {<<"admins">>,{[{<<"names">>,[<<"pow">>,<<"wow">>]}]}},
+        {<<"members">>,{[{<<"names">>,[<<"pow">>,<<"wow">>]}]}}
+    ],
+    create_db(UserDbName),
+    set_security(UserDbName, SecurityProperties),
+    create_user(TestAuthDb, User),
+    {MemberProperties} = proplists:get_value(<<"members">>,
+        get_security(UserDbName)),
+    MemberNames = proplists:get_value(<<"names">>, MemberProperties),
+    ?assert(lists:member(<<"pow">>, MemberNames)),
+    ?assert(lists:member(<<"wow">>, MemberNames)),
+    ?assert(lists:member(<<"qux">>, MemberNames)),
+    delete_user(TestAuthDb, User),
+    {NewMemberProperties} = proplists:get_value(<<"members">>,
+        get_security(UserDbName)),
+    NewMemberNames = proplists:get_value(<<"names">>, NewMemberProperties),
+    ?_assert(lists:member(<<"foo">>, NewMemberNames)),
+    ?_assert(lists:member(<<"bar">>, NewMemberNames)),
+    ?_assert(not lists:member(<<"qux">>, NewMemberNames)).
+
 couchdb_peruser_test_() ->
     {
         "couchdb_peruser test",
@@ -218,7 +266,9 @@ couchdb_peruser_test_() ->
                     fun should_assign_user_to_db_admins/1,
                     fun should_assign_user_to_db_members/1,
                     fun should_not_remove_existing_db_admins/1,
-                    fun should_not_remove_existing_db_members/1
+                    fun should_not_remove_existing_db_members/1,
+                    fun should_remove_user_from_db_admins/1,
+                    fun should_remove_user_from_db_members/1
                 ]
             }
         }


Mime
View raw message