Skip to content
This repository was archived by the owner on May 25, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/couch_auth_cache.erl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
-export([handle_config_change/5]).
-export([handle_db_event/3]).

-export([update_auth_doc/1]).

-include_lib("couch/include/couch_db.hrl").
-include("couch_js_functions.hrl").

Expand Down Expand Up @@ -455,3 +457,9 @@ auth_design_doc(DocId) ->
{<<"validate_doc_update">>, ?AUTH_DB_DOC_VALIDATE_FUNCTION}
],
{ok, couch_doc:from_json_obj({DocProps})}.

update_auth_doc(Doc) ->
DbName = ?l2b(config:get("couch_httpd_auth", "authentication_db", "_users")),
couch_util:with_db(DbName, fun(UserDb) ->
couch_db:update_doc(UserDb, Doc, [])
end).
13 changes: 5 additions & 8 deletions src/couch_httpd_auth.erl
Original file line number Diff line number Diff line change
Expand Up @@ -367,14 +367,11 @@ maybe_upgrade_password_hash(UserName, Password, UserProps, AuthModule) ->
IsAdmin = lists:member(<<"_admin">>, couch_util:get_value(<<"roles">>, UserProps, [])),
case {IsAdmin, couch_util:get_value(<<"password_scheme">>, UserProps, <<"simple">>)} of
{false, <<"simple">>} ->
DbName = ?l2b(config:get("couch_httpd_auth", "authentication_db", "_users")),
couch_util:with_db(DbName, fun(UserDb) ->
UserProps2 = proplists:delete(<<"password_sha">>, UserProps),
UserProps3 = [{<<"password">>, Password} | UserProps2],
NewUserDoc = couch_doc:from_json_obj({UserProps3}),
{ok, _NewRev} = couch_db:update_doc(UserDb, NewUserDoc, []),
AuthModule:get_user_creds(UserName)
end);
UserProps2 = proplists:delete(<<"password_sha">>, UserProps),
UserProps3 = [{<<"password">>, Password} | UserProps2],
NewUserDoc = couch_doc:from_json_obj({UserProps3}),
{ok, _NewRev} = AuthModule:update_auth_doc(NewUserDoc),
AuthModule:get_user_creds(UserName);
_ ->
UserProps
end.
Expand Down
23 changes: 23 additions & 0 deletions src/couch_httpd_db.erl
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,29 @@ db_doc_req(#httpd{method='DELETE'}=Req, Db, DocId) ->
end;

db_doc_req(#httpd{method = 'GET', mochi_req = MochiReq} = Req, Db, DocId) ->
case DocId of
<<"_design/", _/binary>> ->
DbName = mem3:dbname(Db#db.name),
AuthDbName = ?l2b(config:get("couch_httpd_auth", "authentication_db")),
case AuthDbName of
DbName ->
% in the authentication database, design doc access are admin-only.
%{SecProps} = fabric:get_security(DbName),
%case (catch couch_db:check_is_admin(Db#db{security=SecProps})) of
case (catch couch_db:check_is_admin(Db)) of
ok ->
ok;
_ ->
throw({forbidden,
<<"Only administrators can view design docs in the users database.">>})
end;
_Else ->
% on other databases, design doc access is free for all.
ok
end;
_Else ->
ok
end,
#doc_query_args{
rev = Rev,
open_revs = Revs,
Expand Down
34 changes: 18 additions & 16 deletions src/couch_server.erl
Original file line number Diff line number Diff line change
Expand Up @@ -122,24 +122,26 @@ maybe_add_sys_db_callbacks(DbName, Options) ->
DbsDbName = config:get("mem3", "shard_db", "dbs"),
NodesDbName = config:get("mem3", "shard_db", "nodes"),
IsReplicatorDb = DbName == config:get("replicator", "db", "_replicator") orelse
path_ends_with(DbName, <<"_replicator">>),
path_ends_with(DbName, <<"_replicator">>),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_replicator db seems have the same issue right?

IsUsersDb = DbName ==config:get("couch_httpd_auth", "authentication_db", "_users") orelse
path_ends_with(DbName, <<"_users">>),
path_ends_with(DbName, <<"_users">>) orelse
binary_to_list(mem3:dbname(DbName)) ==
config:get("chttpd_auth", "authentication_db", "_users"),
if
DbName == DbsDbName ->
[sys_db | Options];
DbName == NodesDbName ->
[sys_db | Options];
IsReplicatorDb ->
[{before_doc_update, fun couch_replicator_manager:before_doc_update/2},
{after_doc_read, fun couch_replicator_manager:after_doc_read/2},
sys_db | Options];
IsUsersDb ->
[{before_doc_update, fun couch_users_db:before_doc_update/2},
{after_doc_read, fun couch_users_db:after_doc_read/2},
sys_db | Options];
true ->
Options
DbName == DbsDbName ->
[sys_db | Options];
DbName == NodesDbName ->
[sys_db | Options];
IsReplicatorDb ->
[{before_doc_update, fun couch_replicator_manager:before_doc_update/2},
{after_doc_read, fun couch_replicator_manager:after_doc_read/2},
sys_db | Options];
IsUsersDb ->
[{before_doc_update, fun couch_users_db:before_doc_update/2},
{after_doc_read, fun couch_users_db:after_doc_read/2},
sys_db | Options];
true ->
Options
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ixnay on the whitespace only changes.

end.

path_ends_with(Path, Suffix) ->
Expand Down
15 changes: 3 additions & 12 deletions src/couch_users_db.erl
Original file line number Diff line number Diff line change
Expand Up @@ -73,25 +73,16 @@ save_doc(#doc{body={Body}} = Doc) ->
Doc#doc{body={Body3}}
end.

% If the doc is a design doc
% If the request's userCtx identifies an admin
% -> return doc
% Else
% -> 403 // Forbidden
% If the doc is a design doc return it and relay on the http layer to restrict
% access to admins
% If the request's userCtx identifies an admin
% -> return doc
% If the request's userCtx.name doesn't match the doc's name
% -> 404 // Not Found
% Else
% -> return doc
after_doc_read(#doc{id = <<?DESIGN_DOC_PREFIX, _/binary>>} = Doc, Db) ->
case (catch couch_db:check_is_admin(Db)) of
ok ->
Doc;
_ ->
throw({forbidden,
<<"Only administrators can view design docs in the users database.">>})
end;
Doc;
after_doc_read(Doc, #db{user_ctx = UserCtx} = Db) ->
#user_ctx{name=Name} = UserCtx,
DocName = get_doc_name(Doc),
Expand Down