1: -module(acl_SUITE). 2: -compile([export_all, nowarn_export_all]). 3: 4: -include_lib("common_test/include/ct.hrl"). 5: -include_lib("proper/include/proper.hrl"). 6: -include_lib("eunit/include/eunit.hrl"). 7: 8: 9: all() -> 10: [{group, dynamic_domains}, 11: {group, static_domains}]. 12: 13: groups() -> 14: [{dynamic_domains, [], basic_test_cases() ++ host_type_test_cases()}, 15: {static_domains, [], basic_test_cases()}]. 16: 17: basic_test_cases() -> 18: [ 19: all_rule_returns_allow, 20: none_rule_returns_deny, 21: basic_access_rules, 22: compound_access_rules, 23: host_specific_access_rules, 24: global_host_priority, 25: all_and_none_specs, 26: invalid_spec, 27: different_specs_matching_the_same_user 28: ]. 29: 30: host_type_test_cases() -> 31: [ 32: match_host_specific_rule_for_host_type, 33: match_global_rule_for_host_type 34: ]. 35: 36: init_per_suite(Config) -> 37: {ok, _} = application:ensure_all_started(jid), 38: Config. 39: 40: end_per_suite(_Config) -> 41: mongoose_domain_api:stop(), 42: meck:unload(), 43: ok. 44: 45: init_per_group(dynamic_domains, Config) -> 46: [{dynamic_domains, true}|Config]; 47: init_per_group(_Group, Config) -> 48: Config. 49: 50: end_per_group(_Group, Config) -> 51: Config. 52: 53: init_per_testcase(_TC, Config) -> 54: given_clean_config(), 55: Config. 56: 57: end_per_testcase(_TC, _Config) -> 58: ok. 59: 60: all_rule_returns_allow(_Config) -> 61: JID = jid:make(<<"pawel">>, <<"phost">>, <<"test">>), 62: ?assertEqual(allow, acl:match_rule(global, all, JID)), 63: ?assertEqual(allow, acl:match_rule(<<"phost">>, all, JID)), 64: ?assertEqual(allow, acl:match_rule(<<"localhost">>, all, JID)), 65: ok. 66: 67: none_rule_returns_deny(_Config) -> 68: JID = jid:make(<<"gawel">>, <<"phost">>, <<"test">>), 69: ?assertEqual(deny, acl:match_rule(global, none, JID)), 70: ?assertEqual(deny, acl:match_rule(<<"phosty">>, none, JID)), 71: ?assertEqual(deny, acl:match_rule(<<"localhosty">>, none, JID)), 72: ok. 73: 74: basic_access_rules(_Config) -> 75: JID = jid:make(<<"pawel">>, <<"phost">>, <<"test">>), 76: 77: %% rule is not defined deny by default - deny 78: ?assertEqual(deny, (acl:match_rule(global, single_rule, JID))), 79: 80: %% add the rule and recheck 81: set_global_rule(single_rule, [{allow, all}]), 82: ?assertEqual(allow, (acl:match_rule(global, single_rule, JID))), 83: 84: %% override it to deny rule 85: set_global_rule(single_rule, [{deny, all}]), 86: ?assertEqual(deny, (acl:match_rule(global, single_rule, JID))), 87: 88: %% deny by default 89: set_global_rule(single_rule, []), 90: ?assertEqual(deny, (acl:match_rule(global, single_rule, JID))), 91: 92: %% allow nobody 93: set_global_rule(single_rule, [{allow, none}]), 94: ?assertEqual(deny, (acl:match_rule(global, single_rule, JID))), 95: ok. 96: 97: host_specific_access_rules(Config) -> 98: given_registered_domains(Config, [<<"poznan">>, <<"wroclaw">>]), 99: 100: PozAdmin = jid:make(<<"gawel">>, <<"poznan">>, <<"test">>), 101: Pawel = jid:make(<<"pawel">>, <<"wroclaw">>, <<"test">>), 102: 103: set_acl(global, admin_poz, {user, <<"gawel">>, <<"poznan">>}), 104: 105: set_host_rule(only_poz_admin, <<"poznan">>, [{allow, admin_poz}, {deny, all}]), 106: set_host_rule(only_poz_admin, <<"wroclaw">>, [{deny, admin_poz}, {allow, all}]), 107: 108: ?assertEqual(allow, acl:match_rule(<<"poznan">>, only_poz_admin, PozAdmin)), 109: ?assertEqual(deny, acl:match_rule(<<"poznan">>, only_poz_admin, Pawel)), 110: 111: ?assertEqual(deny, acl:match_rule(<<"wroclaw">>, only_poz_admin, PozAdmin)), 112: ?assertEqual(allow, acl:match_rule(<<"wroclaw">>, only_poz_admin, Pawel)), 113: ok. 114: 115: compound_access_rules(Config) -> 116: given_registered_domains(Config, [<<"krakow">>]), 117: 118: KrkAdmin = jid:make(<<"gawel">>, <<"krakow">>, <<"test">>), 119: KrkNormal = jid:make(<<"pawel">>, <<"krakow">>, <<"test">>), 120: 121: %% add admin user rule 122: set_acl(global, admin_wawa, {user, <<"gawel">>, <<"wawa">>}), 123: set_acl(global, admin_krakow, {user, <<"gawel">>, <<"krakow">>}), 124: 125: set_global_rule(only_krakow_admin, [{allow, admin_krakow}, {deny, all}]), 126: set_global_rule(only_wawa_admin, [{allow, admin_wawa}, {deny, all}]), 127: 128: ?assertEqual(deny, acl:match_rule(global, only_krakow_admin, KrkNormal)), 129: ?assertEqual(deny, acl:match_rule(global, only_wawa_admin, KrkNormal)), 130: 131: ?assertEqual(allow, acl:match_rule(global, only_krakow_admin, KrkAdmin)), 132: ?assertEqual(deny, acl:match_rule(global, only_wawa_admin, KrkAdmin)), 133: ok. 134: 135: global_host_priority(Config) -> 136: given_registered_domains(Config, [<<"rzeszow">>, <<"lublin">>]), 137: 138: RzeAdmin = jid:make(<<"pawel">>, <<"rzeszow">>, <<"test">>), 139: 140: %% add admin user rule 141: set_acl(<<"rzeszow">>, admin, {user, <<"pawel">>, <<"rzeszow">>}), 142: set_acl(global, admin, {user, <<"pawel">>, <<"lublin">>}), 143: 144: %% allow only admin 145: set_global_rule(only_admin, [{allow, admin}, {deny, all}]), 146: %% deny all 147: set_host_rule(only_admin, <<"rzeszow">>, [{deny, admin}, {deny, all}]), 148: 149: set_global_rule(ban_admin, [{allow, all}]), 150: set_host_rule(ban_admin, <<"rzeszow">>, [{deny, admin}, {allow, all}]), 151: 152: %% host rule is more important than the host one 153: ?assertEqual(allow, acl:match_rule(<<"rzeszow">>, only_admin, RzeAdmin)), 154: 155: %% host rule applies when global doesn't match and ends up with {allow, all} 156: %% ... 157: ?assertEqual(deny, acl:match_rule(<<"rzeszow">>, ban_admin, RzeAdmin)), 158: ok. 159: 160: all_and_none_specs(Config) -> 161: given_registered_domains(Config, [<<"zakopane">>]), 162: 163: User = jid:make(<<"pawel">>, <<"zakopane">>, <<"test">>), 164: set_acl(global, a_users, all), 165: set_acl(global, n_users, none), 166: 167: set_global_rule(all_users, [{allow, a_users}, {deny, all}]), 168: set_global_rule(none_users, [{allow, n_users}, {deny, all}]), 169: 170: ?assertEqual(allow, acl:match_rule(global, all_users, User)), 171: ?assertEqual(deny, acl:match_rule(global, none_users, User)), 172: ok. 173: 174: invalid_spec(Config) -> 175: given_registered_domains(Config, [<<"bialystok">>]), 176: 177: User = jid:make(<<"pawel">>, <<"bialystok">>, <<"test">>), 178: set_acl(global, invalid, {non_existing_spec, "lalala"}), 179: 180: set_global_rule(invalid, [{allow, invalid}, {deny, all}]), 181: ?assertEqual(deny, acl:match_rule(global, invalid, User)), 182: ok. 183: 184: match_host_specific_rule_for_host_type(Config) -> 185: given_registered_domains(Config, [<<"gdansk">>, <<"koszalin">>]), 186: 187: UserGd = jid:make(<<"pawel">>, <<"gdansk">>, <<"res">>), 188: 189: set_host_rule(allow_admin, <<"test type">>, [{allow, admin}, {deny, all}]), 190: set_acl(<<"test type">>, admin, {user, <<"pawel">>}), 191: 192: %% Check for host type for a specific domain 193: ?assertEqual(allow, acl:match_rule_for_host_type(<<"test type">>, <<"gdansk">>, 194: allow_admin, UserGd)), 195: ?assertEqual(deny, acl:match_rule_for_host_type(<<"test type">>, <<"koszalin">>, 196: allow_admin, UserGd)), 197: ?assertEqual(deny, acl:match_rule_for_host_type(<<"empty type">>, <<"gdansk">>, 198: allow_admin, UserGd)), 199: 200: %% Check for host type for any domain 201: ?assertEqual(allow, acl:match_rule_for_host_type(<<"test type">>, global, allow_admin, UserGd)), 202: ?assertEqual(deny, acl:match_rule_for_host_type(<<"empty type">>, global, allow_admin, UserGd)), 203: 204: %% Check globally for a specific domain 205: ?assertEqual(deny, acl:match_rule_for_host_type(global, <<"gdansk">>, allow_admin, UserGd)), 206: ?assertEqual(deny, acl:match_rule_for_host_type(global, <<"koszalin">>, allow_admin, UserGd)), 207: 208: %% Check globally for any domain 209: ?assertEqual(deny, acl:match_rule_for_host_type(global, global, allow_admin, UserGd)). 210: 211: match_global_rule_for_host_type(Config) -> 212: given_registered_domains(Config, [<<"gdansk">>, <<"koszalin">>]), 213: 214: UserGd = jid:make(<<"pawel">>, <<"gdansk">>, <<"res">>), 215: 216: set_global_rule(allow_admin, [{allow, admin}, {deny, all}]), 217: set_acl(global, admin, {user, <<"pawel">>}), 218: 219: %% Check for host type for a specific domain 220: ?assertEqual(allow, acl:match_rule_for_host_type(<<"test type">>, <<"gdansk">>, 221: allow_admin, UserGd)), 222: ?assertEqual(deny, acl:match_rule_for_host_type(<<"test type">>, <<"koszalin">>, 223: allow_admin, UserGd)), 224: 225: %% Check for host type for any domain 226: ?assertEqual(allow, acl:match_rule_for_host_type(<<"test type">>, global, allow_admin, UserGd)), 227: 228: %% Check globally for a specific domain 229: ?assertEqual(allow, acl:match_rule_for_host_type(global, <<"gdansk">>, allow_admin, UserGd)), 230: ?assertEqual(deny, acl:match_rule_for_host_type(global, <<"koszalin">>, allow_admin, UserGd)), 231: 232: %% Check globally for any domain 233: ?assertEqual(allow, acl:match_rule_for_host_type(global, global, allow_admin, UserGd)). 234: 235: different_specs_matching_the_same_user(Config) -> 236: given_registered_domains(Config, [<<"gdansk">>, <<"koszalin">>]), 237: 238: UserGd = jid:make(<<"pawel">>, <<"gdansk">>, <<"res">>), 239: UserKo = jid:make(<<"pawel">>, <<"koszalin">>,<<"res1">>), 240: 241: %% invariand we are going to change admin acl only 242: set_global_rule(allow_admin, [{allow, admin}, {deny, all}]), 243: 244: %% match on pawel 245: set_acl(global, admin, {user, <<"pawel">>}), 246: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 247: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserKo)), 248: 249: %% match on pawel@gdansk 250: set_acl(global, admin, {user, <<"pawel">>, <<"gdansk">>}), 251: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 252: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserKo)), 253: 254: %% match on gdansk 255: set_acl(global, admin, {server, <<"gdansk">>}), 256: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 257: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserKo)), 258: 259: %% match on res 260: set_acl(global, admin, {resource, <<"res">>}), 261: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 262: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserKo)), 263: 264: %% match on user regex 265: set_acl(global, admin, {user_regexp, <<"^paw.*">>}), 266: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 267: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserKo)), 268: 269: %% match on user regex 270: set_acl(global, admin, {user_regexp, <<"^paw.*">>, <<"gdansk">>}), 271: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 272: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserKo)), 273: 274: %% match on server regex 275: set_acl(global, admin, {server_regexp, <<"^gda.*">>}), 276: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 277: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserKo)), 278: 279: %% match on resource regex 280: set_acl(global, admin, {resource_regexp, <<"^res.*">>}), 281: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 282: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserKo)), 283: 284: %% match node regex 285: set_acl(global, admin, {node_regexp, <<"^pawe.*">>, <<"^gda.*">>}), 286: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 287: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserKo)), 288: 289: %% match on user glob 290: set_acl(global, admin, {user_glob, <<"paw??">>}), 291: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 292: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserKo)), 293: 294: %% match on user glob 295: set_acl(global, admin, {user_glob, <<"paw??">>, <<"gdansk">>}), 296: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 297: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserKo)), 298: 299: %% match on server glob 300: set_acl(global, admin, {server_glob, <<"gda*">>}), 301: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 302: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserKo)), 303: 304: %% match on server glob 305: set_acl(global, admin, {resource_glob, <<"re*">>}), 306: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 307: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserKo)), 308: 309: %% match on node glob 310: set_acl(global, admin, {node_glob, <<"pawe?">>, <<"gd*">>}), 311: ?assertEqual(allow, acl:match_rule(global, allow_admin, UserGd)), 312: ?assertEqual(deny, acl:match_rule(global, allow_admin, UserKo)), 313: 314: ok. 315: 316: set_acl(HostType, ACLName, ACLSpec) -> 317: mongoose_config:set_opt({acl, ACLName, HostType}, [ACLSpec]). 318: 319: given_clean_config() -> 320: [persistent_term:erase(Key) || {Key = {mongoose_config, _}, _Value} <- persistent_term:get()], 321: ok. 322: 323: given_registered_domains(Config, DomainsList) -> 324: case proplists:get_value(dynamic_domains, Config, false) of 325: true -> 326: register_dynamic_domains(DomainsList); 327: false -> 328: register_static_domains(DomainsList) 329: end. 330: 331: register_static_domains(DomainsList) -> 332: mongoose_config:set_opt(hosts, DomainsList), 333: mongoose_config:set_opt(host_types, []), 334: mongoose_domain_api:stop(), 335: mongoose_domain_api:init(). 336: 337: register_dynamic_domains(DomainsList) -> 338: mongoose_config:set_opt(hosts, []), 339: mongoose_config:set_opt(host_types, [<<"test type">>, <<"empty type">>]), 340: mongoose_domain_api:stop(), 341: mongoose_domain_api:init(), 342: [mongoose_domain_core:insert(Domain, <<"test type">>, test) || Domain <- DomainsList]. 343: 344: %% ACLs might be an empty list 345: set_host_rule(Rule, Host, ACLs) -> 346: mongoose_config:set_opt({access, Rule, Host}, ACLs), 347: ok. 348: 349: %% ACLs might be an empty list 350: set_global_rule(Rule, ACLs) -> 351: mongoose_config:set_opt({access, Rule, global}, ACLs), 352: ok.