diff options
author | Eric Avdey <eiri@eiri.ca> | 2017-09-04 14:43:23 -0300 |
---|---|---|
committer | Eric Avdey <eiri@eiri.ca> | 2017-09-04 22:59:03 -0300 |
commit | d3c8d41f60f69f92d3a30e408ae9428d88cf604c (patch) | |
tree | c34801be10efdee593a11d18b9e02c7698e5ae78 | |
parent | 3d0e4f426fcc84808af64c96c22e3f39cb53255f (diff) | |
download | couchdb-d3c8d41f60f69f92d3a30e408ae9428d88cf604c.tar.gz |
Pass user ctx when opening a doc in show handler
-rw-r--r-- | src/chttpd/src/chttpd_show.erl | 13 | ||||
-rw-r--r-- | test/javascript/tests/users_db_security.js | 46 |
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"); |