summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Avdey <eiri@eiri.ca>2017-09-04 14:43:23 -0300
committerEric Avdey <eiri@eiri.ca>2017-09-04 22:59:03 -0300
commitd3c8d41f60f69f92d3a30e408ae9428d88cf604c (patch)
treec34801be10efdee593a11d18b9e02c7698e5ae78
parent3d0e4f426fcc84808af64c96c22e3f39cb53255f (diff)
downloadcouchdb-d3c8d41f60f69f92d3a30e408ae9428d88cf604c.tar.gz
Pass user ctx when opening a doc in show handler
-rw-r--r--src/chttpd/src/chttpd_show.erl13
-rw-r--r--test/javascript/tests/users_db_security.js46
2 files changed, 54 insertions, 5 deletions
diff --git a/src/chttpd/src/chttpd_show.erl b/src/chttpd/src/chttpd_show.erl
index d8e2ea5c7..48f14257e 100644
--- a/src/chttpd/src/chttpd_show.erl
+++ b/src/chttpd/src/chttpd_show.erl
@@ -22,8 +22,8 @@
% it looks up the doc an then passes it to the query server.
% then it sends the response from the query server to the http client.
-maybe_open_doc(Db, DocId) ->
- case fabric:open_doc(Db, DocId, [conflicts]) of
+maybe_open_doc(Db, DocId, Options) ->
+ case fabric:open_doc(Db, DocId, Options) of
{ok, Doc} ->
Doc;
{not_found, _} ->
@@ -35,7 +35,8 @@ handle_doc_show_req(#httpd{
}=Req, Db, DDoc) ->
% open the doc
- Doc = maybe_open_doc(Db, DocId),
+ Options = [conflicts, {user_ctx, Req#httpd.user_ctx}],
+ Doc = maybe_open_doc(Db, DocId, Options),
% we don't handle revs here b/c they are an internal api
% returns 404 if there is no doc with DocId
@@ -49,7 +50,8 @@ handle_doc_show_req(#httpd{
DocId1 = ?l2b(string:join([?b2l(P)|| P <- DocParts], "/")),
% open the doc
- Doc = maybe_open_doc(Db, DocId1),
+ Options = [conflicts, {user_ctx, Req#httpd.user_ctx}],
+ Doc = maybe_open_doc(Db, DocId1, Options),
% we don't handle revs here b/c they are an internal api
% pass 404 docs to the show function
@@ -107,7 +109,8 @@ handle_doc_update_req(#httpd{
path_parts=[_, _, _, _, UpdateName | DocIdParts]
}=Req, Db, DDoc) ->
DocId = ?l2b(string:join([?b2l(P) || P <- DocIdParts], "/")),
- Doc = maybe_open_doc(Db, DocId),
+ Options = [conflicts, {user_ctx, Req#httpd.user_ctx}],
+ Doc = maybe_open_doc(Db, DocId, Options),
send_doc_update_response(Req, Db, DDoc, UpdateName, Doc, DocId);
handle_doc_update_req(Req, _Db, _DDoc) ->
diff --git a/test/javascript/tests/users_db_security.js b/test/javascript/tests/users_db_security.js
index 06f74b1e6..ad516a0c4 100644
--- a/test/javascript/tests/users_db_security.js
+++ b/test/javascript/tests/users_db_security.js
@@ -75,6 +75,17 @@ couchTests.users_db_security = function(debug) {
}
};
+ var request_as = function(db, ddoc_path, username) {
+ loginUser(username);
+ try {
+ var uri = db.uri + ddoc_path;
+ var req = CouchDB.request("GET", uri);
+ return req;
+ } finally {
+ CouchDB.logout();
+ }
+ };
+
var testFun = function()
{
@@ -178,6 +189,14 @@ couchTests.users_db_security = function(debug) {
test: {
map: "function(doc) { emit(doc._id, null); }"
}
+ },
+ lists: {
+ names: "function(head, req) { "
+ + "var row; while (row = getRow()) { send(row.key + \"\\n\"); }"
+ + "}"
+ },
+ shows: {
+ name: "function(doc, req) { return doc.name; }"
}
};
@@ -208,6 +227,33 @@ couchTests.users_db_security = function(debug) {
TEquals("forbidden", e.error, "non-admins can't read design docs");
}
+ // admin shold be able to read _list
+ var listPath = ddoc["_id"] + "/_list/names/test";
+ var result = request_as(usersDb, listPath, "jan");
+ var lines = result.responseText.split("\n");
+ T(result.status == 200, "should allow access to db admin");
+ TEquals(4, lines.length, "should list users to db admin");
+
+ // non-admins can't read _list
+ var result = request_as(usersDb, listPath, "jchris1");
+ T(result.status == 403, "should deny access to non-admin");
+
+ // admin should be able to read _show
+ var showPath = ddoc["_id"] + "/_show/name/org.couchdb.user:jchris";
+ var result = request_as(usersDb, showPath, "jan");
+ T(result.status == 200, "should allow access to db admin");
+ TEquals("jchris", result.responseText, "should show username to db admin");
+
+ // non-admin should be able to access own _show
+ var result = request_as(usersDb, showPath, "jchris1");
+ T(result.status == 200, "should allow access to own user record");
+ TEquals("jchris", result.responseText, "should show own username");
+
+ // non-admin can't read other's _show
+ var showPath = ddoc["_id"] + "/_show/name/org.couchdb.user:jan";
+ var result = request_as(usersDb, showPath, "jchris1");
+ T(result.status == 404, "non-admin can't read others's user docs");
+
// admin should be able to read and edit any user doc
fdmananaDoc.password = "mobile";
var result = save_as(usersDb, fdmananaDoc, "jan");