diff options
author | Jan Lehnardt <jan@apache.org> | 2020-01-04 20:12:58 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-04 20:12:58 +0100 |
commit | 3fc054d86f0844bdf851e402b05df5db08b1c230 (patch) | |
tree | 953092f6131067c342a3b41c685f06a5b26f870b | |
parent | 9eeebabecbf6d4dd20de28ec11353cc315553858 (diff) | |
download | couchdb-3fc054d86f0844bdf851e402b05df5db08b1c230.tar.gz |
Feature/user db security obj readonly (#2395)
* Allow to set the user db security object to readonly
- Add the default config
- Deny update on _security if the database is the user db and if the config is to false
- Add unit test
* Allow edits on _users security for the JS test
Co-authored-by: Alexis Côté <popojargo@users.noreply.github.com>
-rw-r--r-- | rel/overlay/etc/default.ini | 3 | ||||
-rw-r--r-- | src/chttpd/src/chttpd_db.erl | 11 | ||||
-rw-r--r-- | src/chttpd/test/eunit/chttpd_security_tests.erl | 24 | ||||
-rw-r--r-- | test/javascript/tests/users_db_security.js | 20 |
4 files changed, 53 insertions, 5 deletions
diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini index a0c26174c..7bfbbe941 100644 --- a/rel/overlay/etc/default.ini +++ b/rel/overlay/etc/default.ini @@ -80,6 +80,9 @@ default_engine = couch ; document. Default is 24 hours. ;index_lag_warn_seconds = 86400 +; Allow edits on the _security object in the user db. By default, it's disabled. +users_db_security_editable = false + [couchdb_engines] ; The keys in this section are the filename extension that ; the specified engine module will use. This is important so diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl index 1787e3929..6a3df6def 100644 --- a/src/chttpd/src/chttpd_db.erl +++ b/src/chttpd/src/chttpd_db.erl @@ -781,6 +781,8 @@ db_req(#httpd{path_parts=[_,<<"_revs_diff">>]}=Req, _Db) -> db_req(#httpd{method='PUT',path_parts=[_,<<"_security">>],user_ctx=Ctx}=Req, Db) -> + DbName = ?b2l(couch_db:name(Db)), + validate_security_can_be_edited(DbName), SecObj = chttpd:json_body(Req), case fabric:set_security(Db, SecObj, [{user_ctx, Ctx}]) of ok -> @@ -1886,6 +1888,15 @@ extract_header_rev(Req, ExplicitRev) -> throw({bad_request, "Document rev and etag have different values"}) end. +validate_security_can_be_edited(DbName) -> + UserDbName = config:get("chttpd_auth", "authentication_db", "_users"), + CanEditUserSecurityObject = config:get("couchdb","users_db_security_editable","false"), + case {DbName,CanEditUserSecurityObject} of + {UserDbName,"false"} -> + Msg = "You can't edit the security object of the user database.", + throw({forbidden, Msg}); + {_,_} -> ok + end. validate_attachment_names(Doc) -> lists:foreach(fun(Att) -> diff --git a/src/chttpd/test/eunit/chttpd_security_tests.erl b/src/chttpd/test/eunit/chttpd_security_tests.erl index 955b4ff01..0bea9dbcd 100644 --- a/src/chttpd/test/eunit/chttpd_security_tests.erl +++ b/src/chttpd/test/eunit/chttpd_security_tests.erl @@ -137,7 +137,8 @@ security_object_validate_test_() -> fun should_return_ok_for_sec_obj_with_roles_and_names/1, fun should_return_error_for_sec_obj_with_incorrect_roles_and_names/1, fun should_return_error_for_sec_obj_with_incorrect_roles/1, - fun should_return_error_for_sec_obj_with_incorrect_names/1 + fun should_return_error_for_sec_obj_with_incorrect_names/1, + fun should_return_error_for_sec_obj_in_user_db/1 ] } } @@ -382,3 +383,24 @@ should_return_error_for_sec_obj_with_incorrect_names([Url,_UsersUrl]) -> {<<"reason">>,<<"no_majority">>} ]}, ResultJson) ]. + +should_return_error_for_sec_obj_in_user_db([_,_UsersUrl]) -> + SecurityUrl = lists:concat([_UsersUrl, "/_security"]), + SecurityProperties = [ + {<<"admins">>, {[{<<"names">>,[<<?TEST_ADMIN>>]}, + {<<"roles">>,[<<?TEST_ADMIN>>]}]}}, + {<<"members">>,{[{<<"names">>,[<<?TEST_MEMBER>>]}, + {<<"roles">>,[<<?TEST_MEMBER>>]}]}} + ], + + Body = jiffy:encode({SecurityProperties}), + {ok, Status, _, RespBody} = test_request:put(SecurityUrl, + [?CONTENT_JSON, ?AUTH], Body), + ResultJson = ?JSON_DECODE(RespBody), + [ + ?_assertEqual(403, Status), + ?_assertEqual({[ + {<<"error">>,<<"forbidden">>}, + {<<"reason">>,<<"You can't edit the security object of the user database.">>} + ]}, ResultJson) + ]. diff --git a/test/javascript/tests/users_db_security.js b/test/javascript/tests/users_db_security.js index 1db6c14c5..faffd8c27 100644 --- a/test/javascript/tests/users_db_security.js +++ b/test/javascript/tests/users_db_security.js @@ -374,10 +374,22 @@ couchTests.users_db_security = function(debug) { }; run_on_modified_server( - [{section: "couch_httpd_auth", - key: "iterations", value: "1"}, - {section: "admins", - key: "jan", value: "apple"}], + [ + { + section:"couchdb", + key:"users_db_security_editable", + value:"true" + }, + { + section: "couch_httpd_auth", + key: "iterations", + value: "1" + }, + { + section: "admins", + key: "jan", + value: "apple" + }], function() { try { testFun(); |