from pdp.connectors import dynamo from pdp.connectors import neo4j maggie_identity = 'ca034907-1746-4c7b-9c42-502dc4002d6c' def node_to_dict(resource_node, **kwargs): """Convert neo4j Node instance to python dict. Args: resource_node (Node): A graph node with properties and label info. Returns: dict: of metadata from node. """ data = {} for attribute, value in resource_node.items(): data[attribute] = value return data def hydrate_roles_by_type(orchardIdentityId, access, tenantType): """Hydrate roles for an Orchard Identity Id for a tenant type and access level. Example output: [ {'profileType': 'SettingsProfile', 'roles': None, 'tenantUuid': '053a1a75-acc5-4cd8-9206-a194335d2afa'}, {'profileType': 'SettingsProfile', 'roles': None, 'tenantUuid': 'c6594bfc-7140-44ab-a8f3-3c3cf0290ac5'}, {'profileType': 'CollaboratorsProfile', 'roles': ['royalties', 'tenantUuid': 'c6594bfc-7140-44ab-a8f3-3c3cf0290ac5'} ] """ with neo4j.db_session(access_mode="READ") as session: query = f""" MATCH (i:Identity {{id: '{orchardIdentityId}'}}) -[:HAS_PROFILE]->(p:Profile)-[{access}]->({tenantType}) RETURN p.profileType as profileType, p.roles as roles, t.uuid as tenantUuid """ result = session.run( query) data = [] for each in result: data.append(node_to_dict(each)) return data def hydrate_roles(orchardIdentityId='ca034907-1746-4c7b-9c42-502dc4002d6c'): """ Creates a tenants object with all user's roles by profile type Example output: { 'c6594bfc-7140-44ab-a8f3-3c3cf0290ac5': { 'SettingsProfile': { 'roles': ['admin'] }, 'subaccount': False }, '053a1a75-acc5-4cd8-9206-a194335d2afa': { 'SettingsProfile': { 'roles': [] }, 'subaccount': False } } """ tenants = {} admin_vendor = hydrate_roles_by_type(orchardIdentityId, ':HAS_ADMIN_ACCESS_TO', 't:Vendor') for result in admin_vendor: vendor_uuid = str(result['tenantUuid']) profile_type = result['profileType'] if not tenants.get(vendor_uuid): tenants[vendor_uuid] = { profile_type : { 'roles': result['roles'] or ['admin'] }, 'subaccount': False } else: tenants[vendor_uuid][profile_type] = { 'roles': result['roles'] or ['admin'] } admin_subaccount = hydrate_roles_by_type(orchardIdentityId, ':HAS_ADMIN_ACCESS_TO', 't:Subaccount') for result in admin_subaccount: subaccount_uuid = str(result['tenantUuid']) profile_type = result['profileType'] if not tenants.get(subaccount_uuid): tenants[subaccount_uuid] = { profile_type: { 'roles': result['roles'] or ['admin'] }, 'subaccount': True } else: tenants[subaccount_uuid][profile_type] = { 'roles': result['roles'] or ['admin'] } non_admin_vendor = hydrate_roles_by_type(orchardIdentityId, ':HAS_ACCESS_TO', 't:Vendor') for result in non_admin_vendor: vendor_uuid = str(result['tenantUuid']) profile_type = result['profileType'] if not tenants.get(vendor_uuid): tenants[vendor_uuid] = { profile_type : { 'roles': result['roles'] }, 'subaccount': False } else: tenants[vendor_uuid][profile_type] = { 'roles': result['roles'] } non_admin_subaccount = hydrate_roles_by_type(orchardIdentityId, ':HAS_ACCESS_TO', 't:Subaccount') for result in non_admin_subaccount: subaccount_uuid = str(result['tenantUuid']) profile_type = result['profileType'] if not tenants.get(subaccount_uuid): tenants[subaccount_uuid] = { profile_type: { 'roles': result['roles'] }, 'subaccount': True } else: tenants[subaccount_uuid][profile_type] = { 'roles': result['roles'] } return tenants def map_roles(tenant): roles = [] for profile in tenant: if profile == 'subaccount': continue profile_sliced = profile[0:-7] for role in tenant[profile]['roles']: new_role_name = f'{profile_sliced}_{role}'.lower() roles.append(new_role_name) return roles def replace_roles(tenants): for tenant in tenants: curr_tenant = tenants[tenant] roles_by_tenant = map_roles(curr_tenant) curr_tenant['roles'] = roles_by_tenant def write_to_dynamo(identity): """Writes row(s) to a dynamo table row example: [ { 'id': 'ca034907-1746-4c7b-9c42-502dc4002d6c', 'tenant': '053a1a75-acc5-4cd8-9206-a194335d2afa', 'subaccount': False, 'roles': ['settings_admin', 'label_administrator', 'insights_analytics'] } ] """ tenants = hydrate_roles(identity) replace_roles(tenants) table = dynamo.get_table() for tenant in tenants: item = { 'orchard-identity-id': identity, 'tenant': tenant, 'subaccount': tenants[tenant]['subaccount'], 'roles': tenants[tenant]['roles'] } response = table.put_item(Item=item) print(response['ResponseMetadata']['HTTPStatusCode'], ', ', identity) def get_item(oiid, tenant): table = dynamo.get_table() response = table.get_item( Key={ 'orchard-identity-id': oiid, 'tenant': tenant } ) return response