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(),
     )
Example #2
0
 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(),
     )
Example #3
0
    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()
Example #4
0
 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
Example #5
0
    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)