예제 #1
0
    async def test_installation_store_cached_legacy(self):
        installation_store = LegacyMemoryInstallationStore()
        authorize = AsyncInstallationStoreAuthorize(
            logger=installation_store.logger,
            installation_store=installation_store,
            cache_enabled=True,
        )
        assert authorize.find_installation_available is None
        context = AsyncBoltContext()
        context["client"] = self.client
        result = await authorize(context=context,
                                 enterprise_id="E111",
                                 team_id="T0G9PQBBK",
                                 user_id="W11111")
        assert authorize.find_installation_available is False
        assert result.bot_id == "BZYBOTHED"
        assert result.bot_user_id == "W23456789"
        assert result.user_token is None
        await assert_auth_test_count_async(self, 1)

        result = await authorize(context=context,
                                 enterprise_id="E111",
                                 team_id="T0G9PQBBK",
                                 user_id="W11111")
        assert result.bot_id == "BZYBOTHED"
        assert result.bot_user_id == "W23456789"
        assert result.user_token is None
        await assert_auth_test_count_async(self, 1)  # cached
예제 #2
0
    async def __call__(
        self,
        *,
        context: AsyncBoltContext,
        enterprise_id: Optional[str],
        team_id: Optional[str],  # can be None for org-wide installed apps
        user_id: Optional[str],
    ) -> Optional[AuthorizeResult]:
        try:
            all_available_args = {
                "args":
                AsyncAuthorizeArgs(
                    context=context,
                    enterprise_id=enterprise_id,
                    team_id=team_id,
                    user_id=user_id,
                ),
                "logger":
                context.logger,
                "client":
                context.client,
                "context":
                context,
                "enterprise_id":
                enterprise_id,
                "team_id":
                team_id,
                "user_id":
                user_id,
            }
            for k, v in context.items():
                if k not in all_available_args:
                    all_available_args[k] = v

            kwargs: Dict[str, Any] = {  # type: ignore
                k: v
                for k, v in all_available_args.items()
                if k in self.arg_names  # type: ignore
            }
            found_arg_names = kwargs.keys()
            for name in self.arg_names:
                if name not in found_arg_names:
                    self.logger.warning(f"{name} is not a valid argument")
                    kwargs[name] = None

            auth_result: Optional[AuthorizeResult] = await self.func(**kwargs)
            if auth_result is None:
                return auth_result

            if isinstance(auth_result, AuthorizeResult):
                return auth_result
            else:
                raise ValueError(
                    f"Unexpected returned value from authorize function (type: {type(auth_result)})"
                )
        except SlackApiError as err:
            self.logger.debug(
                f"The stored bot token for enterprise_id: {enterprise_id} team_id: {team_id} "
                f"is no longer valid. (response: {err.response})")
            return None
예제 #3
0
    async def test_installation_store(self):
        installation_store = MemoryInstallationStore()
        authorize = AsyncInstallationStoreAuthorize(
            logger=installation_store.logger,
            installation_store=installation_store)
        assert authorize.find_installation_available is None
        context = AsyncBoltContext()
        context["client"] = self.client
        result = await authorize(context=context,
                                 enterprise_id="E111",
                                 team_id="T0G9PQBBK",
                                 user_id="W11111")
        assert authorize.find_installation_available is True
        assert result.bot_id == "BZYBOTHED"
        assert result.bot_user_id == "W23456789"
        assert result.user_token == "xoxp-valid"
        await assert_auth_test_count_async(self, 1)

        result = await authorize(context=context,
                                 enterprise_id="E111",
                                 team_id="T0G9PQBBK",
                                 user_id="W11111")
        assert result.bot_id == "BZYBOTHED"
        assert result.bot_user_id == "W23456789"
        assert result.user_token == "xoxp-valid"
        await assert_auth_test_count_async(self, 2)
예제 #4
0
    async def test_installation_store_legacy(self):
        installation_store = LegacyMemoryInstallationStore()
        authorize = AsyncInstallationStoreAuthorize(
            logger=installation_store.logger,
            installation_store=installation_store)
        assert authorize.find_installation_available is None
        context = AsyncBoltContext()
        context["client"] = self.client
        result = await authorize(context=context,
                                 enterprise_id="E111",
                                 team_id="T0G9PQBBK",
                                 user_id="W11111")
        assert authorize.find_installation_available is False
        assert result.bot_id == "BZYBOTHED"
        assert result.bot_user_id == "W23456789"
        assert result.user_token is None
        assert self.mock_received_requests["/auth.test"] == 1

        result = await authorize(context=context,
                                 enterprise_id="E111",
                                 team_id="T0G9PQBBK",
                                 user_id="W11111")
        assert result.bot_id == "BZYBOTHED"
        assert result.bot_user_id == "W23456789"
        assert result.user_token is None
        assert self.mock_received_requests["/auth.test"] == 2
예제 #5
0
    def __init__(
        self,
        *,
        body: str,
        query: Optional[Union[str, Dict[str, str],
                              Dict[str, Sequence[str]]]] = None,
        headers: Optional[Dict[str, Union[str, Sequence[str]]]] = None,
        context: Optional[Dict[str, str]] = None,
    ):
        """Request to a Bolt app.

        :param body: The raw request body (only plain text is supported)
        :param query: The query string data in any data format.
        :param headers: The request headers.
        :param context: The context in this request.
        """
        self.raw_body = body
        self.query = parse_query(query)
        self.headers = build_normalized_headers(headers)
        self.content_type = extract_content_type(self.headers)
        self.body = parse_body(self.raw_body, self.content_type)
        self.context = build_async_context(
            AsyncBoltContext(context if context else {}), self.body)
        self.lazy_only = self.headers.get("x-slack-bolt-lazy-only", [False])[0]
        self.lazy_function_name = self.headers.get(
            "x-slack-bolt-lazy-function-name", [None])[0]
예제 #6
0
 async def test_root_class(self):
     authorize = AsyncAuthorize()
     with pytest.raises(NotImplementedError):
         await authorize(
             context=AsyncBoltContext(),
             enterprise_id="T111",
             team_id="T111",
             user_id="U111",
         )
예제 #7
0
    def __init__(
            self,
            *,
            body: Union[str, dict],
            query: Optional[Union[str, Dict[str, str],
                                  Dict[str, Sequence[str]]]] = None,
            headers: Optional[Dict[str, Union[str, Sequence[str]]]] = None,
            context: Optional[Dict[str, str]] = None,
            mode: str = "http",  # either "http" or "socket_mode"
    ):
        """Request to a Bolt app.

        Args:
            body: The raw request body (only plain text is supported for "http" mode)
            query: The query string data in any data format.
            headers: The request headers.
            context: The context in this request.
            mode: The mode used for this request. (either "http" or "socket_mode")
        """

        if mode == "http":
            # HTTP Mode
            if body is not None and not isinstance(body, str):
                raise BoltError(error_message_raw_body_required_in_http_mode())
            self.raw_body = body if body is not None else ""
        else:
            # Socket Mode
            if body is not None and isinstance(body, str):
                self.raw_body = body
            else:
                # We don't convert the dict value to str
                # as doing so does not guarantee to keep the original structure/format.
                self.raw_body = ""

        self.query = parse_query(query)
        self.headers = build_normalized_headers(headers)
        self.content_type = extract_content_type(self.headers)

        if isinstance(body, str):
            self.body = parse_body(self.raw_body, self.content_type)
        elif isinstance(body, dict):
            self.body = body
        else:
            self.body = {}

        self.context = build_async_context(
            AsyncBoltContext(context if context else {}), self.body)
        self.lazy_only = bool(
            self.headers.get("x-slack-bolt-lazy-only", [False])[0])
        self.lazy_function_name = self.headers.get(
            "x-slack-bolt-lazy-function-name", [None])[0]
        self.mode = mode
예제 #8
0
 def __init__(
     self,
     *,
     body: str,
     query: Optional[Union[str, Dict[str, str], Dict[str,
                                                     List[str]]]] = None,
     # many framework use Dict[str, str] but the reality is Dict[str, List[str]]
     headers: Optional[Dict[str, Union[str, List[str]]]] = None,
     context: Optional[Dict[str, str]] = None,
 ):
     self.body = body
     self.query = parse_query(query)
     self.headers = build_normalized_headers(headers)
     self.content_type = extract_content_type(self.headers)
     self.payload = parse_payload(self.body, self.content_type)
     self.context = build_async_context(
         AsyncBoltContext(context if context else {}), self.payload)
예제 #9
0
    def __init__(
            self,
            *,
            body: Union[str, dict],
            query: Optional[Union[str, Dict[str, str],
                                  Dict[str, Sequence[str]]]] = None,
            headers: Optional[Dict[str, Union[str, Sequence[str]]]] = None,
            context: Optional[Dict[str, str]] = None,
            mode: str = "http",  # either "http" or "socket_mode"
    ):
        """Request to a Bolt app.

        :param body: The raw request body (only plain text is supported for "http" mode)
        :param query: The query string data in any data format.
        :param headers: The request headers.
        :param context: The context in this request.
        :param mode: The mode used for this request. (either "http" or "socket_mode")
        """
        if mode == "http" and not isinstance(body, str):
            raise BoltError(error_message_raw_body_required_in_http_mode())
        self.raw_body = body if mode == "http" else ""
        self.query = parse_query(query)
        self.headers = build_normalized_headers(headers)
        self.content_type = extract_content_type(self.headers)
        if isinstance(body, str):
            self.body = parse_body(self.raw_body, self.content_type)
        elif isinstance(body, dict):
            self.body = body
        else:
            raise BoltError(error_message_unknown_request_body_type())
        self.context = build_async_context(
            AsyncBoltContext(context if context else {}), self.body)
        self.lazy_only = self.headers.get("x-slack-bolt-lazy-only", [False])[0]
        self.lazy_function_name = self.headers.get(
            "x-slack-bolt-lazy-function-name", [None])[0]
        self.mode = mode