what is the point of wariting in the process registry?
On Sat, Dec 10, 2011 at 9:03 PM, <fdman...@apache.org> wrote: > Fix OAuth authentication with VHosts + URL rewriting > > The OAuth handler was not getting the right path (the one > the client used to compute its OAuth signature) to verify > the client's signature. The right path is the one from > before doing the VHost dispatch. > Secondly, after the OAuth handler succeeds, the rewriter > kicks in and calls couch_httpd:handle_request_int/5 with a > new mochiweb request which contains the rewritten patch. > This will cause all the authentication handlers to run again, > which makes the OAuth handler fail this second time because > it gets a rewritten patch. > > COUCHDB-1320 > > > Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo > Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/b86fa1f6 > Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/b86fa1f6 > Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/b86fa1f6 > > Branch: refs/heads/1.2.x > Commit: b86fa1f6bedee9d441bf4cac53c2794a60c69216 > Parents: 25754ac > Author: Filipe David Borba Manana <fdman...@apache.org> > Authored: Sat Dec 10 19:05:52 2011 +0000 > Committer: Filipe David Borba Manana <fdman...@apache.org> > Committed: Sat Dec 10 19:40:37 2011 +0000 > > ---------------------------------------------------------------------- > src/couchdb/couch_httpd.erl | 3 +- > src/couchdb/couch_httpd_oauth.erl | 11 +++- > src/couchdb/couch_httpd_rewrite.erl | 4 +- > test/etap/160-vhosts.t | 89 +++++++++++++++++++++++++++++- > 4 files changed, 102 insertions(+), 5 deletions(-) > ---------------------------------------------------------------------- > > > http://git-wip-us.apache.org/repos/asf/couchdb/blob/b86fa1f6/src/couchdb/couch_httpd.erl > ---------------------------------------------------------------------- > diff --git a/src/couchdb/couch_httpd.erl b/src/couchdb/couch_httpd.erl > index 11b0bca..2d4c38d 100644 > --- a/src/couchdb/couch_httpd.erl > +++ b/src/couchdb/couch_httpd.erl > @@ -298,7 +298,8 @@ handle_request_int(MochiReq, DefaultFun, > db_url_handlers = DbUrlHandlers, > design_url_handlers = DesignUrlHandlers, > default_fun = DefaultFun, > - url_handlers = UrlHandlers > + url_handlers = UrlHandlers, > + user_ctx = erlang:erase(pre_rewrite_user_ctx) > }, > > HandlerFun = couch_util:dict_find(HandlerKey, UrlHandlers, DefaultFun), > > http://git-wip-us.apache.org/repos/asf/couchdb/blob/b86fa1f6/src/couchdb/couch_httpd_oauth.erl > ---------------------------------------------------------------------- > diff --git a/src/couchdb/couch_httpd_oauth.erl > b/src/couchdb/couch_httpd_oauth.erl > index 4d58a88..65304a3 100644 > --- a/src/couchdb/couch_httpd_oauth.erl > +++ b/src/couchdb/couch_httpd_oauth.erl > @@ -133,8 +133,15 @@ serve_oauth(#httpd{mochi_req=MochiReq}=Req, Fun, > FailSilently) -> > > % get requested path > RequestedPath = case > MochiReq:get_header_value("x-couchdb-requested-path") of > - undefined -> MochiReq:get(raw_path); > - RequestedPath0 -> RequestedPath0 > + undefined -> > + case MochiReq:get_header_value("x-couchdb-vhost-path") of > + undefined -> > + MochiReq:get(raw_path); > + VHostPath -> > + VHostPath > + end; > + RequestedPath0 -> > + RequestedPath0 > end, > {_, QueryString, _} = mochiweb_util:urlsplit_path(RequestedPath), > > > http://git-wip-us.apache.org/repos/asf/couchdb/blob/b86fa1f6/src/couchdb/couch_httpd_rewrite.erl > ---------------------------------------------------------------------- > diff --git a/src/couchdb/couch_httpd_rewrite.erl > b/src/couchdb/couch_httpd_rewrite.erl > index bf93478..c8cab85 100644 > --- a/src/couchdb/couch_httpd_rewrite.erl > +++ b/src/couchdb/couch_httpd_rewrite.erl > @@ -187,8 +187,10 @@ handle_rewrite_req(#httpd{ > db_url_handlers = DbUrlHandlers, > design_url_handlers = DesignUrlHandlers, > default_fun = DefaultFun, > - url_handlers = UrlHandlers > + url_handlers = UrlHandlers, > + user_ctx = UserCtx > } = Req, > + erlang:put(pre_rewrite_user_ctx, UserCtx), > couch_httpd:handle_request_int(MochiReq1, DefaultFun, > UrlHandlers, DbUrlHandlers, DesignUrlHandlers) > end. > > http://git-wip-us.apache.org/repos/asf/couchdb/blob/b86fa1f6/test/etap/160-vhosts.t > ---------------------------------------------------------------------- > diff --git a/test/etap/160-vhosts.t b/test/etap/160-vhosts.t > index e959f74..0b239a1 100755 > --- a/test/etap/160-vhosts.t > +++ b/test/etap/160-vhosts.t > @@ -52,7 +52,7 @@ admin_user_ctx() -> {user_ctx, > #user_ctx{roles=[<<"_admin">>]}}. > main(_) -> > test_util:init_code_path(), > > - etap:plan(15), > + etap:plan(18), > case (catch test()) of > ok -> > etap:end_tests(); > @@ -135,9 +135,11 @@ test() -> > test_vhost_request_path2(), > test_vhost_request_path3(), > test_vhost_request_to_root(), > + test_vhost_request_with_oauth(Db), > > %% restart boilerplate > couch_db:close(Db), > + ok = couch_server:delete(couch_db:name(Db), [admin_user_ctx()]), > timer:sleep(3000), > couch_server_sup:stop(), > > @@ -301,3 +303,88 @@ test_vhost_request_to_root() -> > etap:is(HasCouchDBWelcome, true, "should allow redirect to /"); > _Else -> etap:is(false, true, <<"ibrowse fail">>) > end. > + > +test_vhost_request_with_oauth(Db) -> > + {ok, AuthDb} = couch_db:create( > + <<"tap_test_sec_db">>, [admin_user_ctx(), overwrite]), > + PrevAuthDbName = couch_config:get("couch_httpd_auth", > "authentication_db"), > + couch_config:set("couch_httpd_auth", "authentication_db", > "tap_test_sec_db", false), > + couch_config:set("oauth_token_users", "otoksec1", "joe", false), > + couch_config:set("oauth_consumer_secrets", "consec1", "foo", false), > + couch_config:set("oauth_token_secrets", "otoksec1", "foobar", false), > + couch_config:set("couch_httpd_auth", "require_valid_user", "true", > false), > + > + DDoc = couch_doc:from_json_obj({[ > + {<<"_id">>, <<"_design/test">>}, > + {<<"language">>, <<"javascript">>}, > + {<<"rewrites">>, [ > + {[ > + {<<"from">>, <<"foobar">>}, > + {<<"to">>, <<"_info">>} > + ]} > + ]} > + ]}), > + {ok, _} = couch_db:update_doc(Db, DDoc, []), > + > + RewritePath = "/etap-test-db/_design/test/_rewrite/foobar", > + ok = couch_config:set("vhosts", "oauth-example.com", RewritePath, false), > + couch_httpd_vhost:reload(), > + > + case ibrowse:send_req(server(), [], get, [], [{host_header, > "oauth-example.com"}]) of > + {ok, "401", _, Body} -> > + {JsonBody} = ejson:decode(Body), > + etap:is( > + couch_util:get_value(<<"error">>, JsonBody), > + <<"unauthorized">>, > + "Request without OAuth credentials failed"); > + Error -> > + etap:bail("Request without OAuth credentials did not fail: " ++ > + couch_util:to_list(Error)) > + end, > + > + JoeDoc = couch_doc:from_json_obj({[ > + {<<"_id">>, <<"org.couchdb.user:joe">>}, > + {<<"type">>, <<"user">>}, > + {<<"name">>, <<"joe">>}, > + {<<"roles">>, []}, > + {<<"password_sha">>, <<"fe95df1ca59a9b567bdca5cbaf8412abd6e06121">>}, > + {<<"salt">>, <<"4e170ffeb6f34daecfd814dfb4001a73">>} > + ]}), > + {ok, _} = couch_db:update_doc(AuthDb, JoeDoc, []), > + > + Url = "http://oauth-example.com/", > + Consumer = {"consec1", "foo", hmac_sha1}, > + SignedParams = oauth:signed_params( > + "GET", Url, [], Consumer, "otoksec1", "foobar"), > + OAuthUrl = oauth:uri(server(), SignedParams), > + > + case ibrowse:send_req(OAuthUrl, [], get, [], [{host_header, > "oauth-example.com"}]) of > + {ok, "200", _, Body2} -> > + {JsonBody2} = ejson:decode(Body2), > + etap:is(couch_util:get_value(<<"name">>, JsonBody2), <<"test">>, > + "should return ddoc info with OAuth credentials"); > + Error2 -> > + etap:bail("Failed to access vhost with OAuth credentials: " ++ > + couch_util:to_list(Error2)) > + end, > + > + Consumer2 = {"consec1", "bad_secret", hmac_sha1}, > + SignedParams2 = oauth:signed_params( > + "GET", Url, [], Consumer2, "otoksec1", "foobar"), > + OAuthUrl2 = oauth:uri(server(), SignedParams2), > + > + case ibrowse:send_req(OAuthUrl2, [], get, [], [{host_header, > "oauth-example.com"}]) of > + {ok, "401", _, Body3} -> > + {JsonBody3} = ejson:decode(Body3), > + etap:is( > + couch_util:get_value(<<"error">>, JsonBody3), > + <<"unauthorized">>, > + "Request with bad OAuth credentials failed"); > + Error3 -> > + etap:bail("Failed to access vhost with bad OAuth credentials: " ++ > + couch_util:to_list(Error3)) > + end, > + > + couch_config:set("couch_httpd_auth", "authentication_db", > PrevAuthDbName, false), > + couch_config:set("couch_httpd_auth", "require_valid_user", "false", > false), > + ok = couch_server:delete(couch_db:name(AuthDb), [admin_user_ctx()]). >