33from typing import Optional , Callable , Awaitable , Dict , Any
44
55from slack_sdk .errors import SlackApiError
6- from slack_sdk .oauth .installation_store import Bot
6+ from slack_sdk .oauth .installation_store import Bot , Installation
77from slack_sdk .oauth .installation_store .async_installation_store import (
88 AsyncInstallationStore ,
99)
@@ -92,6 +92,7 @@ async def __call__(
9292
9393class AsyncInstallationStoreAuthorize (AsyncAuthorize ):
9494 authorize_result_cache : Dict [str , AuthorizeResult ] = {}
95+ find_installation_available : Optional [bool ]
9596
9697 def __init__ (
9798 self ,
@@ -103,6 +104,7 @@ def __init__(
103104 self .logger = logger
104105 self .installation_store = installation_store
105106 self .cache_enabled = cache_enabled
107+ self .find_installation_available = None
106108
107109 async def __call__ (
108110 self ,
@@ -112,31 +114,88 @@ async def __call__(
112114 team_id : str ,
113115 user_id : Optional [str ],
114116 ) -> Optional [AuthorizeResult ]:
115- bot : Optional [Bot ] = await self .installation_store .async_find_bot (
116- enterprise_id = enterprise_id , team_id = team_id ,
117- )
118- if bot is None :
119- self .logger .debug (
120- f"No installation data found "
121- f"for enterprise_id: { enterprise_id } team_id: { team_id } "
117+
118+ if self .find_installation_available is None :
119+ self .find_installation_available = hasattr (
120+ self .installation_store , "async_find_installation"
122121 )
122+
123+ bot_token : Optional [str ] = None
124+ user_token : Optional [str ] = None
125+
126+ if self .find_installation_available :
127+ # since v1.1, this is the default way
128+ try :
129+ installation : Optional [
130+ Installation
131+ ] = await self .installation_store .async_find_installation (
132+ enterprise_id = enterprise_id ,
133+ team_id = team_id ,
134+ is_enterprise_install = context .is_enterprise_install ,
135+ )
136+ if installation is None :
137+ self ._debug_log_for_not_found (enterprise_id , team_id )
138+ return None
139+
140+ if installation .user_id != user_id :
141+ # try to fetch the request user's installation
142+ # to reflect the user's access token if exists
143+ user_installation = await self .installation_store .async_find_installation (
144+ enterprise_id = enterprise_id ,
145+ team_id = team_id ,
146+ user_id = user_id ,
147+ is_enterprise_install = context .is_enterprise_install ,
148+ )
149+ if user_installation is not None :
150+ installation = user_installation
151+
152+ bot_token , user_token = installation .bot_token , installation .user_token
153+ except NotImplementedError as _ :
154+ self .find_installation_available = False
155+
156+ if not self .find_installation_available :
157+ # Use find_bot to get bot value (legacy)
158+ bot : Optional [Bot ] = await self .installation_store .async_find_bot (
159+ enterprise_id = enterprise_id ,
160+ team_id = team_id ,
161+ is_enterprise_install = context .is_enterprise_install ,
162+ )
163+ if bot is None :
164+ self ._debug_log_for_not_found (enterprise_id , team_id )
165+ return None
166+ bot_token , user_token = bot .bot_token , None
167+
168+ token : Optional [str ] = bot_token or user_token
169+ if token is None :
123170 return None
124171
125- if self .cache_enabled and bot .bot_token in self .authorize_result_cache :
126- return self .authorize_result_cache [bot .bot_token ]
172+ # Check cache to see if the bot object already exists
173+ if self .cache_enabled and token in self .authorize_result_cache :
174+ return self .authorize_result_cache [token ]
175+
127176 try :
128- auth_result = await context .client .auth_test (token = bot . bot_token )
177+ auth_test_api_response = await context .client .auth_test (token = token )
129178 authorize_result = AuthorizeResult .from_auth_test_response (
130- auth_test_response = auth_result ,
131- bot_token = bot . bot_token ,
132- user_token = None , # Not yet supported
179+ auth_test_response = auth_test_api_response ,
180+ bot_token = bot_token ,
181+ user_token = user_token ,
133182 )
134183 if self .cache_enabled :
135- self .authorize_result_cache [bot . bot_token ] = authorize_result
184+ self .authorize_result_cache [token ] = authorize_result
136185 return authorize_result
137186 except SlackApiError as err :
138187 self .logger .debug (
139188 f"The stored bot token for enterprise_id: { enterprise_id } team_id: { team_id } "
140189 f"is no longer valid. (response: { err .response } )"
141190 )
142191 return None
192+
193+ # ------------------------------------------------
194+
195+ def _debug_log_for_not_found (
196+ self , enterprise_id : Optional [str ], team_id : Optional [str ]
197+ ):
198+ self .logger .debug (
199+ "No installation data found "
200+ f"for enterprise_id: { enterprise_id } team_id: { team_id } "
201+ )
0 commit comments