diff options
author | John Christopher Anderson <jchris@apache.org> | 2010-02-03 17:29:41 +0000 |
---|---|---|
committer | John Christopher Anderson <jchris@apache.org> | 2010-02-03 17:29:41 +0000 |
commit | 6bebee4e85ba211212a9ed3b270077f050214911 (patch) | |
tree | f163dae43e519d34cc3cf8c7ae670f37974f4ff2 | |
parent | 7a1efddfb663068d8ee59ee8f6c655777d4aa662 (diff) |
enhance reader and admin lists
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@906138 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | share/www/script/test/reader_acl.js | 35 | ||||
-rw-r--r-- | src/couchdb/couch_db.erl | 46 |
2 files changed, 53 insertions, 28 deletions
diff --git a/share/www/script/test/reader_acl.js b/share/www/script/test/reader_acl.js index 58f3d001..a5fc6a1a 100644 --- a/share/www/script/test/reader_acl.js +++ b/share/www/script/test/reader_acl.js @@ -50,6 +50,21 @@ couchTests.reader_acl = function(debug) { } CouchDB.logout(); + + // make top-secret an admin + T(secretDb.setDbProperty("_admins", { + roles : ["top-secret"], + names : []}).ok); + + T(CouchDB.login("jchris@apache.org", "funnybone").ok); + + T(secretDb.open("baz").foo == "bar"); + + CouchDB.logout(); + + T(secretDb.setDbProperty("_admins", { + roles : [], + names : []}).ok); // admin now adds the top-secret role to the db's readers T(CouchDB.session().userCtx.roles.indexOf("_admin") != -1); @@ -67,18 +82,26 @@ couchTests.reader_acl = function(debug) { // can't set non string reader names or roles try { - T(!secretDb.setDbProperty("_readers", { + secretDb.setDbProperty("_readers", { roles : ["super-secret-club", {"top-secret":"awesome"}], - names : ["joe","barb"]}).ok); + names : ["joe","barb"]}); T(false && "only string roles"); } catch (e) {} try { - T(!secretDb.setDbProperty("_readers", { - roles : ["super-secret-club", "top-secret"], - names : ["joe",22]}).ok); + secretDb.setDbProperty("_readers", { + roles : ["super-secret-club", "top-secret"], + names : ["joe",22]}); T(false && "only string names"); - } catch (e) {} + } catch (e) {} + + try { + secretDb.setDbProperty("_readers", { + roles : ["super-secret-club", "top-secret"], + names : "joe" + }); + T(false && "only lists of names"); + } catch (e) {} } finally { CouchDB.logout(); } diff --git a/src/couchdb/couch_db.erl b/src/couchdb/couch_db.erl index e3891821..aee3bf95 100644 --- a/src/couchdb/couch_db.erl +++ b/src/couchdb/couch_db.erl @@ -247,26 +247,28 @@ check_is_admin(#db{user_ctx=#user_ctx{name=Name,roles=Roles}}=Db) -> end. check_is_reader(#db{user_ctx=#user_ctx{name=Name,roles=Roles}=UserCtx}=Db) -> - % admins are not readers. this is for good reason. - % we don't want to confuse setting admins with making private dbs - {Readers} = get_readers(Db), - ReaderRoles = proplists:get_value(roles, Readers,[]), - WithAdminRoles = [<<"_admin">> | ReaderRoles], - ReaderNames = proplists:get_value(names, Readers,[]), - case ReaderRoles ++ ReaderNames of - [] -> ok; % no readers == public access - _Else -> - case WithAdminRoles -- Roles of - WithAdminRoles -> % same list, not an reader role - case ReaderNames -- [Name] of - ReaderNames -> % same names, not a reader - ?LOG_DEBUG("Not a reader: UserCtx ~p vs Names ~p Roles ~p",[UserCtx, ReaderNames, WithAdminRoles]), - throw({unauthorized, <<"You are not authorized to access this db.">>}); + case (catch check_is_admin(Db)) of + ok -> ok; + _ -> + {Readers} = get_readers(Db), + ReaderRoles = proplists:get_value(roles, Readers,[]), + WithAdminRoles = [<<"_admin">> | ReaderRoles], + ReaderNames = proplists:get_value(names, Readers,[]), + case ReaderRoles ++ ReaderNames of + [] -> ok; % no readers == public access + _Else -> + case WithAdminRoles -- Roles of + WithAdminRoles -> % same list, not an reader role + case ReaderNames -- [Name] of + ReaderNames -> % same names, not a reader + ?LOG_DEBUG("Not a reader: UserCtx ~p vs Names ~p Roles ~p",[UserCtx, ReaderNames, WithAdminRoles]), + throw({unauthorized, <<"You are not authorized to access this db.">>}); + _ -> + ok + end; _ -> ok - end; - _ -> - ok + end end end. @@ -311,17 +313,17 @@ update_sec_field(Field, SecProps, Value) -> % validate user input and convert proplist to atom keys just_names_and_roles({Props}) when is_list(Props) -> - Names = case proplists:get_value(<<"names">>,Props) of + Names = case proplists:get_value(<<"names">>,Props,[]) of Ns when is_list(Ns) -> [throw("names must be a JSON list of strings") ||N <- Ns, not is_binary(N)], Ns; - _ -> [] + _ -> throw("names must be a JSON list of strings") end, - Roles = case proplists:get_value(<<"roles">>,Props) of + Roles = case proplists:get_value(<<"roles">>,Props,[]) of Rs when is_list(Rs) -> [throw("roles must be a JSON list of strings") ||R <- Rs, not is_binary(R)], Rs; - _ -> [] + _ -> throw("roles must be a JSON list of strings") end, {[ {names, Names}, |