% 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_users_db).

-export([before_doc_update/3, after_doc_read/2, strip_non_public_fields/1]).

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

-define(NAME, <<"name">>).
-define(PASSWORD, <<"password">>).
-define(DERIVED_KEY, <<"derived_key">>).
-define(PASSWORD_SCHEME, <<"password_scheme">>).
-define(SIMPLE, <<"simple">>).
-define(PASSWORD_SHA, <<"password_sha">>).
-define(PBKDF2, <<"pbkdf2">>).
-define(ITERATIONS, <<"iterations">>).
-define(SALT, <<"salt">>).
-define(replace(L, K, V), lists:keystore(K, 1, L, {K, V})).
-define(REQUIREMENT_ERROR, "Password does not conform to requirements.").
-define(PASSWORD_SERVER_ERROR, "Server cannot hash passwords at this time.").

% If the request's userCtx identifies an admin
%   -> save_doc (see below)
%
% If the request's userCtx.name is null:
%   -> save_doc
%   // this is an anonymous user registering a new document
%   // in case a user doc with the same id already exists, the anonymous
%   // user will get a regular doc update conflict.
% If the request's userCtx.name doesn't match the doc's name
%   -> 404 // Not Found
% Else
%   -> save_doc
before_doc_update(Doc, Db, _UpdateType) ->
    #user_ctx{name=Name} = couch_db:get_user_ctx(Db),
    DocName = get_doc_name(Doc),
    case (catch couch_db:check_is_admin(Db)) of
    ok ->
        save_doc(Doc);
    _ when Name =:= DocName orelse Name =:= null ->
        save_doc(Doc);
    _ ->
        throw(not_found)
    end.

% If newDoc.password == null || newDoc.password == undefined:
%   ->
%   noop
% Else -> // calculate password hash server side
%    newDoc.password_sha = hash_pw(newDoc.password + salt)
%    newDoc.salt = salt
%    newDoc.password = null
save_doc(#doc{body={Body}} = Doc) ->
    %% Support both schemes to smooth migration from legacy scheme
    Scheme = chttpd_util:get_chttpd_auth_config("password_scheme", "pbkdf2"),
    case {couch_util:get_value(?PASSWORD, Body), Scheme} of
    {null, _} -> % server admins don't have a user-db password entry
        Doc;
    {undefined, _} ->
        Doc;
    {ClearPassword, "simple"} -> % deprecated
        ok = validate_password(ClearPassword),
        Salt = couch_uuids:random(),
        PasswordSha = couch_passwords:simple(ClearPassword, Salt),
        Body0 = ?replace(Body, ?PASSWORD_SCHEME, ?SIMPLE),
        Body1 = ?replace(Body0, ?SALT, Salt),
        Body2 = ?replace(Body1, ?PASSWORD_SHA, PasswordSha),
        Body3 = proplists:delete(?PASSWORD, Body2),
        Doc#doc{body={Body3}};
    {ClearPassword, "pbkdf2"} ->
        ok = validate_password(ClearPassword),
        Iterations = chttpd_util:get_chttpd_auth_config_integer(
            "iterations", 10),
        Salt = couch_uuids:random(),
        DerivedKey = couch_passwords:pbkdf2(ClearPassword, Salt, Iterations),
        Body0 = ?replace(Body, ?PASSWORD_SCHEME, ?PBKDF2),
        Body1 = ?replace(Body0, ?ITERATIONS, Iterations),
        Body2 = ?replace(Body1, ?DERIVED_KEY, DerivedKey),
        Body3 = ?replace(Body2, ?SALT, Salt),
        Body4 = proplists:delete(?PASSWORD, Body3),
        Doc#doc{body={Body4}};
    {_ClearPassword, Scheme} ->
        couch_log:error("[couch_httpd_auth] password_scheme value of '~p' is invalid.", [Scheme]),
        throw({forbidden, ?PASSWORD_SERVER_ERROR})
    end.

% Validate if a new password matches all RegExp in the password_regexp setting.
% Throws if not.
% In this function the [couch_httpd_auth] password_regexp config is parsed.
validate_password(ClearPassword) ->
    case chttpd_util:get_chttpd_auth_config("password_regexp", "") of
        "" ->
            ok;
        "[]" ->
            ok;
        ValidateConfig ->
            RequirementList = case couch_util:parse_term(ValidateConfig) of
                {ok, RegExpList} when is_list(RegExpList) ->
                    RegExpList;
                {ok, NonListValue} ->
                    couch_log:error(
                        "[couch_httpd_auth] password_regexp value of '~p'"
                        " is not a list.",
                        [NonListValue]
                    ),
                    throw({forbidden, ?PASSWORD_SERVER_ERROR});
                {error, ErrorInfo} ->
                    couch_log:error(
                        "[couch_httpd_auth] password_regexp value of '~p'"
                        " could not get parsed. ~p",
                        [ValidateConfig, ErrorInfo]
                    ),
                    throw({forbidden, ?PASSWORD_SERVER_ERROR})
            end,
            % Check the password on every RegExp.
            lists:foreach(fun(RegExpTuple) ->
                case get_password_regexp_and_error_msg(RegExpTuple) of
                    {ok, RegExp, PasswordErrorMsg} ->
                        check_password(ClearPassword, RegExp, PasswordErrorMsg);
                    {error} ->
                        couch_log:error(
                            "[couch_httpd_auth] password_regexp part of '~p' "
                            "is not a RegExp string or "
                            "a RegExp and Reason tuple.",
                            [RegExpTuple]
                        ),
                        throw({forbidden, ?PASSWORD_SERVER_ERROR})
                end
            end, RequirementList),
            ok
    end.

% Get the RegExp out of the tuple and combine the the error message.
% First is with a Reason string.
get_password_regexp_and_error_msg({RegExp, Reason}) 
        when is_list(RegExp) andalso is_list(Reason)
        andalso length(Reason) > 0 ->
    {ok, RegExp, lists:concat([?REQUIREMENT_ERROR, " ", Reason])};
% With a not correct Reason string.
get_password_regexp_and_error_msg({RegExp, _Reason}) when is_list(RegExp) ->
    {ok, RegExp, ?REQUIREMENT_ERROR};
% Without a Reason string.
get_password_regexp_and_error_msg({RegExp}) when is_list(RegExp) ->
    {ok, RegExp, ?REQUIREMENT_ERROR};
% If the RegExp is only a list/string.
get_password_regexp_and_error_msg(RegExp) when is_list(RegExp) ->
    {ok, RegExp, ?REQUIREMENT_ERROR};
% Not correct RegExpValue.
get_password_regexp_and_error_msg(_) ->
    {error}.

% Check the password if it matches a RegExp.
check_password(Password, RegExp, ErrorMsg) ->
    case re:run(Password, RegExp, [{capture, none}]) of
        match ->
            ok;
        _ ->
            throw({bad_request, ErrorMsg})
    end.

% If the doc is a design doc
%   If the request's userCtx identifies an admin
%     -> return doc
%   Else
%     -> 403 // Forbidden
% If the request's userCtx identifies an admin
%   -> return doc
% If the request's userCtx.name doesn't match the doc's name
%   -> 404 // Not Found
% Else
%   -> return doc
after_doc_read(#doc{id = <<?DESIGN_DOC_PREFIX, _/binary>>} = Doc, Db) ->
    case (catch couch_db:check_is_admin(Db)) of
    ok ->
        Doc;
    _ ->
        throw({forbidden,
        <<"Only administrators can view design docs in the users database.">>})
    end;
after_doc_read(Doc, Db) ->
    #user_ctx{name=Name} = couch_db:get_user_ctx(Db),
    DocName = get_doc_name(Doc),
    case (catch couch_db:check_is_admin(Db)) of
    ok ->
        Doc;
    _ when Name =:= DocName ->
        Doc;
    _ ->
        Doc1 = strip_non_public_fields(Doc),
        case Doc1 of
          #doc{body={[]}} ->
              throw(not_found);
          _ ->
              Doc1
        end
    end.

get_doc_name(#doc{id= <<"org.couchdb.user:", Name/binary>>}) ->
    Name;
get_doc_name(_) ->
    undefined.

strip_non_public_fields(#doc{body={Props}}=Doc) ->
    Public = re:split(chttpd_util:get_chttpd_auth_config("public_fields", ""),
                      "\\s*,\\s*", [{return, binary}]),
    Doc#doc{body={[{K, V} || {K, V} <- Props, lists:member(K, Public)]}}.
