couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j..@apache.org
Subject svn commit: r809135 - in /couchdb/branches/0.10.x: ./ etc/default/couchdb 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:47:00 GMT
Author: jan
Date: Sat Aug 29 13:47:00 2009
New Revision: 809135

URL: http://svn.apache.org/viewvc?rev=809135&view=rev
Log:
merge r809134 from trunk: merge cascading auth patch by Jason Davies, closes COUCHDB-478,
fix tests

Modified:
    couchdb/branches/0.10.x/   (props changed)
    couchdb/branches/0.10.x/etc/default/couchdb   (props changed)
    couchdb/branches/0.10.x/share/www/script/couch.js
    couchdb/branches/0.10.x/share/www/script/sha1.js
    couchdb/branches/0.10.x/share/www/script/test/oauth.js
    couchdb/branches/0.10.x/src/couchdb/couch_httpd_auth.erl

Propchange: couchdb/branches/0.10.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Aug 29 13:47:00 2009
@@ -3,4 +3,4 @@
 /couchdb/branches/form:729440-730015
 /couchdb/branches/list-iterator:782292-784593
 /couchdb/branches/tail_header:775760-778477
-/couchdb/trunk:807208-807478,807771,808574,808632,808716,808876
+/couchdb/trunk:806983,807208-807478,807771,808574,808632,808716,808876,809134

Propchange: couchdb/branches/0.10.x/etc/default/couchdb
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Aug 29 13:47:00 2009
@@ -3,5 +3,5 @@
 /couchdb/branches/form/etc/default/couchdb:729440-730015
 /couchdb/branches/list-iterator/etc/default/couchdb:782292-784593
 /couchdb/branches/tail_header/etc/default/couchdb:775760-778477
-/couchdb/trunk/etc/default/couchdb:807208-807478,807771,808574,808632,808716,808876
+/couchdb/trunk/etc/default/couchdb:806983,807208-807478,807771,808574,808632,808716,808876,809134
 /incubator/couchdb/trunk/etc/default/couchdb:642419-694440

Modified: couchdb/branches/0.10.x/share/www/script/couch.js
URL: http://svn.apache.org/viewvc/couchdb/branches/0.10.x/share/www/script/couch.js?rev=809135&r1=809134&r2=809135&view=diff
==============================================================================
--- couchdb/branches/0.10.x/share/www/script/couch.js [utf-8] (original)
+++ couchdb/branches/0.10.x/share/www/script/couch.js [utf-8] Sat Aug 29 13:47:00 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/branches/0.10.x/share/www/script/sha1.js
URL: http://svn.apache.org/viewvc/couchdb/branches/0.10.x/share/www/script/sha1.js?rev=809135&r1=809134&r2=809135&view=diff
==============================================================================
--- couchdb/branches/0.10.x/share/www/script/sha1.js (original)
+++ couchdb/branches/0.10.x/share/www/script/sha1.js Sat Aug 29 13:47:00 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/branches/0.10.x/share/www/script/test/oauth.js
URL: http://svn.apache.org/viewvc/couchdb/branches/0.10.x/share/www/script/test/oauth.js?rev=809135&r1=809134&r2=809135&view=diff
==============================================================================
--- couchdb/branches/0.10.x/share/www/script/test/oauth.js (original)
+++ couchdb/branches/0.10.x/share/www/script/test/oauth.js Sat Aug 29 13:47:00 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<signatureMethods.length; i++) {
         for (var consumerKey in consumerKeys) {
           var expectedCode = consumerKeys[consumerKey];
@@ -108,11 +126,11 @@
           };
 
           // Get request token via Authorization header
-          xhr = oauthRequest("http://" + host + "/_oauth/request_token", message, accessor);
+          xhr = oauthRequest("GET", "http://" + host + "/_oauth/request_token", message,
accessor);
           T(xhr.status == expectedCode);
 
           // GET request token via query parameters
-          xhr = oauthRequest("http://" + host + "/_oauth/request_token", message, accessor,
"GET");
+          xhr = oauthRequest("GET", "http://" + host + "/_oauth/request_token", message,
accessor);
           T(xhr.status == expectedCode);
 
           responseMessage = OAuth.decodeForm(xhr.responseText);
@@ -122,7 +140,7 @@
           //xhr = CouchDB.request("GET", authorization_url + '?oauth_token=' + responseMessage.oauth_token);
           //T(xhr.status == expectedCode);
 
-          xhr = oauthRequest("http://" + host + "/_session", message, accessor);
+          xhr = oauthRequest("GET", "http://" + host + "/_session", message, accessor);
           T(xhr.status == expectedCode);
           if (xhr.status == expectedCode == 200) {
             data = JSON.parse(xhr.responseText);
@@ -130,25 +148,49 @@
             T(data.roles[0] == "test");
           }
 
-          xhr = oauthRequest("http://" + host + "/_session?foo=bar", message, accessor);
+          xhr = oauthRequest("GET", "http://" + host + "/_session?foo=bar", message, accessor);
           T(xhr.status == expectedCode);
 
           // Test HEAD method
-          xhr = oauthRequest("http://" + host + "/_session?foo=bar", message, accessor, "HEAD");
+          xhr = oauthRequest("HEAD", "http://" + host + "/_session?foo=bar", message, accessor);
           T(xhr.status == expectedCode);
 
           // Replication
           var result = CouchDB.replicate(dbPair.source, dbPair.target);
           T(result.ok);
+
+          // Test auth via admin user defined in .ini
+          var message = {
+            parameters: {
+              oauth_signature_method: signatureMethods[i],
+              oauth_consumer_key: consumerKey,
+              oauth_token: "bar",
+              oauth_token_secret: admintokenSecret,
+              oauth_version: "1.0"
+            }
+          };
+          xhr = oauthRequest("GET", "http://" + host + "/_session?foo=bar", message, adminAccessor);
+          if (xhr.status == expectedCode == 200) {
+            data = JSON.parse(xhr.responseText);
+            T(data.name == "testadmin");
+            T(data.roles[0] == "_admin");
+          }
         }
       }
-
     } finally {
+      var xhr = CouchDB.request("DELETE", "http://" + host + "/_config/admins/testadmin",
{
+        headers: {
+          "Authorization": adminBasicAuthHeaderValue(),
+          "X-Couch-Persist": "false"
+        }
+      });
+      T(xhr.status == 200);
     }
   };
 
   run_on_modified_server(
-    [{section: "httpd",
+    [
+     {section: "httpd",
       key: "WWW-Authenticate", value: 'Basic realm="administrator",OAuth'},
      {section: "couch_httpd_auth",
       key: "secret", value: generateSecret(64)},
@@ -158,13 +200,15 @@
       key: "key", value: consumerSecret},
      {section: "oauth_token_users",
       key: "foo", value: "jason"},
+     {section: "oauth_token_users",
+      key: "bar", value: "testadmin"},
      {section: "oauth_token_secrets",
       key: "foo", value: tokenSecret},
+     {section: "oauth_token_secrets",
+      key: "bar", value: admintokenSecret},
      {section: "couch_httpd_oauth",
-      key: "authorization_url", value: authorization_url},
-     {section: "httpd",
-      key: "authentication_handlers",
-      value: "{couch_httpd_oauth, oauth_authentication_handler}, {couch_httpd_auth, default_authentication_handler}"}],
+      key: "authorization_url", value: authorization_url}
+    ],
     testFun
   );
 };

Modified: couchdb/branches/0.10.x/src/couchdb/couch_httpd_auth.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/0.10.x/src/couchdb/couch_httpd_auth.erl?rev=809135&r1=809134&r2=809135&view=diff
==============================================================================
--- couchdb/branches/0.10.x/src/couchdb/couch_httpd_auth.erl (original)
+++ couchdb/branches/0.10.x/src/couchdb/couch_httpd_auth.erl Sat Aug 29 13:47:00 2009
@@ -45,8 +45,10 @@
     end.
 
 basic_username_pw(Req) ->
-    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) ->



Mime
View raw message