iilyak commented on a change in pull request #2007: Port javascript tests auth cache, cookie auth and users db to elixir URL: https://github.com/apache/couchdb/pull/2007#discussion_r295952442
########## File path: test/elixir/test/cookie_auth_test.exs ########## @@ -0,0 +1,415 @@ +defmodule CookieAuthTest do + use CouchTestCase + + @moduletag :authentication + + @users_db "_users" + + @password "3.141592653589" + + test "test cookie auth" do + # Create db if not exists + Couch.put("/#{@users_db}") + + server_config = [ + %{ + :section => "chttpd_auth", + :key => "authentication_db", + :value => @users_db + }, + %{ + :section => "couch_httpd_auth", + :key => "authentication_db", + :value => @users_db + }, + %{ + :section => "couch_httpd_auth", + :key => "iterations", + :value => "1" + }, + %{ + :section => "admins", + :key => "jan", + :value => "apple" + } + ] + + resp = + Couch.get( + "/#{@users_db}/_changes", + query: [feed: "longpoll", timeout: 5000, filter: "_design"] + ) + + assert resp.body + + run_on_modified_server(server_config, &test_fun/0) + end + + defp login(user, password) do + sess = Couch.login(user, password) + assert sess.cookie, "Login correct is expected" + sess + end + + defp logout(session) do + assert Couch.Session.logout(session).body["ok"] + end + + defp loginAsUser(user) do + pws = %{ + "jan" => "apple", + "Jason Davies" => @password, + "jchris" => "funnybone" + } + + user1 = Regex.replace(~r/[0-9]$/, user, "") + login(user1, pws[user]) + end + + defp create_doc_expect_error(db_name, doc, status_code, msg) do + resp = Couch.post("/#{db_name}", body: doc) + assert resp.status_code == status_code + assert resp.body["error"] == msg + resp + end + + defp open_as(db_name, doc_id, options) do + use_session = Keyword.get(options, :use_session) + user = Keyword.get(options, :user) + expect_response = Keyword.get(options, :expect_response, 200) + expect_message = Keyword.get(options, :error_message) + + session = + if use_session == nil do + loginAsUser(user) + else + use_session + end + + resp = + Couch.get( + "/#{db_name}/#{URI.encode(doc_id)}", + headers: [ + Cookie: session.cookie, + "X-CouchDB-www-Authenticate": "Cookie" + ] + ) + + if use_session == nil do + logout(session) + end + + assert resp.status_code == expect_response + + if expect_message != nil do + assert resp.body["error"] == expect_message + end + + resp.body + end + + defp save_as(db_name, doc, options) do + use_session = Keyword.get(options, :use_session) + user = Keyword.get(options, :user) + expect_response = Keyword.get(options, :expect_response, [201, 202]) + expect_message = Keyword.get(options, :error_message) + + session = + if use_session == nil do + loginAsUser(user) + else + use_session + end + + resp = + Couch.put( + "/#{db_name}/#{URI.encode(doc["_id"])}", + headers: [ + Cookie: session.cookie, + "X-CouchDB-www-Authenticate": "Cookie" + ], + body: doc + ) + + if use_session == nil do + logout(session) + end + + if is_list(expect_response) do + assert resp.status_code in expect_response + else + assert resp.status_code == expect_response + end + + if expect_message != nil do + assert resp.body["error"] == expect_message + end + + resp + end + + defp delete_as(db_name, doc, options) do + use_session = Keyword.get(options, :use_session) + user = Keyword.get(options, :user) + expect_response = Keyword.get(options, :expect_response, [200, 202]) + expect_message = Keyword.get(options, :error_message) + + session = + if use_session == nil do + loginAsUser(user) + else + use_session + end + + resp = + Couch.delete( + "/#{db_name}/#{URI.encode(doc["_id"])}", + headers: [ + Cookie: session.cookie, + "X-CouchDB-www-Authenticate": "Cookie" + ] + ) + + if use_session == nil do + logout(session) + end + + if is_list(expect_response) do + assert resp.status_code in expect_response + else + assert resp.status_code == expect_response + end + + if expect_message != nil do + assert resp.body["error"] == expect_message + end + + resp + end + + defp test_change_admin_fun do + sess = login("jchris", "funnybone") + info = Couch.Session.info(sess) + assert info["userCtx"]["name"] == "jchris" + assert Enum.member?(info["userCtx"]["roles"], "_admin") + assert Enum.member?(info["userCtx"]["roles"], "foo") + + jchris_user_doc = + open_as( + @users_db, + "org.couchdb.user:jchris", + use_session: sess + ) + + jchris_user_doc = Map.drop(jchris_user_doc, [:salt, :password_sha]) + save_as(@users_db, jchris_user_doc, use_session: sess) + logout(sess) + sess = login("jchris", "funnybone") + info = Couch.Session.info(sess) + assert info["userCtx"]["name"] == "jchris" + assert Enum.member?(info["userCtx"]["roles"], "_admin") + assert info["info"]["authenticated"] == "cookie" + assert info["info"]["authentication_db"] == @users_db + assert Enum.member?(info["userCtx"]["roles"], "foo") + logout(sess) + end + + defp test_fun do + # test that the users db is born with the auth ddoc + ddoc = open_as(@users_db, "_design/_auth", user: "jan") + assert ddoc["validate_doc_update"] != nil + + jason_user_doc = + prepare_user_doc([ + {:name, "Jason Davies"}, + {:password, @password} + ]) + + create_doc(@users_db, jason_user_doc) + jason_check_doc = open_as(@users_db, jason_user_doc["_id"], user: "jan") + assert jason_check_doc["name"] == "Jason Davies" + + jchris_user_doc = + prepare_user_doc([ + {:name, "jchris"}, + {:password, "funnybone"} + ]) + + {:ok, resp} = create_doc(@users_db, jchris_user_doc) + jchris_rev = resp.body["rev"] + + duplicate_jchris_user_doc = + prepare_user_doc([ + {:name, "jchris"}, + {:password, "eh, Boo-Boo?"} + ]) + + create_doc_expect_error(@users_db, duplicate_jchris_user_doc, 409, "conflict") + + # we can't create _names + underscore_user_doc = + prepare_user_doc([ + {:name, "_why"}, + {:password, "copperfield"} + ]) + + create_doc_expect_error(@users_db, underscore_user_doc, 403, "forbidden") + + # we can't create malformed ids + bad_id_user_doc = + prepare_user_doc([ + {:id, "org.apache.couchdb:w00x"}, + {:name, "w00x"}, + {:password, "bar"} + ]) + + create_doc_expect_error(@users_db, bad_id_user_doc, 403, "forbidden") + + # login works + session = loginAsUser("Jason Davies") + info = Couch.Session.info(session) + assert info["userCtx"]["name"] == "Jason Davies" + assert not Enum.member?(info["userCtx"]["roles"], "_admin") + + jason_user_doc = Review comment: JavaScript test has a comment [here](https://github.com/apache/couchdb/blob/master/test/javascript/tests/cookie_auth.js#L153) `// update one's own credentials document` ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services