diff options
author | Jan Lehnardt <jan@apache.org> | 2011-11-13 13:06:16 +0100 |
---|---|---|
committer | Jan Lehnardt <jan@apache.org> | 2011-11-13 13:07:05 +0100 |
commit | c307ba95c6edcb0708b948c5fc55d8a6a6192e40 (patch) | |
tree | 8fba07bcabc545c1e2faa85a4b7ff9acb557f508 | |
parent | 2b80b5995ea6f425dd736e16b5a77d5a25178581 (diff) | |
download | couchdb-c307ba95c6edcb0708b948c5fc55d8a6a6192e40.tar.gz |
Fix OAuth validation when using the rewriter.
Patch by Klaus Trainer.
Closes COUCHDB-1321
-rw-r--r-- | share/www/script/test/oauth.js | 24 | ||||
-rw-r--r-- | src/couchdb/couch_httpd_oauth.erl | 13 | ||||
-rw-r--r-- | src/couchdb/couch_httpd_rewrite.erl | 8 |
3 files changed, 42 insertions, 3 deletions
diff --git a/share/www/script/test/oauth.js b/share/www/script/test/oauth.js index 82ebe8a49..9915bff47 100644 --- a/share/www/script/test/oauth.js +++ b/share/www/script/test/oauth.js @@ -22,10 +22,13 @@ couchTests.oauth = function(debug) { var dbA = new CouchDB("test_suite_db_a", {"X-Couch-Full-Commit":"false"}); var dbB = new CouchDB("test_suite_db_b", {"X-Couch-Full-Commit":"false"}); + var dbC = new CouchDB("test_suite_db_c", {"X-Couch-Full-Commit":"false"}); dbA.deleteDb(); dbA.createDb(); dbB.deleteDb(); dbB.createDb(); + dbC.deleteDb(); + dbC.createDb(); // Simple secret key generator function generateSecret(length) { @@ -197,6 +200,27 @@ couchTests.oauth = function(debug) { }); T(result.ok); + // Test if rewriting doesn't break OAuth (c.f. COUCHDB-1321) + var dbC = new CouchDB("test_suite_db_c", { + "X-Couch-Full-Commit":"false", + "Authorization": adminBasicAuthHeaderValue() + }); + var ddocId = "_design/"+ i + consumerKey; + var ddoc = { + _id: ddocId, + language: "javascript", + _attachments:{ + "bar": { + content_type:"text/plain", + data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ=" + } + }, + rewrites: [{"from": "foo/:a", "to": ":a"}] + }; + T(dbC.save(ddoc).ok); + xhr = oauthRequest("GET", CouchDB.protocol + host + "/test_suite_db_c/" + ddocId + "/_rewrite/foo/bar", message, accessor); + T(xhr.status == expectedCode); + // Test auth via admin user defined in .ini var message = { parameters: { diff --git a/src/couchdb/couch_httpd_oauth.erl b/src/couchdb/couch_httpd_oauth.erl index 05ee10e2c..4d58a888d 100644 --- a/src/couchdb/couch_httpd_oauth.erl +++ b/src/couchdb/couch_httpd_oauth.erl @@ -130,7 +130,16 @@ serve_oauth(#httpd{mochi_req=MochiReq}=Req, Fun, FailSilently) -> end, HeaderParams = oauth_uri:params_from_header_string(AuthHeader), %Realm = couch_util:get_value("realm", HeaderParams), - Params = proplists:delete("realm", HeaderParams) ++ MochiReq:parse_qs(), + + % get requested path + RequestedPath = case MochiReq:get_header_value("x-couchdb-requested-path") of + undefined -> MochiReq:get(raw_path); + RequestedPath0 -> RequestedPath0 + end, + {_, QueryString, _} = mochiweb_util:urlsplit_path(RequestedPath), + + Params = proplists:delete("realm", HeaderParams) ++ mochiweb_util:parse_qs(QueryString), + ?LOG_DEBUG("OAuth Params: ~p", [Params]), case couch_util:get_value("oauth_version", Params, "1.0") of "1.0" -> @@ -147,7 +156,7 @@ serve_oauth(#httpd{mochi_req=MochiReq}=Req, Fun, FailSilently) -> couch_httpd:send_error(Req, 400, <<"invalid_consumer">>, <<"Invalid consumer (key or signature method).">>); Consumer -> Signature = couch_util:get_value("oauth_signature", Params), - URL = couch_httpd:absolute_uri(Req, MochiReq:get(raw_path)), + URL = couch_httpd:absolute_uri(Req, RequestedPath), Fun(URL, proplists:delete("oauth_signature", Params), Consumer, Signature) end diff --git a/src/couchdb/couch_httpd_rewrite.erl b/src/couchdb/couch_httpd_rewrite.erl index 8480c1e9a..bf9347843 100644 --- a/src/couchdb/couch_httpd_rewrite.erl +++ b/src/couchdb/couch_httpd_rewrite.erl @@ -165,6 +165,12 @@ handle_rewrite_req(#httpd{ % normalize final path (fix levels "." and "..") RawPath1 = ?b2l(iolist_to_binary(normalize_path(RawPath))), + % in order to do OAuth correctly, + % we have to save the requested path + Headers = mochiweb_headers:enter("x-couchdb-requested-path", + MochiReq:get(raw_path), + MochiReq:get(headers)), + ?LOG_DEBUG("rewrite to ~p ~n", [RawPath1]), % build a new mochiweb request @@ -172,7 +178,7 @@ handle_rewrite_req(#httpd{ MochiReq:get(method), RawPath1, MochiReq:get(version), - MochiReq:get(headers)), + Headers), % cleanup, It force mochiweb to reparse raw uri. MochiReq1:cleanup(), |