From commits-return-3804-apmail-couchdb-commits-archive=couchdb.apache.org@couchdb.apache.org Wed Feb 03 17:30:03 2010 Return-Path: Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: (qmail 22847 invoked from network); 3 Feb 2010 17:30:03 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 3 Feb 2010 17:30:03 -0000 Received: (qmail 63051 invoked by uid 500); 3 Feb 2010 17:30:03 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 62998 invoked by uid 500); 3 Feb 2010 17:30:02 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 62989 invoked by uid 99); 3 Feb 2010 17:30:02 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 03 Feb 2010 17:30:02 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 03 Feb 2010 17:30:01 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 85D8323889B8; Wed, 3 Feb 2010 17:29:41 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r906138 - in /couchdb/trunk: share/www/script/test/reader_acl.js src/couchdb/couch_db.erl Date: Wed, 03 Feb 2010 17:29:41 -0000 To: commits@couchdb.apache.org From: jchris@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100203172941.85D8323889B8@eris.apache.org> Author: jchris Date: Wed Feb 3 17:29:41 2010 New Revision: 906138 URL: http://svn.apache.org/viewvc?rev=906138&view=rev Log: enhance reader and admin lists Modified: couchdb/trunk/share/www/script/test/reader_acl.js couchdb/trunk/src/couchdb/couch_db.erl Modified: couchdb/trunk/share/www/script/test/reader_acl.js URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/reader_acl.js?rev=906138&r1=906137&r2=906138&view=diff ============================================================================== --- couchdb/trunk/share/www/script/test/reader_acl.js (original) +++ couchdb/trunk/share/www/script/test/reader_acl.js Wed Feb 3 17:29:41 2010 @@ -50,6 +50,21 @@ } 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 @@ // 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(); } Modified: couchdb/trunk/src/couchdb/couch_db.erl URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_db.erl?rev=906138&r1=906137&r2=906138&view=diff ============================================================================== --- couchdb/trunk/src/couchdb/couch_db.erl (original) +++ couchdb/trunk/src/couchdb/couch_db.erl Wed Feb 3 17:29:41 2010 @@ -247,26 +247,28 @@ 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 @@ % 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},