You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ja...@apache.org on 2020/01/04 17:42:13 UTC
[couchdb] 01/02: Allow to set the user db security object to
readonly
This is an automated email from the ASF dual-hosted git repository.
jan pushed a commit to branch feature/user-db-security-obj-readonly
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 4e83bc5a04780e6686004959ca88450eb7d59da8
Author: Alexis Côté <al...@hotmail.com>
AuthorDate: Fri Dec 21 23:36:57 2018 -0500
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
---
rel/overlay/etc/default.ini | 3 +++
src/chttpd/src/chttpd_db.erl | 11 +++++++++++
src/chttpd/test/eunit/chttpd_security_tests.erl | 24 +++++++++++++++++++++++-
3 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini
index a0c2617..7bfbbe9 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 1787e39..6a3df6d 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 955b4ff..0bea9db 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)
+ ].