diff --git a/src/config/api-server/tests/test_perms2.py b/src/config/api-server/tests/test_perms2.py index 7463a458589..6a42da42883 100644 --- a/src/config/api-server/tests/test_perms2.py +++ b/src/config/api-server/tests/test_perms2.py @@ -189,6 +189,22 @@ def vnc_aal_add_rule(vnc, rg, rule_str): rg.set_api_access_list_entries(rge) vnc.api_access_list_update(rg) +def vnc_aal_del_rule(vnc, rg, rule_str): + rule = build_rule(rule_str) + rg = vnc_read_obj(vnc, 'api-access-list', rg.get_fq_name()) + rge = rg.get_api_access_list_entries() + match = find_rule(rge, rule) + if not match: + rge.add_rbac_rule(rule) + elif match[1]: + rge.rbac_rule.pop(match[0]-1) + else: + build_perms(rge.rbac_rule[match[0]-1], match[3]) + + rg.set_api_access_list_entries(rge) + vnc.api_access_list_update(rg) + return rg + def token_from_user_info(user_name, tenant_name, domain_name, role_name, tenant_id = None, domain_id = None): token_dict = { @@ -1443,6 +1459,28 @@ def test_bug_1646200(self): obj_dict = result_dict[0] self.assertEquals(obj_dict['perms2']['owner'], 'cloud-admin') + def test_bug_1642464(self): + def fake_static_file(*args, **kwargs): + return + + global_rg = vnc_read_obj(self.admin.vnc_lib, 'api-access-list', + name = ['default-global-system-config', 'default-api-access-list']) + num_default_rules = len(global_rg.api_access_list_entries.rbac_rule) + + # delete a rule and verify permission is denied when accessing resource + vnc_aal_del_rule(self.admin.vnc_lib, global_rg, "documentation *:R") + with test_common.patch(bottle, 'static_file', fake_static_file): + status_code, result = self.alice.vnc_lib._http_get('/documentation/index.html') + self.assertThat(status_code, Equals(403)) + + # simulate API server restart - should add rule back + self._api_server._create_default_rbac_rule() + + # verify permission no longer denied + with test_common.patch(bottle, 'static_file', fake_static_file): + status_code, result = self.alice.vnc_lib._http_get('/documentation/index.html') + self.assertThat(status_code, Equals(200)) + def tearDown(self): super(TestPermissions, self).tearDown() # end tearDown diff --git a/src/config/api-server/vnc_cfg_api_server.py b/src/config/api-server/vnc_cfg_api_server.py index de687f46620..642e841aadb 100644 --- a/src/config/api-server/vnc_cfg_api_server.py +++ b/src/config/api-server/vnc_cfg_api_server.py @@ -2613,14 +2613,6 @@ def _db_init_entries(self): # generate default rbac group rule def _create_default_rbac_rule(self): - obj_type = 'api_access_list' - fq_name = ['default-global-system-config', 'default-api-access-list'] - try: - id = self._db_conn.fq_name_to_uuid(obj_type, fq_name) - return - except NoIdError: - pass - # allow full access to cloud admin rbac_rules = [ { @@ -2650,6 +2642,30 @@ def _create_default_rbac_rule(self): }, ] + obj_type = 'api_access_list' + fq_name = ['default-global-system-config', 'default-api-access-list'] + try: + # ensure global list is not missing any default rules (bug 1642464) + id = self._db_conn.fq_name_to_uuid(obj_type, fq_name) + (ok, obj_dict) = self._db_conn.dbe_read(obj_type, id) + update_obj = False + cur_rbac_rules = copy.deepcopy(obj_dict['api_access_list_entries']['rbac_rule']) + for rule in rbac_rules: + present = False + for existing_rule in cur_rbac_rules: + if rule == existing_rule: + present = True + cur_rbac_rules.remove(existing_rule) + break + if not present: + obj_dict['api_access_list_entries']['rbac_rule'].append(rule) + update_obj = True + if update_obj: + self._db_conn.dbe_update(obj_type, id, obj_dict) + return + except NoIdError: + pass + rge = RbacRuleEntriesType([]) for rule in rbac_rules: rule_perms = [RbacPermType(role_name=p['role_name'], role_crud=p['role_crud']) for p in rule['rule_perms']] diff --git a/src/config/common/rbaclib.py b/src/config/common/rbaclib.py index 5a3bdfff492..514698e9745 100644 --- a/src/config/common/rbaclib.py +++ b/src/config/common/rbaclib.py @@ -69,7 +69,7 @@ def build_rule(rule_str): perms = r[1].split(",") o = obj_field[0] - f = obj_field[1] if len(obj_field) > 1 else None + f = obj_field[1] if len(obj_field) > 1 else '' o_f = "%s.%s" % (o,f) if f else o # perms eg ['foo:CRU', 'bar:CR']