Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1#!/usr/bin/env python3 

2""" 

3A python module to check the compliance status of an app in Veracode via their XML Results API 

4""" 

5 

6# built-ins 

7import logging 

8from typing import Union, Optional 

9from xml.etree import ( # nosec (Used only when TYPE_CHECKING) # nosem: python.lang.security.use-defused-xml.use-defused-xml 

10 ElementTree as InsecureElementTree, 

11) 

12 

13# third party 

14from requests.exceptions import HTTPError, Timeout, RequestException, TooManyRedirects 

15 

16# custom 

17from veracode.api import ResultsAPI 

18from veracode.utils import validate, element_contains_error 

19from veracode import __project_name__ 

20 

21LOG = logging.getLogger(__project_name__ + "." + __name__) 

22 

23 

24@validate 

25def get_latest_completed_build( 

26 *, results_api: ResultsAPI, only_latest: Optional[bool] = True 

27) -> Union[InsecureElementTree.Element, bool]: 

28 """ 

29 Get the latest completed build build_id for a given app_id 

30 https://help.veracode.com/reader/LMv_dtSHyb7iIxAQznC~9w/Q8E6r4JDAN1lykB08oGDSA 

31 """ 

32 endpoint = "getappbuilds.do" 

33 params = {"only_latest": only_latest} 

34 try: 

35 appbuilds = results_api.http_get(endpoint=endpoint, params=params) 

36 if element_contains_error(parsed_xml=appbuilds): 

37 LOG.error("Veracode returned an error when attempting to call %s", endpoint) 

38 return False 

39 except ( 

40 HTTPError, 

41 ConnectionError, 

42 Timeout, 

43 TooManyRedirects, 

44 RequestException, 

45 ): 

46 LOG.error("Exception encountered when calling the Veracode API") 

47 return False 

48 

49 # Filter on the provided app_id 

50 for app in appbuilds: 

51 if app.get("app_id") == results_api.app_id: 

52 LOG.debug("Found app_id %s, returning %s", results_api.app_id, app) 

53 return app 

54 

55 LOG.error( 

56 "Unable to find a completed build for app_id %s", 

57 results_api.app_id, 

58 ) 

59 return False 

60 

61 

62@validate 

63def get_policy_compliance_status(*, results_api: ResultsAPI) -> Union[str, None]: 

64 """ 

65 Retrieve the policy compliance status 

66 """ 

67 tag = "{https://analysiscenter.veracode.com/schema/2.0/applicationbuilds}build" 

68 # See https://analysiscenter.veracode.com/resource/2.0/applicationbuilds.xsd 

69 policy_compliance_status = "Unknown" 

70 

71 LOG.debug("Calling get_latest_completed_scan") 

72 latest_completed_build = get_latest_completed_build(results_api=results_api) 

73 if latest_completed_build: 

74 for build in latest_completed_build.iter(tag=tag): 

75 policy_compliance_status = build.get("policy_compliance_status") 

76 else: 

77 LOG.warning("No builds detected for app_id %s", results_api.app_id) 

78 

79 return policy_compliance_status 

80 

81 

82@validate 

83def in_compliance(*, results_api: ResultsAPI) -> bool: 

84 """ 

85 Identify if a policy compliance status is sufficient 

86 """ 

87 LOG.debug("Calling get_policy_compliance_status") 

88 compliance_status = get_policy_compliance_status(results_api=results_api) 

89 if compliance_status != "Unknown": 

90 LOG.debug( 

91 "app_id %s has a compliance status of %s", 

92 results_api.app_id, 

93 compliance_status, 

94 ) 

95 else: 

96 raise ValueError 

97 

98 return bool(compliance_status == "Pass") 

99 

100 

101@validate 

102def check_compliance(*, results_api: ResultsAPI) -> bool: 

103 """ 

104 Check the compliance status of an app in Veracode 

105 """ 

106 LOG.debug( 

107 "Checking to see if the latest build for app_id %s is in compliance", 

108 results_api.app_id, 

109 ) 

110 try: 

111 if not in_compliance(results_api=results_api): 

112 LOG.warning( 

113 "The latest build for app %s was not in compliance", results_api.app_id 

114 ) 

115 if results_api.ignore_compliance_status: 

116 return True 

117 

118 return False 

119 except ValueError: 

120 LOG.error( 

121 "Unable to determine the compliance status of app_id %s", results_api.app_id 

122 ) 

123 return False 

124 

125 # App was in compliance 

126 LOG.info("App ID %s is in compliance", results_api.app_id) 

127 return True