summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Lehnardt <jan@apache.org>2011-11-13 13:06:16 +0100
committerJan Lehnardt <jan@apache.org>2011-11-13 13:07:05 +0100
commitc307ba95c6edcb0708b948c5fc55d8a6a6192e40 (patch)
tree8fba07bcabc545c1e2faa85a4b7ff9acb557f508
parent2b80b5995ea6f425dd736e16b5a77d5a25178581 (diff)
downloadcouchdb-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.js24
-rw-r--r--src/couchdb/couch_httpd_oauth.erl13
-rw-r--r--src/couchdb/couch_httpd_rewrite.erl8
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(),