Exemple #1
0
    def test_auth_supplied_via_definition_body_uri(self):
        self.template_dict["Resources"]["HelloWorldApi"] = OrderedDict(
            [
                ("Type", "AWS::Serverless::Api"),
                (
                    "Properties",
                    OrderedDict(
                        [
                            ("StageName", "Prod"),
                            (
                                "DefinitionBody",
                                {
                                    "swagger": "2.0",
                                    "info": {"version": "1.0", "title": "local"},
                                    "paths": {"/hello": {"get": {"security": ["OAuth2"]}}},
                                },
                            ),
                        ]
                    ),
                ),
            ]
        )
        # setup the lambda function with a restapiId which has definitionBody defined with auth on the route.
        self.template_dict["Resources"]["HelloWorldFunction"]["Properties"]["Events"]["HelloWorld"]["Properties"][
            "RestApiId"
        ] = {"Ref": "HelloWorldApi"}
        _auth_per_resource = auth_per_resource({}, self.template_dict)

        self.assertEqual(_auth_per_resource, [("HelloWorldFunction", True)])
    def deploy(
        self,
        stack_name,
        template_str,
        parameters,
        capabilities,
        no_execute_changeset,
        role_arn,
        notification_arns,
        s3_uploader,
        tags,
        region,
        fail_on_empty_changeset=True,
        confirm_changeset=False,
    ):

        auth_required_per_resource = auth_per_resource(
            sanitize_parameter_overrides(self.parameter_overrides),
            get_template_data(self.template_file))

        for resource, authorization_required in auth_required_per_resource:
            if not authorization_required:
                click.secho(f"{resource} may not have authorization defined.",
                            fg="yellow")

        try:
            result, changeset_type = self.deployer.create_and_wait_for_changeset(
                stack_name=stack_name,
                cfn_template=template_str,
                parameter_values=parameters,
                capabilities=capabilities,
                role_arn=role_arn,
                notification_arns=notification_arns,
                s3_uploader=s3_uploader,
                tags=tags,
            )
            click.echo(
                self.MSG_SHOWCASE_CHANGESET.format(changeset_id=result["Id"]))

            if no_execute_changeset:
                return

            if confirm_changeset:
                click.secho(self.MSG_CONFIRM_CHANGESET_HEADER, fg="yellow")
                click.secho("=" * len(self.MSG_CONFIRM_CHANGESET_HEADER),
                            fg="yellow")
                if not click.confirm(f"{self.MSG_CONFIRM_CHANGESET}",
                                     default=False):
                    return

            self.deployer.execute_changeset(result["Id"], stack_name)
            self.deployer.wait_for_execute(stack_name, changeset_type)
            click.echo(
                self.MSG_EXECUTE_SUCCESS.format(stack_name=stack_name,
                                                region=region))

        except deploy_exceptions.ChangeEmptyError as ex:
            if fail_on_empty_changeset:
                raise
            click.echo(str(ex))
Exemple #3
0
 def test_auth_per_resource_auth_on_event_properties(self):
     event_properties = self.template_dict["Resources"][
         "HelloWorldFunction"]["Properties"]["Events"]["HelloWorld"][
             "Properties"]
     # setup authorizer and auth explicitly on the event properties.
     event_properties["Auth"] = {"ApiKeyRequired": True, "Authorizer": None}
     self.template_dict["Resources"]["HelloWorldFunction"]["Properties"][
         "Events"]["HelloWorld"]["Properties"] = event_properties
     _auth_per_resource = auth_per_resource(
         [Stack("", "", "", {}, self.template_dict)])
     self.assertEqual(_auth_per_resource, [("HelloWorldFunction", True)])
    def prompt_authorization(self, stacks: List[Stack]):
        auth_required_per_resource = auth_per_resource(stacks)

        for resource, authorization_required in auth_required_per_resource:
            if not authorization_required:
                auth_confirm = confirm(
                    f"\t{self.start_bold}{resource} may not have authorization defined, Is this okay?{self.end_bold}",
                    default=False,
                )
                if not auth_confirm:
                    raise GuidedDeployFailedError(
                        msg="Security Constraints Not Satisfied!")
Exemple #5
0
 def test_auth_per_resource_defined_on_api_resource(self):
     self.template_dict["Resources"]["HelloWorldApi"] = OrderedDict(
         [
             ("Type", "AWS::Serverless::Api"),
             ("Properties", OrderedDict([("StageName", "Prod"), ("Auth", OrderedDict([("ApiKeyRequired", True)]))])),
         ]
     )
     # setup the lambda function with a restapiId which has Auth defined.
     self.template_dict["Resources"]["HelloWorldFunction"]["Properties"]["Events"]["HelloWorld"]["Properties"][
         "RestApiId"
     ] = {"Ref": "HelloWorldApi"}
     _auth_per_resource = auth_per_resource({}, self.template_dict)
     self.assertEqual(_auth_per_resource, [("HelloWorldFunction", True)])
    def prompt_authorization(self, parameter_overrides):
        auth_required_per_resource = auth_per_resource(
            parameter_overrides, get_template_data(self.template_file))

        for resource, authorization_required in auth_required_per_resource:
            if not authorization_required:
                auth_confirm = confirm(
                    f"\t{self.start_bold}{resource} may not have authorization defined, Is this okay?{self.end_bold}",
                    default=False,
                )
                if not auth_confirm:
                    raise GuidedDeployFailedError(
                        msg="Security Constraints Not Satisfied!")
Exemple #7
0
    def test_auth_supplied_via_definition_body_uri_instrinsics_involved_unable_to_determine(
            self):
        self.template_dict["Resources"]["HelloWorldApi"] = OrderedDict([
            ("Type", "AWS::Serverless::Api"),
            (
                "Properties",
                OrderedDict([
                    ("StageName", "Prod"),
                    (
                        "DefinitionBody",
                        {
                            "swagger": "2.0",
                            "info": {
                                "version": "1.0",
                                "title": "local"
                            },
                            "paths": {
                                "/hello": {
                                    "Fn::If": [
                                        "Condition", {
                                            "get": {}
                                        }, {
                                            "Ref": "AWS::NoValue"
                                        }
                                    ]
                                }
                            },
                        },
                    ),
                ]),
            ),
        ])
        # setup the lambda function with a restapiId which has definitionBody defined with auth on the route.
        self.template_dict["Resources"]["HelloWorldFunction"]["Properties"][
            "Events"]["HelloWorld"]["Properties"]["RestApiId"] = {
                "Ref": "HelloWorldApi"
            }
        _auth_per_resource = auth_per_resource(
            [Stack("", "", "", {}, self.template_dict)])

        self.assertEqual(_auth_per_resource, [("HelloWorldFunction", False)])
Exemple #8
0
 def test_auth_per_resource_no_auth(self):
     _auth_per_resource = auth_per_resource(
         [Stack("", "", "", {}, self.template_dict)])
     self.assertEqual(_auth_per_resource, [("HelloWorldFunction", False)])
    def deploy(
        self,
        stack_name,
        template_str,
        parameters,
        capabilities,
        no_execute_changeset,
        role_arn,
        notification_arns,
        s3_uploader,
        tags,
        region,
        fail_on_empty_changeset=True,
        confirm_changeset=False,
    ):
        """
        Deploy the stack to cloudformation.
        - if changeset needs confirmation, it will prompt for customers to confirm.
        - if no_execute_changeset is True, the changeset won't be executed.

        Parameters
        ----------
        stack_name : str
            name of the stack
        template_str : str
            the string content of the template
        parameters : List[Dict]
            List of parameters
        capabilities : List[str]
            List of capabilities
        no_execute_changeset : bool
            A bool indicating whether to execute changeset
        role_arn : str
            the Arn of the role to create changeset
        notification_arns : List[str]
            Arns for sending notifications
        s3_uploader : S3Uploader
            S3Uploader object to upload files to S3 buckets
        tags : List[str]
            List of tags passed to CloudFormation
        region : str
            AWS region to deploy the stack to
        fail_on_empty_changeset : bool
            Should fail when changeset is empty
        confirm_changeset : bool
            Should wait for customer's confirm before executing the changeset
        """
        stacks, _ = SamLocalStackProvider.get_stacks(
            self.template_file,
            parameter_overrides=sanitize_parameter_overrides(
                self.parameter_overrides))
        auth_required_per_resource = auth_per_resource(stacks)

        for resource, authorization_required in auth_required_per_resource:
            if not authorization_required:
                click.secho(f"{resource} may not have authorization defined.",
                            fg="yellow")

        try:
            result, changeset_type = self.deployer.create_and_wait_for_changeset(
                stack_name=stack_name,
                cfn_template=template_str,
                parameter_values=parameters,
                capabilities=capabilities,
                role_arn=role_arn,
                notification_arns=notification_arns,
                s3_uploader=s3_uploader,
                tags=tags,
            )
            click.echo(
                self.MSG_SHOWCASE_CHANGESET.format(changeset_id=result["Id"]))

            if no_execute_changeset:
                return

            if confirm_changeset:
                click.secho(self.MSG_CONFIRM_CHANGESET_HEADER, fg="yellow")
                click.secho("=" * len(self.MSG_CONFIRM_CHANGESET_HEADER),
                            fg="yellow")
                if not click.confirm(f"{self.MSG_CONFIRM_CHANGESET}",
                                     default=False):
                    return

            self.deployer.execute_changeset(result["Id"], stack_name)
            self.deployer.wait_for_execute(stack_name, changeset_type)
            click.echo(
                self.MSG_EXECUTE_SUCCESS.format(stack_name=stack_name,
                                                region=region))

        except deploy_exceptions.ChangeEmptyError as ex:
            if fail_on_empty_changeset:
                raise
            click.echo(str(ex))