Skip to content

Commit

Permalink
Ensure global system config object always has the default RBAC rules.
Browse files Browse the repository at this point in the history
These rules allow access to whitelist objects/URL (such as documentatiuon
and /) without requiring authorization

Change-Id: I075c7a35ab35a099bce885686e6e8d41f5dd1caa
Closes-Bug: #1642464
(cherry picked from commit 2e9dfd7)
  • Loading branch information
Deepinder Setia authored and Sachin Bansal committed Jun 28, 2017
1 parent cad0556 commit 268ba66
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 9 deletions.
38 changes: 38 additions & 0 deletions src/config/api-server/tests/test_perms2.py
Expand Up @@ -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 = {
Expand Down Expand Up @@ -1536,6 +1552,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
32 changes: 24 additions & 8 deletions src/config/api-server/vnc_cfg_api_server.py
Expand Up @@ -2655,14 +2655,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 = [
{
Expand Down Expand Up @@ -2692,6 +2684,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']]
Expand Down
2 changes: 1 addition & 1 deletion src/config/common/rbaclib.py
Expand Up @@ -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']
Expand Down

0 comments on commit 268ba66

Please sign in to comment.