Coverage for webapp/publisher/cve/cve_views.py: 46%
56 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-28 22:05 +0000
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-28 22:05 +0000
1import flask
2from canonicalwebteam.store_api.dashboard import Dashboard
3from canonicalwebteam.exceptions import StoreApiResourceNotFound, StoreApiError
4from webapp.helpers import api_publisher_session
5from webapp.decorators import login_required
6from webapp.publisher.cve.cve_helper import CveHelper
8dashboard = Dashboard(api_publisher_session)
11def can_user_access_cve_data(snap_name):
12 """
13 Check if the user has access to CVE data for the given snap.
15 :return: A tuple containing:
16 has_access (bool): True if the user has access, False otherwise.
17 error_message (str): Error message if access is denied.
18 status_code (int): HTTP status code for the response.
19 """
20 is_user_canonical = flask.session["publisher"].get("is_canonical", False)
22 # TODO: in future with brand store support we will need more specific
23 # checks, such as those implemented in CveHelper.can_user_access_cve_data
24 # For now, we only check if user is Canonical member and has
25 # publisher access to the snap.
26 if not is_user_canonical:
27 return (False, "User is not allowed to see snap's CVE data.", 403)
29 try:
30 snap_details = dashboard.get_snap_info(flask.session, snap_name)
31 except StoreApiResourceNotFound:
32 return (False, f"CVEs data for '{snap_name}' snap not found.", 404)
33 except StoreApiError:
34 return (False, f"Error fetching '{snap_name}' snap details.", 500)
36 if not snap_details:
37 return (False, f"CVEs data for '{snap_name}' snap not found.", 404)
39 return (True, None, 200)
42@login_required
43def get_revisions_with_cves(snap_name):
45 # Check if the user has access to CVE data for the given snap
46 has_access, error_message, status_code = can_user_access_cve_data(
47 snap_name
48 )
49 if not has_access:
50 return (
51 flask.jsonify({"success": False, "message": error_message}),
52 status_code,
53 )
55 revisions_with_cves = CveHelper.get_revisions_with_cves(snap_name)
56 if len(revisions_with_cves) > 0:
57 return flask.jsonify(
58 {"success": True, "data": {"revisions": revisions_with_cves}}
59 )
60 else:
61 return (
62 flask.jsonify(
63 {
64 "success": False,
65 "message": f"CVEs data for '{snap_name}' snap not found.",
66 }
67 ),
68 404,
69 )
72@login_required
73def get_cves(snap_name, revision):
74 # Check if the user has access to CVE data for the given snap
75 has_access, error_message, status_code = can_user_access_cve_data(
76 snap_name
77 )
78 if not has_access:
79 return (
80 flask.jsonify({"success": False, "error": error_message}),
81 status_code,
82 )
84 # Filtering params
85 usn_ids = flask.request.args.getlist("usn_id")
86 binary_statuses = flask.request.args.getlist("binary_status")
87 binary_versions = flask.request.args.getlist("binary_version")
88 binary_fixed_versions = flask.request.args.getlist("binary_fixed_version")
89 binary_names = flask.request.args.getlist("binary_name")
90 cvss_severities = flask.request.args.getlist("cvss_severity")
91 ubuntu_priorities = flask.request.args.getlist("ubuntu_priority")
93 # Sort params
94 sort_by = flask.request.args.get("sort_by", default="id")
95 order = flask.request.args.get("order", default="desc")
97 allowed_fields_for_sort = [
98 "id",
99 "cvss_severity",
100 "cvss_score",
101 "ubuntu_priority",
102 ]
103 if sort_by and sort_by not in allowed_fields_for_sort:
104 return (
105 flask.jsonify(
106 {
107 "success": False,
108 "error": (
109 "Data can only be sorted by id, "
110 "cvss_severity, cvss_score, ubuntu_priority"
111 ),
112 }
113 ),
114 400,
115 )
117 allowed_order_params = ["asc", "desc"]
118 if order and order not in allowed_order_params:
119 return (
120 flask.jsonify(
121 {
122 "success": False,
123 "error": "'order' param can only be 'asc' or 'desc'",
124 }
125 ),
126 400,
127 )
129 # Pagination params
130 page = flask.request.args.get("page", default=1, type=int)
131 page_size = flask.request.args.get("page_size", default=10, type=int)
133 cves = CveHelper.get_cve_with_revision(snap_name, revision)
134 cves = CveHelper.filter_cve_data(
135 cves,
136 usn_ids,
137 binary_statuses,
138 binary_versions,
139 binary_fixed_versions,
140 binary_names,
141 cvss_severities,
142 ubuntu_priorities,
143 )
144 cves = CveHelper.sort_cve_data(cves=cves, order=order, sort_by=sort_by)
145 cves = CveHelper.paginate_cve_list(
146 cves=cves, page=page, page_size=page_size
147 )
149 return flask.jsonify({"success": True, **cves})