summaryrefslogtreecommitdiff
path: root/src/chttpd/src/chttpd_auth_cache.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/chttpd/src/chttpd_auth_cache.erl')
-rw-r--r--src/chttpd/src/chttpd_auth_cache.erl140
1 files changed, 82 insertions, 58 deletions
diff --git a/src/chttpd/src/chttpd_auth_cache.erl b/src/chttpd/src/chttpd_auth_cache.erl
index 17a31bf55..2173eca95 100644
--- a/src/chttpd/src/chttpd_auth_cache.erl
+++ b/src/chttpd/src/chttpd_auth_cache.erl
@@ -14,8 +14,14 @@
-behaviour(gen_server).
-export([start_link/0, get_user_creds/2, update_user_creds/3, dbname/0]).
--export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
- code_change/3]).
+-export([
+ init/1,
+ handle_call/3,
+ handle_cast/2,
+ handle_info/2,
+ terminate/2,
+ code_change/3
+]).
-export([listen_for_changes/1, changes_callback/2]).
-include_lib("couch/include/couch_db.hrl").
@@ -25,7 +31,7 @@
-record(state, {
changes_pid,
- last_seq="0"
+ last_seq = "0"
}).
%% public functions
@@ -36,18 +42,21 @@ start_link() ->
get_user_creds(Req, UserName) when is_list(UserName) ->
get_user_creds(Req, ?l2b(UserName));
get_user_creds(_Req, UserName) when is_binary(UserName) ->
- Resp = case couch_auth_cache:get_admin(UserName) of
- nil ->
- get_from_cache(UserName);
- Props ->
- case get_from_cache(UserName) of
- nil ->
- Props;
- UserProps when is_list(UserProps) ->
- couch_auth_cache:add_roles(Props,
- couch_util:get_value(<<"roles">>, UserProps))
- end
- end,
+ Resp =
+ case couch_auth_cache:get_admin(UserName) of
+ nil ->
+ get_from_cache(UserName);
+ Props ->
+ case get_from_cache(UserName) of
+ nil ->
+ Props;
+ UserProps when is_list(UserProps) ->
+ couch_auth_cache:add_roles(
+ Props,
+ couch_util:get_value(<<"roles">>, UserProps)
+ )
+ end
+ end,
maybe_validate_user_creds(Resp).
update_user_creds(_Req, UserDoc, _Ctx) ->
@@ -109,19 +118,23 @@ handle_call(_Call, _From, State) ->
handle_cast(_Msg, State) ->
{noreply, State}.
-handle_info({'DOWN', _, _, Pid, Reason}, #state{changes_pid=Pid} = State) ->
- Seq = case Reason of
- {seq, EndSeq} ->
- EndSeq;
- {database_does_not_exist, _} ->
- couch_log:notice("~p changes listener died because the _users database does not exist. Create the database to silence this notice.", [?MODULE]),
- 0;
- _ ->
- couch_log:notice("~p changes listener died ~r", [?MODULE, Reason]),
- 0
- end,
+handle_info({'DOWN', _, _, Pid, Reason}, #state{changes_pid = Pid} = State) ->
+ Seq =
+ case Reason of
+ {seq, EndSeq} ->
+ EndSeq;
+ {database_does_not_exist, _} ->
+ couch_log:notice(
+ "~p changes listener died because the _users database does not exist. Create the database to silence this notice.",
+ [?MODULE]
+ ),
+ 0;
+ _ ->
+ couch_log:notice("~p changes listener died ~r", [?MODULE, Reason]),
+ 0
+ end,
erlang:send_after(5000, self(), {start_listener, Seq}),
- {noreply, State#state{last_seq=Seq}};
+ {noreply, State#state{last_seq = Seq}};
handle_info({start_listener, Seq}, State) ->
{noreply, State#state{changes_pid = spawn_changes(Seq)}};
handle_info(_Msg, State) ->
@@ -132,7 +145,7 @@ terminate(_Reason, #state{changes_pid = Pid}) when is_pid(Pid) ->
terminate(_Reason, _State) ->
ok.
-code_change(_OldVsn, #state{}=State, _Extra) ->
+code_change(_OldVsn, #state{} = State, _Extra) ->
{ok, State}.
%% private functions
@@ -175,14 +188,15 @@ changes_callback({error, _}, EndSeq) ->
load_user_from_db(UserName) ->
try fabric:open_doc(dbname(), docid(UserName), [?ADMIN_CTX, ejson_body, conflicts]) of
- {ok, Doc} ->
- {Props} = couch_doc:to_json_obj(Doc, []),
- Props;
- _Else ->
- couch_log:debug("no record of user ~s", [UserName]),
- nil
- catch error:database_does_not_exist ->
- nil
+ {ok, Doc} ->
+ {Props} = couch_doc:to_json_obj(Doc, []),
+ Props;
+ _Else ->
+ couch_log:debug("no record of user ~s", [UserName]),
+ nil
+ catch
+ error:database_does_not_exist ->
+ nil
end.
dbname() ->
@@ -196,23 +210,30 @@ username(<<"org.couchdb.user:", UserName/binary>>) ->
ensure_auth_ddoc_exists(DbName, DDocId) ->
case fabric:open_doc(DbName, DDocId, [?ADMIN_CTX, ejson_body]) of
- {not_found, _Reason} ->
- {ok, AuthDesign} = couch_auth_cache:auth_design_doc(DDocId),
- update_doc_ignoring_conflict(DbName, AuthDesign, [?ADMIN_CTX]);
- {ok, Doc} ->
- {Props} = couch_doc:to_json_obj(Doc, []),
- case couch_util:get_value(<<"validate_doc_update">>, Props, []) of
- ?AUTH_DB_DOC_VALIDATE_FUNCTION ->
- ok;
- _ ->
- Props1 = lists:keyreplace(<<"validate_doc_update">>, 1, Props,
- {<<"validate_doc_update">>,
- ?AUTH_DB_DOC_VALIDATE_FUNCTION}),
- update_doc_ignoring_conflict(DbName, couch_doc:from_json_obj({Props1}), [?ADMIN_CTX])
- end;
- {error, Reason} ->
- couch_log:notice("Failed to ensure auth ddoc ~s/~s exists for reason: ~p", [DbName, DDocId, Reason]),
- ok
+ {not_found, _Reason} ->
+ {ok, AuthDesign} = couch_auth_cache:auth_design_doc(DDocId),
+ update_doc_ignoring_conflict(DbName, AuthDesign, [?ADMIN_CTX]);
+ {ok, Doc} ->
+ {Props} = couch_doc:to_json_obj(Doc, []),
+ case couch_util:get_value(<<"validate_doc_update">>, Props, []) of
+ ?AUTH_DB_DOC_VALIDATE_FUNCTION ->
+ ok;
+ _ ->
+ Props1 = lists:keyreplace(
+ <<"validate_doc_update">>,
+ 1,
+ Props,
+ {<<"validate_doc_update">>, ?AUTH_DB_DOC_VALIDATE_FUNCTION}
+ ),
+ update_doc_ignoring_conflict(DbName, couch_doc:from_json_obj({Props1}), [
+ ?ADMIN_CTX
+ ])
+ end;
+ {error, Reason} ->
+ couch_log:notice("Failed to ensure auth ddoc ~s/~s exists for reason: ~p", [
+ DbName, DDocId, Reason
+ ]),
+ ok
end,
ok.
@@ -229,15 +250,18 @@ maybe_validate_user_creds(nil) ->
% throws if UserCreds includes a _conflicts member
% returns UserCreds otherwise
maybe_validate_user_creds(UserCreds) ->
- AllowConflictedUserDocs = config:get_boolean("chttpd_auth", "allow_conflicted_user_docs", false),
+ AllowConflictedUserDocs = config:get_boolean(
+ "chttpd_auth", "allow_conflicted_user_docs", false
+ ),
case {couch_util:get_value(<<"_conflicts">>, UserCreds), AllowConflictedUserDocs} of
{undefined, _} ->
{ok, UserCreds, nil};
{_, true} ->
{ok, UserCreds, nil};
{_ConflictList, false} ->
- throw({unauthorized,
- <<"User document conflicts must be resolved before the document",
- " is used for authentication purposes.">>
- })
+ throw(
+ {unauthorized,
+ <<"User document conflicts must be resolved before the document",
+ " is used for authentication purposes.">>}
+ )
end.