diff options
author | Jan Lehnardt <jan@apache.org> | 2020-06-13 12:29:27 +0200 |
---|---|---|
committer | Jan Lehnardt <jan@apache.org> | 2020-07-10 19:08:52 +0200 |
commit | 5dc648d420f41b4908a2ec27ca7ba993f22f54b8 (patch) | |
tree | ac178d7aa4a55fd3f01862cdefddbdf70820d9a6 | |
parent | bcf88794bc858606ea84ad65ddc38fd56bd8a761 (diff) | |
download | couchdb-5dc648d420f41b4908a2ec27ca7ba993f22f54b8.tar.gz |
feat: don’t load access ddocs into ddoc cache
fix: don’t apply_open_options twice on couch_db:open_doc*
test: re-enable show and update tests
-rw-r--r-- | src/chttpd/src/chttpd_show.erl | 4 | ||||
-rw-r--r-- | src/couch/src/couch_db.erl | 35 | ||||
-rw-r--r-- | src/couch/test/eunit/couchdb_mrview_cors_tests.erl | 7 | ||||
-rw-r--r-- | src/couch/test/eunit/couchdb_mrview_tests.erl | 20 | ||||
-rw-r--r-- | src/ddoc_cache/src/ddoc_cache_entry_ddocid.erl | 2 | ||||
-rw-r--r-- | src/ddoc_cache/src/ddoc_cache_entry_ddocid_rev.erl | 2 | ||||
-rw-r--r-- | src/mem3/src/mem3_nodes.erl | 1 |
7 files changed, 39 insertions, 32 deletions
diff --git a/src/chttpd/src/chttpd_show.erl b/src/chttpd/src/chttpd_show.erl index 83ae84791..15079b290 100644 --- a/src/chttpd/src/chttpd_show.erl +++ b/src/chttpd/src/chttpd_show.erl @@ -73,7 +73,6 @@ handle_doc_show(Req, Db, DDoc, ShowName, Doc) -> handle_doc_show(Req, Db, DDoc, ShowName, Doc, null). handle_doc_show(Req, Db, DDoc, ShowName, Doc, DocId) -> - ok = couch_util:validate_design_access(DDoc), %% Will throw an exception if the _show handler is missing couch_util:get_nested_json_value(DDoc#doc.body, [<<"shows">>, ShowName]), % get responder for ddoc/showname @@ -123,8 +122,6 @@ handle_doc_update_req(Req, _Db, _DDoc) -> chttpd:send_error(Req, 404, <<"update_error">>, <<"Invalid path.">>). send_doc_update_response(Req, Db, DDoc, UpdateName, Doc, DocId) -> - couch_log:info("~nDDoc: ~p~n", [DDoc]), - ok = couch_util:validate_design_access(DDoc), %% Will throw an exception if the _update handler is missing couch_util:get_nested_json_value(DDoc#doc.body, [<<"updates">>, UpdateName]), JsonReq = chttpd_external:json_req_obj(Req, Db, DocId), @@ -206,7 +203,6 @@ handle_view_list_req(Req, _Db, _DDoc) -> chttpd:send_method_not_allowed(Req, "GET,POST,HEAD"). handle_view_list(Req, Db, DDoc, LName, {ViewDesignName, ViewName}, Keys) -> - ok = couch_util:validate_design_access(DDoc), %% Will throw an exception if the _list handler is missing couch_util:get_nested_json_value(DDoc#doc.body, [<<"lists">>, LName]), DbName = couch_db:name(Db), diff --git a/src/couch/src/couch_db.erl b/src/couch/src/couch_db.erl index b315f07c1..602b0bc08 100644 --- a/src/couch/src/couch_db.erl +++ b/src/couch/src/couch_db.erl @@ -284,6 +284,9 @@ wait_for_compaction(#db{main_pid=Pid}=Db, Timeout) -> has_access_enabled(#db{access=true}) -> true; has_access_enabled(_) -> false. +is_read_from_ddoc_cache(Options) -> + lists:member(ddoc_cache, Options). + delete_doc(Db, Id, Revisions) -> DeletedDocs = [#doc{id=Id, revs=[Rev], deleted=true} || Rev <- Revisions], {ok, [Result]} = update_docs(Db, DeletedDocs, []), @@ -302,26 +305,26 @@ open_doc(Db, Id, Options0) -> {ok, #doc{deleted=true}=Doc} -> case lists:member(deleted, Options) of true -> - apply_open_options(Db, {ok, Doc},Options); + {ok, Doc}; false -> {not_found, deleted} end; Else -> - apply_open_options(Db, Else,Options) + Else end. apply_open_options(Db, {ok, Doc}, Options) -> - ok = validate_access(Db, Doc), + ok = validate_access(Db, Doc, Options), apply_open_options1({ok, Doc}, Options); apply_open_options(_Db, Else, _Options) -> Else. -apply_open_options1({ok, Doc},Options) -> - apply_open_options2(Doc,Options); -apply_open_options1(Else,_Options) -> +apply_open_options1({ok, Doc}, Options) -> + apply_open_options2(Doc, Options); +apply_open_options1(Else, _Options) -> Else. -apply_open_options2(Doc,[]) -> +apply_open_options2(Doc, []) -> {ok, Doc}; apply_open_options2(#doc{atts=Atts0,revs=Revs}=Doc, [{atts_since, PossibleAncestors}|Rest]) -> @@ -335,8 +338,8 @@ apply_open_options2(#doc{atts=Atts0,revs=Revs}=Doc, apply_open_options2(Doc#doc{atts=Atts}, Rest); apply_open_options2(Doc, [ejson_body | Rest]) -> apply_open_options2(couch_doc:with_ejson_body(Doc), Rest); -apply_open_options2(Doc,[_|Rest]) -> - apply_open_options2(Doc,Rest). +apply_open_options2(Doc, [_|Rest]) -> + apply_open_options2(Doc, Rest). find_ancestor_rev_pos({_, []}, _AttsSinceRevs) -> @@ -745,13 +748,19 @@ security_error_type(#user_ctx{name=_}) -> forbidden. validate_access(Db, Doc) -> - validate_access1(has_access_enabled(Db), Db, Doc). + validate_access(Db, Doc, []). -validate_access1(false, _Db, _Doc) -> ok; -validate_access1(true, Db, #doc{meta=Meta}=Doc) -> +validate_access(Db, Doc, Options) -> + validate_access1(has_access_enabled(Db), Db, Doc, Options). + +validate_access1(false, _Db, _Doc, _Options) -> ok; +validate_access1(true, Db, #doc{meta=Meta}=Doc, Options) -> case proplists:get_value(conflicts, Meta) of undefined -> % no conflicts - validate_access2(Db, Doc); + case is_read_from_ddoc_cache(Options) of + true -> throw({not_found, missing}); + _False -> validate_access2(Db, Doc) + end; _Else -> % only admins can read conflicted docs in _access dbs case is_admin(Db) of true -> ok; diff --git a/src/couch/test/eunit/couchdb_mrview_cors_tests.erl b/src/couch/test/eunit/couchdb_mrview_cors_tests.erl index 03dad9587..9d6f726e1 100644 --- a/src/couch/test/eunit/couchdb_mrview_cors_tests.erl +++ b/src/couch/test/eunit/couchdb_mrview_cors_tests.erl @@ -19,6 +19,7 @@ -define(DDOC, {[ {<<"_id">>, <<"_design/foo">>}, + {<<"_access">>, [<<"user_a">>]}, {<<"shows">>, {[ {<<"bar">>, <<"function(doc, req) {return '<h1>wosh</h1>';}">>} ]}} @@ -70,8 +71,8 @@ show_tests() -> { "Check CORS for show", [ - % make_test_case(clustered, [fun should_make_shows_request/2]), - % make_test_case(backdoor, [fun should_make_shows_request/2]) + make_test_case(clustered, [fun should_make_shows_request/2]), + make_test_case(backdoor, [fun should_make_shows_request/2]) ] }. @@ -93,7 +94,7 @@ should_make_shows_request(_, {Host, DbName}) -> end). create_db(backdoor, DbName) -> - {ok, Db} = couch_db:create(DbName, [?ADMIN_CTX]), + {ok, Db} = couch_db:create(DbName, [?ADMIN_CTX, {access, true}]), couch_db:close(Db); create_db(clustered, DbName) -> {ok, Status, _, _} = test_request:put(db_url(DbName), [?AUTH], ""), diff --git a/src/couch/test/eunit/couchdb_mrview_tests.erl b/src/couch/test/eunit/couchdb_mrview_tests.erl index decaa4bea..ec77b190d 100644 --- a/src/couch/test/eunit/couchdb_mrview_tests.erl +++ b/src/couch/test/eunit/couchdb_mrview_tests.erl @@ -122,16 +122,16 @@ make_test_case(Mod, Funs) -> should_return_invalid_request_body(PortType, {Host, DbName}) -> ?_test(begin - % ok = create_doc(PortType, ?l2b(DbName), <<"doc_id">>, {[]}), - % ReqUrl = Host ++ "/" ++ DbName ++ "/_design/foo/_update/report/doc_id", - % {ok, Status, _Headers, Body} = - % test_request:post(ReqUrl, [?AUTH], <<"{truncated}">>), - % {Props} = jiffy:decode(Body), - % ?assertEqual( - % <<"bad_request">>, couch_util:get_value(<<"error">>, Props)), - % ?assertEqual( - % <<"Invalid request body">>, couch_util:get_value(<<"reason">>, Props)), - % ?assertEqual(400, Status), + ok = create_doc(PortType, ?l2b(DbName), <<"doc_id">>, {[]}), + ReqUrl = Host ++ "/" ++ DbName ++ "/_design/foo/_update/report/doc_id", + {ok, Status, _Headers, Body} = + test_request:post(ReqUrl, [?AUTH], <<"{truncated}">>), + {Props} = jiffy:decode(Body), + ?assertEqual( + <<"bad_request">>, couch_util:get_value(<<"error">>, Props)), + ?assertEqual( + <<"Invalid request body">>, couch_util:get_value(<<"reason">>, Props)), + ?assertEqual(400, Status), ok end). diff --git a/src/ddoc_cache/src/ddoc_cache_entry_ddocid.erl b/src/ddoc_cache/src/ddoc_cache_entry_ddocid.erl index 5248469fb..03a4b14c2 100644 --- a/src/ddoc_cache/src/ddoc_cache_entry_ddocid.erl +++ b/src/ddoc_cache/src/ddoc_cache_entry_ddocid.erl @@ -33,7 +33,7 @@ ddocid({_, DDocId}) -> recover({DbName, DDocId}) -> - fabric:open_doc(DbName, DDocId, [ejson_body, ?ADMIN_CTX]). + fabric:open_doc(DbName, DDocId, [ejson_body, ?ADMIN_CTX, ddoc_cache]). insert({DbName, DDocId}, {ok, #doc{revs = Revs} = DDoc}) -> diff --git a/src/ddoc_cache/src/ddoc_cache_entry_ddocid_rev.erl b/src/ddoc_cache/src/ddoc_cache_entry_ddocid_rev.erl index 868fa7789..fa7187f5c 100644 --- a/src/ddoc_cache/src/ddoc_cache_entry_ddocid_rev.erl +++ b/src/ddoc_cache/src/ddoc_cache_entry_ddocid_rev.erl @@ -33,7 +33,7 @@ ddocid({_, DDocId, _}) -> recover({DbName, DDocId, Rev}) -> - Opts = [ejson_body, ?ADMIN_CTX], + Opts = [ejson_body, ?ADMIN_CTX, ddoc_cache], {ok, [Resp]} = fabric:open_revs(DbName, DDocId, [Rev], Opts), Resp. diff --git a/src/mem3/src/mem3_nodes.erl b/src/mem3/src/mem3_nodes.erl index dd5be1a72..ca1449e0e 100644 --- a/src/mem3/src/mem3_nodes.erl +++ b/src/mem3/src/mem3_nodes.erl @@ -124,6 +124,7 @@ changes_callback(start, _) -> changes_callback({stop, EndSeq}, _) -> exit({seq, EndSeq}); changes_callback({change, {Change}, _}, _) -> + % couch_log:info("~nChange: ~p~n", [Change]), Node = couch_util:get_value(<<"id">>, Change), case Node of <<"_design/", _/binary>> -> ok; _ -> case mem3_util:is_deleted(Change) of |