summaryrefslogtreecommitdiff
path: root/src/couchdb/couch_db.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/couchdb/couch_db.erl')
-rw-r--r--src/couchdb/couch_db.erl37
1 files changed, 30 insertions, 7 deletions
diff --git a/src/couchdb/couch_db.erl b/src/couchdb/couch_db.erl
index 6441e2e1..7de5b8db 100644
--- a/src/couchdb/couch_db.erl
+++ b/src/couchdb/couch_db.erl
@@ -21,7 +21,7 @@
-export([enum_docs/4,enum_docs/5,enum_docs_since/4,enum_docs_since/5]).
-export([enum_docs_since_reduce_to_count/1,enum_docs_reduce_to_count/1]).
-export([increment_update_seq/1,get_purge_seq/1,purge_docs/2,get_last_purged/1]).
--export([start_link/3,make_doc/2]).
+-export([start_link/3,make_doc/2,set_admins/2,get_admins/1]).
-export([init/1,terminate/2,handle_call/3,handle_cast/2,code_change/3,handle_info/2]).
@@ -67,9 +67,9 @@ open(DbName, Options) ->
close(#db{fd=Fd}) ->
couch_file:drop_ref(Fd).
-open_ref_counted(MainPid, OpeningPid, UserCred) ->
+open_ref_counted(MainPid, OpeningPid, UserCtx) ->
{ok, Db} = gen_server:call(MainPid, {open_ref_counted_instance, OpeningPid}),
- {ok, Db#db{user_ctx=UserCred}}.
+ {ok, Db#db{user_ctx=UserCtx}}.
num_refs(MainPid) ->
gen_server:call(MainPid, num_refs).
@@ -172,6 +172,16 @@ get_db_info(Db) ->
],
{ok, InfoList}.
+get_admins(#db{admins=Admins}) ->
+ Admins.
+
+set_admins(#db{update_pid=UpdatePid,user_ctx=Ctx},
+ Admins) when is_list(Admins) ->
+ case gen_server:call(UpdatePid, {set_admins, Admins, Ctx}, infinity) of
+ ok -> ok;
+ Error -> throw(Error)
+ end.
+
name(#db{name=Name}) ->
Name.
@@ -203,15 +213,28 @@ group_alike_docs([Doc|Rest], [Bucket|RestBuckets]) ->
group_alike_docs(Rest, [[Doc]|[Bucket|RestBuckets]])
end.
+
+validate_doc_update(#db{user_ctx=UserCtx, admins=Admins},
+ #doc{id= <<"_design/",_/binary>>}=Doc, _GetDiskDocFun) ->
+ UserNames = [UserCtx#user_ctx.name | UserCtx#user_ctx.roles],
+ % if the user is a server admin or db admin, allow the save
+ case length(UserNames -- [<<"_admin">> | Admins]) == length(UserNames) of
+ true ->
+ % not an admin
+ throw({unauthorized, <<"You are not a server or database admin.">>});
+ false ->
+ Doc
+ end;
validate_doc_update(#db{validate_doc_funs=[]}, Doc, _GetDiskDocFun) ->
Doc;
-validate_doc_update(_Db, #doc{id= <<"_design/",_/binary>>}=Doc, _GetDiskDocFun) ->
- Doc;
validate_doc_update(_Db, #doc{id= <<"_local/",_/binary>>}=Doc, _GetDiskDocFun) ->
Doc;
-validate_doc_update(#db{name=DbName,user_ctx={CtxProps}}=Db, Doc, GetDiskDocFun) ->
+validate_doc_update(#db{name=DbName,user_ctx=Ctx}=Db, Doc, GetDiskDocFun) ->
DiskDoc = GetDiskDocFun(),
- [case Fun(Doc, DiskDoc, {[{<<"db">>, DbName} | CtxProps]}) of
+ JsonCtx = {[{<<"db">>, DbName},
+ {<<"name">>,Ctx#user_ctx.name},
+ {<<"roles">>,Ctx#user_ctx.roles}]},
+ [case Fun(Doc, DiskDoc, JsonCtx) of
ok -> ok;
Error -> throw(Error)
end || Fun <- Db#db.validate_doc_funs],