From 674aad6f37355529da81af35105fbb86de5e5974 Mon Sep 17 00:00:00 2001 From: Jan Lehnardt Date: Wed, 25 Sep 2013 17:40:14 +0200 Subject: admins can always read all doc fields, regardless of public_fields Closes COUCHDB-1888 --- share/www/script/test/users_db_security.js | 11 ++++++++-- src/couch_mrview/src/couch_mrview_http.erl | 32 ++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/share/www/script/test/users_db_security.js b/share/www/script/test/users_db_security.js index 888ed007f..9bf9b8a1b 100644 --- a/share/www/script/test/users_db_security.js +++ b/share/www/script/test/users_db_security.js @@ -168,7 +168,7 @@ couchTests.users_db_security = function(debug) { "should not_found opening another user's user doc"); - // save a db amin + // save a db admin var benoitcDoc = { _id: "org.couchdb.user:benoitc", type: "user", @@ -320,7 +320,7 @@ couchTests.users_db_security = function(debug) { { section: "couch_httpd_auth", key: "public_fields", - value: "name,type" + value: "name" }, { section: "couch_httpd_auth", @@ -342,6 +342,13 @@ couchTests.users_db_security = function(debug) { TEquals("forbidden", e.error, "should throw"); } + // COUCHDB-1888 make sure admins always get all fields + TEquals(true, CouchDB.login("jan", "apple").ok); + var all_admin = usersDb.allDocs({ include_docs: "true" }); + TEquals("user", all_admin.rows[2].doc.type, + "should return type"); + + // log in one last time so run_on_modified_server can clean up the admin account TEquals(true, CouchDB.login("jan", "apple").ok); }); diff --git a/src/couch_mrview/src/couch_mrview_http.erl b/src/couch_mrview/src/couch_mrview_http.erl index b8c446517..8b914ef17 100644 --- a/src/couch_mrview/src/couch_mrview_http.erl +++ b/src/couch_mrview/src/couch_mrview_http.erl @@ -129,7 +129,6 @@ all_docs_req(Req, Db, Keys) -> do_all_docs_req(Req, Db, Keys) end. - do_all_docs_req(Req, Db, Keys) -> Args0 = parse_qs(Req, Keys), ETagFun = fun(Sig, Acc0) -> @@ -143,14 +142,11 @@ do_all_docs_req(Req, Db, Keys) -> {ok, Resp} = couch_httpd:etag_maybe(Req, fun() -> VAcc0 = #vacc{db=Db, req=Req}, DbName = ?b2l(Db#db.name), - Callback = case couch_config:get("couch_httpd_auth", + UsersDbName = couch_config:get("couch_httpd_auth", "authentication_db", - "_users") of - DbName -> - fun filtered_view_cb/2; - _ -> - fun view_cb/2 - end, + "_users"), + IsAdmin = is_admin(Db), + Callback = get_view_callback(DbName, UsersDbName, IsAdmin), couch_mrview:query_all_docs(Db, Args, Callback, VAcc0) end), case is_record(Resp, vacc) of @@ -158,6 +154,26 @@ do_all_docs_req(Req, Db, Keys) -> _ -> {ok, Resp} end. +is_admin(Db) -> + case catch couch_db:check_is_admin(Db) of + {unauthorized, _} -> + false; + ok -> + true + end. + + +% admin users always get all fields +get_view_callback(_, _, true) -> + fun view_cb/2; +% if we are operating on the users db and we aren't +% admin, filter the view +get_view_callback(_DbName, _DbName, false) -> + fun filtered_view_cb/2; +% non _users databases get all fields +get_view_callback(_, _, _) -> + fun view_cb/2. + design_doc_view(Req, Db, DDoc, ViewName, Keys) -> Args0 = parse_qs(Req, Keys), -- cgit v1.2.1