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:31:23 UTC
couch commit: updated refs/heads/2491-refactor-couch-httpd-auth to
41e9cdd
Repository: couchdb-couch
Updated Branches:
refs/heads/2491-refactor-couch-httpd-auth 8674de49e -> 41e9cdd62 (forced update)
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/41e9cdd6
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/41e9cdd6
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/41e9cdd6
Branch: refs/heads/2491-refactor-couch-httpd-auth
Commit: 41e9cdd6250b8dc2a8b5f4b023cab3ee03bd4f55
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:30:17 2014 -0600
----------------------------------------------------------------------
src/couch_auth_cache.erl | 26 ++++++++++++++++++++------
src/couch_httpd_auth.erl | 37 +++++++++++++++++++------------------
src/couch_httpd_oauth.erl | 2 +-
3 files changed, 40 insertions(+), 25 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/41e9cdd6/src/couch_auth_cache.erl
----------------------------------------------------------------------
diff --git a/src/couch_auth_cache.erl b/src/couch_auth_cache.erl
index 8cf631b..9eaa7c6 100644
--- a/src/couch_auth_cache.erl
+++ b/src/couch_auth_cache.erl
@@ -16,7 +16,8 @@
-behaviour(config_listener).
% public API
--export([get_user_creds/1, get_admin/1, add_roles/2]).
+-export([get_user_creds/1, get_user_creds/2, update_user_creds/3]).
+-export([get_admin/1, add_roles/2]).
% gen_server API
-export([start_link/0, init/1, handle_call/3, handle_info/2, handle_cast/2]).
@@ -42,12 +43,18 @@
-spec get_user_creds(UserName::string() | binary()) ->
- Credentials::list() | nil.
-
-get_user_creds(UserName) when is_list(UserName) ->
- get_user_creds(?l2b(UserName));
+ {ok, Credentials::list(), term()} | nil.
get_user_creds(UserName) ->
+ get_user_creds(nil, UserName).
+
+-spec get_user_creds(Req::#httpd{}, UserName::string() | binary()) ->
+ {ok, Credentials::list(), term()} | nil.
+
+get_user_creds(Req, UserName) when is_list(UserName) ->
+ get_user_creds(Req, ?l2b(UserName));
+
+get_user_creds(_Req, UserName) ->
UserCreds = case get_admin(UserName) of
nil ->
get_from_cache(UserName);
@@ -61,6 +68,13 @@ get_user_creds(UserName) ->
end,
validate_user_creds(UserCreds).
+update_user_creds(_Req, UserDoc, _AuthCtx) ->
+ 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 +137,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/41e9cdd6/src/couch_httpd_auth.erl
----------------------------------------------------------------------
diff --git a/src/couch_httpd_auth.erl b/src/couch_httpd_auth.erl
index 7c55a2b..8e748e5 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(Req, NewUserDoc, AuthCtx),
+ {ok, NewUserProps, _} = AuthModule:get_user_creds(Req, UserName),
+ NewUserProps;
_ ->
UserProps
end.
http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/41e9cdd6/src/couch_httpd_oauth.erl
----------------------------------------------------------------------
diff --git a/src/couch_httpd_oauth.erl b/src/couch_httpd_oauth.erl
index 0215240..b72e72d 100644
--- a/src/couch_httpd_oauth.erl
+++ b/src/couch_httpd_oauth.erl
@@ -78,7 +78,7 @@ set_user_ctx(Req, Name) ->
couch_log:debug("OAuth handler: user `~p` credentials not found",
[Name]),
Req;
- User ->
+ {ok, User, _AuthCtx} ->
Roles = couch_util:get_value(<<"roles">>, User, []),
Req#httpd{user_ctx=#user_ctx{name=Name, roles=Roles}}
end.