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.