blob: 7a0db4b2d68075b68dcd1939688a66f50e07a501 [file] [log] [blame]
% 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(chttpd_auth_hash_algorithms_tests).
-include_lib("eunit/include/eunit.hrl").
-include_lib("couch/include/couch_eunit.hrl").
-include_lib("couch/include/couch_db.hrl").
-define(ADM_USER, "adm_user").
-define(ADM_PASS, "adm_pass").
-define(WORKING_HASHES, "sha256, sha512, sha, blake2s").
-define(FAILING_HASHES, "md4, md5, ripemd160").
hash_algorithms_test_() ->
{
"Testing hash algorithms for cookie auth",
{
setup,
fun setup/0,
fun teardown/1,
with([
?TDEF(test_hash_algorithms_should_work),
?TDEF(test_hash_algorithms_should_fail)
])
}
}.
% Test utility functions
setup() ->
Ctx = test_util:start_couch([chttpd]),
Hashed = couch_passwords:hash_admin_password(?ADM_PASS),
NewSecret = ?b2l(couch_uuids:random()),
config:set("admins", ?ADM_USER, ?b2l(Hashed), false),
config:set("chttpd_auth", "secret", NewSecret, false),
config:set("chttpd", "require_valid_user", "true", false),
config:set("chttpd_auth", "hash_algorithms", ?WORKING_HASHES, false),
HashesShouldWork = re:split(config:get("chttpd_auth", "hash_algorithms"), "\\s*,\\s*", [
trim, {return, binary}
]),
HashesShouldFail = re:split(?FAILING_HASHES, "\\s*,\\s*", [trim, {return, binary}]),
SupportedHashAlgorithms = crypto:supports(hashs),
{Ctx, {HashesShouldWork, HashesShouldFail, SupportedHashAlgorithms}}.
teardown({Ctx, _}) ->
config:delete("chttpd_auth", "hash_algorithms", false),
config:delete("chttpd", "require_valid_user", false),
config:delete("chttpd_auth", "secret", false),
config:delete("admins", ?ADM_USER, false),
test_util:stop_couch(Ctx).
% Helper functions
base_url() ->
Addr = config:get("chttpd", "bind_address", "127.0.0.1"),
Port = integer_to_list(mochiweb_socket_server:get(chttpd, port)),
"http://" ++ Addr ++ ":" ++ Port.
make_auth_session_string(HashAlgorithm, User, Secret, TimeStamp) ->
"AuthSession=" ++
couch_httpd_auth:cookie_auth_session_value(HashAlgorithm, User, Secret, TimeStamp, false).
get_user_props(User) ->
couch_auth_cache:get_user_creds(User).
get_full_secret(User) ->
{ok, UserProps, _AuthCtx} = get_user_props(User),
UserSalt = couch_util:get_value(<<"salt">>, UserProps, <<"">>),
Secret = ?l2b(chttpd_util:get_chttpd_auth_config("secret")),
<<Secret/binary, UserSalt/binary>>.
% Test functions
test_hash_algorithm([], _) ->
ok;
test_hash_algorithm([DefaultHashAlgorithm | DecodingHashAlgorithmsList] = _, Status) ->
CurrentTime = couch_httpd_auth:make_cookie_time(),
Cookie = make_auth_session_string(
DefaultHashAlgorithm,
?ADM_USER,
get_full_secret(?ADM_USER),
CurrentTime
),
{ok, ReqStatus, _, _} = test_request:request(get, base_url(), [{cookie, Cookie}]),
?assertEqual(Status, ReqStatus),
test_hash_algorithm(DecodingHashAlgorithmsList, Status).
test_hash_algorithms_should_work({_, {WorkingHashes, _, SupportedHashAlgorithms}} = _) ->
Hashes = couch_util:verify_hash_names(WorkingHashes, SupportedHashAlgorithms),
test_hash_algorithm(Hashes, 200).
test_hash_algorithms_should_fail({_, {_, FailingHashes, SupportedHashAlgorithms}} = _) ->
Hashes = couch_util:verify_hash_names(FailingHashes, SupportedHashAlgorithms),
test_hash_algorithm(Hashes, 401).