You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2014/12/04 20:09:03 UTC
couch commit: updated refs/heads/2491-refactor-couch-httpd-auth to
e7323b0
Repository: couchdb-couch
Updated Branches:
refs/heads/2491-refactor-couch-httpd-auth [created] e7323b099
Refactor couch_httpd_auth's AuthModule construct
We were missing the change necessary to upgrade user documents with the
move to pbkdf2 in a cluster. This also adds the ability for an
AuthModule to return a context that will be used when updating user
credentials.
COUCHDB-2491
Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/e7323b09
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/e7323b09
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/e7323b09
Branch: refs/heads/2491-refactor-couch-httpd-auth
Commit: e7323b099be946af531cbc2831af5b6cbf3cf320
Parents: 40c5c85
Author: Paul J. Davis <pa...@gmail.com>
Authored: Thu Dec 4 13:07:56 2014 -0600
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Thu Dec 4 13:07:56 2014 -0600
----------------------------------------------------------------------
src/couch_auth_cache.erl | 21 ++++++++++++++-------
src/couch_httpd_auth.erl | 37 +++++++++++++++++++------------------
2 files changed, 33 insertions(+), 25 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/e7323b09/src/couch_auth_cache.erl
----------------------------------------------------------------------
diff --git a/src/couch_auth_cache.erl b/src/couch_auth_cache.erl
index 8cf631b..144fa14 100644
--- a/src/couch_auth_cache.erl
+++ b/src/couch_auth_cache.erl
@@ -16,7 +16,7 @@
-behaviour(config_listener).
% public API
--export([get_user_creds/1, get_admin/1, add_roles/2]).
+-export([get_user_creds/1, update_user_creds/3, get_admin/1, add_roles/2]).
% gen_server API
-export([start_link/0, init/1, handle_call/3, handle_info/2, handle_cast/2]).
@@ -41,13 +41,13 @@
}).
--spec get_user_creds(UserName::string() | binary()) ->
- Credentials::list() | nil.
+-spec get_user_creds(Req::#httpd{}, UserName::string() | binary()) ->
+ {ok, Credentials::list(), term()} | nil.
-get_user_creds(UserName) when is_list(UserName) ->
- get_user_creds(?l2b(UserName));
+get_user_creds(Req, UserName) when is_list(UserName) ->
+ get_user_creds(Req, ?l2b(UserName));
-get_user_creds(UserName) ->
+get_user_creds(_Req, UserName) ->
UserCreds = case get_admin(UserName) of
nil ->
get_from_cache(UserName);
@@ -61,6 +61,13 @@ get_user_creds(UserName) ->
end,
validate_user_creds(UserCreds).
+update_user_creds(_AuthCtx, _Req, UserDoc) ->
+ DbNameList = config:get("couch_httpd_auth", "authentication_db", "_users"),
+ couch_util:with_db(?l2b(DbNameList), fun(UserDb) ->
+ {ok, _NewRev} = couch_db:update_doc(UserDb, UserDoc, []),
+ ok
+ end).
+
add_roles(Props, ExtraRoles) ->
CurrentRoles = couch_util:get_value(<<"roles">>, Props),
lists:keyreplace(<<"roles">>, 1, Props, {<<"roles">>, CurrentRoles ++ ExtraRoles}).
@@ -123,7 +130,7 @@ validate_user_creds(UserCreds) ->
" is used for authentication purposes.">>
})
end,
- UserCreds.
+ {ok, UserCreds, nil}.
start_link() ->
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/e7323b09/src/couch_httpd_auth.erl
----------------------------------------------------------------------
diff --git a/src/couch_httpd_auth.erl b/src/couch_httpd_auth.erl
index 7c55a2b..95ef7a2 100644
--- a/src/couch_httpd_auth.erl
+++ b/src/couch_httpd_auth.erl
@@ -71,16 +71,17 @@ default_authentication_handler(Req) ->
default_authentication_handler(Req, AuthModule) ->
case basic_name_pw(Req) of
{User, Pass} ->
- case AuthModule:get_user_creds(User) of
+ case AuthModule:get_user_creds(Req, User) of
nil ->
throw({unauthorized, <<"Name or password is incorrect.">>});
- UserProps ->
+ {ok, UserProps, AuthCtx} ->
UserName = ?l2b(User),
Password = ?l2b(Pass),
case authenticate(Password, UserProps) of
true ->
- UserProps2 = maybe_upgrade_password_hash(UserName, Password, UserProps,
- AuthModule),
+ UserProps2 = maybe_upgrade_password_hash(
+ Req, UserName, Password, UserProps,
+ AuthModule, AuthCtx),
Req#httpd{user_ctx=#user_ctx{
name=UserName,
roles=couch_util:get_value(<<"roles">>, UserProps2, [])
@@ -192,9 +193,9 @@ cookie_authentication_handler(#httpd{mochi_req=MochiReq}=Req, AuthModule) ->
Req;
SecretStr ->
Secret = ?l2b(SecretStr),
- case AuthModule:get_user_creds(User) of
+ case AuthModule:get_user_creds(Req, User) of
nil -> Req;
- UserProps ->
+ {ok, UserProps, _AuthCtx} ->
UserSalt = couch_util:get_value(<<"salt">>, UserProps, <<"">>),
FullSecret = <<Secret/binary, UserSalt/binary>>,
ExpectedHash = crypto:sha_mac(FullSecret, User ++ ":" ++ TimeStr),
@@ -281,13 +282,14 @@ handle_session_req(#httpd{method='POST', mochi_req=MochiReq}=Req, AuthModule) ->
UserName = ?l2b(couch_util:get_value("name", Form, "")),
Password = ?l2b(couch_util:get_value("password", Form, "")),
couch_log:debug("Attempt Login: ~s",[UserName]),
- UserProps = case AuthModule:get_user_creds(UserName) of
- nil -> [];
+ {ok, UserProps, AuthCtx} = case AuthModule:get_user_creds(Req, UserName) of
+ nil -> {ok, [], nil};
Result -> Result
end,
case authenticate(Password, UserProps) of
true ->
- UserProps2 = maybe_upgrade_password_hash(UserName, Password, UserProps, AuthModule),
+ UserProps2 = maybe_upgrade_password_hash(
+ Req, UserName, Password, UserProps, AuthModule, AuthCtx),
% setup the session cookie
Secret = ?l2b(ensure_cookie_auth_secret()),
UserSalt = couch_util:get_value(<<"salt">>, UserProps2),
@@ -359,18 +361,17 @@ maybe_value(_Key, undefined, _Fun) -> [];
maybe_value(Key, Else, Fun) ->
[{Key, Fun(Else)}].
-maybe_upgrade_password_hash(UserName, Password, UserProps, AuthModule) ->
+maybe_upgrade_password_hash(Req, UserName, Password, UserProps,
+ AuthModule, AuthCtx) ->
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 = AuthModule:update_user_creds(AuthCtx, Req, NewUserDoc),
+ {ok, NewUserProps, _Ctx} = AuthModule:get_user_creds(Req, UserName),
+ NewUserProps;
_ ->
UserProps
end.