1: %%============================================================================== 2: %% Copyright 2016 Erlang Solutions Ltd. 3: %% 4: %% Licensed under the Apache License, Version 2.0 (the "License"); 5: %% you may not use this file except in compliance with the License. 6: %% You may obtain a copy of the License at 7: %% 8: %% http://www.apache.org/licenses/LICENSE-2.0 9: %% 10: %% Unless required by applicable law or agreed to in writing, software 11: %% distributed under the License is distributed on an "AS IS" BASIS, 12: %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13: %% See the License for the specific language governing permissions and 14: %% limitations under the License. 15: %%============================================================================== 16: 17: -module(sasl_SUITE). 18: -compile([export_all, nowarn_export_all]). 19: 20: -include_lib("escalus/include/escalus.hrl"). 21: -include_lib("common_test/include/ct.hrl"). 22: -include_lib("exml/include/exml.hrl"). 23: 24: -define(TEST_MECHANISM, <<"TEST-MECHANISM">>). 25: -define(TEXT_CONTENT, <<"Call 555-123-1234 for assistance">>). 26: 27: -behaviour(cyrsasl). 28: 29: -import(distributed_helper, [mim/0, 30: require_rpc_nodes/1, 31: rpc/4]). 32: -import(domain_helper, [host_type/0]). 33: 34: %%-------------------------------------------------------------------- 35: %% Suite configuration 36: %%-------------------------------------------------------------------- 37: 38: all() -> 39: [{group, host_type_config}]. 40: 41: groups() -> 42: [{host_type_config, [sequence], all_tests()}]. 43: 44: all_tests() -> 45: [text_response]. 46: 47: suite() -> 48: require_rpc_nodes([mim]) ++ escalus:suite(). 49: 50: %%-------------------------------------------------------------------- 51: %% Init & teardown 52: %%-------------------------------------------------------------------- 53: init_per_suite(Config) -> 54: escalus:init_per_suite(Config). 55: 56: end_per_suite(Config) -> 57: escalus:end_per_suite(Config). 58: 59: init_per_group(_GroupName, Config) -> 60: Config1 = set_sasl_mechanisms(Config), 61: escalus:create_users(Config1, escalus:get_users([alice])). 62: 63: end_per_group(_GroupName, Config) -> 64: reset_sasl_mechanisms(Config), 65: escalus:delete_users(Config, escalus:get_users([alice])). 66: 67: init_per_testcase(CaseName, Config) -> 68: escalus:init_per_testcase(CaseName, Config). 69: 70: end_per_testcase(CaseName, Config) -> 71: escalus:end_per_testcase(CaseName, Config). 72: 73: %%-------------------------------------------------------------------- 74: %% cyrsasl tests 75: %%-------------------------------------------------------------------- 76: 77: text_response(Config) -> 78: mongoose_helper:inject_module(?MODULE), 79: AliceSpec = escalus_users:get_options(Config, alice), 80: {ok, Client, _} = escalus_connection:start(AliceSpec, [start_stream, stream_features]), 81: Stanza = escalus_stanza:auth(?TEST_MECHANISM, 82: [#xmlcdata{content = base64:encode(<<"alice">>)}]), 83: Result = escalus:send_and_wait(Client, Stanza), 84: assert_is_failure_with_text(Result). 85: 86: %%-------------------------------------------------------------------- 87: %% Helpers 88: %%-------------------------------------------------------------------- 89: 90: set_sasl_mechanisms(Config) -> 91: %% pretend that an auth module is set for this mechanism 92: rpc(mim(), meck, new, [ejabberd_auth, [no_link, passthrough]]), 93: rpc(mim(), meck, expect, [ejabberd_auth, supports_sasl_module, 94: fun(_, M) -> M =:= ?MODULE end]), 95: 96: %% configure the mechanism 97: Key = {auth, host_type()}, 98: AuthOpts = rpc(mim(), mongoose_config, get_opt, [Key]), 99: NewAuthOpts = AuthOpts#{sasl_mechanisms => [?MODULE]}, 100: mongoose_helper:backup_and_set_config_option(Config, Key, NewAuthOpts). 101: 102: reset_sasl_mechanisms(Config) -> 103: mongoose_helper:restore_config_option(Config, {auth, host_type()}), 104: rpc(mim(), meck, unload, [ejabberd_auth]). 105: 106: assert_is_failure_with_text(#xmlel{name = <<"failure">>, 107: children = Children}) -> 108: assert_has_text(Children); 109: assert_is_failure_with_text(Result) -> 110: ct:fail("Result is not a failure stanza: ~p", [Result]). 111: 112: assert_has_text([]) -> 113: ct:fail("Result has no or incorrect text field"); 114: assert_has_text([#xmlel{name = <<"text">>, 115: children = [#xmlcdata{content = ?TEXT_CONTENT}]} 116: | _]) -> 117: ok; 118: assert_has_text([_ | Tail]) -> 119: assert_has_text(Tail). 120: 121: %%-------------------------------------------------------------------- 122: %% cyrsasl test callback functions 123: %%-------------------------------------------------------------------- 124: 125: mechanism() -> 126: ?TEST_MECHANISM. 127: 128: mech_new(_Host, _Creds, _Socket) -> 129: {ok, state}. 130: 131: mech_step(_State, _ClientIn) -> 132: {error, {<<"not-authorized">>, ?TEXT_CONTENT}, <<>>}.