async def async_find_bot( self, *, enterprise_id: Optional[str], team_id: Optional[str], is_enterprise_install: Optional[bool] = False, ) -> Optional[Bot]: return Bot( app_id="A111", enterprise_id="E111", team_id="T0G9PQBBK", bot_token="xoxb-valid", bot_id="B", bot_user_id="W", bot_scopes=["commands", "chat:write"], installed_at=datetime.datetime.now().timestamp(), )
async def async_find_bot( self, *, enterprise_id: Optional[str], team_id: Optional[str], is_enterprise_install: Optional[bool] = False, ) -> Optional[Bot]: return Bot( app_id="A111", enterprise_id="E111", team_id="T111", bot_token=valid_token, bot_id="B111", bot_user_id="W111", bot_scopes=["commands"], installed_at=time(), )
def save_bot(self, bot: Bot): b = bot.to_dict() if is_naive(b['installed_at']): b['installed_at'] = make_aware(b['installed_at']) if 'bot_token_expires_at' in b and b[ 'bot_token_expires_at'] is not None and is_naive( b['bot_token_expires_at']): b['bot_token_expires_at'] = make_aware(b['bot_token_expires_at']) b['client_id'] = self.client_id row_to_update = (SlackBot.objects.filter( client_id=self.client_id).filter( enterprise_id=bot.enterprise_id).filter( team_id=bot.team_id).filter( installed_at=b['installed_at']).first()) if row_to_update is not None: for key, value in b.items(): setattr(row_to_update, key, value) row_to_update.save() else: SlackBot(**b).save()
async def async_find_bot(self, *, enterprise_id: Optional[str], team_id: Optional[str]) -> Optional[Bot]: c = self.bots.c query = (self.bots.select().where( and_(c.enterprise_id == enterprise_id, c.team_id == team_id)).order_by(desc( c.installed_at)).limit(1)) async with Database(self.database_url) as database: result = await database.fetch_one(query) if result: return Bot( app_id=result["app_id"], enterprise_id=result["enterprise_id"], team_id=result["team_id"], bot_token=result["bot_token"], bot_id=result["bot_id"], bot_user_id=result["bot_user_id"], bot_scopes=result["bot_scopes"], installed_at=result["installed_at"], ) else: return None
async def perform_bot_token_rotation( # type: ignore self, *, bot: Bot, minutes_before_expiration: int = 120, # 2 hours by default ) -> Optional[Bot]: """Performs bot token rotation if the underlying bot token is expired / expiring. Args: bot: the current bot installation data minutes_before_expiration: the minutes before the token expiration Returns: None if no rotation is necessary for now. """ if bot.bot_token_expires_at is None: return None if bot.bot_token_expires_at > time() + minutes_before_expiration * 60: return None try: refresh_response = await self.client.oauth_v2_access( client_id=self.client_id, client_secret=self.client_secret, grant_type="refresh_token", refresh_token=bot.bot_refresh_token, ) # TODO: error handling if refresh_response.get("token_type") != "bot": return None refreshed_bot = Bot(**bot.to_dict()) # type: ignore refreshed_bot.bot_token = refresh_response.get("access_token") refreshed_bot.bot_refresh_token = refresh_response.get("refresh_token") refreshed_bot.bot_token_expires_at = int(time()) + int( refresh_response.get("expires_in") ) return refreshed_bot except SlackApiError as e: raise SlackTokenRotationError(e)