def handle_patch(cls, **kwargs): """Set status for a CVE""" data = kwargs['data'] cve_list = data['cve'] if isinstance(cve_list, str): cve_list = [cve_list] values = {} updated = [] if 'status_id' in data: values['status_id'] = data['status_id'] if 'status_text' in data: try: values['status_text'] = data['status_text'].strip() \ if data['status_text'].strip() else None except AttributeError: values['status_text'] = None if not values: return cls.format_exception( 'At least one of the "status_id" or "status_text" parameters is required.', 400) try: to_insert = [] cves = CveMetadata.select( CveMetadata.id, CveMetadata.cve).where(CveMetadata.cve << cve_list) rh_account = get_or_create_account() for cve in cves: # pylint: disable=not-an-iterable updated.append(cve.cve) to_insert.append( (cve.id, rh_account[0].id, values.get('status_id', 0), values.get('status_text', None))) if not to_insert: return cls.format_exception( 'At least one given CVE must exist', 404) (CveAccountData.insert_many( to_insert, fields=cls._fields).on_conflict( conflict_target=cls._conflict_target, preserve=[], update=values).execute()) RHAccount.update( last_status_change=datetime.now(timezone.utc)).where( RHAccount.id == rh_account[0].id).execute() except (IntegrityError, psycopg2IntegrityError, DataError): # usually means bad status LOGGER.exception('Error during setting status (IntegrityError):') DB.rollback() return cls.format_exception( f"status_id={data['status_id']} is invalid", 400) except ValueError as value_error: LOGGER.exception('Error during setting status (ValueError):') DB.rollback() return cls.format_exception( f'status_text or other key value is invalid ({value_error})', 400) return {'updated': updated}
def handle_patch(cls, **kwargs): """Update the 'status' field for a system/cve combination""" # pylint: disable=singleton-comparison data = kwargs['data'] try: in_inventory_id_list, status_to_cves_map, status_text_to_cves_map = cls._prepare_data(data) rh_account = get_or_create_account() systems = (SystemPlatform.select(SystemPlatform.id) .where((SystemPlatform.rh_account_id == rh_account[0].id) & (SystemPlatform.opt_out == False) & (SystemPlatform.stale == False) & (SystemPlatform.when_deleted.is_null(True)))) if in_inventory_id_list is not None: systems = systems.where(SystemPlatform.inventory_id << in_inventory_id_list) rows_modified = set() # set statuses and their CVE lists for status_id, status_cve_list in status_to_cves_map.items(): status_id_update = (SystemVulnerabilities.update(status_id=status_id) .where(cls._build_update_condition(rh_account[0].id, systems, status_cve_list)) .returning(SystemVulnerabilities.id)) rows_modified.update([row.id for row in status_id_update]) for status_text, status_cve_list in status_text_to_cves_map.items(): status_text_update = (SystemVulnerabilities.update(status_text=status_text) .where(cls._build_update_condition(rh_account[0].id, systems, status_cve_list)) .returning(SystemVulnerabilities.id)) rows_modified.update([row.id for row in status_text_update]) if rows_modified: RHAccount.update(last_status_change=datetime.now(timezone.utc)).where(RHAccount.id == rh_account[0].id).execute() updated_details = (SystemVulnerabilities.select(SystemPlatform.inventory_id, CveMetadata.cve) .join(CveMetadata, on=(SystemVulnerabilities.cve_id == CveMetadata.id)) .join(SystemPlatform, on=(SystemVulnerabilities.system_id == SystemPlatform.id)) .where((SystemVulnerabilities.id << list(rows_modified)) & (SystemVulnerabilities.rh_account_id == rh_account[0].id)) .dicts()) updated_details = cyndi_join(updated_details) updated = [] for updated_row in updated_details: updated.append({"inventory_id": updated_row["inventory_id"], "cve": updated_row["cve"]}) if not updated: # sysid/cve/acct combination does not exist return cls.format_exception('inventory_id/cve must exist and inventory_id must be visible to user', 404) except (IntegrityError, psycopg2IntegrityError, DataError) as value_error: # usually means bad-status-id LOGGER.error(str(value_error)) DB.rollback() return cls.format_exception(f'status_id={list(status_to_cves_map.keys())} is invalid', 400) except ValueError as value_error: LOGGER.exception('Error during setting status (ValueError):') DB.rollback() return cls.format_exception(f'status_text or other key value is invalid ({value_error})', 400) return {"updated": updated}
def update_cve_cache_keepalive(account_id, last_timestamp): """Update keepalive timestamp for CVE cache in account. Used for maintaining cache only for active accounts.""" if not validate_cve_cache_keepalive(last_timestamp, 1): RHAccount.update(cve_cache_keepalive=datetime.now(timezone.utc)).where( RHAccount.id == account_id).execute()