1: -module(acl_SUITE). 2: -compile([export_all, nowarn_export_all]). 3: 4: -include_lib("eunit/include/eunit.hrl"). 5: 6: -import(mongoose_config, [set_opt/2, unset_opt/1]). 7: 8: all() -> 9: [{group, dynamic_domains}, 10: {group, static_domains}]. 11: 12: groups() -> 13: [{dynamic_domains, [], basic_test_cases() ++ host_type_test_cases()}, 14: {static_domains, [], basic_test_cases()}]. 15: 16: basic_test_cases() -> 17: [ 18: all_rule_returns_allow, 19: none_rule_returns_deny, 20: basic_access_rules, 21: compound_access_rules, 22: host_specific_access_rules, 23: all_and_none_specs, 24: match_domain, 25: different_specs_matching_the_same_user 26: ]. 27: 28: host_type_test_cases() -> 29: [ 30: match_host_specific_rule_for_host_type 31: ]. 32: 33: init_per_suite(Config) -> 34: {ok, _} = application:ensure_all_started(jid), 35: async_helper:start(Config, mongoose_domain_sup, start_link, [[], []]). 36: 37: end_per_suite(Config) -> 38: async_helper:stop_all(Config). 39: 40: init_per_group(dynamic_domains, Config) -> 41: [{dynamic_domains, true}|Config]; 42: init_per_group(_Group, Config) -> 43: Config. 44: 45: end_per_group(_Group, Config) -> 46: Config. 47: 48: init_per_testcase(_TC, Config) -> 49: mongoose_config:set_opts(#{}), 50: Config. 51: 52: end_per_testcase(_TC, _Config) -> 53: mongoose_config:erase_opts(). 54: 55: host_type() -> 56: <<"test host type">>. 57: 58: all_rule_returns_allow(_Config) -> 59: JID = jid:make(<<"pawel">>, <<"phost">>, <<"test">>), 60: ?assertEqual(allow, acl:match_rule(global, all, JID)), 61: ?assertEqual(allow, acl:match_rule(<<"phost">>, all, JID)), 62: ?assertEqual(allow, acl:match_rule(<<"localhost">>, all, JID)), 63: ok. 64: 65: none_rule_returns_deny(_Config) -> 66: JID = jid:make(<<"gawel">>, <<"phost">>, <<"test">>), 67: ?assertEqual(deny, acl:match_rule(global, none, JID)), 68: ?assertEqual(deny, acl:match_rule(<<"phost">>, none, JID)), 69: ?assertEqual(deny, acl:match_rule(<<"localhost">>, none, JID)), 70: ok. 71: 72: basic_access_rules(_Config) -> 73: JID = jid:make(<<"pawel">>, <<"phost">>, <<"test">>), 74: 75: %% rule is not defined deny by default - deny 76: ?assertEqual(deny, (acl:match_rule(global, single_rule, JID))), 77: 78: %% add the rule and recheck 79: set_opt({access, global}, #{single_rule => [#{acl => all, value => allow}]}), 80: ?assertEqual(allow, (acl:match_rule(global, single_rule, JID))), 81: 82: %% override it to deny rule 83: set_opt({access, global}, #{single_rule => [#{acl => all, value => deny}]}), 84: ?assertEqual(deny, (acl:match_rule(global, single_rule, JID))), 85: 86: %% deny by default 87: set_opt({access, global}, #{single_rule => []}), 88: ?assertEqual(deny, (acl:match_rule(global, single_rule, JID))), 89: 90: %% allow nobody 91: set_opt({access, global}, #{single_rule => [#{acl => none, value => allow}]}), 92: ?assertEqual(deny, (acl:match_rule(global, single_rule, JID))), 93: ok. 94: 95: host_specific_access_rules(Config) -> 96: given_registered_domains(Config, [<<"poznan">>, <<"wroclaw">>]), 97: 98: PozAdmin = jid:make(<<"gawel">>, <<"poznan">>, <<"test">>), 99: Pawel = jid:make(<<"pawel">>, <<"wroclaw">>, <<"test">>), 100: 101: set_opt({acl, <<"poznan">>}, #{admin_poz => acl(#{user => <<"gawel">>, 102: server => <<"poznan">>})}), 103: set_opt({acl, <<"wroclaw">>}, #{admin_poz => acl(#{user => <<"gawel">>, 104: server => <<"poznan">>})}), 105: set_opt({access, <<"poznan">>}, #{only_poz_admin => [#{acl => admin_poz, value => allow}, 106: #{acl => all, value => deny}]}), 107: set_opt({access, <<"wroclaw">>}, #{only_poz_admin => [#{acl => admin_poz, value => deny}, 108: #{acl => all, value => allow}]}), 109: 110: ?assertEqual(allow, acl:match_rule(<<"poznan">>, <<"poznan">>, only_poz_admin, PozAdmin)), 111: ?assertEqual(deny, acl:match_rule(<<"poznan">>, <<"wroclaw">>, only_poz_admin, Pawel)), 112: 113: ?assertEqual(deny, acl:match_rule(<<"wroclaw">>, <<"poznan">>, only_poz_admin, PozAdmin)), 114: ?assertEqual(allow, acl:match_rule(<<"wroclaw">>, <<"wroclaw">>, only_poz_admin, Pawel)), 115: ok. 116: 117: compound_access_rules(Config) -> 118: given_registered_domains(Config, [<<"krakow">>]), 119: 120: KrkAdmin = jid:make(<<"gawel">>, <<"krakow">>, <<"test">>), 121: KrkNormal = jid:make(<<"pawel">>, <<"krakow">>, <<"test">>), 122: 123: %% add admin user rule 124: set_opt({acl, global}, #{admin_wawa => acl(#{user => <<"gawel">>, server => <<"wawa">>}), 125: admin_krakow => acl(#{user => <<"gawel">>, server => <<"krakow">>})}), 126: set_opt({access, global}, #{only_krakow_admin => [#{acl => admin_krakow, value => allow}, 127: #{acl => all, value => deny}], 128: only_wawa_admin => [#{acl => admin_wawa, value => allow}, 129: #{acl => all, value => deny}]}), 130: 131: ?assertEqual(deny, acl:match_rule(global, only_krakow_admin, KrkNormal)), 132: ?assertEqual(deny, acl:match_rule(global, only_wawa_admin, KrkNormal)), 133: 134: ?assertEqual(allow, acl:match_rule(global, only_krakow_admin, KrkAdmin)), 135: ?assertEqual(deny, acl:match_rule(global, only_wawa_admin, KrkAdmin)), 136: ok. 137: 138: all_and_none_specs(Config) -> 139: given_registered_domains(Config, [<<"zakopane">>]), 140: 141: User = jid:make(<<"pawel">>, <<"zakopane">>, <<"test">>), 142: set_opt({acl, global}, #{a_users => acl(#{match => all}), 143: n_users => acl(#{match => none})}), 144: set_opt({access, global}, #{all_users => [#{acl => a_users, value => allow}, 145: #{acl => all, value => deny}], 146: none_users => [#{acl => n_users, value => allow}, 147: #{acl => all, value => deny}]}), 148: 149: ?assertEqual(allow, acl:match_rule(global, <<"zakopane">>, all_users, User)), 150: ?assertEqual(deny, acl:match_rule(global, <<"zakopane">>, none_users, User)), 151: 152: %% domain doesn't matter for 'all' 153: ?assertEqual(allow, acl:match_rule(global, <<"any domain">>, all_users, User)), 154: ?assertEqual(deny, acl:match_rule(global, <<"any domain">>, none_users, User)), 155: ok. 156: 157: match_domain(Config) -> 158: given_registered_domains(Config, [<<"zakopane">>, <<"gdansk">>]), 159: 160: UserZa = jid:make(<<"pawel">>, <<"zakopane">>, <<"test">>), 161: UserGd = jid:make(<<"pawel">>, <<"gdansk">>, <<"test">>), 162: UserTo = jid:make(<<"pawel">>, <<"torun">>, <<"test">>), 163: UserZb = jid:make(<<"pawel">>, <<"zakopane">>, <<"best">>), 164: 165: set_opt({acl, global}, #{a_users => [#{match => current_domain, resource => <<"test">>}], 166: b_users => [#{match => any_hosted_domain, resource => <<"test">>}], 167: c_users => [#{match => all, resource => <<"test">>}]}), 168: set_opt({access, global}, #{rule => [#{acl => a_users, value => a}, 169: #{acl => b_users, value => b}, 170: #{acl => c_users, value => c}, 171: #{acl => all, value => d}]}), 172: 173: ?assertEqual(a, acl:match_rule(global, <<"zakopane">>, rule, UserZa)), 174: ?assertEqual(b, acl:match_rule(global, <<"zakopane">>, rule, UserGd)), 175: ?assertEqual(c, acl:match_rule(global, <<"zakopane">>, rule, UserTo)), 176: ?assertEqual(d, acl:match_rule(global, <<"zakopane">>, rule, UserZb)), 177: ok. 178: 179: match_host_specific_rule_for_host_type(Config) -> 180: given_registered_domains(Config, [<<"gdansk">>, <<"koszalin">>]), 181: 182: UserGd = jid:make(<<"pawel">>, <<"gdansk">>, <<"res">>), 183: 184: set_opt({acl, <<"test type">>}, #{admin => acl(#{user => <<"pawel">>})}), 185: set_opt({access, <<"test type">>}, #{allow_admin => [#{acl => admin, value => allow}, 186: #{acl => all, value => deny}]}), 187: 188: %% Check for host type for a specific domain 189: ?assertEqual(allow, acl:match_rule(<<"test type">>, <<"gdansk">>, allow_admin, UserGd)), 190: ?assertEqual(deny, acl:match_rule(<<"test type">>, <<"koszalin">>, allow_admin, UserGd)), 191: ?assertEqual(deny, acl:match_rule(<<"empty type">>, <<"gdansk">>, allow_admin, UserGd)), 192: 193: %% Check for host type for any domain 194: ?assertEqual(allow, acl:match_rule(<<"test type">>, allow_admin, UserGd)), 195: ?assertEqual(deny, acl:match_rule(<<"empty type">>, allow_admin, UserGd)), 196: 197: %% Check globally for a specific domain 198: ?assertEqual(deny, acl:match_rule(global, <<"gdansk">>, allow_admin, UserGd)), 199: ?assertEqual(deny, acl:match_rule(global, <<"koszalin">>, allow_admin, UserGd)), 200: 201: %% Check globally for any domain 202: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserGd)). 203: 204: different_specs_matching_the_same_user(Config) -> 205: given_registered_domains(Config, [<<"gdansk">>, <<"koszalin">>]), 206: 207: UserGd = jid:make(<<"pawel">>, <<"gdansk">>, <<"res">>), 208: UserKo = jid:make(<<"pawel">>, <<"koszalin">>,<<"res1">>), 209: 210: %% invariand we are going to change admin acl only 211: set_opt({access, global}, #{allow_admin => [#{acl => admin, value => allow}, 212: #{acl => all, value => deny}]}), 213: 214: %% match on pawel 215: set_opt({acl, global}, #{admin => acl(#{user => <<"pawel">>})}), 216: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 217: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserKo)), 218: 219: %% match on pawel@gdansk 220: set_opt({acl, global}, #{admin => acl(#{user => <<"pawel">>, server => <<"gdansk">>})}), 221: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 222: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserKo)), 223: 224: %% match on gdansk 225: set_opt({acl, global}, #{admin => acl(#{server => <<"gdansk">>})}), 226: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 227: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserKo)), 228: 229: %% match on res 230: set_opt({acl, global}, #{admin => acl(#{resource => <<"res">>})}), 231: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 232: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserKo)), 233: 234: %% match on user regex 235: set_opt({acl, global}, #{admin => acl(#{user_regexp => <<"^paw.*">>})}), 236: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 237: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserKo)), 238: 239: %% match on user regex 240: set_opt({acl, global}, #{admin => acl(#{user_regexp => <<"^paw.*">>, server => <<"gdansk">>})}), 241: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 242: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserKo)), 243: 244: %% match on server regex 245: set_opt({acl, global}, #{admin => acl(#{server_regexp => <<"^gda.*">>})}), 246: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 247: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserKo)), 248: 249: %% match on resource regex 250: set_opt({acl, global}, #{admin => acl(#{resource_regexp => <<"^res.*">>})}), 251: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 252: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserKo)), 253: 254: %% match node regex 255: set_opt({acl, global}, #{admin => acl(#{user_regexp => <<"^pawe.*">>, 256: server_regexp => <<"^gda.*">>})}), 257: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 258: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserKo)), 259: 260: %% match on user glob 261: set_opt({acl, global}, #{admin => acl(#{user_glob => <<"paw??">>})}), 262: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 263: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserKo)), 264: 265: %% match on user glob 266: set_opt({acl, global}, #{admin => acl(#{user_glob => <<"paw??">>, server => <<"gdansk">>})}), 267: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 268: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserKo)), 269: 270: %% match on server glob 271: set_opt({acl, global}, #{admin => acl(#{server_glob => <<"gda*">>})}), 272: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 273: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserKo)), 274: 275: %% match on server glob 276: set_opt({acl, global}, #{admin => acl(#{resource_glob => <<"re*">>})}), 277: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 278: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserKo)), 279: 280: %% match on node glob 281: set_opt({acl, global}, #{admin => acl(#{user_glob => <<"pawe?">>, server_glob => <<"gd*">>})}), 282: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 283: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserKo)), 284: 285: ok. 286: 287: acl(Spec) -> 288: [maps:merge(#{match => current_domain}, Spec)]. 289: 290: given_registered_domains(Config, DomainsList) -> 291: case proplists:get_value(dynamic_domains, Config, false) of 292: true -> 293: register_dynamic_domains(DomainsList); 294: false -> 295: register_static_domains(DomainsList) 296: end. 297: 298: register_static_domains(DomainsList) -> 299: mongoose_config:set_opt(hosts, DomainsList), 300: mongoose_config:set_opt(host_types, []), 301: mongoose_domain_sup:restart_core([]). 302: 303: register_dynamic_domains(DomainsList) -> 304: mongoose_config:set_opt(hosts, []), 305: mongoose_config:set_opt(host_types, [<<"test type">>, <<"empty type">>]), 306: mongoose_domain_sup:restart_core([]), 307: [mongoose_domain_core:insert(Domain, <<"test type">>, test) || Domain <- DomainsList].