diff options
author | Frederick Kaempfer <frederick.kaempfer@gmail.com> | 2017-07-11 16:12:19 +0200 |
---|---|---|
committer | Joan Touzet <wohali@users.noreply.github.com> | 2017-07-12 11:12:37 -0400 |
commit | 247b9856f0c066a0e37ebfd877f27ea462d17d66 (patch) | |
tree | 49e059a17faaa1debe8499a099532588f65f32d1 | |
parent | 6ff73aa963fafff02c324a0e0842e65a151ce431 (diff) | |
download | couchdb-247b9856f0c066a0e37ebfd877f27ea462d17d66.tar.gz |
Require admin or db admin for compact requests
-rw-r--r-- | src/chttpd/src/chttpd_auth_request.erl | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/src/chttpd/src/chttpd_auth_request.erl b/src/chttpd/src/chttpd_auth_request.erl index 9d9a4ca85..319e70b4b 100644 --- a/src/chttpd/src/chttpd_auth_request.erl +++ b/src/chttpd/src/chttpd_auth_request.erl @@ -62,9 +62,9 @@ authorize_request_int(#httpd{path_parts=[_DbName], method='PUT'}=Req) -> authorize_request_int(#httpd{path_parts=[_DbName], method='DELETE'}=Req) -> require_admin(Req); authorize_request_int(#httpd{path_parts=[_DbName, <<"_compact">>|_]}=Req) -> - require_admin(Req); + require_db_admin(Req); authorize_request_int(#httpd{path_parts=[_DbName, <<"_view_cleanup">>]}=Req) -> - require_admin(Req); + require_db_admin(Req); authorize_request_int(#httpd{path_parts=[_DbName|_]}=Req) -> db_authorization_check(Req). @@ -94,3 +94,33 @@ db_authorization_check(#httpd{path_parts=[DbName|_],user_ctx=Ctx}=Req) -> require_admin(Req) -> ok = couch_httpd:verify_is_server_admin(Req), Req. + +require_db_admin(#httpd{path_parts=[DbName|_],user_ctx=Ctx}=Req) -> + Sec = fabric:get_security(DbName, [{user_ctx, Ctx}]), + + case is_db_admin(Ctx,Sec) of + true -> Req; + false -> throw({unauthorized, <<"You are not a server or db admin.">>}) + end. + +is_db_admin(#user_ctx{name=UserName,roles=UserRoles}, {Security}) -> + {Admins} = couch_util:get_value(<<"admins">>, Security, {[]}), + Names = couch_util:get_value(<<"names">>, Admins, []), + Roles = couch_util:get_value(<<"roles">>, Admins, []), + case check_security(roles, UserRoles, [<<"_admin">> | Roles]) of + true -> true; + false -> check_security(names, UserName, Names) + end. + +check_security(roles, [], _) -> + false; +check_security(roles, UserRoles, Roles) -> + UserRolesSet = ordsets:from_list(UserRoles), + RolesSet = ordsets:from_list(Roles), + not ordsets:is_disjoint(UserRolesSet, RolesSet); +check_security(names, _, []) -> + false; +check_security(names, null, _) -> + false; +check_security(names, UserName, Names) -> + lists:member(UserName, Names).
\ No newline at end of file |