def get_roles_for_user(user_db, include_remote=True): """ Retrieve all the roles assigned to the provided user. :param user_db: User to retrieve the roles for. :type user_db: :class:`UserDB` :param include_remote: True to also include remote role assignments. :type include_remote: ``bool`` :rtype: ``list`` of :class:`RoleDB` """ if include_remote: queryset = UserRoleAssignment.query(user=user_db.name) else: # when upgrading from pre v2.3.0 when this field didn't exist yet # Note: We also include None for pre v2.3 when this field didn't exist yet queryset_filter = ( Q(user=user_db.name) & (Q(is_remote=False) | Q(is_remote__exists=False))) queryset = UserRoleAssignmentDB.objects(queryset_filter) role_names = queryset.only('role').scalar('role') result = Role.query(name__in=role_names) return result
def get_all_permission_grants_for_user(user_db, resource_uid=None, resource_types=None, permission_types=None): """ Retrieve all the permission grants for a particular user optionally filtering on: - Resource uid - Resource types - Permission types The result is a union of all the permission grants assigned to the roles which are assigned to the user. :rtype: ``list`` or :class:`PermissionGrantDB` """ role_names = UserRoleAssignment.query(user=user_db.name).only("role").scalar("role") permission_grant_ids = Role.query(name__in=role_names).scalar("permission_grants") permission_grant_ids = sum(permission_grant_ids, []) permission_grants_filters = {} permission_grants_filters["id__in"] = permission_grant_ids if resource_uid: permission_grants_filters["resource_uid"] = resource_uid if resource_types: permission_grants_filters["resource_type__in"] = resource_types if permission_types: permission_grants_filters["permission_types__in"] = permission_types permission_grant_dbs = PermissionGrant.query(**permission_grants_filters) return permission_grant_dbs
def get_all_permission_grants_for_user(user_db, resource_uid=None, resource_types=None, permission_types=None): """ Retrieve all the permission grants for a particular user optionally filtering on: - Resource uid - Resource types - Permission types The result is a union of all the permission grants assigned to the roles which are assigned to the user. :rtype: ``list`` or :class:`PermissionGrantDB` """ role_names = UserRoleAssignment.query(user=user_db.name).only('role').scalar('role') permission_grant_ids = Role.query(name__in=role_names).scalar('permission_grants') permission_grant_ids = sum(permission_grant_ids, []) permission_grants_filters = {} permission_grants_filters['id__in'] = permission_grant_ids if resource_uid: permission_grants_filters['resource_uid'] = resource_uid if resource_types: permission_grants_filters['resource_type__in'] = resource_types if permission_types: permission_grants_filters['permission_types__in'] = permission_types permission_grant_dbs = PermissionGrant.query(**permission_grants_filters) return permission_grant_dbs
def _sync_user_role_assignments(self, user_db, role_assignment_dbs, role_assignment_api): """ Synchronize role assignments for a particular user. :param user_db: User to synchronize the assignments for. :type user_db: :class:`UserDB` :param role_assignment_dbs: Existing user role assignments. :type role_assignment_dbs: ``list`` of :class:`UserRoleAssignmentDB` :param role_assignment_api: Role assignment API for a particular user. :param role_assignment_api: :class:`UserRoleAssignmentFileFormatAPI` :rtype: ``tuple`` """ db_role_names = [role_assignment_db.role for role_assignment_db in role_assignment_dbs] db_role_names = set(db_role_names) api_role_names = role_assignment_api.roles if role_assignment_api else [] api_role_names = set(api_role_names) # A list of new assignments which should be added to the database new_role_names = api_role_names.difference(db_role_names) # A list of assgignments which need to be updated in the database updated_role_names = db_role_names.intersection(api_role_names) # A list of assignments which should be removed from the database removed_role_names = db_role_names - api_role_names LOG.debug('New assignments for user "%s": %r' % (user_db.name, new_role_names)) LOG.debug('Updated assignments for user "%s": %r' % (user_db.name, updated_role_names)) LOG.debug('Removed assignments for user "%s": %r' % (user_db.name, removed_role_names)) # Build a list of role assignments to delete role_names_to_delete = updated_role_names.union(removed_role_names) role_assignment_dbs_to_delete = [ role_assignment_db for role_assignment_db in role_assignment_dbs if role_assignment_db.role in role_names_to_delete ] UserRoleAssignment.query(user=user_db.name, role__in=role_names_to_delete).delete() LOG.debug('Removed %s assignments for user "%s"' % (len(role_assignment_dbs_to_delete), user_db.name)) # Build a list of roles assignments to create role_names_to_create = new_role_names.union(updated_role_names) role_dbs_to_assign = Role.query(name__in=role_names_to_create) created_role_assignment_dbs = [] for role_db in role_dbs_to_assign: if role_db.name in role_assignment_api.roles: description = getattr(role_assignment_api, "description", None) else: description = None assignment_db = rbac_services.assign_role_to_user(role_db=role_db, user_db=user_db, description=description) created_role_assignment_dbs.append(assignment_db) LOG.debug('Created %s new assignments for user "%s"' % (len(role_dbs_to_assign), user_db.name)) return (created_role_assignment_dbs, role_assignment_dbs_to_delete)
def get_key_uids_for_user(user): role_names = UserRoleAssignment.query(user=user).only("role").scalar("role") permission_grant_ids = Role.query(name__in=role_names).scalar("permission_grants") permission_grant_ids = sum(permission_grant_ids, []) permission_grants_filters = {} permission_grants_filters["id__in"] = permission_grant_ids permission_grants_filters["resource_type"] = ResourceType.KEY_VALUE_PAIR return PermissionGrant.query(**permission_grants_filters).scalar("resource_uid")
def get_system_roles(): """ Retrieve all the available system roles. :rtype: ``list`` of :class:`RoleDB` """ result = Role.query(system=True) return result
def get_roles_for_user(user_db): """ Retrieve all the roles assigned to the provided user. :param user_db: User to retrieve the roles for. :type user_db: :class:`UserDB` :rtype: ``list`` of :class:`RoleDB` """ role_names = UserRoleAssignment.query(user=user_db.name).only("role").scalar("role") result = Role.query(name__in=role_names) return result
def get_roles_for_user(user_db): """ Retrieve all the roles assigned to the provided user. :param user_db: User to retrieve the roles for. :type user_db: :class:`UserDB` :rtype: ``list`` of :class:`RoleDB` """ role_names = UserRoleAssignment.query( user=user_db.name).only('role').scalar('role') result = Role.query(name__in=role_names) return result
def get_all_roles(exclude_system=False): """ Retrieve all the available roles. :param exclude_system: True to exclude system roles. :type exclude_system: ``bool`` :rtype: ``list`` of :class:`RoleDB` """ if exclude_system: result = Role.query(system=False) else: result = Role.get_all() return result
def get_roles_for_user(user_db, include_remote=True): """ Retrieve all the roles assigned to the provided user. :param user_db: User to retrieve the roles for. :type user_db: :class:`UserDB` :param include_remote: True to also include remote role assignments. :type include_remote: ``bool`` :rtype: ``list`` of :class:`RoleDB` """ if include_remote: queryset = UserRoleAssignment.query(user=user_db.name) else: queryset = UserRoleAssignment.query(user=user_db.name, is_remote=False) role_names = queryset.only('role').scalar('role') result = Role.query(name__in=role_names) return result
def get_roles_for_user(user_db, include_remote=True): """ Retrieve all the roles assigned to the provided user. :param user_db: User to retrieve the roles for. :type user_db: :class:`UserDB` :param include_remote: True to also include remote role assignments. :type include_remote: ``bool`` :rtype: ``list`` of :class:`RoleDB` """ if include_remote: queryset = UserRoleAssignment.query(user=user_db.name) else: # when upgrading from pre v2.3.0 when this field didn't exist yet # Note: We also include None for pre v2.3 when this field didn't exist yet queryset_filter = (Q(user=user_db.name) & (Q(is_remote=False) | Q(is_remote__exists=False))) queryset = UserRoleAssignmentDB.objects(queryset_filter) role_names = queryset.only('role').scalar('role') result = Role.query(name__in=role_names) return result
def sync_roles(self, role_definition_apis): """ Synchronize all the role definitions in the database. :param role_dbs: RoleDB objects for the roles which are currently in the database. :type role_dbs: ``list`` of :class:`RoleDB` :param role_definition_apis: RoleDefinition API objects for the definitions loaded from the files. :type role_definition_apis: ``list`` of :class:RoleDefinitionFileFormatAPI` :rtype: ``tuple`` """ LOG.info('Synchronizing roles...') # Retrieve all the roles currently in the DB role_dbs = rbac_services.get_all_roles(exclude_system=True) role_db_names = [role_db.name for role_db in role_dbs] role_db_names = set(role_db_names) role_api_names = [ role_definition_api.name for role_definition_api in role_definition_apis ] role_api_names = set(role_api_names) # A list of new roles which should be added to the database new_role_names = role_api_names.difference(role_db_names) # A list of roles which need to be updated in the database updated_role_names = role_db_names.intersection(role_api_names) # A list of roles which should be removed from the database removed_role_names = (role_db_names - role_api_names) LOG.debug('New roles: %r' % (new_role_names)) LOG.debug('Updated roles: %r' % (updated_role_names)) LOG.debug('Removed roles: %r' % (removed_role_names)) # Build a list of roles to delete role_names_to_delete = updated_role_names.union(removed_role_names) role_dbs_to_delete = [ role_db for role_db in role_dbs if role_db.name in role_names_to_delete ] # Build a list of roles to create role_names_to_create = new_role_names.union(updated_role_names) role_apis_to_create = [ role_definition_api for role_definition_api in role_definition_apis if role_definition_api.name in role_names_to_create ] ######## # 1. Remove obsolete roles and associated permission grants from the DB ######## # Remove roles role_ids_to_delete = [] for role_db in role_dbs_to_delete: role_ids_to_delete.append(role_db.id) LOG.debug('Deleting %s stale roles' % (len(role_ids_to_delete))) Role.query(id__in=role_ids_to_delete, system=False).delete() LOG.debug('Deleted %s stale roles' % (len(role_ids_to_delete))) # Remove associated permission grants permission_grant_ids_to_delete = [] for role_db in role_dbs_to_delete: permission_grant_ids_to_delete.extend(role_db.permission_grants) LOG.debug('Deleting %s stale permission grants' % (len(permission_grant_ids_to_delete))) PermissionGrant.query(id__in=permission_grant_ids_to_delete).delete() LOG.debug('Deleted %s stale permission grants' % (len(permission_grant_ids_to_delete))) ######## # 2. Add new / updated roles to the DB ######## LOG.debug('Creating %s new roles' % (len(role_apis_to_create))) # Create new roles created_role_dbs = [] for role_api in role_apis_to_create: role_db = rbac_services.create_role( name=role_api.name, description=role_api.description) # Create associated permission grants permission_grants = getattr(role_api, 'permission_grants', []) for permission_grant in permission_grants: resource_uid = permission_grant.get('resource_uid', None) if resource_uid: resource_type, _ = parse_uid(resource_uid) else: resource_type = None permission_types = permission_grant['permission_types'] assignment_db = rbac_services.create_permission_grant( role_db=role_db, resource_uid=resource_uid, resource_type=resource_type, permission_types=permission_types) role_db.permission_grants.append(str(assignment_db.id)) created_role_dbs.append(role_db) LOG.debug('Created %s new roles' % (len(created_role_dbs))) LOG.info('Roles synchronized (%s created, %s updated, %s removed)' % (len(new_role_names), len(updated_role_names), len(removed_role_names))) return [created_role_dbs, role_dbs_to_delete]
def sync_roles(self, role_definition_apis): """ Synchronize all the role definitions in the database. :param role_dbs: RoleDB objects for the roles which are currently in the database. :type role_dbs: ``list`` of :class:`RoleDB` :param role_definition_apis: RoleDefinition API objects for the definitions loaded from the files. :type role_definition_apis: ``list`` of :class:RoleDefinitionFileFormatAPI` :rtype: ``tuple`` """ LOG.info("Synchronizing roles...") # Retrieve all the roles currently in the DB role_dbs = rbac_services.get_all_roles(exclude_system=True) role_db_names = [role_db.name for role_db in role_dbs] role_db_names = set(role_db_names) role_api_names = [role_definition_api.name for role_definition_api in role_definition_apis] role_api_names = set(role_api_names) # A list of new roles which should be added to the database new_role_names = role_api_names.difference(role_db_names) # A list of roles which need to be updated in the database updated_role_names = role_db_names.intersection(role_api_names) # A list of roles which should be removed from the database removed_role_names = role_db_names - role_api_names LOG.debug("New roles: %r" % (new_role_names)) LOG.debug("Updated roles: %r" % (updated_role_names)) LOG.debug("Removed roles: %r" % (removed_role_names)) # Build a list of roles to delete role_names_to_delete = updated_role_names.union(removed_role_names) role_dbs_to_delete = [role_db for role_db in role_dbs if role_db.name in role_names_to_delete] # Build a list of roles to create role_names_to_create = new_role_names.union(updated_role_names) role_apis_to_create = [ role_definition_api for role_definition_api in role_definition_apis if role_definition_api.name in role_names_to_create ] ######## # 1. Remove obsolete roles and associated permission grants from the DB ######## # Remove roles role_ids_to_delete = [] for role_db in role_dbs_to_delete: role_ids_to_delete.append(role_db.id) LOG.debug("Deleting %s stale roles" % (len(role_ids_to_delete))) Role.query(id__in=role_ids_to_delete, system=False).delete() LOG.debug("Deleted %s stale roles" % (len(role_ids_to_delete))) # Remove associated permission grants permission_grant_ids_to_delete = [] for role_db in role_dbs_to_delete: permission_grant_ids_to_delete.extend(role_db.permission_grants) LOG.debug("Deleting %s stale permission grants" % (len(permission_grant_ids_to_delete))) PermissionGrant.query(id__in=permission_grant_ids_to_delete).delete() LOG.debug("Deleted %s stale permission grants" % (len(permission_grant_ids_to_delete))) ######## # 2. Add new / updated roles to the DB ######## LOG.debug("Creating %s new roles" % (len(role_apis_to_create))) # Create new roles created_role_dbs = [] for role_api in role_apis_to_create: role_db = rbac_services.create_role(name=role_api.name, description=role_api.description) # Create associated permission grants for permission_grant in role_api.permission_grants: resource_uid = permission_grant["resource_uid"] resource_type, _ = parse_uid(resource_uid) permission_types = permission_grant["permission_types"] assignment_db = rbac_services.create_permission_grant( role_db=role_db, resource_uid=resource_uid, resource_type=resource_type, permission_types=permission_types, ) role_db.permission_grants.append(str(assignment_db.id)) created_role_dbs.append(role_db) LOG.debug("Created %s new roles" % (len(created_role_dbs))) LOG.info( "Roles synchronized (%s created, %s updated, %s removed)" % (len(new_role_names), len(updated_role_names), len(removed_role_names)) ) return [created_role_dbs, role_dbs_to_delete]
def _sync_user_role_assignments(self, user_db, role_assignment_dbs, role_assignment_api): """ Synchronize role assignments for a particular user. :param user_db: User to synchronize the assignments for. :type user_db: :class:`UserDB` :param role_assignment_dbs: Existing user role assignments. :type role_assignment_dbs: ``list`` of :class:`UserRoleAssignmentDB` :param role_assignment_api: Role assignment API for a particular user. :param role_assignment_api: :class:`UserRoleAssignmentFileFormatAPI` :rtype: ``tuple`` """ db_role_names = [role_assignment_db.role for role_assignment_db in role_assignment_dbs] db_role_names = set(db_role_names) api_role_names = role_assignment_api.roles if role_assignment_api else [] api_role_names = set(api_role_names) # A list of new assignments which should be added to the database new_role_names = api_role_names.difference(db_role_names) # A list of assignments which need to be updated in the database updated_role_names = db_role_names.intersection(api_role_names) # A list of assignments which should be removed from the database removed_role_names = (db_role_names - api_role_names) LOG.debug('New assignments for user "%s": %r' % (user_db.name, new_role_names)) LOG.debug('Updated assignments for user "%s": %r' % (user_db.name, updated_role_names)) LOG.debug('Removed assignments for user "%s": %r' % (user_db.name, removed_role_names)) # Build a list of role assignments to delete role_names_to_delete = updated_role_names.union(removed_role_names) role_assignment_dbs_to_delete = [role_assignment_db for role_assignment_db in role_assignment_dbs if role_assignment_db.role in role_names_to_delete] UserRoleAssignment.query(user=user_db.name, role__in=role_names_to_delete, is_remote=False).delete() LOG.debug('Removed %s assignments for user "%s"' % (len(role_assignment_dbs_to_delete), user_db.name)) # Build a list of roles assignments to create role_names_to_create = new_role_names.union(updated_role_names) role_dbs_to_assign = Role.query(name__in=role_names_to_create) created_role_assignment_dbs = [] for role_db in role_dbs_to_assign: if role_db.name in role_assignment_api.roles: description = getattr(role_assignment_api, 'description', None) else: description = None assignment_db = rbac_services.assign_role_to_user(role_db=role_db, user_db=user_db, description=description) created_role_assignment_dbs.append(assignment_db) LOG.debug('Created %s new assignments for user "%s"' % (len(role_dbs_to_assign), user_db.name)) return (created_role_assignment_dbs, role_assignment_dbs_to_delete)