From 5e7f864e980d82c7278e9760c8f96d6cde47b2b3 Mon Sep 17 00:00:00 2001 From: wenxin Date: Thu, 8 Jun 2023 20:29:19 +0800 Subject: [PATCH] fix issue:paging args validation rules and hp status filter exception (cherry picked from commit cd606acdb7b393b1e91a821476a1bc1847d7cdd1) --- ...fix-hotpatch-status-filter-exception.patch | 145 +++++++++++++++ ...lidation-rules-for-paging-parameters.patch | 175 ++++++++++++++++++ aops-apollo.spec | 8 +- 3 files changed, 327 insertions(+), 1 deletion(-) create mode 100644 0007-fix-hotpatch-status-filter-exception.patch create mode 100644 0008-update-validation-rules-for-paging-parameters.patch diff --git a/0007-fix-hotpatch-status-filter-exception.patch b/0007-fix-hotpatch-status-filter-exception.patch new file mode 100644 index 0000000..4e02029 --- /dev/null +++ b/0007-fix-hotpatch-status-filter-exception.patch @@ -0,0 +1,145 @@ +From 8bfb66a3f9a6e1293b7cc4d72cc02e455be9cea9 Mon Sep 17 00:00:00 2001 +From: rabbitali +Date: Thu, 8 Jun 2023 10:39:45 +0800 +Subject: [PATCH] fix issue: hotpatch status filter exception + +--- + apollo/database/proxy/cve.py | 22 +++++++++++++++------- + apollo/database/proxy/host.py | 22 +++++++++++++++++----- + 2 files changed, 32 insertions(+), 12 deletions(-) + +diff --git a/apollo/database/proxy/cve.py b/apollo/database/proxy/cve.py +index 13a1ae6..24245de 100644 +--- a/apollo/database/proxy/cve.py ++++ b/apollo/database/proxy/cve.py +@@ -187,8 +187,7 @@ class CveMysqlProxy(MysqlProxy): + + cve_id = data["cve_id"] + filters = self._get_cve_hosts_filters(data.get("filter", {})) +- cve_hosts_query = self._query_cve_hosts( +- data["username"], cve_id, filters) ++ cve_hosts_query = self._query_cve_hosts(data["username"], cve_id, filters, data.get("filter", {})) + + total_count = cve_hosts_query.count() + if not total_count: +@@ -238,33 +237,42 @@ class CveMysqlProxy(MysqlProxy): + filters.add(Host.host_group_name.in_(filter_dict["host_group"])) + if filter_dict.get("repo"): + filters.add(Host.repo_name.in_(filter_dict["repo"])) +- if filter_dict.get("hp_status"): +- filters.add(CveHostAssociation.hp_status.in_(filter_dict["hp_status"])) ++ + if filter_dict.get("hotpatch") and fixed is True: + filters.add(CveHostAssociation.fixed_by_hp.in_(filter_dict["hotpatch"])) + elif filter_dict.get("hotpatch") and fixed is False: + filters.add(CveHostAssociation.support_hp.in_(filter_dict["hotpatch"])) + return filters + +- def _query_cve_hosts(self, username, cve_id, filters): ++ def _query_cve_hosts(self, username: str, cve_id: str, filters: set, filter_dict: dict): + """ + query needed cve hosts info + Args: + username (str): user name of the request + cve_id (str): cve id + filters (set): filter given by user +- ++ filter_dict { ++ "fixed": bool, ++ "hotpatch": [true, false], ++ "hp_status": [accepted, active] ++ } + Returns: + sqlalchemy.orm.query.Query + """ + cve_query = self.session.query(Host.host_id, Host.host_name, Host.host_ip, Host.host_group_name, + Host.repo_name, Host.last_scan, CveHostAssociation.support_hp, + CveHostAssociation.fixed, CveHostAssociation.fixed_by_hp, +- CveHostAssociation.hp_status ) \ ++ CveHostAssociation.hp_status) \ + .join(CveHostAssociation, Host.host_id == CveHostAssociation.host_id) \ + .filter(Host.user == username, CveHostAssociation.cve_id == cve_id) \ + .filter(*filters) + ++ if filter_dict.get("fixed"): ++ if filter_dict.get("hotpatch") == [True] and filter_dict.get("hp_status"): ++ return cve_query.filter(CveHostAssociation.hp_status.in_(filter_dict["hp_status"])) ++ elif len(filter_dict.get("hotpatch")) != 1 and filter_dict.get("hp_status"): ++ return cve_query.filter(CveHostAssociation.hp_status.in_(filter_dict["hp_status"]), ++ CveHostAssociation.fixed_by_hp == True).union(cve_query.filter(CveHostAssociation.fixed_by_hp == False)) + return cve_query + + @staticmethod +diff --git a/apollo/database/proxy/host.py b/apollo/database/proxy/host.py +index 3fdf97b..bc30288 100644 +--- a/apollo/database/proxy/host.py ++++ b/apollo/database/proxy/host.py +@@ -475,7 +475,7 @@ class HostProxy(HostMysqlProxy, CveEsProxy): + host_id = data["host_id"] + filters = self._get_host_cve_filters(data.get("filter", {})) + host_cve_query = self._query_host_cve( +- data["username"], host_id, filters) ++ data["username"], host_id, filters, data.get("filter", {})) + + total_count = host_cve_query.count() + if not total_count: +@@ -514,6 +514,8 @@ class HostProxy(HostMysqlProxy, CveEsProxy): + Returns: + set + """ ++ # when fixed does not have a value, the query data is not meaningful ++ # the default query is unfixed CVE information + fixed = filter_dict.get("fixed", False) + filters = {CveHostAssociation.fixed == fixed} + +@@ -525,8 +527,6 @@ class HostProxy(HostMysqlProxy, CveEsProxy): + "%" + filter_dict["cve_id"] + "%")) + if filter_dict.get("severity"): + filters.add(Cve.severity.in_(filter_dict["severity"])) +- if filter_dict.get("hp_status"): +- filters.add(CveHostAssociation.hp_status.in_(filter_dict["hp_status"])) + if filter_dict.get("hotpatch") and fixed is True: + filters.add(CveHostAssociation.fixed_by_hp.in_(filter_dict["hotpatch"])) + elif filter_dict.get("hotpatch") and fixed is False: +@@ -536,17 +536,22 @@ class HostProxy(HostMysqlProxy, CveEsProxy): + filters.add(CveHostAssociation.affected == filter_dict["affected"]) + return filters + +- def _query_host_cve(self, username, host_id, filters): ++ def _query_host_cve(self, username: str, host_id: int, filters: set, filter_dict: dict): + """ + query needed host CVEs info + Args: + username (str): user name of the request + host_id (int): host id + filters (set): filter given by user +- ++ filter_dict { ++ "fixed": bool, ++ "hotpatch": [true, false], ++ "hp_status": [accepted, active] ++ } + Returns: + sqlalchemy.orm.query.Query + """ ++ + host_cve_query = self.session.query(CveHostAssociation.cve_id, Cve.publish_time, Cve.severity, Cve.cvss_score, + CveHostAssociation.fixed, CveHostAssociation.support_hp, + CveHostAssociation.fixed_by_hp, CveHostAssociation.hp_status) \ +@@ -556,6 +561,13 @@ class HostProxy(HostMysqlProxy, CveEsProxy): + .filter(CveHostAssociation.host_id == host_id, Host.user == username) \ + .filter(*filters) + ++ if filter_dict.get("fixed"): ++ if filter_dict.get("hotpatch") == [True] and filter_dict.get("hp_status"): ++ return host_cve_query.filter(CveHostAssociation.hp_status.in_(filter_dict["hp_status"])) ++ ++ elif len(filter_dict.get("hotpatch")) != 1 and filter_dict.get("hp_status"): ++ return host_cve_query.filter(CveHostAssociation.hp_status.in_(filter_dict["hp_status"]), ++ CveHostAssociation.fixed_by_hp == True).union(host_cve_query.filter(CveHostAssociation.fixed_by_hp == False)) + return host_cve_query + + @staticmethod +-- +Gitee + diff --git a/0008-update-validation-rules-for-paging-parameters.patch b/0008-update-validation-rules-for-paging-parameters.patch new file mode 100644 index 0000000..b1284dc --- /dev/null +++ b/0008-update-validation-rules-for-paging-parameters.patch @@ -0,0 +1,175 @@ +From 4ada4a45e7c73e34e73ce4e8a48d434e459063f6 Mon Sep 17 00:00:00 2001 +From: rabbitali +Date: Tue, 6 Jun 2023 16:22:54 +0800 +Subject: [PATCH] update validation rules for paging parameters +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +--- + apollo/function/schema/cve.py | 10 +++------- + apollo/function/schema/host.py | 10 +++------- + apollo/function/schema/task.py | 13 ++++--------- + 3 files changed, 10 insertions(+), 23 deletions(-) + +diff --git a/apollo/function/schema/cve.py b/apollo/function/schema/cve.py +index 6584941..d18e454 100644 +--- a/apollo/function/schema/cve.py ++++ b/apollo/function/schema/cve.py +@@ -18,7 +18,7 @@ Description: For cve related restful interfaces schema + from marshmallow import Schema + from marshmallow import fields + from marshmallow import validate +- ++from vulcanus.restful.serialize.validate import PaginationSchema + + class CveListFilterSchema(Schema): + """ +@@ -31,7 +31,7 @@ class CveListFilterSchema(Schema): + fixed = fields.Boolean(required=True, default=True, validate=validate.OneOf([True, False])) + + +-class GetCveListSchema(Schema): ++class GetCveListSchema(PaginationSchema): + """ + validators for parameter of /vulnerability/cve/list/get + """ +@@ -39,8 +39,6 @@ class GetCveListSchema(Schema): + ["cve_id", "publish_time", "cvss_score", "host_num"])) + direction = fields.String(required=False, validate=validate.OneOf( + ["asc", "desc"])) +- page = fields.Integer(required=False, validate=lambda s: s > 0) +- per_page = fields.Integer(required=False, validate=lambda s: 0 < s < 50) + filter = fields.Nested(CveListFilterSchema, required=False) + + +@@ -65,7 +63,7 @@ class CveHostFilterSchema(Schema): + hp_status = fields.List(fields.String(validate=validate.OneOf(["ACCEPTED", "ACTIVED"])), required=False) + + +-class GetCveHostsSchema(Schema): ++class GetCveHostsSchema(PaginationSchema): + """ + validators for parameter of /vulnerability/cve/host/get + """ +@@ -74,8 +72,6 @@ class GetCveHostsSchema(Schema): + ["last_scan"])) + direction = fields.String(required=False, validate=validate.OneOf( + ["asc", "desc"])) +- page = fields.Integer(required=False, validate=lambda s: s > 0) +- per_page = fields.Integer(required=False, validate=lambda s: 0 < s < 50) + filter = fields.Nested(CveHostFilterSchema, required=False) + + +diff --git a/apollo/function/schema/host.py b/apollo/function/schema/host.py +index a0cc4b5..c609fd4 100644 +--- a/apollo/function/schema/host.py ++++ b/apollo/function/schema/host.py +@@ -18,7 +18,7 @@ Description: For host related restful interfaces schema + from marshmallow import Schema + from marshmallow import fields + from marshmallow import validate +- ++from vulcanus.restful.serialize.validate import PaginationSchema + + class ScanHostFilterSchema(Schema): + """ +@@ -61,7 +61,7 @@ class GetHostListFilterSchema(Schema): + required=False) + + +-class GetHostListSchema(Schema): ++class GetHostListSchema(PaginationSchema): + """ + validators for parameter of /vulnerability/host/list/get + """ +@@ -69,8 +69,6 @@ class GetHostListSchema(Schema): + ["last_scan", "cve_num"])) + direction = fields.String(required=False, validate=validate.OneOf( + ["asc", "desc"])) +- page = fields.Integer(required=False, validate=lambda s: s > 0) +- per_page = fields.Integer(required=False, validate=lambda s: 0 < s < 50) + filter = fields.Nested(GetHostListFilterSchema, required=False) + + +@@ -96,7 +94,7 @@ class HostCvesFilterSchema(Schema): + hp_status = fields.List(fields.String(validate=validate.OneOf(["ACCEPTED", "ACTIVED"])), required=False) + + +-class GetHostCvesSchema(Schema): ++class GetHostCvesSchema(PaginationSchema): + """ + validators for parameter of /vulnerability/host/cve/get + """ +@@ -105,6 +103,4 @@ class GetHostCvesSchema(Schema): + ["publish_time", "cvss_score"])) + direction = fields.String(required=False, validate=validate.OneOf( + ["asc", "desc"])) +- page = fields.Integer(required=False, validate=lambda s: s > 0) +- per_page = fields.Integer(required=False, validate=lambda s: 0 < s < 50) + filter = fields.Nested(HostCvesFilterSchema, required=False) +diff --git a/apollo/function/schema/task.py b/apollo/function/schema/task.py +index 415c2ca..5e8744b 100644 +--- a/apollo/function/schema/task.py ++++ b/apollo/function/schema/task.py +@@ -20,6 +20,7 @@ from marshmallow import fields + from marshmallow import validate + + from apollo.conf.constant import TaskType ++from vulcanus.restful.serialize.validate import PaginationSchema + + class TaskListFilterSchema(Schema): + """ +@@ -30,7 +31,7 @@ class TaskListFilterSchema(Schema): + validate=validate.OneOf([getattr(TaskType,p) for p in dir(TaskType) if p.isupper()])), required=False) + + +-class GetTaskListSchema(Schema): ++class GetTaskListSchema(PaginationSchema): + """ + validators for parameter of /vulnerability/task/list/get + """ +@@ -38,8 +39,6 @@ class GetTaskListSchema(Schema): + ["host_num", "create_time"])) + direction = fields.String(required=False, validate=validate.OneOf( + ["asc", "desc"])) +- page = fields.Integer(required=False, validate=lambda s: s > 0) +- per_page = fields.Integer(required=False, validate=lambda s: 0 < s < 50) + filter = fields.Nested(TaskListFilterSchema, required=False) + + +@@ -105,15 +104,13 @@ class CveTaskInfoFilterSchema(Schema): + ["succeed", "fail", "running", "unknown"])), required=False) + + +-class GetCveTaskInfoSchema(Schema): ++class GetCveTaskInfoSchema(PaginationSchema): + """ + validators for parameter of /vulnerability/task/cve/info/get + """ + task_id = fields.String(required=True, validate=lambda s: len(s) != 0) + sort = fields.String(required=False, validate=validate.OneOf(["host_num"])) + direction = fields.String(required=False, validate=validate.OneOf(["asc", "desc"])) +- page = fields.Integer(required=False, validate=lambda s: s > 0) +- per_page = fields.Integer(required=False, validate=lambda s: 0 < s < 50) + filter = fields.Nested(CveTaskInfoFilterSchema, required=False) + + +@@ -169,13 +166,11 @@ class RepoTaskInfoFilterSchema(Schema): + required=False) + + +-class GetRepoTaskInfoSchema(Schema): ++class GetRepoTaskInfoSchema(PaginationSchema): + """ + validators for parameter of /vulnerability/task/repo/info/get + """ + task_id = fields.String(required=True, validate=lambda s: len(s) != 0) +- page = fields.Integer(required=False, validate=lambda s: s > 0) +- per_page = fields.Integer(required=False, validate=lambda s: 0 < s < 50) + filter = fields.Nested(RepoTaskInfoFilterSchema, required=False) + + +-- +Gitee + diff --git a/aops-apollo.spec b/aops-apollo.spec index 4489b61..3607b40 100644 --- a/aops-apollo.spec +++ b/aops-apollo.spec @@ -1,6 +1,6 @@ Name: aops-apollo Version: v1.2.1 -Release: 3 +Release: 4 Summary: Cve management service, monitor machine vulnerabilities and provide fix functions. License: MulanPSL2 URL: https://gitee.com/openeuler/%{name} @@ -11,6 +11,8 @@ Patch0003: 0003-fix-hotpatch-updateinfo-for-search-hotpatch-info.patch Patch0004: 0004-add-dnf-full-repair.patch Patch0005: 0005-fix-generate-task-is-not-verified-host-and-cve.patch Patch0006: 0006-update-hotpatch-status-related-operation-support.patch +Patch0007: 0007-fix-hotpatch-status-filter-exception.patch +Patch0008: 0008-update-validation-rules-for-paging-parameters.patch BuildRequires: python3-setuptools Requires: aops-vulcanus >= v1.2.0 @@ -81,6 +83,10 @@ cp -r hotpatch %{buildroot}/%{python3_sitelib}/dnf-plugins/ %{python3_sitelib}/aops_apollo_tool/* %changelog +* Thu Jun 08 2023 wenxin - v1.2.1-4 +- fix issue: hotpatch status filter exception +- update validation rules for paging parameters + * Fri Jun 2 2023 gongzhengtang - v1.2.1-3 - fix bug and update the code of parsing src.rpm - fix hotpatch updateinfo for search hotpatch information