def test_bot_to_entity_to_bot(self):
     bot = Bot(
         app_id='app_id',
         bot_id='bot_id',
         bot_token='bot_token',
         bot_user_id='bot_user_id',
         installed_at=55.00,
     )
     entity = Entity()
     entity.update(bot.__dict__)
     from_entity = Bot(**entity)
     self.assertEqual(bot.__dict__, from_entity.__dict__)
Esempio n. 2
0
 def find_bot(
     self,
     *,
     enterprise_id: Optional[str],
     team_id: Optional[str],
     is_enterprise_install: Optional[bool] = False,
 ) -> Optional[Bot]:
     none = "none"
     e_id = enterprise_id or none
     t_id = team_id or none
     if is_enterprise_install:
         t_id = none
     workspace_path = f"{self.client_id}/{e_id}-{t_id}"
     try:
         fetch_response = self.s3_client.get_object(
             Bucket=self.bucket_name,
             Key=f"{workspace_path}/bot-latest",
         )
         self.logger.debug(f"S3 get_object response: {fetch_response}")
         body = fetch_response["Body"].read().decode("utf-8")
         data = json.loads(body)
         return Bot(**data)
     except Exception as e:  # skipcq: PYL-W0703
         message = f"Failed to find bot installation data for enterprise: {e_id}, team: {t_id}: {e}"
         self.logger.warning(message)
         return None
Esempio n. 3
0
    def find_bot(
        self,
        *,
        enterprise_id: Optional[str],
        team_id: Optional[str],
        is_enterprise_install: Optional[bool] = False,
    ) -> Optional[Bot]:
        if is_enterprise_install or team_id is None:
            team_id = None

        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)
        )

        with self.engine.connect() as conn:
            result: object = conn.execute(query)
            for row in result:
                return Bot(
                    app_id=row["app_id"],
                    enterprise_id=row["enterprise_id"],
                    enterprise_name=row["enterprise_name"],
                    team_id=row["team_id"],
                    team_name=row["team_name"],
                    bot_token=row["bot_token"],
                    bot_id=row["bot_id"],
                    bot_user_id=row["bot_user_id"],
                    bot_scopes=row["bot_scopes"],
                    is_enterprise_install=row["is_enterprise_install"],
                    installed_at=row["installed_at"],
                )
            return None
    def test_find_bot(self, mock_client_get):
        workspace_key = ds_util.client.key('SlackWorkspace',
                                           'enterprise_id-team_id')
        store = DatastoreInstallationStore(ds_util.client)

        bot_entity = Entity(
            ds_util.client.key('SlackBot', 'bot-latest', parent=workspace_key))
        bot_entity.update(
            Bot(
                app_id='app_id',
                bot_id='bot_id',
                bot_token='bot_token',
                bot_user_id='bot_user_id',
                installed_at=55.00,
            ).__dict__)
        mock_client_get.return_value = bot_entity
        found_bot = store.find_bot(enterprise_id='enterprise_id',
                                   team_id='team_id')
        self.assertIsNotNone(found_bot)
        self.assertIsInstance(found_bot, Bot)

        # Make sure we searched for the right key.
        key = mock_client_get.call_args[0][0]
        self.assertEqual(
            key,
            ds_util.client.key('SlackBot', 'bot-latest', parent=workspace_key))
    def test_installation_bot_to_entity_to_bot(self):
        installation = Installation(app_id='app_id', user_id='user_id')

        bot = installation.to_bot()
        entity = Entity()
        entity.update(bot.__dict__)
        from_entity = Bot(**entity)
        self.assertEqual(bot.__dict__, from_entity.__dict__)
Esempio n. 6
0
    def find_bot(
        self,
        *,
        enterprise_id: Optional[str],
        team_id: Optional[str],
    ) -> Optional[Bot]:
        # Not yet implemented: org-apps support
        try:
            with self.connect() as conn:
                cur = conn.execute(
                    """
                    select
                        app_id,
                        enterprise_id,
                        team_id,
                        bot_token,
                        bot_id,
                        bot_user_id,
                        bot_scopes,
                        installed_at
                    from
                        slack_bots
                    where
                        client_id = ?
                        and
                        enterprise_id = ?
                        and
                        team_id = ?
                    order by installed_at desc
                    limit 1
                    """,
                    [self.client_id, enterprise_id or "", team_id or ""],
                )
                row = cur.fetchone()
                result = "found" if row and len(row) > 0 else "not found"
                self.logger.debug(
                    f"find_bot's query result: {result} (database: {self.database})"
                )
                if row and len(row) > 0:
                    bot = Bot(
                        app_id=row[0],
                        enterprise_id=row[1],
                        team_id=row[2],
                        bot_token=row[3],
                        bot_id=row[4],
                        bot_user_id=row[5],
                        bot_scopes=row[6],
                        installed_at=row[7],
                    )
                    return bot
                return None

        except Exception as e:  # skipcq: PYL-W0703
            message = f"Failed to find bot installation data for enterprise: {enterprise_id}, team: {team_id}: {e}"
            self.logger.warning(message)
            return None
Esempio n. 7
0
 def to_bot(self) -> Bot:
     return Bot(
         app_id=self.app_id,
         enterprise_id=self.enterprise_id,
         team_id=self.team_id,
         bot_token=self.bot_token,
         bot_id=self.bot_id,
         bot_user_id=self.bot_user_id,
         bot_scopes=self.bot_scopes,
         installed_at=self.installed_at,
     )
Esempio n. 8
0
 def to_bot(self) -> Bot:
     return Bot(
         app_id=self.app_id,
         enterprise_id=self.enterprise_id,
         enterprise_name=self.enterprise_name,
         team_id=self.team_id,
         team_name=self.team_name,
         bot_token=self.bot_token,
         bot_id=self.bot_id,
         bot_user_id=self.bot_user_id,
         bot_scopes=self.bot_scopes,
         is_enterprise_install=self.is_enterprise_install,
         installed_at=self.installed_at,
         custom_values=self.custom_values,
     )
Esempio n. 9
0
 def find_bot(
     self,
     *,
     enterprise_id: Optional[str],
     team_id: Optional[str],
 ) -> Optional[Bot]:
     # Not yet implemented: org-apps support
     none = "none"
     e_id = enterprise_id or none
     t_id = team_id or none
     bot_filepath = f"{self.base_dir}/{e_id}-{t_id}/bot-latest"
     try:
         with open(bot_filepath) as f:
             data = json.loads(f.read())
             return Bot(**data)
     except FileNotFoundError as e:
         message = f"Failed to find bot installation data for enterprise: {e_id}, team: {t_id}: {e}"
         self.logger.warning(message)
         return None
Esempio n. 10
0
 def find_bot(
     self,
     *,
     enterprise_id: Optional[str],
     team_id: Optional[str],
     is_enterprise_install: Optional[bool] = False,
 ) -> Optional[Bot]:
     if is_enterprise_install:
         team_id = None
     workspace_key = SlackWorkspace.key(enterprise_id,
                                        team_id,
                                        parent=self.parent)
     bot_key = SlackBot.key('bot-latest', parent=workspace_key)
     try:
         entity = self.client.get(bot_key)
         self.logger.debug(f"DS get response: {entity}")
         return Bot(**entity)
     except Exception:
         self.logger.exception(
             f"Failed to find bot installation for: {bot_key}")
         return None
Esempio n. 11
0
    def find_bot(
        self,
        *,
        enterprise_id: Optional[str],
        team_id: Optional[str],
        is_enterprise_install: Optional[bool] = False,
    ) -> Optional[Bot]:
        try:
            enterprise_id, team_id = self._input_sanitize(
                enterprise_id, team_id)
            response = self._store_service.find_bot(
                enterprise_id=enterprise_id, team_id=team_id)

            bot_payload = json.loads(response.data)
            return Bot(**bot_payload)
        except Exception as e:
            message = \
                "Failed to find bot installation data for enterprise:" \
                f"{enterprise_id}, team: {team_id}: {e}"

            self.logger.warning(message)
            return None
Esempio n. 12
0
 def find_bot(
     self,
     *,
     enterprise_id: Optional[str],
     team_id: Optional[str],
     is_enterprise_install: Optional[bool] = False,
 ) -> Optional[Bot]:
     none = "none"
     e_id = enterprise_id or none
     t_id = team_id or none
     if is_enterprise_install:
         t_id = none
     bot_filepath = f"{self.base_dir}/{e_id}-{t_id}/bot-latest"
     try:
         with open(bot_filepath) as f:
             data = json.loads(f.read())
             return Bot(**data)
     except FileNotFoundError as e:
         message = (
             f"Installation data missing for enterprise: {e_id}, team: {t_id}: {e}"
         )
         self.logger.debug(message)
         return None
Esempio n. 13
0
    def save_bot(self, bot: Bot):
        with self.engine.begin() as conn:
            # bots
            b = bot.to_dict()
            b["client_id"] = self.client_id

            b_column = self.bots.c
            bots_rows = conn.execute(
                sqlalchemy.select([b_column.id]).where(
                    and_(
                        b_column.client_id == self.client_id,
                        b_column.enterprise_id == bot.enterprise_id,
                        b_column.team_id == bot.team_id,
                        b_column.installed_at == b.get("installed_at"),
                    )).limit(1))
            bots_row_id: Optional[str] = None
            for row in bots_rows:
                bots_row_id = row["id"]
            if bots_row_id is None:
                conn.execute(self.bots.insert(), b)
            else:
                update_statement = (self.bots.update().where(
                    b_column.id == bots_row_id).values(**b))
                conn.execute(update_statement, b)
Esempio n. 14
0
    def find_bot(
        self,
        *,
        enterprise_id: Optional[str],
        team_id: Optional[str],
        is_enterprise_install: Optional[bool] = False,
    ) -> Optional[Bot]:
        if is_enterprise_install or team_id is None:
            team_id = ""

        try:
            with self.connect() as conn:
                cur = conn.execute(
                    """
                    select
                        app_id,
                        enterprise_id,
                        enterprise_name,
                        team_id,
                        team_name,
                        bot_token,
                        bot_id,
                        bot_user_id,
                        bot_scopes,
                        bot_refresh_token,  -- since v3.8
                        bot_token_expires_at,  -- since v3.8
                        is_enterprise_install,
                        installed_at
                    from
                        slack_bots
                    where
                        client_id = ?
                        and
                        enterprise_id = ?
                        and
                        team_id = ?
                    order by installed_at desc
                    limit 1
                    """,
                    [self.client_id, enterprise_id or "", team_id or ""],
                )
                row = cur.fetchone()
                result = "found" if row and len(row) > 0 else "not found"
                self.logger.debug(
                    f"find_bot's query result: {result} (database: {self.database})"
                )
                if row and len(row) > 0:
                    bot = Bot(
                        app_id=row[0],
                        enterprise_id=row[1],
                        enterprise_name=row[2],
                        team_id=row[3],
                        team_name=row[4],
                        bot_token=row[5],
                        bot_id=row[6],
                        bot_user_id=row[7],
                        bot_scopes=row[8],
                        bot_refresh_token=row[9],
                        bot_token_expires_at=row[10],
                        is_enterprise_install=row[11],
                        installed_at=row[12],
                    )
                    return bot
                return None

        except Exception as e:  # skipcq: PYL-W0703
            message = f"Failed to find bot installation data for enterprise: {enterprise_id}, team: {team_id}: {e}"
            if self.logger.level <= logging.DEBUG:
                self.logger.exception(message)
            else:
                self.logger.warning(message)
            return None