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_role_assignments(include_remote=True): """ Retrieve all the UserRoleAssignmentDB objects. :param include_remote: True to also include remote role assignments. :type include_remote: ``bool`` :rtype: ``list`` of :class:`UserRoleAssignmentDB` """ if include_remote: result = UserRoleAssignment.query() else: # Note: We also include documents with no "is_remote" field so it also works correctly # when upgrading from pre v2.3.0 when this field didn't exist yet queryset_filter = (Q(is_remote=False) | Q(is_remote__exists=False)) result = UserRoleAssignmentDB.objects(queryset_filter) return result
def get_role_assignments_for_user(user_db, include_remote=True): """ Retrieve all the UserRoleAssignmentDB objects for a particular user. :param user_db: User to retrieve the role assignments for. :type user_db: :class:`UserDB` :param include_remote: True to also include remote role assignments. :type include_remote: ``bool`` :rtype: ``list`` of :class:`UserRoleAssignmentDB` """ if include_remote: result = UserRoleAssignment.query(user=user_db.name) else: # Note: We also include documents with no "is_remote" field so it also works correctly # when upgrading from pre v2.3.0 when this field didn't exist yet queryset_filter = (Q(user=user_db.name) & (Q(is_remote=False) | Q(is_remote__exists=False))) result = UserRoleAssignmentDB.objects(queryset_filter) 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_user_role_assignments(self, user_db, role_assignment_dbs, role_assignment_apis): """ 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_apis: List of user role assignments to apply. :param role_assignment_apis: ``list`` of :class:`UserRoleAssignmentFileFormatAPI` :rtype: ``tuple`` """ db_roles = set([(entry.role, entry.source) for entry in role_assignment_dbs]) api_roles = [ list(izip_longest(entry.roles, [], fillvalue=entry.file_path)) for entry in role_assignment_apis ] api_roles = set(list(chain.from_iterable(api_roles))) # A list of new assignments which should be added to the database new_roles = api_roles.difference(db_roles) # A list of assignments which need to be updated in the database updated_roles = db_roles.intersection(api_roles) # A list of assignments which should be removed from the database removed_roles = (db_roles - api_roles) LOG.debug('New assignments for user "%s": %r' % (user_db.name, new_roles)) LOG.debug('Updated assignments for user "%s": %r' % (user_db.name, updated_roles)) LOG.debug('Removed assignments for user "%s": %r' % (user_db.name, removed_roles)) # Build a list of role assignments to delete roles_to_delete = updated_roles.union(removed_roles) role_assignment_dbs_to_delete = [ role_assignment_db for role_assignment_db in role_assignment_dbs if (role_assignment_db.role, role_assignment_db.source) in roles_to_delete ] for role_name, assignment_source in roles_to_delete: queryset_filter = ( Q(user=user_db.name) & Q(role=role_name) & Q(source=assignment_source) & (Q(is_remote=False) | Q(is_remote__exists=False))) UserRoleAssignmentDB.objects(queryset_filter).delete() LOG.debug('Removed role "%s" from "%s" for user "%s".' % (role_name, assignment_source, user_db.name)) # Build a list of roles assignments to create roles_to_create = new_roles.union(updated_roles) created_role_assignment_dbs = [] for role_name, assignment_source in roles_to_create: role_db = Role.get(name=role_name) if not role_db: msg = 'Role "%s" referenced in assignment file "%s" doesn\'t exist' raise ValueError(msg % (role_name, assignment_source)) role_assignment_api = [ r for r in role_assignment_apis if r.file_path == assignment_source ][0] description = getattr(role_assignment_api, 'description', None) assignment_db = rbac_services.assign_role_to_user( role_db=role_db, user_db=user_db, source=assignment_source, description=description) created_role_assignment_dbs.append(assignment_db) LOG.debug('Assigned role "%s" from "%s" for user "%s".' % (role_name, assignment_source, user_db.name)) return (created_role_assignment_dbs, role_assignment_dbs_to_delete)
def _sync_user_role_assignments(self, user_db, role_assignment_dbs, role_assignment_apis): """ 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_apis: List of user role assignments to apply. :param role_assignment_apis: ``list`` of :class:`UserRoleAssignmentFileFormatAPI` :rtype: ``tuple`` """ db_roles = set([(entry.role, entry.source) for entry in role_assignment_dbs]) api_roles = [ list(izip_longest(entry.roles, [], fillvalue=entry.file_path)) for entry in role_assignment_apis ] api_roles = set(list(chain.from_iterable(api_roles))) # A list of new assignments which should be added to the database new_roles = api_roles.difference(db_roles) # A list of assignments which need to be updated in the database updated_roles = db_roles.intersection(api_roles) # A list of assignments which should be removed from the database removed_roles = (db_roles - api_roles) LOG.debug('New assignments for user "%s": %r' % (user_db.name, new_roles)) LOG.debug('Updated assignments for user "%s": %r' % (user_db.name, updated_roles)) LOG.debug('Removed assignments for user "%s": %r' % (user_db.name, removed_roles)) # Build a list of role assignments to delete roles_to_delete = updated_roles.union(removed_roles) role_assignment_dbs_to_delete = [ role_assignment_db for role_assignment_db in role_assignment_dbs if (role_assignment_db.role, role_assignment_db.source) in roles_to_delete ] for role_name, assignment_source in roles_to_delete: queryset_filter = ( Q(user=user_db.name) & Q(role=role_name) & Q(source=assignment_source) & (Q(is_remote=False) | Q(is_remote__exists=False)) ) UserRoleAssignmentDB.objects(queryset_filter).delete() LOG.debug('Removed role "%s" from "%s" for user "%s".' % (role_name, assignment_source, user_db.name)) # Build a list of roles assignments to create roles_to_create = new_roles.union(updated_roles) created_role_assignment_dbs = [] for role_name, assignment_source in roles_to_create: role_db = Role.get(name=role_name) if not role_db: msg = 'Role "%s" referenced in assignment file "%s" doesn\'t exist' raise ValueError(msg % (role_name, assignment_source)) role_assignment_api = [r for r in role_assignment_apis if r.file_path == assignment_source][0] description = getattr(role_assignment_api, 'description', None) assignment_db = rbac_services.assign_role_to_user( role_db=role_db, user_db=user_db, source=assignment_source, description=description) created_role_assignment_dbs.append(assignment_db) LOG.debug('Assigned role "%s" from "%s" for user "%s".' % (role_name, assignment_source, user_db.name)) return (created_role_assignment_dbs, role_assignment_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 ] queryset_filter = (Q(user=user_db.name) & Q(role__in=role_names_to_delete) & (Q(is_remote=False) | Q(is_remote__exists=False))) UserRoleAssignmentDB.objects(queryset_filter).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)