summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/www/script/test/reader_acl.js16
-rw-r--r--src/couchdb/couch_db.erl9
-rw-r--r--src/couchdb/couch_rep.erl6
-rw-r--r--src/couchdb/couch_view_group.erl16
4 files changed, 35 insertions, 12 deletions
diff --git a/share/www/script/test/reader_acl.js b/share/www/script/test/reader_acl.js
index 6f834bfb..a42e9bea 100644
--- a/share/www/script/test/reader_acl.js
+++ b/share/www/script/test/reader_acl.js
@@ -90,10 +90,26 @@ couchTests.reader_acl = function(debug) {
// server _admin can always read
T(secretDb.open("baz").foo == "bar");
+ // and run temp views
+ TEquals(secretDb.query(function(doc) {
+ emit(null, null)
+ }).total_rows, 1);
+
+ T(secretDb.save({
+ "_id" : "_design/foo",
+ views : {
+ bar : {
+ map : "function(doc){emit(null, null)}"
+ }
+ }
+ }).ok)
+
// now top-secret users can read too
T(CouchDB.login("jchris@apache.org", "funnybone").ok);
T(CouchDB.session().userCtx.roles.indexOf("_admin") == -1);
T(secretDb.open("baz").foo == "bar");
+ // readers can query stored views
+ T(secretDb.view("foo/bar").total_rows == 1);
CouchDB.logout();
diff --git a/src/couchdb/couch_db.erl b/src/couchdb/couch_db.erl
index 6d5da15b..e5635f55 100644
--- a/src/couchdb/couch_db.erl
+++ b/src/couchdb/couch_db.erl
@@ -13,7 +13,7 @@
-module(couch_db).
-behaviour(gen_server).
--export([open/2,close/1,create/2,start_compact/1,get_db_info/1,get_design_docs/1]).
+-export([open/2,open_int/2,close/1,create/2,start_compact/1,get_db_info/1,get_design_docs/1]).
-export([open_ref_counted/2,is_idle/1,monitor/1,count_changes_since/2]).
-export([update_doc/3,update_doc/4,update_docs/4,update_docs/2,update_docs/3,delete_doc/3]).
-export([get_doc_info/2,open_doc/2,open_doc/3,open_doc_revs/4]).
@@ -64,6 +64,13 @@ open_db_file(Filepath, Options) ->
create(DbName, Options) ->
couch_server:create(DbName, Options).
+% this is for opening a database for internal purposes like the replicator
+% or the view indexer. it never throws a reader error.
+open_int(DbName, Options) ->
+ couch_server:open(DbName, Options).
+
+% this should be called anytime an http request opens the database.
+% it ensures that the http userCtx is a valid reader
open(DbName, Options) ->
case couch_server:open(DbName, Options) of
{ok, Db} ->
diff --git a/src/couchdb/couch_rep.erl b/src/couchdb/couch_rep.erl
index 82716809..4bad4a9f 100644
--- a/src/couchdb/couch_rep.erl
+++ b/src/couchdb/couch_rep.erl
@@ -646,7 +646,7 @@ ensure_full_commit(#http_db{} = Target) ->
true = proplists:get_value(<<"ok">>, ResultProps),
proplists:get_value(<<"instance_start_time">>, ResultProps);
ensure_full_commit(Target) ->
- {ok, NewDb} = couch_db:open(Target#db.name, []),
+ {ok, NewDb} = couch_db:open_int(Target#db.name, []),
UpdateSeq = couch_db:get_update_seq(Target),
CommitSeq = couch_db:get_committed_update_seq(NewDb),
InstanceStartTime = NewDb#db.instance_start_time,
@@ -674,7 +674,7 @@ ensure_full_commit(#http_db{} = Source, RequiredSeq) ->
proplists:get_value(<<"instance_start_time">>, ResultProps);
undefined -> nil end;
ensure_full_commit(Source, RequiredSeq) ->
- {ok, NewDb} = couch_db:open(Source#db.name, []),
+ {ok, NewDb} = couch_db:open_int(Source#db.name, []),
CommitSeq = couch_db:get_committed_update_seq(NewDb),
InstanceStartTime = NewDb#db.instance_start_time,
couch_db:close(NewDb),
@@ -705,7 +705,7 @@ update_local_doc(Db, Doc) ->
up_to_date(#http_db{}, _Seq) ->
true;
up_to_date(Source, Seq) ->
- {ok, NewDb} = couch_db:open(Source#db.name, []),
+ {ok, NewDb} = couch_db:open_int(Source#db.name, []),
T = NewDb#db.update_seq == Seq,
couch_db:close(NewDb),
T.
diff --git a/src/couchdb/couch_view_group.erl b/src/couchdb/couch_view_group.erl
index 8439304d..bb4102c2 100644
--- a/src/couchdb/couch_view_group.erl
+++ b/src/couchdb/couch_view_group.erl
@@ -125,7 +125,7 @@ handle_call({request_group, RequestSeq}, From,
updater_pid=nil,
waiting_list=WaitList
}=State) when RequestSeq > Seq ->
- {ok, Db} = couch_db:open(DbName, []),
+ {ok, Db} = couch_db:open_int(DbName, []),
Group2 = Group#group{db=Db},
Owner = self(),
Pid = spawn_link(fun()-> couch_view_updater:update(Owner, Group2) end),
@@ -164,7 +164,7 @@ handle_cast({start_compact, CompactFun}, #group_state{compactor_pid=nil}
init_args = {RootDir, DbName, _}
} = State,
?LOG_INFO("View index compaction starting for ~s ~s", [DbName, GroupId]),
- {ok, Db} = couch_db:open(DbName, []),
+ {ok, Db} = couch_db:open_int(DbName, []),
{ok, Fd} = open_index_file(compact, RootDir, DbName, GroupSig),
NewGroup = reset_file(Db, Fd, DbName, Group),
Pid = spawn_link(fun() -> CompactFun(Group, NewGroup) end),
@@ -224,7 +224,7 @@ handle_cast({compact_done, NewGroup}, State) ->
?LOG_INFO("View index compaction still behind for ~s ~s -- current: ~p " ++
"compact: ~p", [DbName, GroupId, CurrentSeq, NewGroup#group.current_seq]),
couch_db:close(NewGroup#group.db),
- {ok, Db} = couch_db:open(DbName, []),
+ {ok, Db} = couch_db:open_int(DbName, []),
Pid = spawn_link(fun() ->
{_,Ref} = erlang:spawn_monitor(fun() ->
couch_view_updater:update(nil, NewGroup#group{db = Db})
@@ -257,7 +257,7 @@ handle_cast({partial_update, _, _}, State) ->
{noreply, State}.
handle_info(delayed_commit, #group_state{db_name=DbName,group=Group}=State) ->
- {ok, Db} = couch_db:open(DbName, []),
+ {ok, Db} = couch_db:open_int(DbName, []),
CommittedSeq = couch_db:get_committed_update_seq(Db),
couch_db:close(Db),
if CommittedSeq >= Group#group.current_seq ->
@@ -292,7 +292,7 @@ handle_info({'EXIT', FromPid, {new_group, #group{db=Db}=Group}},
group=Group#group{db=nil}, updater_pid=nil}};
StillWaiting ->
% we still have some waiters, reopen the database and reupdate the index
- {ok, Db2} = couch_db:open(DbName, []),
+ {ok, Db2} = couch_db:open_int(DbName, []),
Group2 = Group#group{db=Db2},
Owner = self(),
Pid = spawn_link(fun() -> couch_view_updater:update(Owner, Group2) end),
@@ -372,7 +372,7 @@ reply_all(#group_state{waiting_list=WaitList}=State, Reply) ->
State#group_state{waiting_list=[]}.
prepare_group({RootDir, DbName, #group{sig=Sig}=Group}, ForceReset)->
- case couch_db:open(DbName, []) of
+ case couch_db:open_int(DbName, []) of
{ok, Db} ->
case open_index_file(RootDir, DbName, Sig) of
{ok, Fd} ->
@@ -437,7 +437,7 @@ open_index_file(compact, RootDir, DbName, GroupSig) ->
end.
open_temp_group(DbName, Language, DesignOptions, MapSrc, RedSrc) ->
- case couch_db:open(DbName, []) of
+ case couch_db:open_int(DbName, []) of
{ok, Db} ->
View = #view{map_names=[<<"_temp">>],
id_num=0,
@@ -459,7 +459,7 @@ set_view_sig(#group{
G#group{sig=erlang:md5(term_to_binary({Views, Language, DesignOptions}))}.
open_db_group(DbName, GroupId) ->
- case couch_db:open(DbName, []) of
+ case couch_db:open_int(DbName, []) of
{ok, Db} ->
case couch_db:open_doc(Db, GroupId) of
{ok, Doc} ->