% Licensed under the Apache License, Version 2.0 (the "License"); you may not
% use this file except in compliance with the License. You may obtain a copy of
% the License at
%
%   http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
% License for the specific language governing permissions and limitations under
% the License.

-module(couch_passwords).

-export([simple/2, pbkdf2/3, pbkdf2/4, verify/2]).
-export([hash_admin_password/1, get_unhashed_admins/0]).

-include_lib("couch/include/couch_db.hrl").

-define(MAX_DERIVED_KEY_LENGTH, (1 bsl 32 - 1)).
-define(SHA1_OUTPUT_LENGTH, 20).

%% legacy scheme, not used for new passwords.
-spec simple(binary(), binary()) -> binary().
simple(Password, Salt) when is_binary(Password), is_binary(Salt) ->
    ?l2b(couch_util:to_hex(crypto:hash(sha, <<Password/binary, Salt/binary>>)));
simple(Password, Salt) when is_binary(Salt) ->
    Msg = io_lib:format("Password value of '~p' is invalid.", [Password]),
    throw({forbidden, Msg});
simple(Password, Salt) when is_binary(Password) ->
    Msg = io_lib:format("Salt value of '~p' is invalid.", [Salt]),
    throw({forbidden, Msg}).

%% CouchDB utility functions
-spec hash_admin_password(binary() | list()) -> binary().
hash_admin_password(ClearPassword) when is_list(ClearPassword) ->
    hash_admin_password(?l2b(ClearPassword));
hash_admin_password(ClearPassword) when is_binary(ClearPassword) ->
    %% Support both schemes to smooth migration from legacy scheme
    Scheme = chttpd_util:get_chttpd_auth_config("password_scheme", "pbkdf2"),
    hash_admin_password(Scheme, ClearPassword).

% deprecated
hash_admin_password("simple", ClearPassword) ->
    Salt = couch_uuids:random(),
    Hash = crypto:hash(sha, <<ClearPassword/binary, Salt/binary>>),
    ?l2b("-hashed-" ++ couch_util:to_hex(Hash) ++ "," ++ ?b2l(Salt));
hash_admin_password("pbkdf2", ClearPassword) ->
    Iterations = chttpd_util:get_chttpd_auth_config("iterations", "10"),
    Salt = couch_uuids:random(),
    DerivedKey = couch_passwords:pbkdf2(
        couch_util:to_binary(ClearPassword),
        Salt,
        list_to_integer(Iterations)
    ),
    ?l2b(
        "-pbkdf2-" ++ ?b2l(DerivedKey) ++ "," ++
            ?b2l(Salt) ++ "," ++
            Iterations
    ).

-spec get_unhashed_admins() -> list().
get_unhashed_admins() ->
    lists:filter(
        fun
            ({_User, "-hashed-" ++ _}) ->
                % already hashed
                false;
            ({_User, "-pbkdf2-" ++ _}) ->
                % already hashed
                false;
            ({_User, _ClearPassword}) ->
                true
        end,
        config:get("admins")
    ).


pbkdf2(Password, Salt, Iterations) ->
    case couch_pbkdf2:pbkdf2(sha, Password, Salt, Iterations, ?SHA1_OUTPUT_LENGTH) of
        {ok, Hash} ->
            couch_pbkdf2:to_hex(Hash);
        Else ->
            Else
    end.


pbkdf2(Password, Salt, Iterations, DerivedLength) ->
    case couch_pbkdf2:pbkdf2(sha, Password, Salt, Iterations, DerivedLength) of
        {ok, Hash} ->
            couch_pbkdf2:to_hex(Hash);
        Else ->
            Else
    end.

verify(X, Y) ->
    couch_pbkdf2:compare_secure(X, Y).
