Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions keepercommander/commands/enterprise.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,8 @@ def execute(self, params, **kwargs):
nodes[node_id] = {
'node_id': node_id,
'parent_id': node.get('parent_id') or 0,
'name': (node['data'].get('displayname') or '') if node.get('parent_id') else params.enterprise['enterprise_name'],
'name': node['data'].get('displayname') or
(params.enterprise['enterprise_name'] if not node.get('parent_id') else ''),
'isolated': node.get('restrict_visibility') or False,
'users': [],
'teams': [],
Expand Down Expand Up @@ -1554,7 +1555,9 @@ def is_in_chain(node_id, parent_id):
'node_id': node['node_id'],
'encrypted_data': encrypted_data
}
rq['parent_id'] = parent_id if parent_id else node.get('parent_id')
effective_parent_id = parent_id if parent_id else node.get('parent_id')
if effective_parent_id:
rq['parent_id'] = effective_parent_id
request_batch.append(rq)

if request_batch:
Expand Down
29 changes: 19 additions & 10 deletions keepercommander/commands/enterprise_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def __init__(self):
self.public_keys = {}
self.team_keys = {}
self._node_map = None
self._node_map_enterprise_name = None
self._node_map_signature = None

def execute_args(self, params, args, **kwargs):
if params.enterprise:
Expand Down Expand Up @@ -296,11 +296,21 @@ def get_enterprise_ids(params, num_ids=1):
return enterprise_ids

def get_node_path(self, params, node_id, omit_root=False):
current_enterprise_name = params.enterprise.get('enterprise_name')
if self._node_map is None or self._node_map_enterprise_name != current_enterprise_name:
self._node_map_enterprise_name = current_enterprise_name
node_map_signature = (
params.enterprise.get('enterprise_name'),
tuple(
(x['node_id'], x.get('parent_id', 0), x['data'].get('displayname'), x.get('name'))
for x in params.enterprise['nodes']
),
)
if self._node_map is None or self._node_map_signature != node_map_signature:
self._node_map_signature = node_map_signature
self._node_map = {
x['node_id']: (x['data'].get('displayname') or x.get('name') or str(x['node_id']) if x.get('parent_id', 0) > 0 else params.enterprise['enterprise_name'], x.get('parent_id', 0))
x['node_id']: (
x['data'].get('displayname') or x.get('name') or
(params.enterprise['enterprise_name'] if not x.get('parent_id') else str(x['node_id'])),
x.get('parent_id', 0),
)
for x in params.enterprise['nodes']}
path = ''
node = self._node_map.get(node_id)
Expand Down Expand Up @@ -328,11 +338,10 @@ def resolve_nodes(params, name): # type: (KeeperParams, str) -> collections.It
yield node
continue
if node_name:
if 'parent_id' in node:
display_name = node['data'].get('displayname') or ''
else:
display_name = params.enterprise['enterprise_name'] or ''
if display_name and display_name.lower() == node_name:
display_names = [node['data'].get('displayname') or '']
if not node.get('parent_id'):
display_names.append(params.enterprise['enterprise_name'] or '')
if any(x and x.lower() == node_name for x in display_names):
yield node
else:
if 'parent_id' not in node:
Expand Down
77 changes: 77 additions & 0 deletions unit-tests/test_command_enterprise.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,83 @@ def test_enterprise_info_users_verbose_returns_ids(self):
'role_name': ent_env.role1_name,
}])

def test_enterprise_info_uses_root_displayname(self):
params = get_connected_params()
api.query_enterprise(params)
params.enterprise['nodes'][0]['data']['displayname'] = 'ECC-cmdr'
cmd = enterprise.EnterpriseInfoCommand()

report = json.loads(cmd.execute(params, nodes=True, format='json', quiet=True))
root = next(x for x in report if x['node_id'] == ent_env.node1_id)
self.assertEqual(root['name'], 'ECC-cmdr')
self.assertIn('ECC-cmdr', cmd.execute(params, quiet=True))
self.assertIn('ECC-cmdr', cmd.execute(params, nodes=True, format='csv', quiet=True))

self.assertEqual(
[x['node_id'] for x in cmd.resolve_nodes(params, 'ECC-cmdr')],
[ent_env.node1_id],
)
self.assertEqual(
[x['node_id'] for x in cmd.resolve_nodes(params, 'Enterprise 1')],
[ent_env.node1_id],
)
self.assertEqual(cmd.get_node_path(params, ent_env.node2_id), 'ECC-cmdr\\Sub node 1')

def test_enterprise_node_path_cache_refreshes_displayname(self):
params = get_connected_params()
api.query_enterprise(params)
cmd = enterprise.EnterpriseInfoCommand()

self.assertEqual(cmd.get_node_path(params, ent_env.node2_id), 'Enterprise 1\\Sub node 1')
params.enterprise['nodes'][0]['data']['displayname'] = 'ECC-cmdr'
self.assertEqual(cmd.get_node_path(params, ent_env.node2_id), 'ECC-cmdr\\Sub node 1')

def test_enterprise_node_rename_root_omits_parent_id(self):
params = get_connected_params()
api.query_enterprise(params)
cmd = enterprise.EnterpriseNodeCommand()

with mock.patch('keepercommander.commands.enterprise.api.execute_batch',
return_value=[{'result': 'success'}]) as execute_batch:
cmd.execute(params, node=[str(ent_env.node1_id)], displayname='Renamed Enterprise')

request = execute_batch.call_args.args[1][0]
self.assertNotIn('parent_id', request)
data = crypto.decrypt_aes_v1(
utils.base64_url_decode(request['encrypted_data']),
params.enterprise['unencrypted_tree_key'],
)
self.assertEqual(json.loads(data.decode('utf-8'))['displayname'], 'Renamed Enterprise')

def test_enterprise_node_rename_child_preserves_parent_id(self):
params = get_connected_params()
api.query_enterprise(params)
cmd = enterprise.EnterpriseNodeCommand()

with mock.patch('keepercommander.commands.enterprise.api.execute_batch',
return_value=[{'result': 'success'}]) as execute_batch:
cmd.execute(params, node=[str(ent_env.node2_id)], displayname='Renamed Child')

request = execute_batch.call_args.args[1][0]
self.assertEqual(request['parent_id'], ent_env.node1_id)
data = crypto.decrypt_aes_v1(
utils.base64_url_decode(request['encrypted_data']),
params.enterprise['unencrypted_tree_key'],
)
self.assertEqual(json.loads(data.decode('utf-8'))['displayname'], 'Renamed Child')

def test_enterprise_node_move_sets_selected_parent_id(self):
params = get_connected_params()
api.query_enterprise(params)
cmd = enterprise.EnterpriseNodeCommand()

with mock.patch('keepercommander.commands.enterprise.api.execute_batch',
return_value=[{'result': 'success'}]) as execute_batch:
cmd.execute(params, node=[str(ent_env.node2_id)], parent=str(ent_env.node1_id))

request = execute_batch.call_args.args[1][0]
self.assertEqual(request['parent_id'], ent_env.node1_id)

def test_enterprise_add_user(self):
params = get_connected_params()
api.query_enterprise(params)
Expand Down
Loading