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
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
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)
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
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]
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", )
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
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)
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