예제 #1
0
    def test_installation_store_conflicts(self):
        store1 = FileInstallationStore()
        store2 = FileInstallationStore()
        app = App(
            signing_secret="valid",
            oauth_settings=OAuthSettings(
                client_id="111.222",
                client_secret="valid",
                installation_store=store1,
            ),
            installation_store=store2,
        )
        assert app.installation_store is store1

        app = App(
            signing_secret="valid",
            oauth_flow=OAuthFlow(settings=OAuthSettings(
                client_id="111.222",
                client_secret="valid",
                installation_store=store1,
            )),
            installation_store=store2,
        )
        assert app.installation_store is store1

        app = App(
            signing_secret="valid",
            oauth_flow=OAuthFlow(settings=OAuthSettings(
                client_id="111.222",
                client_secret="valid",
            )),
            installation_store=store1,
        )
        assert app.installation_store is store1
예제 #2
0
    def setup_server(cls):
        cls.old_os_env = remove_os_env_temporarily()

        signing_secret = "secret"
        valid_token = "xoxb-valid"
        mock_api_server_base_url = "http://localhost:8888"
        web_client = WebClient(token=valid_token, base_url=mock_api_server_base_url,)
        app = App(
            client=web_client,
            signing_secret=signing_secret,
            oauth_settings=OAuthSettings(
                client_id="111.111",
                client_secret="xxx",
                scopes=["chat:write", "commands"],
            ),
        )
        handler = SlackRequestHandler(app)

        class SlackApp(object):
            @cherrypy.expose
            @cherrypy.tools.slack_in()
            def install(self, **kwargs):
                return handler.handle()

        cherrypy.tree.mount(SlackApp(), "/slack")
예제 #3
0
    def __init__(
        self,
        *,
        client: Optional[WebClient] = None,
        logger: Optional[Logger] = None,
        settings: OAuthSettings,
    ):
        """The module to run the Slack app installation flow (OAuth flow).

        :param client: The WebClient.
        :param logger: The logger.
        :param settings: OAuth settings to configure this module.
        """
        self._client = client
        self._logger = logger
        self.settings = settings
        self.settings.logger = self._logger

        self.client_id = self.settings.client_id
        self.redirect_uri = self.settings.redirect_uri
        self.install_path = self.settings.install_path
        self.redirect_uri_path = self.settings.redirect_uri_path

        self.default_callback_options = DefaultCallbackOptions(
            logger=logger,
            state_utils=self.settings.state_utils,
            redirect_uri_page_renderer=self.settings.
            redirect_uri_page_renderer,
        )
        if settings.callback_options is None:
            settings.callback_options = self.default_callback_options
        self.success_handler = settings.callback_options.success
        self.failure_handler = settings.callback_options.failure
예제 #4
0
    def test_authorize_conflicts(self):
        oauth_settings = OAuthSettings(
            client_id="111.222",
            client_secret="valid",
            installation_store=FileInstallationStore(),
            state_store=FileOAuthStateStore(expiration_seconds=120),
        )

        # no error with this
        App(signing_secret="valid", oauth_settings=oauth_settings)

        def authorize() -> AuthorizeResult:
            return AuthorizeResult(enterprise_id="E111", team_id="T111")

        with pytest.raises(BoltError):
            App(
                signing_secret="valid",
                authorize=authorize,
                oauth_settings=oauth_settings,
            )

        oauth_flow = OAuthFlow(settings=oauth_settings)
        # no error with this
        App(signing_secret="valid", oauth_flow=oauth_flow)

        with pytest.raises(BoltError):
            App(signing_secret="valid",
                authorize=authorize,
                oauth_flow=oauth_flow)
예제 #5
0
    def test_oauth(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            oauth_settings=OAuthSettings(
                client_id="111.111",
                client_secret="xxx",
                scopes=["chat:write", "commands"],
            ),
        )
        app_handler = SlackRequestHandler(app)

        async def endpoint(req: Request):
            return await app_handler.handle(req)

        api = Starlette(
            debug=True,
            routes=[
                Route("/slack/install", endpoint=endpoint, methods=["GET"])
            ],
        )
        client = TestClient(api)
        response = client.get("/slack/install", allow_redirects=False)
        assert response.status_code == 200
        assert response.headers.get(
            "content-type") == "text/html; charset=utf-8"
        assert "https://slack.com/oauth/v2/authorize?state=" in response.text
예제 #6
0
 def test_valid_multi_auth(self):
     app = App(
         signing_secret="valid",
         oauth_settings=OAuthSettings(client_id="111.222",
                                      client_secret="valid"),
     )
     assert app != None
 async def test_instantiation_non_async_settings(self):
     with pytest.raises(BoltError):
         AsyncOAuthFlow(settings=OAuthSettings(
             client_id="111.222",
             client_secret="xxx",
             scopes="chat:write,commands",
         ))
예제 #8
0
    def test_oauth(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            oauth_settings=OAuthSettings(
                client_id="111.111",
                client_secret="xxx",
                scopes=["chat:write", "commands"],
            ),
        )

        chalice_app = Chalice(app_name="bolt-python-chalice")
        slack_handler = ChaliceSlackRequestHandler(app=app,
                                                   chalice=chalice_app)

        @chalice_app.route("/slack/install", methods=["GET"])
        def install() -> Response:
            return slack_handler.handle(chalice_app.current_request)

        response: Dict[str, Any] = LocalGateway(
            chalice_app, Config()).handle_request(method="GET",
                                                  path="/slack/install",
                                                  body="",
                                                  headers={})
        assert response["statusCode"] == 200
        assert response["headers"][
            "content-type"] == "text/html; charset=utf-8"
        assert response["headers"]["content-length"] == "565"
        assert "https://slack.com/oauth/v2/authorize?state=" in response.get(
            "body")
예제 #9
0
 def test_valid_multi_auth_secret_absence(self):
     with pytest.raises(BoltError):
         App(
             signing_secret="valid",
             oauth_settings=OAuthSettings(client_id="111.222",
                                          client_secret=None),
         )
예제 #10
0
    def sqlite3(
        cls,
        database: str,
        # OAuth flow parameters/credentials
        client_id: Optional[str] = None,  # required
        client_secret: Optional[str] = None,  # required
        scopes: Optional[Sequence[str]] = None,
        user_scopes: Optional[Sequence[str]] = None,
        redirect_uri: Optional[str] = None,
        # Handler configuration
        install_path: Optional[str] = None,
        redirect_uri_path: Optional[str] = None,
        callback_options: Optional[CallbackOptions] = None,
        success_url: Optional[str] = None,
        failure_url: Optional[str] = None,
        authorization_url: Optional[str] = None,
        # Installation Management
        # state parameter related configurations
        state_cookie_name: str = OAuthStateUtils.default_cookie_name,
        state_expiration_seconds: int = OAuthStateUtils.default_expiration_seconds,
        client: Optional[WebClient] = None,
        logger: Optional[Logger] = None,
    ) -> "OAuthFlow":

        client_id = client_id or os.environ["SLACK_CLIENT_ID"]  # required
        client_secret = client_secret or os.environ["SLACK_CLIENT_SECRET"]  # required
        scopes = scopes or os.environ.get("SLACK_SCOPES", "").split(",")
        user_scopes = user_scopes or os.environ.get("SLACK_USER_SCOPES", "").split(",")
        redirect_uri = redirect_uri or os.environ.get("SLACK_REDIRECT_URI")
        return OAuthFlow(
            client=client or WebClient(),
            logger=logger,
            settings=OAuthSettings(
                # OAuth flow parameters/credentials
                client_id=client_id,
                client_secret=client_secret,
                scopes=scopes,
                user_scopes=user_scopes,
                redirect_uri=redirect_uri,
                # Handler configuration
                install_path=install_path,
                redirect_uri_path=redirect_uri_path,
                callback_options=callback_options,
                success_url=success_url,
                failure_url=failure_url,
                authorization_url=authorization_url,
                # Installation Management
                installation_store=SQLite3InstallationStore(
                    database=database, client_id=client_id, logger=logger,
                ),
                # state parameter related configurations
                state_store=SQLite3OAuthStateStore(
                    database=database,
                    expiration_seconds=state_expiration_seconds,
                    logger=logger,
                ),
                state_cookie_name=state_cookie_name,
                state_expiration_seconds=state_expiration_seconds,
            ),
        )
예제 #11
0
    def test_handle_callback(self):
        oauth_flow = OAuthFlow(
            client=WebClient(base_url=self.mock_api_server_base_url),
            settings=OAuthSettings(
                client_id="111.222",
                client_secret="xxx",
                scopes=["chat:write", "commands"],
                installation_store=FileInstallationStore(),
                state_store=FileOAuthStateStore(expiration_seconds=120),
                success_url="https://www.example.com/completion",
                failure_url="https://www.example.com/failure",
            ),
        )
        state = oauth_flow.issue_new_state(None)
        req = BoltRequest(
            body="",
            query=f"code=foo&state={state}",
            headers={
                "cookie": [f"{oauth_flow.settings.state_cookie_name}={state}"]
            },
        )
        resp = oauth_flow.handle_callback(req)
        assert resp.status == 200
        assert "https://www.example.com/completion" in resp.body

        app = App(signing_secret="signing_secret", oauth_flow=oauth_flow)
        global_shortcut_body = {
            "type": "shortcut",
            "token": "verification_token",
            "action_ts": "111.111",
            "team": {
                "id": "T111",
                "domain": "workspace-domain",
                "enterprise_id": "E111",
                "enterprise_name": "Org Name",
            },
            "user": {
                "id": "W111",
                "username": "******",
                "team_id": "T111"
            },
            "callback_id": "test-shortcut",
            "trigger_id": "111.111.xxxxxx",
        }
        body = f"payload={quote(json.dumps(global_shortcut_body))}"
        timestamp = str(int(time()))
        signature_verifier = SignatureVerifier("signing_secret")
        headers = {
            "content-type": ["application/x-www-form-urlencoded"],
            "x-slack-signature": [
                signature_verifier.generate_signature(body=body,
                                                      timestamp=timestamp)
            ],
            "x-slack-request-timestamp": [timestamp],
        }
        request = BoltRequest(body=body, headers=headers)
        response = app.dispatch(request)
        assert response.status == 200
        assert self.mock_received_requests["/auth.test"] == 1
예제 #12
0
 def test_scopes_as_str(self):
     settings = OAuthSettings(
         client_id="111.222",
         client_secret="xxx",
         scopes="chat:write,commands",
         user_scopes="search:read",
     )
     assert settings.scopes == ["chat:write", "commands"]
     assert settings.user_scopes == ["search:read"]
예제 #13
0
 def test_valid_multi_auth_oauth_flow(self):
     oauth_flow = OAuthFlow(settings=OAuthSettings(
         client_id="111.222",
         client_secret="valid",
         installation_store=FileInstallationStore(),
         state_store=FileOAuthStateStore(expiration_seconds=120),
     ))
     app = App(signing_secret="valid", oauth_flow=oauth_flow)
     assert app != None
 async def test_instantiation_non_async_settings_to_app(self):
     with pytest.raises(BoltError):
         AsyncApp(
             signing_secret="xxx",
             oauth_settings=OAuthSettings(
                 client_id="111.222",
                 client_secret="xxx",
                 scopes="chat:write,commands",
             ),
         )
예제 #15
0
 def test_instantiation(self):
     oauth_flow = OAuthFlow(settings=OAuthSettings(
         client_id="111.222",
         client_secret="xxx",
         scopes=["chat:write", "commands"],
         installation_store=FileInstallationStore(),
         state_store=FileOAuthStateStore(expiration_seconds=120),
     ))
     assert oauth_flow is not None
     assert oauth_flow.logger is not None
     assert oauth_flow.client is not None
예제 #16
0
    def __init__(
            self,
            *,
            client: Optional[WebClient] = None,
            logger: Optional[Logger] = None,
            settings: Optional[OAuthSettings] = None,
            oauth_state_bucket_name: Optional[str] = None,  # required
            installation_bucket_name: Optional[str] = None,  # required
    ):
        logger = logger or logging.getLogger(__name__)
        settings = settings or OAuthSettings(
            client_id=os.environ["SLACK_CLIENT_ID"],
            client_secret=os.environ["SLACK_CLIENT_SECRET"],
        )
        oauth_state_bucket_name = (oauth_state_bucket_name
                                   or os.environ["SLACK_STATE_S3_BUCKET_NAME"])
        installation_bucket_name = (
            installation_bucket_name
            or os.environ["SLACK_INSTALLATION_S3_BUCKET_NAME"])
        self.s3_client = boto3.client("s3")
        if settings.state_store is None or not isinstance(
                settings.state_store, AmazonS3OAuthStateStore):
            settings.state_store = AmazonS3OAuthStateStore(
                logger=logger,
                s3_client=self.s3_client,
                bucket_name=oauth_state_bucket_name,
                expiration_seconds=settings.state_expiration_seconds,
            )

        if settings.installation_store is None or not isinstance(
                settings.installation_store, AmazonS3InstallationStore):
            settings.installation_store = AmazonS3InstallationStore(
                logger=logger,
                s3_client=self.s3_client,
                bucket_name=installation_bucket_name,
                client_id=settings.client_id,
            )

        # Set up authorize function to surely use this installation_store.
        # When a developer use a settings initialized outside this constructor,
        # the settings may already have pre-defined authorize.
        # In this case, the /slack/events endpoint doesn't work along with the OAuth flow.
        settings.authorize = InstallationStoreAuthorize(
            logger=logger,
            installation_store=settings.installation_store,
            bot_only=settings.installation_store_bot_only,
        )

        OAuthFlow.__init__(self,
                           client=client,
                           logger=logger,
                           settings=settings)
예제 #17
0
 def test_instantiation(self):
     oauth_flow = LambdaS3OAuthFlow(
         settings=OAuthSettings(
             client_id="111.222",
             client_secret="xxx",
             scopes=["chat:write"],
         ),
         installation_bucket_name="dummy-installation",
         oauth_state_bucket_name="dummy-state",
     )
     assert oauth_flow is not None
     assert oauth_flow.client is not None
     assert oauth_flow.logger is not None
예제 #18
0
 def test_handle_installation(self):
     oauth_flow = OAuthFlow(settings=OAuthSettings(
         client_id="111.222",
         client_secret="xxx",
         scopes=["chat:write", "commands"],
         installation_store=FileInstallationStore(),
         state_store=FileOAuthStateStore(expiration_seconds=120),
     ))
     req = BoltRequest(body="")
     resp = oauth_flow.handle_installation(req)
     assert resp.status == 200
     assert resp.headers.get("content-type") == ["text/html; charset=utf-8"]
     assert resp.headers.get("content-length") == ["565"]
     assert "https://slack.com/oauth/v2/authorize?state=" in resp.body
예제 #19
0
 def test_handle_installation_no_rendering(self):
     oauth_flow = OAuthFlow(settings=OAuthSettings(
         client_id="111.222",
         client_secret="xxx",
         scopes=["chat:write", "commands"],
         user_scopes=["search:read"],
         installation_store=FileInstallationStore(),
         install_page_rendering_enabled=False,  # disabled
         state_store=FileOAuthStateStore(expiration_seconds=120),
     ))
     req = BoltRequest(body="")
     resp = oauth_flow.handle_installation(req)
     assert resp.status == 302
     location_header = resp.headers.get("location")[0]
     assert "https://slack.com/oauth/v2/authorize?state=" in location_header
예제 #20
0
 def test_oauth(self):
     app = App(
         client=self.web_client,
         signing_secret=self.signing_secret,
         oauth_settings=OAuthSettings(
             client_id="111.111",
             client_secret="xxx",
             scopes=["chat:write", "commands"],
         ),
     )
     request = self.rf.get("/slack/install")
     response = SlackRequestHandler(app).handle(request)
     assert response.status_code == 200
     assert response.get("content-type") == "text/html; charset=utf-8"
     assert "https://slack.com/oauth/v2/authorize?state=" in response.content.decode(
         "utf-8")
예제 #21
0
    def test_oauth(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            oauth_settings=OAuthSettings(
                client_id="111.111",
                client_secret="xxx",
                scopes=["chat:write", "commands"],
            ),
        )

        event = {
            "body": "",
            "queryStringParameters": {},
            "headers": {},
            "requestContext": {
                "http": {
                    "method": "GET"
                }
            },
            "isBase64Encoded": False,
        }
        response = SlackRequestHandler(app).handle(event, self.context)
        assert response["statusCode"] == 200
        assert response["headers"][
            "content-type"] == "text/html; charset=utf-8"
        assert response["headers"]["content-length"] == "565"
        assert response.get("body") is not None

        event = {
            "body": "",
            "queryStringParameters": {},
            "headers": {},
            "requestContext": {
                "httpMethod": "GET"
            },
            "isBase64Encoded": False,
        }
        response = SlackRequestHandler(app).handle(event, self.context)
        assert response["statusCode"] == 200
        assert response["headers"][
            "content-type"] == "text/html; charset=utf-8"
        assert response["headers"]["content-length"] == "565"
        assert "https://slack.com/oauth/v2/authorize?state=" in response.get(
            "body")
예제 #22
0
    def test_handle_callback_using_options(self):
        def success(args: SuccessArgs) -> BoltResponse:
            assert args.request is not None
            return BoltResponse(status=200, body="customized")

        def failure(args: FailureArgs) -> BoltResponse:
            assert args.request is not None
            assert args.reason is not None
            return BoltResponse(status=502, body="customized")

        oauth_flow = OAuthFlow(
            client=WebClient(base_url=self.mock_api_server_base_url),
            settings=OAuthSettings(
                client_id="111.222",
                client_secret="xxx",
                scopes=["chat:write", "commands"],
                installation_store=FileInstallationStore(),
                state_store=FileOAuthStateStore(expiration_seconds=120),
                callback_options=CallbackOptions(success=success,
                                                 failure=failure),
            ),
        )
        state = oauth_flow.issue_new_state(None)
        req = BoltRequest(
            body="",
            query=f"code=foo&state={state}",
            headers={
                "cookie": [f"{oauth_flow.settings.state_cookie_name}={state}"]
            },
        )
        resp = oauth_flow.handle_callback(req)
        assert resp.status == 200
        assert resp.body == "customized"

        state = oauth_flow.issue_new_state(None)
        req = BoltRequest(
            body="",
            query=f"code=foo&state=invalid",
            headers={
                "cookie": [f"{oauth_flow.settings.state_cookie_name}={state}"]
            },
        )
        resp = oauth_flow.handle_callback(req)
        assert resp.status == 502
        assert resp.body == "customized"
예제 #23
0
    def test_oauth(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            oauth_settings=OAuthSettings(
                client_id="111.111",
                client_secret="xxx",
                scopes=["chat:write", "commands"],
            ),
        )
        api = falcon.API()
        resource = SlackAppResource(app)
        api.add_route("/slack/install", resource)

        client = testing.TestClient(api)
        response = client.simulate_get("/slack/install")
        assert response.status_code == 200
        assert "https://slack.com/oauth/v2/authorize?state=" in response.text
예제 #24
0
    def test_oauth(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            oauth_settings=OAuthSettings(
                client_id="111.111",
                client_secret="xxx",
                scopes=["chat:write", "commands"],
            ),
        )

        request: Request = testing.DummyRequest()
        request.path = "/slack/install"
        request.method = "GET"
        response: Response = SlackRequestHandler(app).handle(request)
        assert response.status_code == 200
        assert "https://slack.com/oauth/v2/authorize?state=" in response.body.decode(
            "utf-8")
예제 #25
0
 def test_handle_callback_invalid_state(self):
     oauth_flow = OAuthFlow(
         settings=OAuthSettings(
             client_id="111.222",
             client_secret="xxx",
             scopes=["chat:write", "commands"],
             installation_store=FileInstallationStore(),
             state_store=FileOAuthStateStore(expiration_seconds=120),
         )
     )
     state = oauth_flow.issue_new_state(None)
     req = BoltRequest(
         body="",
         query=f"code=foo&state=invalid",
         headers={"cookie": [f"{oauth_flow.settings.state_cookie_name}={state}"]},
     )
     resp = oauth_flow.handle_callback(req)
     assert resp.status == 400
예제 #26
0
    def test_oauth(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            oauth_settings=OAuthSettings(
                client_id="111.111",
                client_secret="xxx",
                scopes=["chat:write", "commands"],
            ),
        )
        flask_app = Flask(__name__)

        @flask_app.route("/slack/install", methods=["GET"])
        def endpoint():
            return SlackRequestHandler(app).handle(request)

        with flask_app.test_client() as client:
            rv = client.get("/slack/install")
            assert rv.status_code == 200
예제 #27
0
def test_it_redirects(mocker):
    # given
    oauth = TeamiclinkOAuth(settings=OAuthSettings(
        client_id="any_client_id", client_secret="any_client_secret"))
    issue_state = mocker.patch.object(oauth, "issue_new_state")
    issue_state.return_value = "any_state"
    build_url = mocker.patch.object(oauth, "build_authorize_url")
    build_url.return_value = "https://any_url.com"
    build_cookie = mocker.patch.object(oauth.settings.state_utils,
                                       "build_set_cookie_for_new_state")
    build_cookie.return_value = "any_cookie"
    bolt_request = BoltRequest(body="any_body")

    # when
    result = oauth.handle_installation(request=bolt_request)

    # then
    assert result.status == 302
    assert result.headers["location"] == [build_url.return_value]
    assert result.headers["set-cookie"] == [build_cookie.return_value]
    issue_state.assert_called_once_with(bolt_request)
    build_url.assert_called_once_with(issue_state.return_value, bolt_request)
    build_cookie.assert_called_once_with(issue_state.return_value)
예제 #28
0
)

try:
    engine.execute("select count(*) from slack_bots")
except Exception as e:
    installation_store.metadata.create_all(engine)
    oauth_state_store.metadata.create_all(engine)
# update ngrok/production links in slash commands and enable events page
# Initializes your app with your bot token and signing secret
app = App(
    logger=logger,
    signing_secret=signing_secret,
    installation_store=installation_store,
    oauth_settings=OAuthSettings(
        client_id=client_id,
        client_secret=client_secret,
        state_store=oauth_state_store,
    ),
)


@app.middleware
def log_request(logger: logging.Logger, body: dict, next: Callable):
    logger.debug(body)
    return next()


def extract_subtype(body: dict, context: BoltContext, next: Callable):
    context["type"] = body.get("event", {}).get("type", None)
    next()
예제 #29
0
class TestApp:
    signing_secret = "secret"
    valid_token = "xoxb-valid"
    mock_api_server_base_url = "http://*****:*****@W111> Hi there!",
            "user": "******",
            "ts": "1595926230.009600",
            "team": "T111",
            "channel": "C111",
            "event_ts": "1595926230.009600",
        },
        "type": "event_callback",
        "event_id": "Ev111",
        "event_time": 1595926230,
        "authed_users": ["W111"],
    }

    @staticmethod
    def handle_app_mention(body, say: Say, payload, event):
        assert body["event"] == payload
        assert payload == event
        say("What's up?")

    oauth_settings_bot_only = OAuthSettings(
        client_id="111.222",
        client_secret="valid",
        installation_store=BotOnlyMemoryInstallationStore(),
        installation_store_bot_only=True,
        state_store=FileOAuthStateStore(expiration_seconds=120),
    )

    oauth_settings = OAuthSettings(
        client_id="111.222",
        client_secret="valid",
        installation_store=BotOnlyMemoryInstallationStore(),
        installation_store_bot_only=False,
        state_store=FileOAuthStateStore(expiration_seconds=120),
    )

    def build_app_mention_request(self):
        timestamp, body = str(int(time())), json.dumps(
            self.app_mention_request_body)
        return BoltRequest(body=body,
                           headers=self.build_headers(timestamp, body))

    def test_installation_store_bot_only_default(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            installation_store=MemoryInstallationStore(),
        )

        app.event("app_mention")(self.handle_app_mention)
        response = app.dispatch(self.build_app_mention_request())
        assert response.status == 200
        assert_auth_test_count(self, 1)
        sleep(1)  # wait a bit after auto ack()
        assert self.mock_received_requests["/chat.postMessage"] == 1

    def test_installation_store_bot_only_false(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            installation_store=MemoryInstallationStore(),
            # the default is False
            installation_store_bot_only=False,
        )

        app.event("app_mention")(self.handle_app_mention)
        response = app.dispatch(self.build_app_mention_request())
        assert response.status == 200
        assert_auth_test_count(self, 1)
        sleep(1)  # wait a bit after auto ack()
        assert self.mock_received_requests["/chat.postMessage"] == 1

    def test_installation_store_bot_only(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            installation_store=BotOnlyMemoryInstallationStore(),
            installation_store_bot_only=True,
        )

        app.event("app_mention")(self.handle_app_mention)
        response = app.dispatch(self.build_app_mention_request())
        assert response.status == 200
        assert_auth_test_count(self, 1)
        sleep(1)  # wait a bit after auto ack()
        assert self.mock_received_requests["/chat.postMessage"] == 1

    def test_installation_store_bot_only_oauth_settings(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            oauth_settings=self.oauth_settings_bot_only,
        )

        app.event("app_mention")(self.handle_app_mention)
        response = app.dispatch(self.build_app_mention_request())
        assert response.status == 200
        assert_auth_test_count(self, 1)
        sleep(1)  # wait a bit after auto ack()
        assert self.mock_received_requests["/chat.postMessage"] == 1

    def test_installation_store_bot_only_oauth_settings_conflicts(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            installation_store_bot_only=True,
            oauth_settings=self.oauth_settings,
        )

        app.event("app_mention")(self.handle_app_mention)
        response = app.dispatch(self.build_app_mention_request())
        assert response.status == 200
        assert_auth_test_count(self, 1)
        sleep(1)  # wait a bit after auto ack()
        assert self.mock_received_requests["/chat.postMessage"] == 1

    def test_installation_store_bot_only_oauth_flow(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            oauth_flow=OAuthFlow(settings=self.oauth_settings_bot_only),
        )

        app.event("app_mention")(self.handle_app_mention)
        response = app.dispatch(self.build_app_mention_request())
        assert response.status == 200
        assert_auth_test_count(self, 1)
        sleep(1)  # wait a bit after auto ack()
        assert self.mock_received_requests["/chat.postMessage"] == 1

    def test_installation_store_bot_only_oauth_flow_conflicts(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            installation_store_bot_only=True,
            oauth_flow=OAuthFlow(settings=self.oauth_settings),
        )

        app.event("app_mention")(self.handle_app_mention)
        response = app.dispatch(self.build_app_mention_request())
        assert response.status == 200
        assert_auth_test_count(self, 1)
        sleep(1)  # wait a bit after auto ack()
        assert self.mock_received_requests["/chat.postMessage"] == 1
예제 #30
0
from slack_bolt.response import BoltResponse

from listeners.listeners import register_listeners

dotenv.load_dotenv()

logging.basicConfig(level=logging.DEBUG)

oauth_settings = OAuthSettings(
    client_id=os.environ["SLACK_CLIENT_ID"],
    client_secret=os.environ["SLACK_CLIENT_SECRET"],
    scopes=[
        "channels:history",
        "commands",
        "groups:history",
        "im:history",
        "mpim:history",
        "chat:write",
    ],
    state_store=FileOAuthStateStore(expiration_seconds=600,
                                    base_dir="./data/states"),
    installation_store=FileInstallationStore(base_dir="./data/installations"),
)

app = App(signing_secret=os.environ["SLACK_SIGNING_SECRET"],
          oauth_settings=oauth_settings)
register_listeners(app)

podthai = [
    "UJM7Z5VGD", "U014KC3E9MF", "U0145C1684V", "U014CUFPNJG", "U01401MQJAJ"
]