You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by wo...@apache.org on 2017/07/09 22:06:03 UTC

[couchdb] branch master updated: Remove deprecated OAuth 1.0 implementation

This is an automated email from the ASF dual-hosted git repository.

wohali pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/couchdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 34b803a  Remove deprecated OAuth 1.0 implementation
34b803a is described below

commit 34b803a35531f305e05080c35c3e9af9e3b9dbf2
Author: Joan Touzet <jo...@atypical.net>
AuthorDate: Sat Jul 8 01:28:39 2017 -0400

    Remove deprecated OAuth 1.0 implementation
    
    Helps resolve issue #656. Implementation broken since bigcouch merge.
    
    Replicator oauth hooks are left in place for future work towards
    adding cookie-based authentication support.
---
 LICENSE                                            |  25 -
 NOTICE                                             |   4 -
 build-aux/print-committerlist.sh                   |   2 +-
 license.skip                                       |   2 -
 rebar.config.script                                |   4 +-
 rel/overlay/etc/default.ini                        |  29 +-
 rel/reltool.config                                 |   2 -
 src/couch/include/couch_js_functions.hrl           |  18 -
 src/couch/src/couch.app.src                        |   1 -
 src/couch/src/couch.erl                            |   1 -
 src/couch/src/couch_httpd_handlers.erl             |   1 -
 src/couch/src/couch_httpd_oauth.erl                | 391 ----------------
 src/couch/src/test_util.erl                        |   1 -
 src/couch/test/chttpd_endpoints_tests.erl          |   1 -
 src/couch/test/couchdb_auth_tests.erl              |   2 +-
 src/couch/test/couchdb_vhosts_tests.erl            | 139 ------
 src/couch/test/fixtures/os_daemon_configer.escript |   1 -
 test/javascript/oauth.js                           | 511 ---------------------
 test/javascript/run                                |   1 -
 test/javascript/tests/oauth_users_db.js            | 168 -------
 test/javascript/tests/replicator_db_security.js    |  28 --
 21 files changed, 5 insertions(+), 1327 deletions(-)

diff --git a/LICENSE b/LICENSE
index 086b2dd..1f0b270 100644
--- a/LICENSE
+++ b/LICENSE
@@ -272,31 +272,6 @@ For the src/ibrowse component:
   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-For the src/oauth component:
-
-  Copyright the authors and contributors. All rights reserved.
-
-  Permission is hereby granted, free of charge, to any person
-  obtaining a copy of this software and associated documentation
-  files (the "Software"), to deal in the Software without
-  restriction, including without limitation the rights to use,
-  copy, modify, merge, publish, distribute, sublicense, and/or sell
-  copies of the Software, and to permit persons to whom the
-  Software is furnished to do so, subject to the following
-  conditions:
-
-  The above copyright notice and this permission notice shall be
-  included in all copies or substantial portions of the Software.
-
-  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-  OTHER DEALINGS IN THE SOFTWARE.
-
 For the test/etap/etap.erl component:
 
   Copyright (c) 2008-2009 Nick Gerakines <ni...@gerakines.net>
diff --git a/NOTICE b/NOTICE
index d0c9f98..cc1621b 100644
--- a/NOTICE
+++ b/NOTICE
@@ -38,10 +38,6 @@ This product also includes the following third-party components:
 
    Copyright 2005-2012, Chandrashekhar Mullaparthi
 
- * Erlang OAuth (http://github.com/tim/erlang-oauth)
-
-   Copyright 2012, the authors and contributors
-
  * ETap (http://github.com/ngerakines/etap/)
 
    Copyright 2009, Nick Gerakines <ni...@gerakines.net>
diff --git a/build-aux/print-committerlist.sh b/build-aux/print-committerlist.sh
index 7fbb96b..f6abc4c 100755
--- a/build-aux/print-committerlist.sh
+++ b/build-aux/print-committerlist.sh
@@ -40,7 +40,7 @@ function get_contributors {
 
 function print_comitter_list {
   # list of external repos that we exclude
-  local EXCLUDE=("bear" "folsom" "goldrush" "ibrowse" "jiffy" "lager" "meck" "mochiweb" "oauth" "snappy")
+  local EXCLUDE=("bear" "folsom" "goldrush" "ibrowse" "jiffy" "lager" "meck" "mochiweb" "snappy")
   local EXCLUDE=$(printf "\|%s" "${EXCLUDE[@]}")
   local EXCLUDE=${EXCLUDE:2}
   local SUBREPOS=$(ls src/ | grep -v "$EXCLUDE")
diff --git a/license.skip b/license.skip
index c1bd0e9..1436392 100644
--- a/license.skip
+++ b/license.skip
@@ -133,7 +133,6 @@
 ^src/couchjs-node/README.md
 ^src/couchjs-node/Makefile
 ^src/couchjs-node/Makefile.in
-^src/erlang-oauth/.*
 ^src/couch_dbupdates
 ^src/ejson/.*
 ^src/etap/.*
@@ -188,7 +187,6 @@
 ^src/twig/ebin/twig.app
 ^src/twig/README.md
 ^src/twig/src/trunc_io.erl
-^src/oauth/.*
 ^stamp-h1
 ^test/Makefile
 ^test/Makefile.in
diff --git a/rebar.config.script b/rebar.config.script
index 5d0e4e8..ebf4d94 100644
--- a/rebar.config.script
+++ b/rebar.config.script
@@ -64,10 +64,8 @@ DepDescs = [
 {ibrowse,          "ibrowse",          "4af2d408607874d124414ac45df1edbe3961d1cd"},
 {jiffy,            "jiffy",            "1acdd1ac389dff3d763589f64331227ae594f3b7"},
 {mochiweb,         "mochiweb",         "bd6ae7cbb371666a1f68115056f7b30d13765782"},
-{meck,             "meck",             {tag, "0.8.2"}},
+{meck,             "meck",             {tag, "0.8.2"}}
 
-%% Deprecated
-{oauth,            "oauth",            "099057a98e41f3aff91e77e3cf496d6c6fd901df"}
 ],
 
 
diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini
index 30a03bc..eaa0801 100644
--- a/rel/overlay/etc/default.ini
+++ b/rel/overlay/etc/default.ini
@@ -76,10 +76,10 @@ delete_dbs = false
 [httpd]
 port = {{backend_port}}
 bind_address = 127.0.0.1
-authentication_handlers = {couch_httpd_oauth, oauth_authentication_handler}, {couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler}
+authentication_handlers = {couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler}
 default_handler = {couch_httpd_db, handle_request}
 secure_rewrites = true
-vhost_global_handlers = _utils, _uuids, _session, _oauth, _users
+vhost_global_handlers = _utils, _uuids, _session, _users
 allow_jsonp = false
 ; Options for the MochiWeb HTTP server.
 ;server_options = [{backlog, 128}, {acceptor_pool_size, 16}]
@@ -196,30 +196,6 @@ credentials = false
 ; List of hosts separated by a comma. * means accept all
 ; hosts =
 
-[couch_httpd_oauth]
-; If set to 'true', oauth token and consumer secrets will be looked up
-; in the authentication database (_users). These secrets are stored in
-; a top level property named "oauth" in user documents. Example:
-;     {
-;         "_id": "org.couchdb.user:joe",
-;         "type": "user",
-;         "name": "joe",
-;         "password_sha": "fe95df1ca59a9b567bdca5cbaf8412abd6e06121",
-;         "salt": "4e170ffeb6f34daecfd814dfb4001a73"
-;         "roles": ["foo", "bar"],
-;         "oauth": {
-;             "consumer_keys": {
-;                 "consumerKey1": "key1Secret",
-;                 "consumerKey2": "key2Secret"
-;             },
-;             "tokens": {
-;                 "token1": "token1Secret",
-;                 "token2": "token2Secret"
-;             }
-;         }
-;     }
-use_users_db = false
-
 [query_servers]
 javascript = {{prefix}}/bin/couchjs {{prefix}}/share/server/main.js
 coffeescript = {{prefix}}/bin/couchjs {{prefix}}/share/server/main-coffee.js
@@ -266,7 +242,6 @@ _uuids = {couch_httpd_misc_handlers, handle_uuids_req}
 _restart = {couch_httpd_misc_handlers, handle_restart_req}
 _stats = {couch_stats_httpd, handle_stats_req}
 _session = {couch_httpd_auth, handle_session_req}
-_oauth = {couch_httpd_oauth, handle_oauth_req}
 _plugins = {couch_plugins_httpd, handle_req}
 _system = {chttpd_misc, handle_system_req}
 
diff --git a/rel/reltool.config b/rel/reltool.config
index 135d386..762848f 100644
--- a/rel/reltool.config
+++ b/rel/reltool.config
@@ -53,7 +53,6 @@
         mango,
         mem3,
         mochiweb,
-        oauth,
         rexi,
         setup,
         snappy
@@ -107,7 +106,6 @@
     {app, mango, [{incl_cond, include}]},
     {app, mem3, [{incl_cond, include}]},
     {app, mochiweb, [{incl_cond, include}]},
-    {app, oauth, [{incl_cond, include}]},
     {app, rexi, [{incl_cond, include}]},
     {app, setup, [{incl_cond, include}]},
     {app, snappy, [{incl_cond, include}]}
diff --git a/src/couch/include/couch_js_functions.hrl b/src/couch/include/couch_js_functions.hrl
index 0ae6427..6851718 100644
--- a/src/couch/include/couch_js_functions.hrl
+++ b/src/couch/include/couch_js_functions.hrl
@@ -150,21 +150,3 @@
         }
     }
 ">>).
-
-
--define(OAUTH_MAP_FUN, <<"
-    function(doc) {
-        if (doc.type === 'user' && doc.oauth && doc.oauth.consumer_keys) {
-            for (var consumer_key in doc.oauth.consumer_keys) {
-                for (var token in doc.oauth.tokens) {
-                    var obj = {
-                        'consumer_secret': doc.oauth.consumer_keys[consumer_key],
-                        'token_secret': doc.oauth.tokens[token],
-                        'username': doc.name
-                    };
-                    emit([consumer_key, token], obj);
-                }
-            }
-        }
-    }
-">>).
diff --git a/src/couch/src/couch.app.src b/src/couch/src/couch.app.src
index cf3dc79..8fc0d89 100644
--- a/src/couch/src/couch.app.src
+++ b/src/couch/src/couch.app.src
@@ -39,7 +39,6 @@
         % Upstream deps
         ibrowse,
         mochiweb,
-        oauth,
 
         % ASF deps
         couch_epi,
diff --git a/src/couch/src/couch.erl b/src/couch/src/couch.erl
index 44cea06..fd5c9e1 100644
--- a/src/couch/src/couch.erl
+++ b/src/couch/src/couch.erl
@@ -23,7 +23,6 @@ deps() ->
         crypto,
         public_key,
         ssl,
-        oauth,
         ibrowse,
         mochiweb,
         config,
diff --git a/src/couch/src/couch_httpd_handlers.erl b/src/couch/src/couch_httpd_handlers.erl
index b8ee3ef..e642875 100644
--- a/src/couch/src/couch_httpd_handlers.erl
+++ b/src/couch/src/couch_httpd_handlers.erl
@@ -14,7 +14,6 @@
 
 -export([url_handler/1, db_handler/1, design_handler/1]).
 
-url_handler(<<"_oauth">>)          -> fun couch_httpd_oauth:handle_oauth_req/1;
 url_handler(_) -> no_match.
 
 db_handler(_) -> no_match.
diff --git a/src/couch/src/couch_httpd_oauth.erl b/src/couch/src/couch_httpd_oauth.erl
deleted file mode 100644
index 0310752..0000000
--- a/src/couch/src/couch_httpd_oauth.erl
+++ /dev/null
@@ -1,391 +0,0 @@
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License.  You may obtain a copy of
-% the License at
-%
-%   http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
--module(couch_httpd_oauth).
-
--include_lib("couch/include/couch_db.hrl").
--include_lib("couch/include/couch_js_functions.hrl").
-
--export([oauth_authentication_handler/1, handle_oauth_req/1]).
-
--define(OAUTH_DDOC_ID, <<"_design/oauth">>).
--define(OAUTH_VIEW_NAME, <<"oauth_credentials">>).
-
--record(callback_params, {
-    consumer,
-    token,
-    token_secret,
-    url,
-    signature,
-    params,
-    username
-}).
-
-% OAuth auth handler using per-node user db
-oauth_authentication_handler(Req) ->
-    serve_oauth(Req, fun oauth_auth_callback/2, true).
-
-
-oauth_auth_callback(Req, #callback_params{token_secret = undefined}) ->
-    couch_httpd:send_error(
-         Req, 400, <<"invalid_token">>, <<"Invalid OAuth token.">>);
-
-oauth_auth_callback(#httpd{mochi_req = MochiReq} = Req, CbParams) ->
-    Method = atom_to_list(MochiReq:get(method)),
-    #callback_params{
-        consumer = Consumer,
-        token = Token,
-        token_secret = TokenSecret,
-        url = Url,
-        signature = Sig,
-        params = Params,
-        username = User
-    } = CbParams,
-    case oauth:verify(Sig, Method, Url, Params, Consumer, TokenSecret) of
-    true ->
-        set_user_ctx(Req, User);
-    false ->
-        couch_log:debug("OAuth handler: signature verification failed for"
-                        " user `~p`~n"
-                        "Received signature is `~p`~n"
-                        "HTTP method is `~p`~n"
-                        "URL is `~p`~n"
-                        "Parameters are `~p`~n"
-                        "Consumer is `~p`, token secret is `~p`~n"
-                        "Expected signature was `~p`~n",
-                        [User, Sig, Method, Url, Params, Consumer, TokenSecret,
-                         oauth:sign(Method, Url, Params, Consumer, Token,
-                                    TokenSecret)]),
-        Req
-    end.
-
-
-% Look up the consumer key and get the roles to give the consumer
-set_user_ctx(_Req, undefined) ->
-    throw({bad_request, unknown_oauth_token});
-set_user_ctx(Req, Name) ->
-    case couch_auth_cache:get_user_creds(Name) of
-        nil ->
-            couch_log:debug("OAuth handler: user `~p` credentials not found",
-                            [Name]),
-            Req;
-        {ok, User, _AuthCtx} ->
-            Roles = couch_util:get_value(<<"roles">>, User, []),
-            Req#httpd{user_ctx=#user_ctx{name=Name, roles=Roles}}
-    end.
-
-% OAuth request_token
-handle_oauth_req(#httpd{path_parts=[_OAuth, <<"request_token">>], method=Method}=Req1) ->
-    serve_oauth(Req1, fun(Req, CbParams) ->
-        #callback_params{
-            consumer = Consumer,
-            token_secret = TokenSecret,
-            url = Url,
-            signature = Sig,
-            params = Params
-        } = CbParams,
-        case oauth:verify(
-            Sig, atom_to_list(Method), Url, Params, Consumer, TokenSecret) of
-        true ->
-            ok(Req, <<"oauth_token=requestkey&oauth_token_secret=requestsecret">>);
-        false ->
-            invalid_signature(Req)
-        end
-    end, false);
-handle_oauth_req(#httpd{path_parts=[_OAuth, <<"authorize">>]}=Req) ->
-    {ok, serve_oauth_authorize(Req)};
-handle_oauth_req(#httpd{path_parts=[_OAuth, <<"access_token">>], method='GET'}=Req1) ->
-    serve_oauth(Req1, fun(Req, CbParams) ->
-        #callback_params{
-            consumer = Consumer,
-            token = Token,
-            url = Url,
-            signature = Sig,
-            params = Params
-        } = CbParams,
-        case Token of
-        "requestkey" ->
-            case oauth:verify(
-                Sig, "GET", Url, Params, Consumer, "requestsecret") of
-            true ->
-                ok(Req,
-                    <<"oauth_token=accesskey&oauth_token_secret=accesssecret">>);
-            false ->
-                invalid_signature(Req)
-            end;
-        _ ->
-            couch_httpd:send_error(
-                Req, 400, <<"invalid_token">>, <<"Invalid OAuth token.">>)
-        end
-    end, false);
-handle_oauth_req(#httpd{path_parts=[_OAuth, <<"access_token">>]}=Req) ->
-    couch_httpd:send_method_not_allowed(Req, "GET").
-
-invalid_signature(Req) ->
-    couch_httpd:send_error(Req, 400, <<"invalid_signature">>, <<"Invalid signature value.">>).
-
-% This needs to be protected i.e. force user to login using HTTP Basic Auth or form-based login.
-serve_oauth_authorize(#httpd{method=Method}=Req1) ->
-    case Method of
-        'GET' ->
-            % Confirm with the User that they want to authenticate the Consumer
-            serve_oauth(Req1, fun(Req, CbParams) ->
-                #callback_params{
-                    consumer = Consumer,
-                    token_secret = TokenSecret,
-                    url = Url,
-                    signature = Sig,
-                    params = Params
-                } = CbParams,
-                case oauth:verify(
-                    Sig, "GET", Url, Params, Consumer, TokenSecret) of
-                true ->
-                    ok(Req, <<"oauth_token=requestkey&",
-                        "oauth_token_secret=requestsecret">>);
-                false ->
-                    invalid_signature(Req)
-                end
-            end, false);
-        'POST' ->
-            % If the User has confirmed, we direct the User back to the Consumer with a verification code
-            serve_oauth(Req1, fun(Req, CbParams) ->
-                #callback_params{
-                    consumer = Consumer,
-                    token_secret = TokenSecret,
-                    url = Url,
-                    signature = Sig,
-                    params = Params
-                } = CbParams,
-                case oauth:verify(
-                    Sig, "POST", Url, Params, Consumer, TokenSecret) of
-                true ->
-                    %redirect(oauth_callback, oauth_token, oauth_verifier),
-                    ok(Req, <<"oauth_token=requestkey&",
-                        "oauth_token_secret=requestsecret">>);
-                false ->
-                    invalid_signature(Req)
-                end
-            end, false);
-        _ ->
-            couch_httpd:send_method_not_allowed(Req1, "GET,POST")
-    end.
-
-serve_oauth(#httpd{mochi_req=MochiReq}=Req, Fun, FailSilently) ->
-    % 1. In the HTTP Authorization header as defined in OAuth HTTP Authorization Scheme.
-    % 2. As the HTTP POST request body with a content-type of application/x-www-form-urlencoded.
-    % 3. Added to the URLs in the query part (as defined by [RFC3986] section 3).
-    AuthHeader = case MochiReq:get_header_value("authorization") of
-        undefined ->
-            "";
-        Else ->
-            [Head | Tail] = re:split(Else, "\\s", [{parts, 2}, {return, list}]),
-            case [string:to_lower(Head) | Tail] of
-                ["oauth", Rest] -> Rest;
-                _ -> ""
-            end
-    end,
-    HeaderParams = oauth:header_params_decode(AuthHeader),
-    %Realm = couch_util:get_value("realm", HeaderParams),
-
-    % get requested path
-    RequestedPath = case MochiReq:get_header_value("x-couchdb-requested-path") of
-        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),
-
-    Params = proplists:delete("realm", HeaderParams) ++ mochiweb_util:parse_qs(QueryString),
-
-    couch_log:debug("OAuth Params: ~p", [Params]),
-    case couch_util:get_value("oauth_version", Params, "1.0") of
-        "1.0" ->
-            case couch_util:get_value("oauth_consumer_key", Params, undefined) of
-                undefined ->
-                    case FailSilently of
-                        true -> Req;
-                        false -> couch_httpd:send_error(Req, 400, <<"invalid_consumer">>, <<"Invalid consumer.">>)
-                    end;
-                ConsumerKey ->
-                    Url = couch_httpd:absolute_uri(Req, RequestedPath),
-                    case get_callback_params(ConsumerKey, Params, Url) of
-                        {ok, CallbackParams} ->
-                            Fun(Req, CallbackParams);
-                        invalid_consumer_token_pair ->
-                            couch_httpd:send_error(
-                                Req, 400,
-                                <<"invalid_consumer_token_pair">>,
-                                <<"Invalid consumer and token pair.">>);
-                        {error, {Error, Reason}} ->
-                            couch_httpd:send_error(Req, 400, Error, Reason)
-                    end
-            end;
-        _ ->
-            couch_httpd:send_error(Req, 400, <<"invalid_oauth_version">>, <<"Invalid OAuth version.">>)
-    end.
-
-
-get_callback_params(ConsumerKey, Params, Url) ->
-    Token = couch_util:get_value("oauth_token", Params),
-    SigMethod = sig_method(Params),
-    CbParams0 = #callback_params{
-        token = Token,
-        signature = couch_util:get_value("oauth_signature", Params),
-        params = proplists:delete("oauth_signature", Params),
-        url = Url
-    },
-    case oauth_credentials_info(Token, ConsumerKey) of
-    nil ->
-        invalid_consumer_token_pair;
-    {error, _} = Err ->
-        Err;
-    {OauthCreds} ->
-        User = couch_util:get_value(<<"username">>, OauthCreds, []),
-        ConsumerSecret = ?b2l(couch_util:get_value(
-            <<"consumer_secret">>, OauthCreds, <<>>)),
-        TokenSecret = ?b2l(couch_util:get_value(
-            <<"token_secret">>, OauthCreds, <<>>)),
-        case (User =:= []) orelse (ConsumerSecret =:= []) orelse
-            (TokenSecret =:= []) of
-        true ->
-            invalid_consumer_token_pair;
-        false ->
-            CbParams = CbParams0#callback_params{
-                consumer = {ConsumerKey, ConsumerSecret, SigMethod},
-                token_secret = TokenSecret,
-                username = User
-            },
-            couch_log:debug("Got OAuth credentials, for ConsumerKey `~p` and "
-                            "Token `~p`, from the views, User: `~p`, "
-                            "ConsumerSecret: `~p`, TokenSecret: `~p`",
-                            [ConsumerKey, Token, User, ConsumerSecret,
-                             TokenSecret]),
-            {ok, CbParams}
-        end
-    end.
-
-
-sig_method(Params) ->
-    sig_method_1(couch_util:get_value("oauth_signature_method", Params)).
-sig_method_1("PLAINTEXT") ->
-    plaintext;
-% sig_method_1("RSA-SHA1") ->
-%    rsa_sha1;
-sig_method_1("HMAC-SHA1") ->
-    hmac_sha1;
-sig_method_1(_) ->
-    undefined.
-
-
-ok(#httpd{mochi_req=MochiReq}, Body) ->
-    {ok, MochiReq:respond({200, [], Body})}.
-
-
-oauth_credentials_info(Token, ConsumerKey) ->
-    case use_auth_db() of
-    {ok, Db} ->
-        Result = case query_oauth_view(Db, [?l2b(ConsumerKey), ?l2b(Token)]) of
-        [] ->
-            nil;
-        [Creds] ->
-            Creds;
-        [_ | _] ->
-            Reason = iolist_to_binary(
-                io_lib:format("Found multiple OAuth credentials for the pair "
-                    " (consumer_key: `~p`, token: `~p`)", [ConsumerKey, Token])),
-            {error, {<<"oauth_token_consumer_key_pair">>, Reason}}
-        end,
-        couch_db:close(Db),
-        Result;
-    nil ->
-        {
-            case config:get("oauth_consumer_secrets", ConsumerKey) of
-            undefined -> [];
-            ConsumerSecret -> [{<<"consumer_secret">>, ?l2b(ConsumerSecret)}]
-            end
-            ++
-            case config:get("oauth_token_secrets", Token) of
-            undefined -> [];
-            TokenSecret -> [{<<"token_secret">>, ?l2b(TokenSecret)}]
-            end
-            ++
-            case config:get("oauth_token_users", Token) of
-            undefined -> [];
-            User -> [{<<"username">>, ?l2b(User)}]
-            end
-        }
-    end.
-
-
-use_auth_db() ->
-    case config:get("couch_httpd_oauth", "use_users_db", "false") of
-    "false" ->
-        nil;
-    "true" ->
-        AuthDb = open_auth_db(),
-        {ok, _AuthDb2} = ensure_oauth_views_exist(AuthDb)
-    end.
-
-
-open_auth_db() ->
-    DbName = ?l2b(config:get("couch_httpd_auth", "authentication_db")),
-    {ok, AuthDb} = couch_db:open_int(DbName, [?ADMIN_CTX]),
-    AuthDb.
-
-
-ensure_oauth_views_exist(AuthDb) ->
-    case couch_db:open_doc(AuthDb, ?OAUTH_DDOC_ID, []) of
-    {ok, _DDoc} ->
-        {ok, AuthDb};
-    _ ->
-        {ok, DDoc} = get_oauth_ddoc(),
-        {ok, _Rev} = couch_db:update_doc(AuthDb, DDoc, []),
-        {ok, _AuthDb2} = couch_db:reopen(AuthDb)
-    end.
-
-
-get_oauth_ddoc() ->
-    Json = {[
-        {<<"_id">>, ?OAUTH_DDOC_ID},
-        {<<"language">>, <<"javascript">>},
-        {<<"views">>,
-            {[
-                {?OAUTH_VIEW_NAME,
-                    {[
-                        {<<"map">>, ?OAUTH_MAP_FUN}
-                    ]}
-                }
-            ]}
-        }
-    ]},
-    {ok, couch_doc:from_json_obj(Json)}.
-
-
-query_oauth_view(Db, Key) ->
-    ViewOptions = [
-        {start_key, Key},
-        {end_key, Key}
-    ],
-    Callback = fun({row, Row}, Acc) ->
-            {ok, [couch_util:get_value(value, Row) | Acc]};
-        (_, Acc) ->
-            {ok, Acc}
-    end,
-    {ok, Result} = couch_mrview:query_view(
-        Db, ?OAUTH_DDOC_ID, ?OAUTH_VIEW_NAME, ViewOptions, Callback, []),
-    Result.
diff --git a/src/couch/src/test_util.erl b/src/couch/src/test_util.erl
index 54fefd5..e652dd9 100644
--- a/src/couch/src/test_util.erl
+++ b/src/couch/src/test_util.erl
@@ -47,7 +47,6 @@ init_code_path() ->
     Paths = [
         "couchdb",
         "jiffy",
-        "oauth",
         "ibrowse",
         "mochiweb",
         "snappy"
diff --git a/src/couch/test/chttpd_endpoints_tests.erl b/src/couch/test/chttpd_endpoints_tests.erl
index 06de1e9..7155767 100644
--- a/src/couch/test/chttpd_endpoints_tests.erl
+++ b/src/couch/test/chttpd_endpoints_tests.erl
@@ -47,7 +47,6 @@ handlers(url_handler) ->
         {<<"_replicate">>, chttpd_misc, handle_replicate_req},
         {<<"_uuids">>, chttpd_misc, handle_uuids_req},
         {<<"_session">>, chttpd_auth, handle_session_req},
-        {<<"_oauth">>, couch_httpd_oauth, handle_oauth_req},
         {<<"_up">>, chttpd_misc, handle_up_req},
         {<<"_membership">>, mem3_httpd, handle_membership_req},
         {<<"_db_updates">>, global_changes_httpd, handle_global_changes_req},
diff --git a/src/couch/test/couchdb_auth_tests.erl b/src/couch/test/couchdb_auth_tests.erl
index b2a490f..ed2c064 100644
--- a/src/couch/test/couchdb_auth_tests.erl
+++ b/src/couch/test/couchdb_auth_tests.erl
@@ -68,7 +68,7 @@ should_not_return_authenticated_field(_PortType, Url) ->
         end).
 
 should_return_list_of_handlers(backdoor, Url) ->
-    ?_assertEqual([<<"oauth">>,<<"cookie">>,<<"default">>],
+    ?_assertEqual([<<"cookie">>,<<"default">>],
         begin
             couch_util:get_nested_json_value(session(Url), [
                 <<"info">>, <<"authentication_handlers">>])
diff --git a/src/couch/test/couchdb_vhosts_tests.erl b/src/couch/test/couchdb_vhosts_tests.erl
index d1da063..dfac73c 100644
--- a/src/couch/test/couchdb_vhosts_tests.erl
+++ b/src/couch/test/couchdb_vhosts_tests.erl
@@ -59,42 +59,6 @@ setup() ->
     Url = "http://" ++ Addr ++ ":" ++ Port,
     {Url, ?b2l(DbName)}.
 
-setup_oauth() ->
-    DbName = ?tempdb(),
-    {ok, Db} = couch_db:create(DbName, [?ADMIN_CTX]),
-
-    config:set("couch_httpd_auth", "authentication_db",
-                     ?b2l(?tempdb()), false),
-    config:set("oauth_token_users", "otoksec1", "joe", false),
-    config:set("oauth_consumer_secrets", "consec1", "foo", false),
-    config:set("oauth_token_secrets", "otoksec1", "foobar", false),
-    config:set("couchdb", "default_security", "everyone", false),
-    config:set("couch_httpd_auth", "require_valid_user", "true", false),
-
-    ok = config:set(
-        "vhosts", "oauth-example.com",
-        "/" ++ ?b2l(DbName) ++ "/_design/test/_rewrite/foobar", false),
-
-    DDoc = couch_doc:from_json_obj({[
-        {<<"_id">>, <<"_design/test">>},
-        {<<"language">>, <<"javascript">>},
-        {<<"rewrites">>, [
-            {[
-                {<<"from">>, <<"foobar">>},
-                {<<"to">>, <<"_info">>}
-            ]}
-        ]}
-    ]}),
-    {ok, _} = couch_db:update_doc(Db, DDoc, []),
-
-    couch_db:ensure_full_commit(Db),
-    couch_db:close(Db),
-
-    Addr = config:get("httpd", "bind_address", "127.0.0.1"),
-    Port = integer_to_list(mochiweb_socket_server:get(couch_httpd, port)),
-    Url = "http://" ++ Addr ++ ":" ++ Port,
-    {Url, ?b2l(DbName)}.
-
 teardown({_, DbName}) ->
     ok = couch_server:delete(?l2b(DbName), []),
     ok.
@@ -127,25 +91,6 @@ vhosts_test_() ->
         }
     }.
 
-oauth_test_() ->
-    {
-        "Virtual Hosts OAuth tests",
-        {
-            setup,
-            fun test_util:start_couch/0, fun test_util:stop_couch/1,
-            {
-                foreach,
-                fun setup_oauth/0, fun teardown/1,
-                [
-                    fun should_require_auth/1,
-                    fun should_succeed_oauth/1,
-                    fun should_fail_oauth_with_wrong_credentials/1
-                ]
-            }
-        }
-    }.
-
-
 should_return_database_info({Url, DbName}) ->
     ?_test(begin
         ok = config:set("vhosts", "example.com", "/" ++ DbName, false),
@@ -351,90 +296,6 @@ should_return_path_for_vhost_with_wildcard_host({Url, DbName}) ->
         end
     end).
 
-should_require_auth({Url, _}) ->
-    ?_test(begin
-        case test_request:get(Url, [], [{host_header, "oauth-example.com"}]) of
-            {ok, Code, _, Body} ->
-                ?assertEqual(401, Code),
-                {JsonBody} = jiffy:decode(Body),
-                ?assertEqual(<<"unauthorized">>,
-                             couch_util:get_value(<<"error">>, JsonBody));
-            Else ->
-                erlang:error({assertion_failed,
-                             [{module, ?MODULE},
-                              {line, ?LINE},
-                              {reason, ?iofmt("Request failed: ~p", [Else])}]})
-        end
-    end).
-
-should_succeed_oauth({Url, _}) ->
-    ?_test(begin
-        AuthDbName = config:get("couch_httpd_auth", "authentication_db"),
-        JoeDoc = couch_doc:from_json_obj({[
-            {<<"_id">>, <<"org.couchdb.user:joe">>},
-            {<<"type">>, <<"user">>},
-            {<<"name">>, <<"joe">>},
-            {<<"roles">>, []},
-            {<<"password_sha">>, <<"fe95df1ca59a9b567bdca5cbaf8412abd6e06121">>},
-            {<<"salt">>, <<"4e170ffeb6f34daecfd814dfb4001a73">>}
-        ]}),
-        {ok, AuthDb} = couch_db:open_int(?l2b(AuthDbName), [?ADMIN_CTX]),
-        {ok, _} = couch_db:update_doc(AuthDb, JoeDoc, [?ADMIN_CTX]),
-
-        Host = "oauth-example.com",
-        Consumer = {"consec1", "foo", hmac_sha1},
-        SignedParams = oauth:sign(
-            "GET", "http://" ++ Host ++ "/", [], Consumer, "otoksec1", "foobar"),
-        OAuthUrl = oauth:uri(Url, SignedParams),
-
-        case test_request:get(OAuthUrl, [], [{host_header, Host}]) of
-            {ok, Code, _, Body} ->
-                ?assertEqual(200, Code),
-                {JsonBody} = jiffy:decode(Body),
-                ?assertEqual(<<"test">>,
-                             couch_util:get_value(<<"name">>, JsonBody));
-            Else ->
-                erlang:error({assertion_failed,
-                             [{module, ?MODULE},
-                              {line, ?LINE},
-                              {reason, ?iofmt("Request failed: ~p", [Else])}]})
-        end
-    end).
-
-should_fail_oauth_with_wrong_credentials({Url, _}) ->
-    ?_test(begin
-        AuthDbName = config:get("couch_httpd_auth", "authentication_db"),
-        JoeDoc = couch_doc:from_json_obj({[
-            {<<"_id">>, <<"org.couchdb.user:joe">>},
-            {<<"type">>, <<"user">>},
-            {<<"name">>, <<"joe">>},
-            {<<"roles">>, []},
-            {<<"password_sha">>, <<"fe95df1ca59a9b567bdca5cbaf8412abd6e06121">>},
-            {<<"salt">>, <<"4e170ffeb6f34daecfd814dfb4001a73">>}
-        ]}),
-        {ok, AuthDb} = couch_db:open_int(?l2b(AuthDbName), [?ADMIN_CTX]),
-        {ok, _} = couch_db:update_doc(AuthDb, JoeDoc, [?ADMIN_CTX]),
-
-        Host = "oauth-example.com",
-        Consumer = {"consec1", "bad_secret", hmac_sha1},
-        SignedParams = oauth:sign(
-            "GET", "http://" ++ Host ++ "/", [], Consumer, "otoksec1", "foobar"),
-        OAuthUrl = oauth:uri(Url, SignedParams),
-
-        case test_request:get(OAuthUrl, [], [{host_header, Host}]) of
-            {ok, Code, _, Body} ->
-                ?assertEqual(401, Code),
-                {JsonBody} = jiffy:decode(Body),
-                ?assertEqual(<<"unauthorized">>,
-                             couch_util:get_value(<<"error">>, JsonBody));
-            Else ->
-                erlang:error({assertion_failed,
-                             [{module, ?MODULE},
-                              {line, ?LINE},
-                              {reason, ?iofmt("Request failed: ~p", [Else])}]})
-        end
-    end).
-
 ensure_index_file() ->
     Body = <<"<!DOCTYPE html>\n<html>\n<body>\nHello world\n</body>\n</html>">>,
     file:write_file(filename:join([?TEMPDIR, "index.html"]), Body).
diff --git a/src/couch/test/fixtures/os_daemon_configer.escript b/src/couch/test/fixtures/os_daemon_configer.escript
index 3e02ef9..f146b83 100755
--- a/src/couch/test/fixtures/os_daemon_configer.escript
+++ b/src/couch/test/fixtures/os_daemon_configer.escript
@@ -88,7 +88,6 @@ init_code_path() ->
     Paths = [
         "couchdb",
         "jiffy",
-        "erlang-oauth",
         "ibrowse",
         "mochiweb",
         "snappy"
diff --git a/test/javascript/oauth.js b/test/javascript/oauth.js
deleted file mode 100644
index ada00a2..0000000
--- a/test/javascript/oauth.js
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * Copyright 2008 Netflix, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* Here's some JavaScript software for implementing OAuth.
-
-   This isn't as useful as you might hope.  OAuth is based around
-   allowing tools and websites to talk to each other.  However,
-   JavaScript running in web browsers is hampered by security
-   restrictions that prevent code running on one website from
-   accessing data stored or served on another.
-
-   Before you start hacking, make sure you understand the limitations
-   posed by cross-domain XMLHttpRequest.
-
-   On the bright side, some platforms use JavaScript as their
-   language, but enable the programmer to access other web sites.
-   Examples include Google Gadgets, and Microsoft Vista Sidebar.
-   For those platforms, this library should come in handy.
-*/
-
-// The HMAC-SHA1 signature method calls b64_hmac_sha1, defined by
-// http://pajhome.org.uk/crypt/md5/sha1.js
-
-/* An OAuth message is represented as an object like this:
-   {method: "GET", action: "http://server.com/path", parameters: ...}
-
-   The parameters may be either a map {name: value, name2: value2}
-   or an Array of name-value pairs [[name, value], [name2, value2]].
-   The latter representation is more powerful: it supports parameters
-   in a specific sequence, or several parameters with the same name;
-   for example [["a", 1], ["b", 2], ["a", 3]].
-
-   Parameter names and values are NOT percent-encoded in an object.
-   They must be encoded before transmission and decoded after reception.
-   For example, this message object:
-   {method: "GET", action: "http://server/path", parameters: {p: "x y"}}
-   ... can be transmitted as an HTTP request that begins:
-   GET /path?p=x%20y HTTP/1.0
-   (This isn't a valid OAuth request, since it lacks a signature etc.)
-   Note that the object "x y" is transmitted as x%20y.  To encode
-   parameters, you can call OAuth.addToURL, OAuth.formEncode or
-   OAuth.getAuthorization.
-
-   This message object model harmonizes with the browser object model for
-   input elements of an form, whose value property isn't percent encoded.
-   The browser encodes each value before transmitting it. For example,
-   see consumer.setInputs in example/consumer.js.
- */
-var OAuth; if (OAuth == null) OAuth = {};
-
-OAuth.setProperties = function setProperties(into, from) {
-    if (into != null && from != null) {
-        for (var key in from) {
-            into[key] = from[key];
-        }
-    }
-    return into;
-}
-
-OAuth.setProperties(OAuth, // utility functions
-{
-    percentEncode: function percentEncode(s) {
-        if (s == null) {
-            return "";
-        }
-        if (s instanceof Array) {
-            var e = "";
-            for (var i = 0; i < s.length; ++i) {
-                if (e != "") e += '&';
-                e += percentEncode(s[i]);
-            }
-            return e;
-        }
-        s = encodeURIComponent(s);
-        // Now replace the values which encodeURIComponent doesn't do
-        // encodeURIComponent ignores: - _ . ! ~ * ' ( )
-        // OAuth dictates the only ones you can ignore are: - _ . ~
-        // Source: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Functions:encodeURIComponent
-        s = s.replace(/\!/g, "%21");
-        s = s.replace(/\*/g, "%2A");
-        s = s.replace(/\'/g, "%27");
-        s = s.replace(/\(/g, "%28");
-        s = s.replace(/\)/g, "%29");
-        return s;
-    }
-,
-    decodePercent: function decodePercent(s) {
-        if (s != null) {
-            // Handle application/x-www-form-urlencoded, which is defined by
-            // http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1
-            s = s.replace(/\+/g, " ");
-        }
-        return decodeURIComponent(s);
-    }
-,
-    /** Convert the given parameters to an Array of name-value pairs. */
-    getParameterList: function getParameterList(parameters) {
-        if (parameters == null) {
-            return [];
-        }
-        if (typeof parameters != "object") {
-            return decodeForm(parameters + "");
-        }
-        if (parameters instanceof Array) {
-            return parameters;
-        }
-        var list = [];
-        for (var p in parameters) {
-            list.push([p, parameters[p]]);
-        }
-        return list;
-    }
-,
-    /** Convert the given parameters to a map from name to value. */
-    getParameterMap: function getParameterMap(parameters) {
-        if (parameters == null) {
-            return {};
-        }
-        if (typeof parameters != "object") {
-            return getParameterMap(decodeForm(parameters + ""));
-        }
-        if (parameters instanceof Array) {
-            var map = {};
-            for (var p = 0; p < parameters.length; ++p) {
-                var key = parameters[p][0];
-                if (map[key] === undefined) { // first value wins
-                    map[key] = parameters[p][1];
-                }
-            }
-            return map;
-        }
-        return parameters;
-    }
-,
-    getParameter: function getParameter(parameters, name) {
-        if (parameters instanceof Array) {
-            for (var p = 0; p < parameters.length; ++p) {
-                if (parameters[p][0] == name) {
-                    return parameters[p][1]; // first value wins
-                }
-            }
-        } else {
-            return OAuth.getParameterMap(parameters)[name];
-        }
-        return null;
-    }
-,
-    formEncode: function formEncode(parameters) {
-        var form = "";
-        var list = OAuth.getParameterList(parameters);
-        for (var p = 0; p < list.length; ++p) {
-            var value = list[p][1];
-            if (value == null) value = "";
-            if (form != "") form += '&';
-            form += OAuth.percentEncode(list[p][0])
-              +'='+ OAuth.percentEncode(value);
-        }
-        return form;
-    }
-,
-    decodeForm: function decodeForm(form) {
-        var list = [];
-        var nvps = form.split('&');
-        for (var n = 0; n < nvps.length; ++n) {
-            var nvp = nvps[n];
-            if (nvp == "") {
-                continue;
-            }
-            var equals = nvp.indexOf('=');
-            var name;
-            var value;
-            if (equals < 0) {
-                name = OAuth.decodePercent(nvp);
-                value = null;
-            } else {
-                name = OAuth.decodePercent(nvp.substring(0, equals));
-                value = OAuth.decodePercent(nvp.substring(equals + 1));
-            }
-            list.push([name, value]);
-        }
-        return list;
-    }
-,
-    setParameter: function setParameter(message, name, value) {
-        var parameters = message.parameters;
-        if (parameters instanceof Array) {
-            for (var p = 0; p < parameters.length; ++p) {
-                if (parameters[p][0] == name) {
-                    if (value === undefined) {
-                        parameters.splice(p, 1);
-                    } else {
-                        parameters[p][1] = value;
-                        value = undefined;
-                    }
-                }
-            }
-            if (value !== undefined) {
-                parameters.push([name, value]);
-            }
-        } else {
-            parameters = OAuth.getParameterMap(parameters);
-            parameters[name] = value;
-            message.parameters = parameters;
-        }
-    }
-,
-    setParameters: function setParameters(message, parameters) {
-        var list = OAuth.getParameterList(parameters);
-        for (var i = 0; i < list.length; ++i) {
-            OAuth.setParameter(message, list[i][0], list[i][1]);
-        }
-    }
-,
-    /** Fill in parameters to help construct a request message.
-        This function doesn't fill in every parameter.
-        The accessor object should be like:
-        {consumerKey:'foo', consumerSecret:'bar', accessorSecret:'nurn', token:'krelm', tokenSecret:'blah'}
-        The accessorSecret property is optional.
-     */
-    completeRequest: function completeRequest(message, accessor) {
-        if (message.method == null) {
-            message.method = "GET";
-        }
-        var map = OAuth.getParameterMap(message.parameters);
-        if (map.oauth_consumer_key == null) {
-            OAuth.setParameter(message, "oauth_consumer_key", accessor.consumerKey || "");
-        }
-        if (map.oauth_token == null && accessor.token != null) {
-            OAuth.setParameter(message, "oauth_token", accessor.token);
-        }
-        if (map.oauth_version == null) {
-            OAuth.setParameter(message, "oauth_version", "1.0");
-        }
-        if (map.oauth_timestamp == null) {
-            OAuth.setParameter(message, "oauth_timestamp", OAuth.timestamp());
-        }
-        if (map.oauth_nonce == null) {
-            OAuth.setParameter(message, "oauth_nonce", OAuth.nonce(6));
-        }
-        OAuth.SignatureMethod.sign(message, accessor);
-    }
-,
-    setTimestampAndNonce: function setTimestampAndNonce(message) {
-        OAuth.setParameter(message, "oauth_timestamp", OAuth.timestamp());
-        OAuth.setParameter(message, "oauth_nonce", OAuth.nonce(6));
-    }
-,
-    addToURL: function addToURL(url, parameters) {
-        newURL = url;
-        if (parameters != null) {
-            var toAdd = OAuth.formEncode(parameters);
-            if (toAdd.length > 0) {
-                var q = url.indexOf('?');
-                if (q < 0) newURL += '?';
-                else       newURL += '&';
-                newURL += toAdd;
-            }
-        }
-        return newURL;
-    }
-,
-    /** Construct the value of the Authorization header for an HTTP request. */
-    getAuthorizationHeader: function getAuthorizationHeader(realm, parameters) {
-        var header = 'OAuth realm="' + OAuth.percentEncode(realm) + '"';
-        var list = OAuth.getParameterList(parameters);
-        for (var p = 0; p < list.length; ++p) {
-            var parameter = list[p];
-            var name = parameter[0];
-            if (name.indexOf("oauth_") == 0) {
-                header += ',' + OAuth.percentEncode(name) + '="' + OAuth.percentEncode(parameter[1]) + '"';
-            }
-        }
-        return header;
-    }
-,
-    timestamp: function timestamp() {
-        var d = new Date();
-        return Math.floor(d.getTime()/1000);
-    }
-,
-    nonce: function nonce(length) {
-        var chars = OAuth.nonce.CHARS;
-        var result = "";
-        for (var i = 0; i < length; ++i) {
-            var rnum = Math.floor(Math.random() * chars.length);
-            result += chars.substring(rnum, rnum+1);
-        }
-        return result;
-    }
-});
-
-OAuth.nonce.CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
-
-/** Define a constructor function,
-    without causing trouble to anyone who was using it as a namespace.
-    That is, if parent[name] already existed and had properties,
-    copy those properties into the new constructor.
- */
-OAuth.declareClass = function declareClass(parent, name, newConstructor) {
-    var previous = parent[name];
-    parent[name] = newConstructor;
-    if (newConstructor != null && previous != null) {
-        for (var key in previous) {
-            if (key != "prototype") {
-                newConstructor[key] = previous[key];
-            }
-        }
-    }
-    return newConstructor;
-}
-
-/** An abstract algorithm for signing messages. */
-OAuth.declareClass(OAuth, "SignatureMethod", function OAuthSignatureMethod(){});
-
-OAuth.setProperties(OAuth.SignatureMethod.prototype, // instance members
-{
-    /** Add a signature to the message. */
-    sign: function sign(message) {
-        var baseString = OAuth.SignatureMethod.getBaseString(message);
-        var signature = this.getSignature(baseString);
-        OAuth.setParameter(message, "oauth_signature", signature);
-        return signature; // just in case someone's interested
-    }
-,
-    /** Set the key string for signing. */
-    initialize: function initialize(name, accessor) {
-        var consumerSecret;
-        if (accessor.accessorSecret != null
-            && name.length > 9
-            && name.substring(name.length-9) == "-Accessor")
-        {
-            consumerSecret = accessor.accessorSecret;
-        } else {
-            consumerSecret = accessor.consumerSecret;
-        }
-        this.key = OAuth.percentEncode(consumerSecret)
-             +"&"+ OAuth.percentEncode(accessor.tokenSecret);
-    }
-});
-
-/* SignatureMethod expects an accessor object to be like this:
-   {tokenSecret: "lakjsdflkj...", consumerSecret: "QOUEWRI..", accessorSecret: "xcmvzc..."}
-   The accessorSecret property is optional.
- */
-// Class members:
-OAuth.setProperties(OAuth.SignatureMethod, // class members
-{
-    sign: function sign(message, accessor) {
-        var name = OAuth.getParameterMap(message.parameters).oauth_signature_method;
-        if (name == null || name == "") {
-            name = "HMAC-SHA1";
-            OAuth.setParameter(message, "oauth_signature_method", name);
-        }
-        OAuth.SignatureMethod.newMethod(name, accessor).sign(message);
-    }
-,
-    /** Instantiate a SignatureMethod for the given method name. */
-    newMethod: function newMethod(name, accessor) {
-        var impl = OAuth.SignatureMethod.REGISTERED[name];
-        if (impl != null) {
-            var method = new impl();
-            method.initialize(name, accessor);
-            return method;
-        }
-        var err = new Error("signature_method_rejected");
-        var acceptable = "";
-        for (var r in OAuth.SignatureMethod.REGISTERED) {
-            if (acceptable != "") acceptable += '&';
-            acceptable += OAuth.percentEncode(r);
-        }
-        err.oauth_acceptable_signature_methods = acceptable;
-        throw err;
-    }
-,
-    /** A map from signature method name to constructor. */
-    REGISTERED : {}
-,
-    /** Subsequently, the given constructor will be used for the named methods.
-        The constructor will be called with no parameters.
-        The resulting object should usually implement getSignature(baseString).
-        You can easily define such a constructor by calling makeSubclass, below.
-     */
-    registerMethodClass: function registerMethodClass(names, classConstructor) {
-        for (var n = 0; n < names.length; ++n) {
-            OAuth.SignatureMethod.REGISTERED[names[n]] = classConstructor;
-        }
-    }
-,
-    /** Create a subclass of OAuth.SignatureMethod, with the given getSignature function. */
-    makeSubclass: function makeSubclass(getSignatureFunction) {
-        var superClass = OAuth.SignatureMethod;
-        var subClass = function() {
-            superClass.call(this);
-        }; 
-        subClass.prototype = new superClass();
-        // Delete instance variables from prototype:
-        // delete subclass.prototype... There aren't any.
-        subClass.prototype.getSignature = getSignatureFunction;
-        subClass.prototype.constructor = subClass;
-        return subClass;
-    }
-,
-    getBaseString: function getBaseString(message) {
-        var URL = message.action;
-        var q = URL.indexOf('?');
-        var parameters;
-        if (q < 0) {
-            parameters = message.parameters;
-        } else {
-            // Combine the URL query string with the other parameters:
-            parameters = OAuth.decodeForm(URL.substring(q + 1));
-            var toAdd = OAuth.getParameterList(message.parameters);
-            for (var a = 0; a < toAdd.length; ++a) {
-                parameters.push(toAdd[a]);
-            }
-        }
-        return OAuth.percentEncode(message.method.toUpperCase())
-         +'&'+ OAuth.percentEncode(OAuth.SignatureMethod.normalizeUrl(URL))
-         +'&'+ OAuth.percentEncode(OAuth.SignatureMethod.normalizeParameters(parameters));
-    }
-,
-    normalizeUrl: function normalizeUrl(url) {
-        var uri = OAuth.SignatureMethod.parseUri(url);
-        var scheme = uri.protocol.toLowerCase();
-        var authority = uri.authority.toLowerCase();
-        var dropPort = (scheme == "http" && uri.port == 80)
-                    || (scheme == "https" && uri.port == 443);
-        if (dropPort) {
-            // find the last : in the authority
-            var index = authority.lastIndexOf(":");
-            if (index >= 0) {
-                authority = authority.substring(0, index);
-            }
-        }
-        var path = uri.path;
-        if (!path) {
-            path = "/"; // conforms to RFC 2616 section 3.2.2
-        }
-        // we know that there is no query and no fragment here.
-        return scheme + "://" + authority + path;
-    }
-,
-    parseUri: function parseUri (str) {
-        /* This function was adapted from parseUri 1.2.1
-           http://stevenlevithan.com/demo/parseuri/js/assets/parseuri.js
-         */
-        var o = {key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
-                 parser: {strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/ }};
-        var m = o.parser.strict.exec(str);
-        var uri = {};
-        var i = 14;
-        while (i--) uri[o.key[i]] = m[i] || "";
-        return uri;
-    }
-,
-    normalizeParameters: function normalizeParameters(parameters) {
-        if (parameters == null) {
-            return "";
-        }
-        var list = OAuth.getParameterList(parameters);
-        var sortable = [];
-        for (var p = 0; p < list.length; ++p) {
-            var nvp = list[p];
-            if (nvp[0] != "oauth_signature") {
-                sortable.push([ OAuth.percentEncode(nvp[0])
-                              + " " // because it comes before any character that can appear in a percentEncoded string.
-                              + OAuth.percentEncode(nvp[1])
-                              , nvp]);
-            }
-        }
-        sortable.sort(function(a,b) {
-                          if (a[0] < b[0]) return  -1;
-                          if (a[0] > b[0]) return 1;
-                          return 0;
-                      });
-        var sorted = [];
-        for (var s = 0; s < sortable.length; ++s) {
-            sorted.push(sortable[s][1]);
-        }
-        return OAuth.formEncode(sorted);
-    }
-});
-
-OAuth.SignatureMethod.registerMethodClass(["PLAINTEXT", "PLAINTEXT-Accessor"],
-    OAuth.SignatureMethod.makeSubclass(
-        function getSignature(baseString) {
-            return this.key;
-        }
-    ));
-
-OAuth.SignatureMethod.registerMethodClass(["HMAC-SHA1", "HMAC-SHA1-Accessor"],
-    OAuth.SignatureMethod.makeSubclass(
-        function getSignature(baseString) {
-            b64pad = '=';
-            var signature = b64_hmac_sha1(this.key, baseString);
-            return signature;
-        }
-    ));
diff --git a/test/javascript/run b/test/javascript/run
index 7f366eb..f7659b0 100755
--- a/test/javascript/run
+++ b/test/javascript/run
@@ -29,7 +29,6 @@ COUCHJS = "src/couch/priv/couchjs"
 SCRIPTS = """
     test/javascript/json2.js
     test/javascript/sha1.js
-    test/javascript/oauth.js
     test/javascript/couch.js
     test/javascript/replicator_db_inc.js
     test/javascript/couch_test_runner.js
diff --git a/test/javascript/tests/oauth_users_db.js b/test/javascript/tests/oauth_users_db.js
deleted file mode 100644
index 6e4b3de..0000000
--- a/test/javascript/tests/oauth_users_db.js
+++ /dev/null
@@ -1,168 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License.  You may obtain a copy
-// of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-couchTests.oauth_users_db = function(debug) {
-  return console.log('TODO: oauth not available on clustered interface');
-  // This tests OAuth authentication using the _users DB instead of the ini
-  // configuration for storing OAuth tokens and secrets.
-
-  if (debug) debugger;
-
-  var users_db_name = get_random_db_name();
-  var usersDb = new CouchDB(users_db_name, {"X-Couch-Full-Commit":"false"});
-  usersDb.createDb();
-
-  var db_name = get_random_db_name();
-  var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
-  db.createDb();
-
-  var host = CouchDB.host;
-  var authorization_url = "/_oauth/authorize";
-
-
-  // Simple secret key generator
-  function generateSecret(length) {
-    var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-    var secret = '';
-    for (var i = 0; i < length; i++) {
-      secret += tab.charAt(Math.floor(Math.random() * 64));
-    }
-    return secret;
-  }
-
-
-  function oauthRequest(method, path, message, accessor) {
-    message.action = path;
-    message.method = method || 'GET';
-    OAuth.SignatureMethod.sign(message, accessor);
-    var parameters = message.parameters;
-    if (method == "POST" || method == "GET") {
-      if (method == "GET") {
-        return CouchDB.request("GET", OAuth.addToURL(path, parameters));
-      } else {
-        return CouchDB.request("POST", path, {
-          headers: {"Content-Type": "application/x-www-form-urlencoded"},
-          body: OAuth.formEncode(parameters)
-        });
-      }
-    } else {
-      return CouchDB.request(method, path, {
-        headers: {Authorization: OAuth.getAuthorizationHeader('', parameters)}
-      });
-    }
-  }
-
-
-  // this function will be called on the modified server
-  var testFun = function () {
-    var fdmanana = CouchDB.prepareUserDoc({
-      name: "fdmanana",
-      roles: ["dev"],
-      oauth: {
-        consumer_keys: {
-          "key_foo": "bar",
-          "key_xpto": "mars"
-        },
-        tokens: {
-          "salut": "ola",
-          "tok1": "123"
-        }
-      }
-    }, "qwerty");
-    TEquals(true, usersDb.save(fdmanana).ok);
-
-    var signatureMethods = ["PLAINTEXT", "HMAC-SHA1"];
-    var message, xhr, responseMessage, accessor, data;
-
-    for (var i = 0; i < signatureMethods.length; i++) {
-      message = {
-        parameters: {
-          oauth_signature_method: signatureMethods[i],
-          oauth_consumer_key: "key_foo",
-          oauth_token: "tok1",
-          oauth_version: "1.0"
-        }
-      };
-      accessor = {
-        consumerSecret: "bar",
-        tokenSecret: "123"
-      };
-
-      xhr = oauthRequest("GET", CouchDB.protocol + host + "/_oauth/request_token",
-        message, accessor
-      );
-      TEquals(200, xhr.status);
-
-      responseMessage = OAuth.decodeForm(xhr.responseText);
-
-      // Obtaining User Authorization
-      // Only needed for 3-legged OAuth
-      //xhr = CouchDB.request(
-      //  "GET", authorization_url + '?oauth_token=' + responseMessage.oauth_token);
-      //TEquals(200, xhr.status);
-
-      xhr = oauthRequest(
-        "GET", CouchDB.protocol + host + "/_session", message, accessor);
-      TEquals(200, xhr.status);
-      data = JSON.parse(xhr.responseText);
-      TEquals(true, data.ok);
-      TEquals("object", typeof data.userCtx);
-      TEquals("fdmanana", data.userCtx.name);
-      TEquals("dev", data.userCtx.roles[0]);
-      TEquals("oauth", data.info.authenticated);
-
-      // test invalid token
-      message.parameters.oauth_token = "not a token!";
-      xhr = oauthRequest("GET", CouchDB.protocol + host + "/_session",
-        message, accessor
-      );
-      TEquals(400, xhr.status, "Request should be invalid.");
-
-      // test invalid secret
-      message.parameters.oauth_token = "tok1";
-      accessor.tokenSecret = "badone";
-      xhr = oauthRequest("GET", CouchDB.protocol + host + "/_session",
-        message, accessor
-      );
-      data = JSON.parse(xhr.responseText);
-      TEquals(null, data.userCtx.name);
-      TEquals(1, data.userCtx.roles.length);
-      TEquals("_admin", data.userCtx.roles[0]);
-      TEquals(true, data.info.authentication_handlers.indexOf("default") >= 0);
-      TEquals("default", data.info.authenticated);
-    }
-  };
-
-
-  usersDb.deleteDb();
-
-  run_on_modified_server(
-    [
-     {section: "httpd",
-      key: "WWW-Authenticate", value: 'OAuth'},
-     {section: "couch_httpd_auth",
-      key: "secret", value: generateSecret(64)},
-     {section: "couch_httpd_auth",
-      key: "authentication_db", value: usersDb.name},
-     {section: "couch_httpd_oauth",
-      key: "use_users_db", value: "true"},
-     {section: "httpd", key: "authentication_handlers",
-      value: "{couch_httpd_oauth, oauth_authentication_handler}, " +
-        "{couch_httpd_auth, default_authentication_handler}"}
-    ],
-    testFun
-  );
-
-  // cleanup
-  usersDb.deleteDb();
-  db.deleteDb();
-};
diff --git a/test/javascript/tests/replicator_db_security.js b/test/javascript/tests/replicator_db_security.js
index 2fc0f6c..ffb5c40 100644
--- a/test/javascript/tests/replicator_db_security.js
+++ b/test/javascript/tests/replicator_db_security.js
@@ -344,34 +344,6 @@ couchTests.replicator_db_security = function(debug) {
            doc.source, "source field contains credentials (doc from _changes)");
         CouchDB.logout();
 
-        var fdmananaRepDocOAuth = {
-          _id: "fdmanana-rep-doc-oauth",
-          source: dbC.name,
-          target: {
-            url: "http://" + CouchDB.host + "/" + dbA.name,
-            oauth: {
-              token: "abc",
-              token_secret: "foo",
-              consumer_key: "123",
-              consumer_secret: "321"
-            }
-          },
-          user_ctx: { name: "fdmanana", roles: [] }
-        };
-
-        var result = save_as(repDb, fdmananaRepDocOAuth, "fdmanana");
-        TEquals(true, result.ok, "should create rep doc");
-        waitForDocPos(repDb, fdmananaRepDocOAuth._id, 3);
-        fdmananaRepDocOAuth = open_as(repDb, fdmananaRepDocOAuth._id, "fdmanana");
-        TEquals("fdmanana", fdmananaRepDocOAuth.owner, "should assign correct owner");
-        TEquals("object", typeof fdmananaRepDocOAuth.target.oauth,
-          "target field has oauth credentials");
-
-        fdmananaRepDocOAuth = open_as(repDb, fdmananaRepDocOAuth._id, "jchris");
-        TEquals("fdmanana", fdmananaRepDocOAuth.owner, "should assign correct owner");
-        TEquals("undefined", typeof fdmananaRepDocOAuth.target.oauth,
-          "target field doesn't have oauth credentials");
-
         // ensure "old" replicator docs still work
         // done in replicator_db.js?
 

-- 
To stop receiving notification emails like this one, please contact
['"commits@couchdb.apache.org" <co...@couchdb.apache.org>'].