From 196532f6847c195d1b7e614c8842c25962772b57 Mon Sep 17 00:00:00 2001 From: Nick Vatamaniuc Date: Thu, 12 Sep 2019 12:53:30 -0400 Subject: Improve credential stripping for replication document reads Allow a special field for plugin writers to stash endpoint credentials, which gets the same treatment as headers and user:pass combinations for already existing plugins (session, noop aka basic auth). Instead of complicating the plugin API, use a simple convention of just calling it "auth" for now. --- src/couch_replicator/src/couch_replicator_auth.erl | 6 ++++++ src/couch_replicator/src/couch_replicator_docs.erl | 12 ++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/couch_replicator/src/couch_replicator_auth.erl b/src/couch_replicator/src/couch_replicator_auth.erl index 7f51cdd1c..272e10af5 100644 --- a/src/couch_replicator/src/couch_replicator_auth.erl +++ b/src/couch_replicator/src/couch_replicator_auth.erl @@ -33,6 +33,12 @@ % Behavior API +% Note for plugin developers: consider using the "auth" field in the source and +% target objects to store credentials. In that case non-owner and non-admin +% users will have those credentials stripped when they read the replication +% document, which mimicks the behavior for "headers" and user and pass fields +% in endpoint URLs". + -callback initialize(#httpdb{}) -> {ok, #httpdb{}, term()} | {error, term()} | ignore. diff --git a/src/couch_replicator/src/couch_replicator_docs.erl b/src/couch_replicator/src/couch_replicator_docs.erl index 2d6db1b73..81685cd48 100644 --- a/src/couch_replicator/src/couch_replicator_docs.erl +++ b/src/couch_replicator/src/couch_replicator_docs.erl @@ -683,8 +683,12 @@ strip_credentials(Url) when is_binary(Url) -> "http(s)?://(?:[^:]+):[^@]+@(.*)$", "http\\1://\\2", [{return, binary}]); -strip_credentials({Props}) -> - {lists:keydelete(<<"headers">>, 1, Props)}. +strip_credentials({Props0}) -> + Props1 = lists:keydelete(<<"headers">>, 1, Props0), + % Strip "auth" just like headers, for replication plugins it can be a place + % to stash credential that are not necessarily in headers + Props2 = lists:keydelete(<<"auth">>, 1, Props1), + {Props2}. error_reason({shutdown, Error}) -> @@ -773,6 +777,10 @@ check_strip_credentials_test() -> { {[{<<"_id">>, <<"foo">>}]}, {[{<<"_id">>, <<"foo">>}, {<<"headers">>, <<"baz">>}]} + }, + { + {[{<<"_id">>, <<"foo">>}]}, + {[{<<"_id">>, <<"foo">>}, {<<"auth">>, <<"pluginsecret">>}]} } ]]. -- cgit v1.2.1