summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Vatamaniuc <vatamane@apache.org>2019-09-12 12:53:30 -0400
committerNick Vatamaniuc <nickva@users.noreply.github.com>2019-09-12 16:00:44 -0400
commit196532f6847c195d1b7e614c8842c25962772b57 (patch)
treefe7728c6d8cdb8e4743cf9e78936be24024c7385
parente746d9027f82bfe394cb95c6b2fad09df43fcca9 (diff)
downloadcouchdb-196532f6847c195d1b7e614c8842c25962772b57.tar.gz
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.
-rw-r--r--src/couch_replicator/src/couch_replicator_auth.erl6
-rw-r--r--src/couch_replicator/src/couch_replicator_docs.erl12
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">>}]}
}
]].