Ejemplo n.º 1
0
    def test_results_api_http_post(self, mock_http_request):
        """
        Test the ResultsAPI http_post method
        """
        with patch("veracode.api.get_app_id",
                   return_value=constants.VALID_UPLOAD_API["app_id"]):
            results_api = ResultsAPI(
                app_name=constants.VALID_RESULTS_API["app_name"])

        # Fail when attempting to call the http_post method with invalid
        # arguments
        self.assertRaises(KeyError,
                          results_api.http_post,
                          endpoint="removefile.do")

        # Succeed when calling the http_post method with valid arguments
        #
        # As of the writing of this Veracode's Results API doesn't have any
        # endpoints that take a POST so the constants and endpoints below don't
        # align with a real-world scenario (because one doesn't exist)
        mock_http_request.return_value = constants.VALID_RESULTS_API_GETAPPBUILDS_RESPONSE_XML_PASSING_POLICY_COMPLIANCE_STATUS[
            "Element"]
        self.assertIsInstance(
            results_api.http_post(endpoint="detailedreport.do"),
            InsecureElementTree.Element,
        )

        # Fail when attempting to delete the http_post method, because the
        # deleter is intentionally missing
        self.assertRaises(AttributeError, delattr, results_api, "http_post")
Ejemplo n.º 2
0
    def test_results_api__validate(self, mock_is_valid_attribute):
        """
        Test the ResultsAPI _validate method
        """
        with patch("veracode.api.get_app_id",
                   return_value=constants.VALID_UPLOAD_API["app_id"]):
            results_api = ResultsAPI(
                app_name=constants.VALID_RESULTS_API["app_name"])

        # Mock all attributes are invalid
        mock_is_valid_attribute.return_value = False

        # Fail when attempting to call the _validate method, given that the
        # attributes are invalid
        self.assertRaises(
            ValueError,
            results_api._validate,  # pylint: disable=protected-access
            key="key",
            value="patched to be invalid",
        )

        # Mock all attributes are valid
        mock_is_valid_attribute.return_value = True

        # Succeed when calling the _validate method, given that the attributes
        # are valid
        self.assertTrue(
            results_api._validate(  # pylint: disable=protected-access
                key="key",
                value="patched to be valid"))

        # Fail when attempting to delete the _validate method, because the
        # deleter is intentionally missing
        self.assertRaises(AttributeError, delattr, results_api, "_validate")
Ejemplo n.º 3
0
    def test_results_api_version(self):
        """
        Test the ResultsAPI version property
        """
        with patch("veracode.api.get_app_id",
                   return_value=constants.VALID_UPLOAD_API["app_id"]):
            results_api = ResultsAPI(
                app_name=constants.VALID_RESULTS_API["app_name"])

        # Succeed when getting a valid version property
        self.assertIsInstance(results_api.version, dict)

        # Succeed when setting the version property to a valid value
        self.assertIsNone(
            setattr(results_api, "version",
                    constants.VALID_RESULTS_API["version"]))

        # Fail when attempting to set the version property to an invalid value
        self.assertRaises(
            ValueError,
            setattr,
            results_api,
            "version",
            constants.INVALID_RESULTS_API_INCORRECT_VERSION_VALUES["version"],
        )

        # Fail when attempting to get the version property when it contains an
        # invalid value
        results_api._version = constants.INVALID_RESULTS_API_INCORRECT_VERSION_VALUES[  # pylint: disable=protected-access
            "version"]
        self.assertRaises(ValueError, getattr, results_api, "version")

        # Fail when attempting to delete the version property, because the
        # deleter is intentionally missing
        self.assertRaises(AttributeError, delattr, results_api, "version")
Ejemplo n.º 4
0
    def test_results_api_http_get(self, mock_http_request):
        """
        Test the ResultsAPI http_get method
        """
        with patch("veracode.api.get_app_id",
                   return_value=constants.VALID_UPLOAD_API["app_id"]):
            results_api = ResultsAPI(
                app_name=constants.VALID_RESULTS_API["app_name"])

        # Fail when attempting to call the http_get method with invalid
        # arguments
        self.assertRaises(KeyError,
                          results_api.http_get,
                          endpoint="getbuildlist.do")

        # Succeed when calling the http_get method with valid arguments
        mock_http_request.return_value = constants.VALID_RESULTS_API_GETAPPBUILDS_RESPONSE_XML_PASSING_POLICY_COMPLIANCE_STATUS[
            "Element"]
        self.assertIsInstance(
            results_api.http_get(endpoint="getappbuilds.do"),
            InsecureElementTree.Element,
        )

        # Fail when attempting to delete the http_get method, because the
        # deleter is intentionally missing
        self.assertRaises(AttributeError, delattr, results_api, "http_get")
Ejemplo n.º 5
0
    def test_results_api_base_url(self):
        """
        Test the ResultsAPI base_url property
        """
        with patch("veracode.api.get_app_id",
                   return_value=constants.VALID_UPLOAD_API["app_id"]):
            results_api = ResultsAPI(
                app_name=constants.VALID_RESULTS_API["app_name"])

        # Succeed when getting a valid base_url property
        self.assertIsInstance(results_api.base_url, str)

        # Succeed when setting the base_url property to a valid value
        self.assertIsNone(
            setattr(results_api, "base_url",
                    constants.VALID_RESULTS_API["base_url"]))

        # Fail when attempting to set the base_url property to an invalid value
        self.assertRaises(
            ValueError,
            setattr,
            results_api,
            "base_url",
            constants.INVALID_RESULTS_API_MISSING_DOMAIN["base_url"],
        )

        # Fail when attempting to get the base_url property when it contains an
        # invalid value
        results_api._base_url = constants.INVALID_RESULTS_API_MISSING_DOMAIN[  # pylint: disable=protected-access
            "base_url"]
        self.assertRaises(ValueError, getattr, results_api, "base_url")

        # Fail when attempting to delete the base_url property, because the
        # deleter is intentionally missing
        self.assertRaises(AttributeError, delattr, results_api, "base_url")
Ejemplo n.º 6
0
    def test_get_policy_compliance_status(self,
                                          mock_get_latest_completed_build):
        """
        Test the get_policy_compliance_status function
        """
        # Return a non-"Pass"ing string when calling the
        # get_policy_compliance_status function with a valid results_api and
        # get_latest_completed_build has a mocked response of "Did Not Pass"
        results_api = ResultsAPI(
            app_id=test_constants.VALID_RESULTS_API["app_id"])
        mock_get_latest_completed_build.return_value = test_constants.VALID_RESULTS_API_GETAPPBUILDS_RESPONSE_XML_FAILING_POLICY_COMPLIANCE_STATUS[
            "Element"]
        self.assertEqual(
            check_compliance.get_policy_compliance_status(
                results_api=results_api),
            "Did Not Pass",
        )
        self.assertNotEqual(
            check_compliance.get_policy_compliance_status(
                results_api=results_api),
            "Pass",
        )

        # Return a "Pass"ing string when calling the
        # get_policy_compliance_status function with a valid results_api and
        # get_latest_completed_build has a mocked response that returns None
        results_api = ResultsAPI(
            app_id=test_constants.VALID_RESULTS_API["app_id"])
        mock_get_latest_completed_build.return_value = None
        self.assertNotEqual(
            check_compliance.get_policy_compliance_status(
                results_api=results_api),
            "Pass",
        )

        # Return a non-"Pass"ing string when calling the
        # get_policy_compliance_status function with a valid results_api and
        # get_latest_completed_build has a mocked response that returns an
        # application with no build
        results_api = ResultsAPI(
            app_id=test_constants.VALID_RESULTS_API["app_id"])
        mock_get_latest_completed_build.return_value = (
            test_constants.
            VALID_RESULTS_API_GETAPPBUILDS_RESPONSE_XML_NO_BUILDS["Element"])
        self.assertEqual(
            check_compliance.get_policy_compliance_status(
                results_api=results_api),
            "Unknown",
        )
        self.assertNotEqual(
            check_compliance.get_policy_compliance_status(
                results_api=results_api),
            "Pass",
        )
Ejemplo n.º 7
0
    def test_in_compliance(self, mock_get_policy_compliance_status):
        """
        Test the in_compliance function
        """
        # Succeed when calling the in_compliance function with a valid
        # results_api and compliance_status has a mocked response of "Pass"
        with patch("veracode.api.get_app_id", return_value="1337"):
            results_api = ResultsAPI(
                app_name=test_constants.VALID_RESULTS_API["app_name"])

        mock_get_policy_compliance_status.return_value = "Pass"
        self.assertTrue(
            check_compliance.in_compliance(results_api=results_api))

        # Return False when calling the in_compliance function with a valid
        # results_api and compliance_status has a mocked response of "Unknown"
        with patch("veracode.api.get_app_id", return_value="1337"):
            results_api = ResultsAPI(
                app_name=test_constants.VALID_RESULTS_API["app_name"])

        mock_get_policy_compliance_status.return_value = "Unknown"
        self.assertRaises(ValueError,
                          check_compliance.in_compliance,
                          results_api=results_api)

        # Succeed when calling the in_compliance function with a valid
        # results_api and compliance_status has a mocked response of anything
        # but "Pass"
        #
        # https://analysiscenter.veracode.com/resource/2.0/applicationbuilds.xsd
        # and https://help.veracode.com/viewer/document/mo49_yYZJCUuKhwdE9WRFQ
        # for possible values
        with patch("veracode.api.get_app_id", return_value="1337"):
            results_api = ResultsAPI(
                app_name=test_constants.VALID_RESULTS_API["app_name"])

        for value in [
                "Calculating...",
                "Not Assessed",
                "Did Not Pass",
                "Conditional Pass",
                "Under Vendor Review",
                "UNKNOWN VALUE!()&@%",
                300,
                7.12,
                results_api,
        ]:
            mock_get_policy_compliance_status.return_value = value
            self.assertFalse(
                check_compliance.in_compliance(results_api=results_api))
Ejemplo n.º 8
0
    def test_apply_config(self):
        """
        Test the apply_config function
        """
        configuration = copy.deepcopy(test_constants.CLEAN_EFFECTIVE_CONFIG)

        # Succeed when calling the apply_config function with a valid
        # Upload API object and config
        upload_api = UploadAPI(app_id="31337")
        applied_upload_api = config.apply_config(api=upload_api, config=configuration)
        self.assertEqual(applied_upload_api, upload_api)

        # Succeed when calling the apply_config function with a valid
        # Results API object and config
        results_api = ResultsAPI(app_id="31337")
        applied_results_api = config.apply_config(api=results_api, config=configuration)
        self.assertEqual(applied_results_api, results_api)

        # Succeed when calling the apply_config function with a valid
        # Sandbox API object and config
        sandbox_api = SandboxAPI(
            app_id="31337", sandbox_name="easy_sast/fb/jonzeolla/testing"
        )
        applied_sandbox_api = config.apply_config(api=sandbox_api, config=configuration)
        self.assertEqual(applied_sandbox_api, sandbox_api)

        # Ensure calling the apply_config function with different `app_id`s
        # does not result in an object with the same version string (which is
        # unique per-API)
        upload_api = UploadAPI(app_id="31337")
        applied_upload_api = config.apply_config(api=upload_api, config=configuration)
        # Note: This must be different than the above app_id
        results_api = ResultsAPI(app_id="1337")
        applied_results_api = config.apply_config(api=results_api, config=configuration)
        self.assertNotEqual(applied_results_api.version, applied_upload_api.version)

        # Fail when calling the apply_config function with a string instead of
        # an API object
        astring = "wrong type"
        self.assertRaises(
            TypeError, config.apply_config, api=astring, config=configuration
        )

        # Succeed when calling the apply_config function with a valid
        # Results API object and config
        configuration["apis"]["unknown"] = {"a": "b"}
        results_api = ResultsAPI(app_id="31337")
        self.assertEqual(
            config.apply_config(api=results_api, config=configuration), results_api
        )
Ejemplo n.º 9
0
def get_latest_completed_build(
    *, results_api: ResultsAPI, only_latest: Optional[bool] = True
) -> Union[InsecureElementTree.Element, bool]:
    """
    Get the latest completed build build_id for a given app_id
    https://help.veracode.com/reader/LMv_dtSHyb7iIxAQznC~9w/Q8E6r4JDAN1lykB08oGDSA
    """
    endpoint = "getappbuilds.do"
    params = {"only_latest": only_latest}
    try:
        appbuilds = results_api.http_get(endpoint=endpoint, params=params)
        if element_contains_error(parsed_xml=appbuilds):
            LOG.error("Veracode returned an error when attempting to call %s", endpoint)
            return False
    except (
        HTTPError,
        ConnectionError,
        Timeout,
        TooManyRedirects,
        RequestException,
    ):
        LOG.error("Exception encountered when calling the Veracode API")
        return False

    # Filter on the provided app_id
    for app in appbuilds:
        if app.get("app_id") == results_api.app_id:
            LOG.debug("Found app_id %s, returning %s", results_api.app_id, app)
            return app

    LOG.error(
        "Unable to find a completed build for app_id %s",
        results_api.app_id,
    )
    return False
Ejemplo n.º 10
0
    def test_results_api_ignore_compliance_status(self):
        """
        Test the ResultsAPI ignore_compliance_status property
        """
        with patch("veracode.api.get_app_id",
                   return_value=constants.VALID_UPLOAD_API["app_id"]):
            results_api = ResultsAPI(
                app_name=constants.VALID_RESULTS_API["app_name"])

        # Succeed when getting a valid ignore_compliance_status property
        self.assertIsInstance(results_api.ignore_compliance_status, bool)

        # Succeed when setting the ignore_compliance_status property to a valid
        # value
        self.assertIsNone(
            setattr(
                results_api,
                "ignore_compliance_status",
                constants.VALID_RESULTS_API["ignore_compliance_status"],
            ))

        # Fail when attempting to set the ignore_compliance_status property to
        # an invalid value
        self.assertRaises(
            ValueError,
            setattr,
            results_api,
            "ignore_compliance_status",
            constants.INVALID_RESULTS_API_INCORRECT_COMPLIANCE_STATUS[
                "ignore_compliance_status"],
        )

        # Fail when attempting to get the ignore_compliance_status property
        # when it contains an invalid value
        results_api._ignore_compliance_status = constants.INVALID_RESULTS_API_INCORRECT_COMPLIANCE_STATUS[  # pylint: disable=protected-access
            "ignore_compliance_status"]
        self.assertRaises(ValueError, getattr, results_api,
                          "ignore_compliance_status")

        # Fail when attempting to delete the ignore_compliance_status property,
        # because the deleter is intentionally missing
        self.assertRaises(AttributeError, delattr, results_api,
                          "ignore_compliance_status")
Ejemplo n.º 11
0
    def test_results_api_app_name(self):
        """
        Test the ResultsAPI app_name property
        """
        # Fail when attempting to create a ResultsAPI object when the app_name
        # property wasn't provided to the constructor
        self.assertRaises(TypeError, ResultsAPI)

        # Succeed when creating a ResultsAPI object when the app_name property is
        # properly provided to the constructor
        with patch("veracode.api.get_app_id",
                   return_value=constants.VALID_UPLOAD_API["app_id"]):
            results_api = ResultsAPI(
                app_name=constants.VALID_RESULTS_API["app_name"])

        self.assertIsInstance(getattr(results_api, "app_name"), str)

        # Succeed when setting the app_name property to a valid value
        self.assertIsNone(
            setattr(results_api, "app_name",
                    constants.VALID_RESULTS_API["app_name"]))

        # Succeed when getting a valid app_name property
        self.assertIsInstance(results_api.app_name, str)

        # Fail when attempting to set the app_name property to an invalid value
        self.assertRaises(
            ValueError,
            setattr,
            results_api,
            "app_name",
            constants.INVALID_RESULTS_API_INCORRECT_APP_NAME["app_name"],
        )

        # Fail when attempting to get the app_name property when it contains an
        # invalid value
        results_api._app_name = constants.INVALID_RESULTS_API_INCORRECT_APP_NAME[  # pylint: disable=protected-access
            "app_name"]
        self.assertRaises(ValueError, getattr, results_api, "app_name")

        # Fail when attempting to delete the app_name property, because the
        # deleter is intentionally missing
        self.assertRaises(AttributeError, delattr, results_api, "app_name")
Ejemplo n.º 12
0
def main() -> None:
    """
    Integration with Veracode Static Analysis
    """
    ## Setup logging
    # Format the logs as JSON for simplicity
    formatting = json.dumps(
        {
            "timestamp": "%(asctime)s",
            "namespace": "%(name)s",
            "loglevel": "%(levelname)s",
            "message": "%(message)s",
        }
    )
    # Default to a log level of WARNING until the config is parsed
    logging.basicConfig(level="WARNING", format=formatting)
    log = logging.getLogger(__project_name__)

    # Get the effective config
    try:
        config = get_config()
    except ValueError:
        log.error("Unable to create a valid configuration")
        sys.exit(1)

    # Update the log level to whatever was set in the config
    logging.getLogger().setLevel(config["loglevel"])

    # Create the API objects and apply the config
    try:
        results_api = apply_config(
            api=ResultsAPI(app_id=config["apis"]["results"]["app_id"]), config=config
        )
        upload_api = apply_config(
            api=UploadAPI(app_id=config["apis"]["upload"]["app_id"]), config=config
        )
        if "sandbox_name" in config["apis"]["sandbox"]:
            sandbox_api = apply_config(
                api=SandboxAPI(
                    app_id=config["apis"]["sandbox"]["app_id"],
                    sandbox_name=config["apis"]["sandbox"]["sandbox_name"],
                ),
                config=config,
            )
        else:
            sandbox_api = None
    except (TypeError, NameError):
        log.error("Unable to create valid API objects")
        sys.exit(1)

    # Configure the environment
    for step in config["workflow"]:
        if step == "submit_artifacts":
            configure_environment(
                api_key_id=config["api_key_id"], api_key_secret=config["api_key_secret"]
            )
            success = submit_artifacts(upload_api=upload_api, sandbox_api=sandbox_api)

            if success:
                log.info("Successfully submit build artifacts for scanning")
            else:
                log.error("Failed to submit build artifacts for scanning")
                sys.exit(1)
        elif step == "check_compliance":
            configure_environment(
                api_key_id=config["api_key_id"], api_key_secret=config["api_key_secret"]
            )
            if not check_compliance(results_api=results_api):
                sys.exit(1)
Ejemplo n.º 13
0
    def test_check_compliance(self, mock_in_compliance):
        """
        Test the check_compliance function
        """
        # Return True when calling the check_compliance function with a valid
        # results_api with ignore_compliance_status set to True and
        # ignore_compliance_status is True
        with patch("veracode.api.get_app_id", return_value="1337"):
            results_api = ResultsAPI(
                app_name=test_constants.VALID_RESULTS_API["app_name"])

        results_api.ignore_compliance_status = True
        mock_in_compliance.return_value = True
        self.assertTrue(
            check_compliance.check_compliance(results_api=results_api))

        # Return False when calling the check_compliance function with a valid
        # results_api with ignore_compliance_status set to False and
        # ignore_compliance_status is False
        with patch("veracode.api.get_app_id", return_value="1337"):
            results_api = ResultsAPI(
                app_name=test_constants.VALID_RESULTS_API["app_name"])

        results_api.ignore_compliance_status = False
        mock_in_compliance.return_value = False
        self.assertFalse(
            check_compliance.check_compliance(results_api=results_api))

        # Return True when calling the check_compliance function with a valid
        # results_api with ignore_compliance_status set to True and
        # ignore_compliance_status is False
        with patch("veracode.api.get_app_id", return_value="1337"):
            results_api = ResultsAPI(
                app_name=test_constants.VALID_RESULTS_API["app_name"])

        results_api.ignore_compliance_status = True
        mock_in_compliance.return_value = False
        self.assertTrue(
            check_compliance.check_compliance(results_api=results_api))

        # Return True when calling the check_compliance function with a valid
        # results_api with ignore_compliance_status set to False and
        # ignore_compliance_status is True
        with patch("veracode.api.get_app_id", return_value="1337"):
            results_api = ResultsAPI(
                app_name=test_constants.VALID_RESULTS_API["app_name"])

        results_api.ignore_compliance_status = False
        mock_in_compliance.return_value = True
        self.assertTrue(
            check_compliance.check_compliance(results_api=results_api))

        # Return False after calling the check_compliance function with a valid
        # results_api with ignore_compliance_status set to False and
        # ignore_compliance_status is True, but in_compliance's mock raises a
        # ValueError when called
        with patch("veracode.api.get_app_id", return_value="1337"):
            results_api = ResultsAPI(
                app_name=test_constants.VALID_RESULTS_API["app_name"])

        results_api.ignore_compliance_status = False
        mock_in_compliance.return_value = True
        mock_in_compliance.side_effect = ValueError
        self.assertFalse(
            check_compliance.check_compliance(results_api=results_api))
Ejemplo n.º 14
0
    def test_get_latest_completed_build(self):
        """
        Test the get_latest_completed_build function
        """
        # Succeed when calling the get_latest_completed_build function with a
        # valid results_api and the http_get method returns an
        # ElementTree.Element which contains the provided app_id
        with patch.object(
                ResultsAPI,
                "http_get",
                return_value=test_constants.
                VALID_RESULTS_API_GETAPPBUILDS_RESPONSE_XML_PASSING_POLICY_COMPLIANCE_STATUS[
                    "Element"],
        ):
            with patch("veracode.check_compliance.element_contains_error",
                       return_value=False):
                with patch("veracode.api.get_app_id", return_value="1337"):
                    results_api = ResultsAPI(app_name="TestApp")
                    output = check_compliance.get_latest_completed_build(
                        results_api=results_api)
                    expected = ElementTree.fromstring(
                        b'<ns0:application xmlns:ns0="https://analysiscenter.veracode.com/schema/2.0/applicationbuilds" app_name="TestApp" app_id="1337" industry_vertical="Manufacturing" assurance_level="Very High" business_criticality="Very High" origin="Not Specified" modified_date="2019-08-13T14:00:10-04:00" cots="false" business_unit="Not Specified" tags="">\n      <ns0:customfield name="Custom 1" value="" />\n      <ns0:customfield name="Custom 2" value="" />\n      <ns0:customfield name="Custom 3" value="" />\n      <ns0:customfield name="Custom 4" value="" />\n      <ns0:customfield name="Custom 5" value="" />\n      <ns0:customfield name="Custom 6" value="" />\n      <ns0:customfield name="Custom 7" value="" />\n      <ns0:customfield name="Custom 8" value="" />\n      <ns0:customfield name="Custom 9" value="" />\n      <ns0:customfield name="Custom 10" value="" />\n      <ns0:build version="2019-10 Testing" build_id="1234321" submitter="Jon Zeolla" platform="Not Specified" lifecycle_stage="Deployed (In production and actively developed)" results_ready="true" policy_name="Veracode Recommended Medium" policy_version="1" policy_compliance_status="Pass" rules_status="Pass" grace_period_expired="false" scan_overdue="false">\n         <ns0:analysis_unit analysis_type="Static" published_date="2019-10-13T16:20:30-04:00" published_date_sec="1570998030" status="Results Ready" />\n      </ns0:build>\n   </ns0:application>\n'
                    )

                    self.assertEqual([output.tag, output.attrib],
                                     [expected.tag, expected.attrib])

            # However, return False when the element_contains_error function
            # returns True
            with patch("veracode.check_compliance.element_contains_error",
                       return_value=True):
                self.assertFalse(
                    check_compliance.get_latest_completed_build(
                        results_api=results_api))

        # Return False when calling the get_latest_completed_build function
        # with a valid results_api and the http_get method returns an
        # ElementTree.Element which doesn't contain the provided app_id
        with patch.object(
                ResultsAPI,
                "http_get",
                return_value=test_constants.
                VALID_RESULTS_API_GETAPPBUILDS_RESPONSE_XML_PASSING_POLICY_COMPLIANCE_STATUS[
                    "Element"],
        ):
            with patch("veracode.check_compliance.element_contains_error",
                       return_value=False):
                with patch("veracode.api.get_app_id", return_value="31337"):
                    results_api = ResultsAPI(app_name="TestApp")
                    output = check_compliance.get_latest_completed_build(
                        results_api=results_api)
                    self.assertFalse(output)

        # Return False when calling the get_latest_completed_build function
        # with a valid results_api and the http_get method raises one of a
        # series of exceptions
        with patch("veracode.api.get_app_id", return_value="1337"):
            results_api = ResultsAPI(app_name="TestApp")
            for err in [
                    HTTPError,
                    ConnectionError,
                    Timeout,
                    TooManyRedirects,
                    RequestException,
            ]:
                with patch(
                        "veracode.check_compliance.element_contains_error",
                        return_value=False,
                ):
                    with patch.object(ResultsAPI, "http_get", side_effect=err):
                        output = check_compliance.get_latest_completed_build(
                            results_api=results_api)
                        self.assertFalse(output)