This is an automated email from the ASF dual-hosted git repository.

rnewson pushed a commit to branch admin-2fa
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 9de7f2b49a7a2bc0fbb9791114baa0c6d41aa129
Author: Robert Newson <[email protected]>
AuthorDate: Sun Mar 22 22:29:05 2020 +0000

    Allow admins to have a TOTP secret
---
 src/couch/src/couch_auth_cache.erl | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/src/couch/src/couch_auth_cache.erl 
b/src/couch/src/couch_auth_cache.erl
index c564cee..f77c79e 100644
--- a/src/couch/src/couch_auth_cache.erl
+++ b/src/couch/src/couch_auth_cache.erl
@@ -68,15 +68,15 @@ add_roles(Props, ExtraRoles) ->
 get_admin(UserName) when is_binary(UserName) ->
     get_admin(?b2l(UserName));
 get_admin(UserName) when is_list(UserName) ->
-    case config:get("admins", UserName) of
+    Result = case config:get("admins", UserName) of
     "-hashed-" ++ HashedPwdAndSalt ->
         % the name is an admin, now check to see if there is a user doc
         % which has a matching name, salt, and password_sha
         [HashedPwd, Salt] = string:tokens(HashedPwdAndSalt, ","),
-        make_admin_doc(HashedPwd, Salt);
+        add_totp(UserName, make_admin_doc(HashedPwd, Salt));
     "-pbkdf2-" ++ HashedPwdSaltAndIterations ->
         [HashedPwd, Salt, Iterations] = 
string:tokens(HashedPwdSaltAndIterations, ","),
-        make_admin_doc(HashedPwd, Salt, Iterations);
+        add_totp(UserName, make_admin_doc(HashedPwd, Salt, Iterations));
     _Else ->
        nil
     end.
@@ -94,6 +94,19 @@ make_admin_doc(DerivedKey, Salt, Iterations) ->
      {<<"password_scheme">>, <<"pbkdf2">>},
      {<<"derived_key">>, ?l2b(DerivedKey)}].
 
+add_totp(UserName, Props) ->
+    case config:get("admins_totp", UserName) of
+       undefined ->
+           Props;
+       TOTP ->
+           [Alg, Len, Key] = string:tokens(TOTP, ","),
+           [{<<"totp">>,
+             {[
+               {<<"algorithm">>, list_to_existing_atom(Alg)},
+               {<<"length">>, list_to_integer(Len)},
+               {<<"key">>, ?l2b(Key)}]}}
+            | Props]
+    end.
 
 get_from_db(UserName) ->
     ok = ensure_users_db_exists(),

Reply via email to