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

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 

7 

8dashboard = Dashboard(api_publisher_session) 

9 

10 

11def can_user_access_cve_data(snap_name): 

12 """ 

13 Check if the user has access to CVE data for the given snap. 

14 

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) 

21 

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) 

28 

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) 

35 

36 if not snap_details: 

37 return (False, f"CVEs data for '{snap_name}' snap not found.", 404) 

38 

39 return (True, None, 200) 

40 

41 

42@login_required 

43def get_revisions_with_cves(snap_name): 

44 

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 ) 

54 

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 ) 

70 

71 

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 ) 

83 

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") 

92 

93 # Sort params 

94 sort_by = flask.request.args.get("sort_by", default="id") 

95 order = flask.request.args.get("order", default="desc") 

96 

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 ) 

116 

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 ) 

128 

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) 

132 

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 ) 

148 

149 return flask.jsonify({"success": True, **cves})