def _get_permission()

in samtranslator/model/eventsources/push.py [0:0]


    def _get_permission(self, resources_to_link, stage):  # type: ignore[no-untyped-def]
        # It turns out that APIGW doesn't like trailing slashes in paths (#665)
        # and removes as a part of their behaviour, but this isn't documented.
        # The regex removes the tailing slash to ensure the permission works as intended
        path = re.sub(r"^(.+)/$", r"\1", self._path)

        editor = None
        if resources_to_link["explicit_api"].get("DefinitionBody"):
            try:
                editor = OpenApiEditor(resources_to_link["explicit_api"].get("DefinitionBody"))
            except InvalidDocumentException as e:
                api_logical_id = self.ApiId.get("Ref") if isinstance(self.ApiId, dict) else self.ApiId
                # TODO: api_logical_id is never None, try to make it consistent with what mypy thinks
                raise InvalidResourceException(
                    cast(str, api_logical_id), " ".join(ex.message for ex in e.causes)
                ) from e

        # If this is using the new $default path, keep path blank and add a * permission
        if path == OpenApiEditor._DEFAULT_PATH:
            path = ""
        elif editor and editor.is_integration_function_logical_id_match(  # type: ignore[no-untyped-call]
            OpenApiEditor._DEFAULT_PATH, OpenApiEditor._X_ANY_METHOD, resources_to_link.get("function").logical_id
        ):
            # Case where default exists for this function, and so the permissions for that will apply here as well
            # This can save us several CFN resources (not duplicating permissions)
            return None
        path = OpenApiEditor.get_path_without_trailing_slash(path)  # type: ignore[no-untyped-call]

        # Handle case where Method is already the ANY ApiGateway extension
        method = (
            "*"
            if self._method.lower() == "any" or self._method.lower() == OpenApiEditor._X_ANY_METHOD
            else self._method.upper()
        )

        api_id = self.ApiId

        # when the Method is "ANY" and the path is '/$default' it adds an extra "*" which causes a bug
        # the generated ARN for permissions ends with /*/*/$default which causes the path to be invalid
        # see this issue: https://github.com/aws/serverless-application-model/issues/1860
        resource = "${__ApiId__}/${__Stage__}"
        if self._method.lower() == "any" and path == f"/{OpenApiEditor._DEFAULT_PATH}":
            resource += path
        else:
            resource += f"/{method}{path}"

        # ApiId can be a simple string or intrinsic function like !Ref. Using Fn::Sub will handle both cases
        source_arn = fnSub(
            ArnGenerator.generate_arn(partition="${AWS::Partition}", service="execute-api", resource=resource),
            {"__ApiId__": api_id, "__Stage__": stage},
        )

        return self._construct_permission(resources_to_link["function"], source_arn=source_arn)  # type: ignore[no-untyped-call]