couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dav...@apache.org
Subject [22/22] couch commit: updated refs/heads/2491-refactor-couch-httpd-auth to 3e8286d
Date Thu, 04 Dec 2014 20:09:53 GMT
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/3e8286d4
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/3e8286d4
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/3e8286d4

Branch: refs/heads/2491-refactor-couch-httpd-auth
Commit: 3e8286d40664fa0d7f32a3d375f64e64d181022c
Parents: 2a45cb0
Author: Paul J. Davis <paul.joseph.davis@gmail.com>
Authored: Thu Dec 4 13:07:56 2014 -0600
Committer: Paul J. Davis <paul.joseph.davis@gmail.com>
Committed: Thu Dec 4 14:04:57 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/3e8286d4/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/3e8286d4/src/couch_httpd_auth.erl
----------------------------------------------------------------------
diff --git a/src/couch_httpd_auth.erl b/src/couch_httpd_auth.erl
index 752dd20..e1af621 100644
--- a/src/couch_httpd_auth.erl
+++ b/src/couch_httpd_auth.erl
@@ -73,17 +73,18 @@ 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} ->
                 reject_if_totp(UserProps),
                 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,
[])
@@ -195,9 +196,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),
@@ -284,14 +285,15 @@ 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 ->
             verify_totp(UserProps, Form),
-            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),
@@ -363,18 +365,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/3e8286d4/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.


Mime
View raw message