Return-Path: Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: (qmail 61419 invoked from network); 29 Aug 2009 13:43:17 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 29 Aug 2009 13:43:17 -0000 Received: (qmail 59919 invoked by uid 500); 29 Aug 2009 13:43:16 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 59825 invoked by uid 500); 29 Aug 2009 13:43:16 -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 59813 invoked by uid 99); 29 Aug 2009 13:43:16 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 29 Aug 2009 13:43:16 +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; Sat, 29 Aug 2009 13:43:12 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 66F6723888D0; Sat, 29 Aug 2009 13:42:51 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r809134 - in /couchdb/trunk: share/www/script/couch.js share/www/script/sha1.js share/www/script/test/oauth.js src/couchdb/couch_httpd_auth.erl Date: Sat, 29 Aug 2009 13:42:51 -0000 To: commits@couchdb.apache.org From: jan@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090829134251.66F6723888D0@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: jan Date: Sat Aug 29 13:42:50 2009 New Revision: 809134 URL: http://svn.apache.org/viewvc?rev=809134&view=rev Log: merge cascading auth patch by Jason Davies, closes COUCHDB-478, fix tests Modified: couchdb/trunk/share/www/script/couch.js couchdb/trunk/share/www/script/sha1.js couchdb/trunk/share/www/script/test/oauth.js couchdb/trunk/src/couchdb/couch_httpd_auth.erl Modified: couchdb/trunk/share/www/script/couch.js URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/couch.js?rev=809134&r1=809133&r2=809134&view=diff ============================================================================== --- couchdb/trunk/share/www/script/couch.js [utf-8] (original) +++ couchdb/trunk/share/www/script/couch.js [utf-8] Sat Aug 29 13:42:50 2009 @@ -324,7 +324,9 @@ } } var headers = {"Content-Type": "application/x-www-form-urlencoded"}; - if (!basicAuth) { + if (basicAuth) { + headers['Authorization'] = basicAuth + } else { headers['X-CouchDB-WWW-Authenticate'] = 'Cookie'; } Modified: couchdb/trunk/share/www/script/sha1.js URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/sha1.js?rev=809134&r1=809133&r2=809134&view=diff ============================================================================== --- couchdb/trunk/share/www/script/sha1.js (original) +++ couchdb/trunk/share/www/script/sha1.js Sat Aug 29 13:42:50 2009 @@ -12,7 +12,7 @@ * the server-side, but the defaults work in most cases. */ var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ -var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ +var b64pad = "="; /* base-64 pad character. "=" for strict RFC compliance */ var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ /* Modified: couchdb/trunk/share/www/script/test/oauth.js URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/oauth.js?rev=809134&r1=809133&r2=809134&view=diff ============================================================================== --- couchdb/trunk/share/www/script/test/oauth.js (original) +++ couchdb/trunk/share/www/script/test/oauth.js Sat Aug 29 13:42:50 2009 @@ -36,7 +36,7 @@ return secret; } - function oauthRequest(path, message, accessor, method) { + function oauthRequest(method, path, message, accessor) { message.action = path; message.method = method || 'GET'; OAuth.SignatureMethod.sign(message, accessor); @@ -59,6 +59,8 @@ var consumerSecret = generateSecret(64); var tokenSecret = generateSecret(64); + var admintokenSecret = generateSecret(64); + var testadminPassword = "ohsosecret"; var host = CouchDB.host; var dbPair = { @@ -76,24 +78,40 @@ target: "http://" + host + "/test_suite_db_b" }; + var adminBasicAuthHeaderValue = function() { + var retval = 'Basic ' + binb2b64(str2binb("testadmin:" + testadminPassword)); + return retval; + } + // this function will be called on the modified server var testFun = function () { try { - var usersDb = new CouchDB("test_suite_users", {"X-Couch-Full-Commit":"false"}); + CouchDB.request("PUT", "http://" + host + "/_config/admins/testadmin", { + headers: {"X-Couch-Persist": "false"}, + body: JSON.stringify(testadminPassword) + }); + + var usersDb = new CouchDB("test_suite_users", { + "X-Couch-Full-Commit":"false", + "Authorization": adminBasicAuthHeaderValue() + }); usersDb.deleteDb(); usersDb.createDb(); - + // Create a user - T(CouchDB.createUser("jason", "testpassword", "test@somemail.com", ['test'], true).ok); + T(CouchDB.createUser("jason", "testpassword", "test@somemail.com", ['test'], adminBasicAuthHeaderValue()).ok); var accessor = { consumerSecret: consumerSecret, tokenSecret: tokenSecret }; + var adminAccessor = { + consumerSecret: consumerSecret, + tokenSecret: admintokenSecret + }; var signatureMethods = ["PLAINTEXT", "HMAC-SHA1"]; var consumerKeys = {key: 200, nonexistent_key: 400}; - for (var i=0; i - case header_value(Req, "Authorization") of + AuthorizationHeader = header_value(Req, "Authorization"), + case AuthorizationHeader of "Basic " ++ Base64Value -> + io:format("~n~nBase64Value: '~p'~n~n", [Base64Value]), case string:tokens(?b2l(couch_util:decodeBase64(Base64Value)),":") of [User, Pass] -> {User, Pass}; @@ -109,29 +111,41 @@ % maybe we can use hovercraft to simplify running this view query get_user(Db, UserName) -> - DesignId = <<"_design/_auth">>, - ViewName = <<"users">>, - % if the design doc or the view doesn't exist, then make it - ensure_users_view_exists(Db, DesignId, ViewName), - - case (catch couch_view:get_map_view(Db, DesignId, ViewName, nil)) of - {ok, View, _Group} -> - FoldlFun = fun - ({{Key, _DocId}, Value}, _, nil) when Key == UserName -> {ok, Value}; - (_, _, Acc) -> {stop, Acc} - end, - case couch_view:fold(View, {UserName, nil}, fwd, FoldlFun, nil) of - {ok, {Result}} -> Result; - _Else -> nil - end; - {not_found, _Reason} -> - nil - % case (catch couch_view:get_reduce_view(Db, DesignId, ViewName, nil)) of - % {ok, _ReduceView, _Group} -> - % not_implemented; - % {not_found, _Reason} -> - % nil - % end + % In the future this will be pluggable. For now we check the .ini first, + % then fall back to querying the db. + io:format("~n~nget-user: '~p'~n", [get_user]), + case couch_config:get("admins", ?b2l(UserName)) of + "-hashed-" ++ HashedPwdAndSalt -> + io:format("hashed: '~p'~n", [hashed]), + [HashedPwd, Salt] = string:tokens(HashedPwdAndSalt, ","), + [{<<"roles">>, [<<"_admin">>]}, + {<<"salt">>, ?l2b(Salt)}, + {<<"password_sha">>, ?l2b(HashedPwd)}]; + _ -> + DesignId = <<"_design/_auth">>, + ViewName = <<"users">>, + % if the design doc or the view doesn't exist, then make it + ensure_users_view_exists(Db, DesignId, ViewName), + + case (catch couch_view:get_map_view(Db, DesignId, ViewName, nil)) of + {ok, View, _Group} -> + FoldlFun = fun + ({{Key, _DocId}, Value}, _, nil) when Key == UserName -> {ok, Value}; + (_, _, Acc) -> {stop, Acc} + end, + case couch_view:fold(View, {UserName, nil}, fwd, FoldlFun, nil) of + {ok, {Result}} -> Result; + _Else -> nil + end; + {not_found, _Reason} -> + nil + % case (catch couch_view:get_reduce_view(Db, DesignId, ViewName, nil)) of + % {ok, _ReduceView, _Group} -> + % not_implemented; + % {not_found, _Reason} -> + % nil + % end + end end. ensure_users_db_exists(DbName) ->