def _system_exists_and_visible(cls, inventory_id):
     system = (SystemPlatform.select()
               .join(RHAccount, on=(SystemPlatform.rh_account_id == RHAccount.id))
               .where((RHAccount.name == connexion.context['user']) &
                      (SystemPlatform.inventory_id == inventory_id)))
     if not system.exists():
         raise ApplicationException("inventory_id must exist and inventory_id must be visible to user", 404)
 def _system_exists(cls, inventory_id):
     if inventory_id is None:
         raise ApplicationException("invalid inventory_id", 400)
     system = (SystemPlatform.select().where(
         SystemPlatform.inventory_id == inventory_id))
     if not system.exists():
         raise ApplicationException("inventory_id must exist", 404)
Exemplo n.º 3
0
    def handle_get(cls, **kwargs):
        """Get system details"""
        inventory_id = kwargs['inventory_id']
        try:
            selectables = [SystemPlatform.last_evaluation,
                           SystemPlatform.advisor_evaluated,
                           SystemPlatform.opt_out,
                           SystemPlatform.last_upload,
                           SystemPlatform.stale]
            if CYNDI_ENABLED:
                selectables.append(InventoryHosts.tags)
                selectables.append(InventoryHosts.updated)

            query = (SystemPlatform.select(*selectables)
                     .join(RHAccount, on=(SystemPlatform.rh_account_id == RHAccount.id))
                     .where(SystemPlatform.inventory_id == inventory_id)
                     .where(RHAccount.name == connexion.context['user'])
                     .where(SystemPlatform.when_deleted.is_null(True)).dicts())
            system = cyndi_query(query).get()
        except DoesNotExist:
            raise ApplicationException('inventory_id must exist and inventory_id must be visible to user', 404)
        return {'data': {'last_evaluation': system['last_evaluation'], 'rules_evaluation': system['advisor_evaluated'], 'opt_out': system['opt_out'],
                         'last_upload': system['last_upload'], 'stale': system['stale'],
                         'tags': system['tags'] if CYNDI_ENABLED and system['tags'] is not None else [],
                         'updated': system['updated'] if CYNDI_ENABLED else system['last_upload']}}
Exemplo n.º 4
0
 def __init__(self, list_args, query_args, filter_args, parsed_args, uri):
     # pylint: disable=singleton-comparison
     query = (SystemPlatform.select(
         SystemPlatform.inventory_id,
         SystemPlatform.last_evaluation,
         SystemPlatform.opt_out,
         SystemPlatform.cve_count_cache.alias("cve_count"),
         SystemPlatform.last_upload,
     ).join(RHAccount,
            on=(RHAccount.id == SystemPlatform.rh_account_id)).where(
                RHAccount.name == query_args['rh_account_number']).where(
                    SystemPlatform.last_evaluation.is_null(False)).dicts())
     if 'opt_out' in filter_args and filter_args['opt_out']:
         query = query.where(
             SystemPlatform.opt_out == filter_args['opt_out'])
     else:
         query = query.where(SystemPlatform.opt_out == False)  # noqa: E712
     sortable_columns = {
         'id': SystemPlatform.id,
         'cve_count': SystemPlatform.cve_count_cache,
         'inventory_id': SystemPlatform.inventory_id,
         'last_evaluation': SystemPlatform.last_evaluation,
         'last_upload': SystemPlatform.last_upload
     }
     default_sort_columns = ['id']
     filterable_columns = {'inventory_id': SystemPlatform.inventory_id}
     super(SystemView,
           self).__init__(query, sortable_columns, default_sort_columns,
                          filterable_columns, list_args, parsed_args, uri)
    def _full_query(rh_account_id):
        # pylint: disable=singleton-comparison
        selectables = [
            SystemPlatform.inventory_id,
            SystemPlatform.display_name,
            SystemPlatform.last_evaluation,
            SystemPlatform.advisor_evaluated.alias('rules_evaluation'),
            SystemPlatform.opt_out,
            SystemPlatform.last_upload,
            SystemPlatform.stale_timestamp,
            SystemPlatform.stale_warning_timestamp,
            SystemPlatform.culled_timestamp,
            Case(None, (((SystemPlatform.opt_out
                          == False), SystemPlatform.cve_count_cache), ),
                 None).alias("cve_count"),
            InventoryHosts.tags,
            InventoryHosts.updated,
            InventoryHosts.insights_id,
            OS_INFO_QUERY.alias('os'),
        ]

        return (SystemPlatform.select(*selectables).where(
            SystemPlatform.rh_account_id == rh_account_id).where(
                SystemPlatform.last_evaluation.is_null(False)
                | SystemPlatform.advisor_evaluated.is_null(False)).where(
                    SystemPlatform.when_deleted.is_null(True)).dicts())
Exemplo n.º 6
0
    def handle_get(cls, **kwargs):
        """Get system details"""
        inventory_id = kwargs['inventory_id']
        try:
            selectables = [SystemPlatform.last_evaluation,
                           SystemPlatform.advisor_evaluated,
                           SystemPlatform.opt_out,
                           SystemPlatform.last_upload,
                           SystemPlatform.stale,
                           InventoryHosts.tags,
                           InventoryHosts.updated,
                           InventoryHosts.insights_id,
                           OS_INFO_QUERY.alias('os'),
                           ]

            query = (SystemPlatform.select(*selectables)
                     .join(RHAccount, on=(SystemPlatform.rh_account_id == RHAccount.id))
                     .where(SystemPlatform.inventory_id == inventory_id)
                     .where(RHAccount.name == connexion.context['user'])
                     .where(SystemPlatform.when_deleted.is_null(True)).dicts())
            system = cyndi_join(query).get()
        except DoesNotExist as exc:
            raise ApplicationException('inventory_id must exist and inventory_id must be visible to user', 404) from exc
        return {'data': {'last_evaluation': system['last_evaluation'], 'rules_evaluation': system['advisor_evaluated'], 'opt_out': system['opt_out'],
                         'last_upload': system['last_upload'], 'stale': system['stale'], 'os': system.get('os', 'N/A'),
                         'tags': system['tags'] if system['tags'] is not None else [],
                         'updated': system['updated'],
                         'insights_id': system['insights_id']}}
 def handle_get(cls, **kwargs):
     """Get system details"""
     inventory_id = kwargs['inventory_id']
     stale = kwargs.get('stale', False)
     try:
         system = (SystemPlatform.select(
             SystemPlatform.last_evaluation,
             SystemPlatform.advisor_evaluated, SystemPlatform.opt_out,
             SystemPlatform.last_upload, SystemPlatform.stale).join(
                 RHAccount,
                 on=(SystemPlatform.rh_account_id == RHAccount.id)).where(
                     SystemPlatform.inventory_id == inventory_id).where(
                         RHAccount.name == connexion.context['user']).where(
                             SystemPlatform.stale == stale).get())
     except DoesNotExist:
         raise ApplicationException(
             'inventory_id must exist and inventory_id must be visible to user',
             404)
     return {
         'data': {
             'last_evaluation': system.last_evaluation,
             'rules_evaluation': system.advisor_evaluated,
             'opt_out': system.opt_out,
             'last_upload': system.last_upload,
             'stale': system.stale
         }
     }
    def handle_patch(cls, **kwargs):
        """Bulk/single system change of opt_out status"""

        args_desc = [{
            'arg_name': 'opt_out',
            'convert_func': None
        }, {
            'arg_name': 'inventory_id',
            'convert_func': parse_str_or_list
        }]
        args = cls._parse_arguments(kwargs['data'], args_desc)

        opt_out = args['opt_out']
        system_list = args['inventory_id']

        update = (SystemPlatform.update(opt_out=opt_out).where(
            ((RHAccount.select(RHAccount.id).where(
                RHAccount.name == connexion.context['user']).get()
              ).id == SystemPlatform.rh_account_id)
            & (SystemPlatform.inventory_id << system_list)).returning(
                SystemPlatform))
        updated = []
        for system in update.execute():
            updated.append(system.inventory_id)
        if not updated:
            raise ApplicationException(
                'inventory_id must exist and inventory_id must be visible to user',
                404)
        return {'updated': updated}
 def handle_patch(cls, **kwargs):
     """Update the 'status' field for a system/cve combination"""
     data = kwargs['data']
     in_inventory_id = data['inventory_id']
     in_cve = data['cve']
     in_status_id = data['status_id']
     LOGGER.debug('SYSID [%s] CVE [%s] STATUS-ID [%s] ACCT [%s]',
                  in_inventory_id, in_cve, in_status_id, connexion.context['user'])
     try:
         plat = (SystemPlatform.select(SystemPlatform.inventory_id)
                 .where((SystemPlatform.rh_account == connexion.context['user']) &
                        (SystemPlatform.inventory_id == in_inventory_id) &
                        (SystemPlatform.opt_out == False)))  # pylint: disable=singleton-comparison
         if cls.hide_satellite_managed():
             plat = plat.where(SystemPlatform.satellite_managed == False)  # pylint: disable=singleton-comparison
         vuln = (SystemVulnerabilities.update(status_id=in_status_id)
                 .from_(plat)
                 .where((SystemVulnerabilities.inventory_id == in_inventory_id) &
                        (SystemVulnerabilities.cve == in_cve)))
         rows_modified = vuln.execute()
         if rows_modified == 0:
             # 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, ValueError, psycopg2IntegrityError) as integ_error:
         # usually means bad-status-id
         DB.rollback()
         return cls.format_exception(str(integ_error), 500)
     return ''
Exemplo n.º 10
0
 def _id_query(query_args):
     return (SystemPlatform.select(SystemPlatform.inventory_id, ).join(
         RHAccount,
         on=(RHAccount.id == SystemPlatform.rh_account_id)).where(
             RHAccount.name == query_args['rh_account_number']).where(
                 SystemPlatform.last_evaluation.is_null(False)
                 | SystemPlatform.advisor_evaluated.is_null(False)).where(
                     SystemPlatform.when_deleted.is_null(True)).dicts())
Exemplo n.º 11
0
def get_system_count(rh_account):
    """Get count of nonstale, nonoptouted, evaluated user systems"""
    # pylint: disable=singleton-comparison
    return SystemPlatform.select(fn.COUNT(SystemPlatform.id).alias('count')) \
                         .where((SystemPlatform.rh_account_id == rh_account)
                                & ((SystemPlatform.last_evaluation.is_null(False)) | (SystemPlatform.advisor_evaluated.is_null(False)))
                                & ((SystemPlatform.opt_out == False) & (SystemPlatform.stale == False) & (SystemPlatform.when_deleted.is_null(True)))) \
                         .first().count  # noqa: E712
 def _account_exists(cls, account):
     if account is None:
         raise ApplicationException("invalid account_id", 400)
     systems = (SystemPlatform.select().join(
         RHAccount,
         on=(SystemPlatform.rh_account_id == RHAccount.id)).where(
             RHAccount.name == account))
     if not systems.exists():
         raise ApplicationException("account_id must exist", 404)
    def handle_get(cls, **kwargs):
        """Gets affected CVEs for a system"""
        inventory_id = kwargs['inventory_id']
        args_desc = [{'arg_name': 'cvss_from', 'convert_func': None},
                     {'arg_name': 'cvss_to', 'convert_func': None},
                     {'arg_name': 'public_from', 'convert_func': dateutil.parser.parse},
                     {'arg_name': 'public_to', 'convert_func': dateutil.parser.parse},
                     {'arg_name': 'impact', 'convert_func': parse_int_list},
                     {'arg_name': 'status_id', 'convert_func': parse_int_list},
                     {'arg_name': 'business_risk_id', 'convert_func': parse_int_list},
                     {'arg_name': 'stale', 'convert_func': None}
                     ]
        args = cls._parse_arguments(kwargs, args_desc)
        list_arguments = cls._parse_list_arguments(kwargs)

        # check if system was evaluated
        try:
            system = (SystemPlatform.select(
                SystemPlatform.last_evaluation, SystemPlatform.opt_out)
                      .join(RHAccount, on=(SystemPlatform.rh_account_id == RHAccount.id))
                      .where(SystemPlatform.inventory_id == inventory_id)
                      .where(RHAccount.name == connexion.context['user'])
                      .get())
        except DoesNotExist:
            raise ApplicationException('inventory_id must exist and inventory_id must be visible to user', 404)
        if system.last_evaluation is None:
            raise ApplicationException('inventory_id exists but is not evaluated', 404)

        cves_view = SystemCvesView(list_arguments, {"rh_account_number": connexion.context['user'],
                                                    'inventory_id': inventory_id}, args, args, connexion.request.path)

        response = {}
        result = []
        for cve in cves_view:
            record = {}
            record['synopsis'] = cve['cve_name']
            record['public_date'] = cve['public_date'].isoformat() if cve['public_date'] else None
            record['impact'] = cve['impact']
            record['description'] = cve['cve_description']
            # Store everything we know about CVSS - maybe UI needs to decide what to show
            record['cvss2_score'] = str(cve['cvss2_score']) if cve['cvss2_score'] is not None else None
            record['cvss3_score'] = str(cve['cvss3_score']) if cve['cvss3_score'] is not None else None
            # Store status information
            record['cve_status_id'] = cve['cve_status_id']
            record['status_id'] = cve['status_id']
            record['status'] = cve['status_name']
            record['status_text'] = cve['status_text']
            record['business_risk'] = cve['business_risk']
            record['business_risk_id'] = cve['business_risk_id']
            record['business_risk_text'] = cve['business_risk_text']

            result.append({'type': 'cve', 'id': cve['cve_name'], 'attributes': record})
        response['meta'] = cves_view.get_metadata()
        response['meta']['opt_out'] = system.opt_out
        response['links'] = cves_view.get_pagination_links()
        response['data'] = cls._format_data(list_arguments["data_format"], result)
        return response
Exemplo n.º 14
0
    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, in_cve_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)))  # noqa: E712
            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((SystemVulnerabilities.system_id << systems) &
                                           (SystemVulnerabilities.cve_id <<
                                            (CveMetadata.select(CveMetadata.id).where(
                                                CveMetadata.cve << status_cve_list))))
                                    .returning(SystemVulnerabilities.id))
                rows_modified.update([row.id for row in status_id_update])

            cls._update_divergent_status_count(in_cve_list, rh_account[0].id)

            for status_text, status_cve_list in status_text_to_cves_map.items():
                status_text_update = (SystemVulnerabilities.update(status_text=status_text)
                                      .where((SystemVulnerabilities.system_id << systems) &
                                             (SystemVulnerabilities.cve_id <<
                                              (CveMetadata.select(CveMetadata.id).where(
                                                  CveMetadata.cve << status_cve_list))))
                                      .returning(SystemVulnerabilities.id))
                rows_modified.update([row.id for row in status_text_update])

            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))
                               .dicts())
            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 handle_patch(cls, **kwargs):
     """Logic of the opt out feature"""
     inventory_id = kwargs['inventory_id']
     value = kwargs['value']
     update = (SystemPlatform.update(opt_out=value)
               .where(((RHAccount.select(RHAccount.id)
                        .where(RHAccount.name == connexion.context['user'])
                        .get()).id == SystemPlatform.rh_account_id) &
                      (SystemPlatform.inventory_id == inventory_id)))
     rows_affected = update.execute()
     if rows_affected == 0:
         raise ApplicationException('inventory_id must exist and inventory_id must be visible to user', 404)
Exemplo n.º 16
0
    def _id_query(rh_account_id, list_args):
        selectables = [SystemPlatform.inventory_id, SystemPlatform.opt_out]

        # pylint: disable=singleton-comparison
        if list_args["sort"] and "cve_count" in list_args["sort"]:
            selectables.append(
                Case(None, (((SystemPlatform.opt_out
                              == False), SystemPlatform.cve_count_cache), ),
                     None).alias("cve_count"))

        query = (SystemPlatform.select(*selectables).where(
            SystemPlatform.rh_account_id == rh_account_id).where(
                SystemPlatform.last_evaluation.is_null(False)
                | SystemPlatform.advisor_evaluated.is_null(False)).where(
                    SystemPlatform.when_deleted.is_null(True)).dicts())

        return query
Exemplo n.º 17
0
 def _full_query(query_args):
     return (SystemPlatform.select(
         SystemPlatform.inventory_id,
         SystemPlatform.display_name,
         SystemPlatform.last_evaluation,
         SystemPlatform.advisor_evaluated.alias('rules_evaluation'),
         SystemPlatform.opt_out,
         SystemPlatform.cve_count_cache.alias("cve_count"),
         SystemPlatform.last_upload,
         SystemPlatform.stale_timestamp,
         SystemPlatform.stale_warning_timestamp,
     ).join(
         RHAccount,
         on=(RHAccount.id == SystemPlatform.rh_account_id)).where(
             RHAccount.name == query_args['rh_account_number']).where(
                 SystemPlatform.last_evaluation.is_null(False)
                 | SystemPlatform.advisor_evaluated.is_null(False)).where(
                     SystemPlatform.when_deleted.is_null(True)).dicts())
Exemplo n.º 18
0
 def handle_patch(cls, **kwargs):
     """Logic of the opt out feature"""
     inventory_id = kwargs['inventory_id']
     value = kwargs['value']
     try:
         account = (RHAccount.select(RHAccount.id).where(
             RHAccount.name == connexion.context['user']).get())
     except DoesNotExist as exc:
         raise ApplicationException('user does not exist', 403) from exc
     update = (SystemPlatform.update(opt_out=value).where(
         (account.id == SystemPlatform.rh_account_id)
         & (SystemPlatform.inventory_id == inventory_id)
         & (SystemPlatform.when_deleted.is_null(True))))
     rows_affected = update.execute()
     if rows_affected == 0:
         raise ApplicationException(
             'inventory_id must exist and inventory_id must be visible to user',
             404)
 def __init__(self, list_args, query_args, filter_args, parsed_args, uri):
     # pylint: disable=singleton-comparison
     query = (SystemPlatform.select(
         SystemPlatform.inventory_id,
         SystemPlatform.display_name,
         SystemPlatform.last_evaluation,
         SystemPlatform.advisor_evaluated.alias('rules_evaluation'),
         SystemPlatform.opt_out,
         SystemPlatform.cve_count_cache.alias("cve_count"),
         SystemPlatform.last_upload,
         SystemPlatform.stale_timestamp,
         SystemPlatform.stale_warning_timestamp,
     ).join(
         RHAccount,
         on=(RHAccount.id == SystemPlatform.rh_account_id)).where(
             RHAccount.name == query_args['rh_account_number']).where(
                 SystemPlatform.last_evaluation.is_null(False)
                 | SystemPlatform.advisor_evaluated.is_null(False)).dicts())
     if 'opt_out' in filter_args and filter_args['opt_out']:
         query = query.where(
             SystemPlatform.opt_out == filter_args['opt_out'])
     else:
         query = query.where(SystemPlatform.opt_out == False)  # noqa: E712
     if 'stale' in filter_args and filter_args['stale']:
         query = query.where(SystemPlatform.stale == filter_args['stale'])
     else:
         query = query.where(SystemPlatform.stale == False)  # noqa: E712
     if 'uuid' in filter_args and filter_args['uuid']:
         query = query.where(
             SystemPlatform.inventory_id.contains(filter_args['uuid']))
     sortable_columns = {
         'id': SystemPlatform.id,
         'cve_count': SystemPlatform.cve_count_cache,
         'inventory_id': SystemPlatform.inventory_id,
         'last_evaluation': SystemPlatform.last_evaluation,
         'last_upload': SystemPlatform.last_upload,
         'display_name': SystemPlatform.display_name,
         'rules_evaluation': SystemPlatform.advisor_evaluated
     }
     default_sort_columns = ['-last_upload', 'id']
     filterable_columns = {'display_name': SystemPlatform.display_name}
     super(SystemView,
           self).__init__(query, sortable_columns, default_sort_columns,
                          filterable_columns, list_args, parsed_args, uri)
Exemplo n.º 20
0
    def handle_patch(cls, **kwargs):
        """Bulk/single system change of opt_out status"""
        opt_out = kwargs['data']['opt_out']
        system_list = kwargs['data']['inventory_id']
        if isinstance(system_list, str):
            system_list = [system_list]

        update = (SystemPlatform.update(opt_out=opt_out).where(
            ((RHAccount.select(RHAccount.id).where(
                RHAccount.name == connexion.context['user']).get()
              ).id == SystemPlatform.rh_account_id)
            & (SystemPlatform.inventory_id << system_list)).returning(
                SystemPlatform))
        updated = []
        for system in update.execute():
            updated.append(system.inventory_id)
        if not updated:
            raise ApplicationException(
                'inventory_id must exist and inventory_id must be visible to user',
                404)
        return {'updated': updated}
Exemplo n.º 21
0
def get_system_count(rh_account,
                     include_cyndi=True,
                     filters=None,
                     filters_args=None):
    """Get count of nonstale, nonoptouted, evaluated user systems"""
    # pylint: disable=singleton-comparison
    query = SystemPlatform.select(fn.COUNT(SystemPlatform.id).alias('count'))\
        .where((SystemPlatform.rh_account_id == rh_account)
               & ((SystemPlatform.last_evaluation.is_null(False)) | (SystemPlatform.advisor_evaluated.is_null(False)))
               & ((SystemPlatform.opt_out == False) & (SystemPlatform.stale == False) & (SystemPlatform.when_deleted.is_null(True))))

    if include_cyndi:
        query = query.join(
            InventoryHosts,
            JOIN.INNER,
            on=(SystemPlatform.inventory_id == InventoryHosts.id))

    if filters:
        query = apply_filters(query, filters_args, filters, {})

    return query.first().count
Exemplo n.º 22
0
 def __init__(self, list_args, query_args, filter_args, parsed_args, uri):
     query = (SystemPlatform.select(
         SystemPlatform.inventory_id, SystemPlatform.satellite_managed,
         SystemPlatform.last_evaluation, SystemPlatform.opt_out,
         SystemPlatform.cve_count_cache.alias("cve_count")).where(
             SystemPlatform.rh_account ==
             query_args['rh_account_number']).where(
                 SystemPlatform.last_evaluation.is_null(False)).dicts())
     if query_args['hide_satellite_managed']:
         query = query.where(SystemPlatform.satellite_managed == False)  # pylint: disable=singleton-comparison
     if 'opt_out' in filter_args and filter_args['opt_out']:
         query = query.where(
             SystemPlatform.opt_out == filter_args['opt_out'])
     else:
         query = query.where(SystemPlatform.opt_out == False)  # pylint: disable=singleton-comparison
     sortable_columns = {
         'cve_count': SystemPlatform.cve_count_cache,
         'inventory_id': SystemPlatform.inventory_id,
         'last_evaluation': SystemPlatform.last_evaluation
     }
     filterable_columns = {'inventory_id': SystemPlatform.inventory_id}
     super(SystemView,
           self).__init__(query, sortable_columns, filterable_columns,
                          list_args, parsed_args, uri)
Exemplo n.º 23
0
    def handle_get(cls, **kwargs):  # pylint: disable=too-many-statements
        """Gets affected CVEs for a system"""
        inventory_id = kwargs['inventory_id']
        args_desc = [{'arg_name': 'cvss_from', 'convert_func': None},
                     {'arg_name': 'cvss_to', 'convert_func': None},
                     {'arg_name': 'public_from', 'convert_func': dateutil.parser.parse},
                     {'arg_name': 'public_to', 'convert_func': dateutil.parser.parse},
                     {'arg_name': 'impact', 'convert_func': parse_int_list},
                     {'arg_name': 'status_id', 'convert_func': parse_int_list},
                     {'arg_name': 'business_risk_id', 'convert_func': parse_int_list},
                     {'arg_name': 'security_rule', 'convert_func': None},
                     {'arg_name': 'rule_presence', 'convert_func': unique_bool_list},
                     {'arg_name': 'show_advisories', 'convert_func': None},
                     {'arg_name': 'advisory', 'convert_func': None}]
        args = cls._parse_arguments(kwargs, args_desc)
        list_arguments = cls._parse_list_arguments(kwargs)

        # check if system was evaluated
        try:
            system = (SystemPlatform.select(
                SystemPlatform.last_evaluation, SystemPlatform.advisor_evaluated, SystemPlatform.opt_out)
                      .join(RHAccount, on=(SystemPlatform.rh_account_id == RHAccount.id))
                      .where(SystemPlatform.inventory_id == inventory_id)
                      .where(RHAccount.name == connexion.context['user'])
                      .where(SystemPlatform.when_deleted.is_null(True))
                      .get())
        except DoesNotExist:
            raise ApplicationException('inventory_id must exist and inventory_id must be visible to user', 404)
        if system.last_evaluation is None and system.advisor_evaluated is None:
            raise ApplicationException('inventory_id exists but is not evaluated', 404)

        cves_view = SystemCvesView(list_arguments, {"rh_account_number": connexion.context['user'],
                                                    'inventory_id': inventory_id}, args, args, connexion.request.path, cls._ids_only)

        patch_access = None
        cve_advisories = {}
        cve_advisories_filtered = {}
        if 'show_advisories' in args and args['show_advisories'] is True:
            cve_names = []
            for cve in cves_view:
                cve_names.append(cve['cve_name'])
            cve_advisories, patch_access = cls._get_advisories_per_cve(cve_names, inventory_id)
            if 'advisory' in args and args['advisory']:
                cve_advisories_filtered = {cve: advisories for cve, advisories in cve_advisories.items() if args['advisory'] in advisories}

        response = {}
        result = []
        if not cls._ids_only:
            for cve in cves_view:
                if 'advisory' in args and args['advisory']:
                    if cve['cve_name'] in cve_advisories_filtered:
                        record = cls._build_attributes(cve, cve_advisories_filtered)
                        result.append({'type': 'cve', 'id': cve['cve_name'], 'attributes': record})
                else:
                    record = cls._build_attributes(cve, cve_advisories)
                    result.append({'type': 'cve', 'id': cve['cve_name'], 'attributes': record})
        else:
            for cve in cves_view:
                result.append(cve['cve_name'])
        response['meta'] = cves_view.get_metadata()
        response['meta']['opt_out'] = system.opt_out
        response['meta']['patch_access'] = patch_access
        response['links'] = cves_view.get_pagination_links()
        response['data'] = cls._format_data(list_arguments["data_format"], result)
        return response
Exemplo n.º 24
0
    def handle_get(cls, **kwargs):
        # pylint: disable=singleton-comparison
        cve_count_by_severity = []
        retval = {
            'system_count': 0,
            'cves_total': 0,
            'cves_by_severity': {
                '0to3.9': {
                    'percentage': 0,
                    'count': 0
                },
                '4to7.9': {
                    'percentage': 0,
                    'count': 0
                },
                '8to10': {
                    'percentage': 0,
                    'count': 0
                }
            },
            'recent_cves': {
                'last7days': 0,
                'last30days': 0,
                'last90days': 0
            },
            'top_cves': []
        }
        rh_account = RHAccount.select(RHAccount.id).where(RHAccount.name == connexion.context['user']).first()
        if rh_account is None:
            return retval
        rh_account = rh_account.id
        retval['system_count'] = SystemPlatform.select(fn.COUNT(SystemPlatform.id).alias('count')).where(
            (SystemPlatform.rh_account_id == rh_account) & (SystemPlatform.last_evaluation.is_null(False))
            & (SystemPlatform.opt_out == False)).first().count  # noqa: E712
        if retval['system_count'] == 0:
            return retval
        cves_total = CveAccountData.select(CveAccountData.cve_id).where((CveAccountData.rh_account_id == rh_account) & (CveAccountData.systems_affected > 0))
        if cves_total.count() == 0:
            return retval
        retval['cves_total'] = cves_total.count()
        cve_details = CveMetadata.select(fn.COALESCE(CveMetadata.cvss3_score, CveMetadata.cvss2_score).alias('cvss'),
                                         CveMetadata.public_date).where(CveMetadata.id << cves_total)
        retval['cves_by_severity']['0to3.9']['count'] = cve_details.select_from(fn.COUNT('*').alias('count')).where(cve_details.c.cvss < 4).first().count
        retval['cves_by_severity']['4to7.9']['count'] = cve_details.select_from(
            fn.COUNT('*').alias('count')).where((cve_details.c.cvss >= 4) & (cve_details.c.cvss < 8)).first().count
        retval['cves_by_severity']['8to10']['count'] = cve_details.select_from(fn.COUNT('*').alias('count')).where(cve_details.c.cvss >= 8).first().count

        cve_count_by_severity = [v['count'] for v in retval['cves_by_severity'].values()]

        rounded_percentage = round_to_100_percent(cve_count_by_severity)

        for indx, keys in enumerate(retval['cves_by_severity']):
            retval['cves_by_severity'][keys]['percentage'] = rounded_percentage[indx]

        today = datetime.utcnow().date()
        retval['recent_cves']['last7days'] = cve_details.select_from(
            fn.COUNT('*').alias('count')).where(cve_details.c.public_date >= (today - timedelta(days=7))).first().count
        retval['recent_cves']['last30days'] = cve_details.select_from(
            fn.COUNT('*').alias('count')).where(cve_details.c.public_date >= (today - timedelta(days=30))).first().count
        retval['recent_cves']['last90days'] = cve_details.select_from(
            fn.COUNT('*').alias('count')).where(cve_details.c.public_date >= (today - timedelta(days=90))).first().count
        top_cves = CveMetadata.select(CveMetadata.cve, CveMetadata.cvss3_score, CveMetadata.cvss2_score, CveMetadata.description,
                                      CveAccountData.systems_affected).join(CveAccountData, on=(CveMetadata.id == CveAccountData.cve_id)).where(
                                          (CveAccountData.rh_account_id == rh_account) & (CveAccountData.systems_affected > 0)).order_by(
                                              CveAccountData.systems_affected.desc(),
                                              fn.COALESCE(CveMetadata.cvss3_score, CveMetadata.cvss2_score).desc(nulls='LAST'),
                                              CveMetadata.id).limit(3)
        for cve in top_cves:
            cve_dict = {}
            cve_dict['synopsis'] = cve.cve
            cve_dict['cvss2_score'] = str(cve.cvss2_score)
            cve_dict['cvss3_score'] = str(cve.cvss3_score)
            cve_dict['description'] = cve.description
            cve_dict['systems_affected'] = cve.cveaccountdata.systems_affected
            retval['top_cves'].append(cve_dict)
        return retval
Exemplo n.º 25
0
"""
import math

from common.peewee_model import SystemPlatform
from manager.base import InvalidArgumentException
from manager.list_view import ListView

from .vuln_testcase import FlaskTestCase

SORTABLE = {
    'inventory_id': SystemPlatform.inventory_id,
    'vmaas_json': SystemPlatform.vmaas_json,
    'last_evaluation': SystemPlatform.last_evaluation
}
FILTERABLE = {}
QUERY = (SystemPlatform.select(SystemPlatform.inventory_id))
URI = 'http://localhost:6666/api/v1/vulnerability/systems'

TOTAL_ITEMS = 127
LIMIT = 5
LIST_ARGS = {
    'page': 4,
    'page_size': 5,
    'pages': 66,
    'opt_out': 'foo',
    'limit': LIMIT,
    'offset': 15,
    'total_items': TOTAL_ITEMS
}

QUERY_ARGS = {
Exemplo n.º 26
0
    def handle_get(cls, **kwargs):  # pylint: disable=too-many-statements,too-many-branches
        """Gets affected CVEs for a system"""
        inventory_id = kwargs['inventory_id']
        args_desc = [
            {
                'arg_name': 'cvss_from',
                'convert_func': None
            },
            {
                'arg_name': 'cvss_to',
                'convert_func': None
            },
            {
                'arg_name': 'public_from',
                'convert_func': dateutil.parser.parse
            },
            {
                'arg_name': 'public_to',
                'convert_func': dateutil.parser.parse
            },
            {
                'arg_name': 'impact',
                'convert_func': parse_int_list
            },
            {
                'arg_name': 'status_id',
                'convert_func': parse_int_list
            },
            {
                'arg_name': 'business_risk_id',
                'convert_func': parse_int_list
            },
            {
                'arg_name': 'rule_presence',
                'convert_func': unique_bool_list
            },
            {
                'arg_name': 'show_advisories',
                'convert_func': None
            },
            {
                'arg_name': 'advisory',
                'convert_func': None
            },
            {
                'arg_name': 'rule_key',
                'convert_func': None
            },
            {
                'arg_name': 'known_exploit',
                'convert_func': unique_bool_list
            },
            {
                'arg_name': 'first_reported_from',
                'convert_func': dateutil.parser.parse
            },
            {
                'arg_name': 'first_reported_to',
                'convert_func': dateutil.parser.parse
            },
            {
                'arg_name': 'advisory_available',
                'convert_func': unique_bool_list
            },
            {
                'arg_name': 'remediation',
                'convert_func': parse_int_list
            },
        ]

        args = cls._parse_arguments(kwargs, args_desc)
        list_arguments = cls._parse_list_arguments(kwargs)

        # check if advisory parameter comes with show_advisories parameter
        if 'advisory' in args and args['advisory'] and (
                'show_advisories' not in args or not args['show_advisories']):
            raise ApplicationException(
                "Advisory parameter shouldn't be used without show_advisories parameter",
                400)

        # check if system was evaluated
        try:
            system = (SystemPlatform.select(
                SystemPlatform.last_evaluation,
                SystemPlatform.advisor_evaluated, SystemPlatform.opt_out).join(
                    RHAccount,
                    on=(SystemPlatform.rh_account_id == RHAccount.id)).
                      where(SystemPlatform.inventory_id == inventory_id).where(
                          RHAccount.name == connexion.context['user']).where(
                              SystemPlatform.when_deleted.is_null(True)).get())
        except DoesNotExist as exc:
            raise ApplicationException(
                'inventory_id must exist and inventory_id must be visible to user',
                404) from exc
        if system.last_evaluation is None and system.advisor_evaluated is None:
            raise ApplicationException(
                'inventory_id exists but is not evaluated', 404)

        rh_account_id, _, _ = get_account_data(connexion.context['user'])

        cve_advisories = {}
        patch_access = None
        if 'show_advisories' in args and args[
                'show_advisories'] and 'advisory' in args and args['advisory']:
            raw_cve_names = (SystemVulnerabilities.select(
                CveMetadata.cve.alias('cve_name'), ).join(
                    SystemPlatform,
                    on=(SystemVulnerabilities.system_id == SystemPlatform.id)
                ).join(
                    CveMetadata,
                    on=(SystemVulnerabilities.cve_id == CveMetadata.id)).join(
                        CveAccountData,
                        JOIN.LEFT_OUTER,
                        on=((CveAccountData.cve_id == CveMetadata.id)
                            & (CveAccountData.rh_account_id == rh_account_id))
                    ).where(
                        SystemVulnerabilities.rh_account_id == rh_account_id
                    ).where(
                        SystemPlatform.inventory_id == inventory_id)).dicts()
            cve_names = [cve['cve_name'] for cve in raw_cve_names]
            # get advisory data from PATCH
            cve_advisories, patch_access = cls._get_advisories_per_cve(
                cve_names, inventory_id, adv=args['advisory'])
            # filter advisories by advisory name
            cve_advisories = filter_by_advisory(args['advisory'],
                                                cve_advisories)

            cves_view = SystemCvesView(rh_account_id, list_arguments,
                                       {'inventory_id': inventory_id}, args,
                                       args, connexion.request.path,
                                       cls._ids_only, cve_advisories)
            cves = list(cves_view)
        elif 'show_advisories' in args and args['show_advisories'] and (
                'advisory' not in args or not args['advisory']):
            cves_view = SystemCvesView(rh_account_id, list_arguments,
                                       {'inventory_id': inventory_id}, args,
                                       args, connexion.request.path,
                                       cls._ids_only)
            cves = list(cves_view)
            cve_names = [
                cve['cve_name'] if not cls._ids_only else cve['id']
                for cve in cves
            ]
            # get advisory data from PATCH
            cve_advisories, patch_access = cls._get_advisories_per_cve(
                cve_names, inventory_id)
        else:
            cves_view = SystemCvesView(rh_account_id, list_arguments,
                                       {'inventory_id': inventory_id}, args,
                                       args, connexion.request.path,
                                       cls._ids_only)
            cves = list(cves_view)

        response = {}
        result = []
        if not cls._ids_only:
            for cve in cves:
                if 'show_advisories' in args and args['show_advisories']:
                    record = cls._build_attributes(
                        cve, cve_advisories.get(cve['cve_name'], []))
                    result.append({
                        'type': 'cve',
                        'id': cve['cve_name'],
                        'attributes': record
                    })
                else:
                    record = cls._build_attributes(cve)
                    result.append({
                        'type': 'cve',
                        'id': cve['cve_name'],
                        'attributes': record
                    })
        else:
            result = cves

        response['meta'] = cves_view.get_metadata()
        response['meta'][
            'patch_access'] = patch_access.status if patch_access else None
        response['links'] = cves_view.get_pagination_links()
        response['data'] = cls._format_data(list_arguments["data_format"],
                                            result)
        return response
Exemplo n.º 27
0
    def handle_get(cls, **kwargs):
        # pylint: disable=singleton-comparison
        retval = {
            'system_count': 0,
            'cves_total': 0,
            'cves_by_severity': {
                '0to3.9': {
                    'percentage': 0,
                    'count': 0
                },
                '4to7.9': {
                    'percentage': 0,
                    'count': 0
                },
                '8to10': {
                    'percentage': 0,
                    'count': 0
                }
            },
            'recent_cves': {
                'last7days': 0,
                'last30days': 0,
                'last90days': 0
            },
            'top_cves': []
        }
        rh_account = RHAccount.select(RHAccount.id).where(RHAccount.name == connexion.context['user']).first()
        if rh_account is None:
            return retval
        rh_account = rh_account.id
        retval['system_count'] = SystemPlatform.select(fn.COUNT(SystemPlatform.id).alias('count')).where(
            (SystemPlatform.rh_account_id == rh_account) & ((SystemPlatform.last_evaluation.is_null(False)) | (SystemPlatform.advisor_evaluated.is_null(False)))
            & ((SystemPlatform.opt_out == False) & (SystemPlatform.stale == False))).first().count  # noqa: E712
        if retval['system_count'] == 0:
            return retval
        cves_total = CveAccountData.select(CveAccountData.cve_id).where((CveAccountData.rh_account_id == rh_account) & (CveAccountData.systems_affected > 0))
        if cves_total.count() == 0:
            return retval
        retval['cves_total'] = cves_total.count()
        cve_details = CveMetadata.select(fn.COALESCE(CveMetadata.cvss3_score, CveMetadata.cvss2_score).alias('cvss'),
                                         CveMetadata.public_date).where(CveMetadata.id << cves_total)
        retval['cves_by_severity']['0to3.9']['count'] = cve_details.select_from(fn.COUNT('*').alias('count')).where(cve_details.c.cvss < 4).first().count
        retval['cves_by_severity']['4to7.9']['count'] = cve_details.select_from(
            fn.COUNT('*').alias('count')).where((cve_details.c.cvss >= 4) & (cve_details.c.cvss < 8)).first().count
        retval['cves_by_severity']['8to10']['count'] = cve_details.select_from(fn.COUNT('*').alias('count')).where(cve_details.c.cvss >= 8).first().count

        cve_count_by_severity = [v['count'] for v in retval['cves_by_severity'].values()]

        rounded_percentage = round_to_100_percent(cve_count_by_severity)

        for indx, keys in enumerate(retval['cves_by_severity']):
            retval['cves_by_severity'][keys]['percentage'] = rounded_percentage[indx]

        today = datetime.utcnow().date()
        retval['recent_cves']['last7days'] = cve_details.select_from(
            fn.COUNT('*').alias('count')).where(cve_details.c.public_date >= (today - timedelta(days=7))).first().count
        retval['recent_cves']['last30days'] = cve_details.select_from(
            fn.COUNT('*').alias('count')).where(cve_details.c.public_date >= (today - timedelta(days=30))).first().count
        retval['recent_cves']['last90days'] = cve_details.select_from(
            fn.COUNT('*').alias('count')).where(cve_details.c.public_date >= (today - timedelta(days=90))).first().count

        # The algorithm searches for CVEs with cvss score between 8 and 10, and then sort by a number of affected
        # systems if there are not 3 CVE in the 8 to 10 range, then it looks for CVEs in 4 to 8 range, sorted by a
        # number of systems affected. The high-end range check is exclusive that is why 11 here.
        cves_limit = 3
        top_cves = cls._get_top_cves_by_cvss(8.0, 11, rh_account, limit=cves_limit)
        cls._build_top_cves(top_cves, retval)
        cves_count = top_cves.count()
        if cves_count < cves_limit:
            next_tier_top = cls._get_top_cves_by_cvss(4.0, 8.0, rh_account, limit=cves_limit-cves_count)
            cls._build_top_cves(next_tier_top, retval)
            next_cves_count = next_tier_top.count()
            if next_cves_count < (cves_limit - cves_count):
                last_tier_top = cls._get_top_cves_by_cvss(0.0, 4.0, rh_account, limit=cves_limit-(cves_count+next_cves_count))
                cls._build_top_cves(last_tier_top, retval)

        return retval
Exemplo n.º 28
0
    def handle_get(cls, **kwargs):
        """Gets affected CVEs for a system"""
        inventory_id = kwargs['inventory_id']
        args_desc = [{
            'arg_name': 'cvss_from',
            'convert_func': None
        }, {
            'arg_name': 'cvss_to',
            'convert_func': None
        }, {
            'arg_name': 'public_from',
            'convert_func': dateutil.parser.parse
        }, {
            'arg_name': 'public_to',
            'convert_func': dateutil.parser.parse
        }, {
            'arg_name': 'impact',
            'convert_func': parse_int_list
        }, {
            'arg_name': 'status_id',
            'convert_func': parse_int_list
        }, {
            'arg_name': 'business_risk_id',
            'convert_func': parse_int_list
        }, {
            'arg_name': 'security_rule',
            'convert_func': None
        }, {
            'arg_name': 'rule_presence',
            'convert_func': unique_bool_list
        }]
        args = cls._parse_arguments(kwargs, args_desc)
        list_arguments = cls._parse_list_arguments(kwargs)

        # check if system was evaluated
        try:
            system = (SystemPlatform.select(
                SystemPlatform.last_evaluation,
                SystemPlatform.advisor_evaluated, SystemPlatform.opt_out).join(
                    RHAccount,
                    on=(SystemPlatform.rh_account_id == RHAccount.id)).
                      where(SystemPlatform.inventory_id == inventory_id).where(
                          RHAccount.name == connexion.context['user']).where(
                              SystemPlatform.when_deleted.is_null(True)).get())
        except DoesNotExist:
            raise ApplicationException(
                'inventory_id must exist and inventory_id must be visible to user',
                404)
        if system.last_evaluation is None and system.advisor_evaluated is None:
            raise ApplicationException(
                'inventory_id exists but is not evaluated', 404)

        cves_view = SystemCvesView(
            list_arguments, {
                "rh_account_number": connexion.context['user'],
                'inventory_id': inventory_id
            }, args, args, connexion.request.path, cls._ids_only)

        response = {}
        result = []
        if not cls._ids_only:
            for cve in cves_view:
                record = {}
                record['synopsis'] = cve['cve_name']
                record['public_date'] = cve['public_date'].isoformat(
                ) if cve['public_date'] else None
                record['impact'] = cve['impact']
                record['description'] = cve['cve_description']
                # Store everything we know about CVSS - maybe UI needs to decide what to show
                record['cvss2_score'] = str(
                    cve['cvss2_score']
                ) if cve['cvss2_score'] is not None else None
                record['cvss3_score'] = str(
                    cve['cvss3_score']
                ) if cve['cvss3_score'] is not None else None
                # Store status information
                record['cve_status_id'] = cve['cve_status_id']
                record['status_id'] = cve['status_id']
                record['status'] = cve['status_name']
                record['status_text'] = cve['status_text']
                record['cve_status_text'] = cve['cve_status_text']
                record['business_risk'] = cve['business_risk']
                record['business_risk_id'] = cve['business_risk_id']
                record['business_risk_text'] = cve['business_risk_text']
                record['reporter'] = (
                    reporter.VMAAS.value if not cve['when_mitigated'] else
                    0) | (reporter.RULE.value if cve['rule_active'] else 0)
                if cve['rule_active']:
                    record['rule'] = {
                        'rule_id': cve['rule_id'],
                        'description': cve['description_text'],
                        'summary': cve['summary_text'],
                        'generic': cve['generic_text'],
                        'reboot_required': cve['reboot_required'],
                        'playbook_count': cve['playbook_count'],
                        'change_risk': cve['change_risk'],
                        'kbase_node_id': cve['kbase_node_id'],
                    }
                else:
                    record['rule'] = None

                result.append({
                    'type': 'cve',
                    'id': cve['cve_name'],
                    'attributes': record
                })
        else:
            for cve in cves_view:
                result.append(cve['cve_name'])
        response['meta'] = cves_view.get_metadata()
        response['meta']['opt_out'] = system.opt_out
        response['links'] = cves_view.get_pagination_links()
        response['data'] = cls._format_data(list_arguments["data_format"],
                                            result)
        return response