Ejemplo n.º 1
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)
Ejemplo n.º 2
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
Ejemplo n.º 3
0
    def test_token_verification_enabled_False(self):
        App(
            signing_secret="valid",
            client=self.web_client,
            token_verification_enabled=False,
        )
        App(
            signing_secret="valid",
            token="xoxb-invalid",
            token_verification_enabled=False,
        )

        assert self.mock_received_requests.get("/auth.test") is None
Ejemplo n.º 4
0
    def test_invalid_message_events(self):
        app = App(client=self.web_client, signing_secret=self.signing_secret)

        def handle():
            pass

        # valid
        app.event("message")(handle)

        with pytest.raises(ValueError):
            app.event("message.channels")(handle)
        with pytest.raises(ValueError):
            app.event("message.groups")(handle)
        with pytest.raises(ValueError):
            app.event("message.im")(handle)
        with pytest.raises(ValueError):
            app.event("message.mpim")(handle)

        with pytest.raises(ValueError):
            app.event(re.compile("message\\..*"))(handle)

        with pytest.raises(ValueError):
            app.event({"type": "message.channels"})(handle)
        with pytest.raises(ValueError):
            app.event({"type": re.compile("message\\..*")})(handle)
Ejemplo n.º 5
0
    def test_uninstallation_and_revokes(self):
        app = App(client=self.web_client, signing_secret=self.signing_secret)
        app._client = WebClient(token="uninstalled-revoked",
                                base_url=self.mock_api_server_base_url)

        @app.event("app_uninstalled")
        def handler1(say: Say):
            say(channel="C111", text="What's up?")

        @app.event("tokens_revoked")
        def handler2(say: Say):
            say(channel="C111", text="What's up?")

        app_uninstalled_body = {
            "token": "verification_token",
            "team_id": "T111",
            "enterprise_id": "E111",
            "api_app_id": "A111",
            "event": {
                "type": "app_uninstalled"
            },
            "type": "event_callback",
            "event_id": "Ev111",
            "event_time": 1599616881,
        }

        timestamp, body = str(int(time())), json.dumps(app_uninstalled_body)
        request: BoltRequest = BoltRequest(body=body,
                                           headers=self.build_headers(
                                               timestamp, body))
        response = app.dispatch(request)
        assert response.status == 200

        tokens_revoked_body = {
            "token": "verification_token",
            "team_id": "T111",
            "enterprise_id": "E111",
            "api_app_id": "A111",
            "event": {
                "type": "tokens_revoked",
                "tokens": {
                    "oauth": ["UXXXXXXXX"],
                    "bot": ["UXXXXXXXX"]
                },
            },
            "type": "event_callback",
            "event_id": "Ev111",
            "event_time": 1599616881,
        }

        timestamp, body = str(int(time())), json.dumps(tokens_revoked_body)
        request: BoltRequest = BoltRequest(body=body,
                                           headers=self.build_headers(
                                               timestamp, body))
        response = app.dispatch(request)
        assert response.status == 200

        assert self.mock_received_requests["/auth.test"] == 1
        sleep(1)  # wait a bit after auto ack()
        assert self.mock_received_requests["/chat.postMessage"] == 2
Ejemplo n.º 6
0
 def build_app(self, callback_id: str):
     app = App(client=self.web_client, signing_secret=self.signing_secret)
     app.step(callback_id=callback_id,
              edit=edit,
              save=save,
              execute=execute)
     return app
    def test_interactions(self):

        app = App(client=self.web_client)

        result = {"shortcut": False, "command": False}

        @app.shortcut("do-something")
        def shortcut_handler(ack):
            result["shortcut"] = True
            ack()

        @app.command("/hello-socket-mode")
        def command_handler(ack):
            result["command"] = True
            ack()

        handler = SocketModeHandler(
            app_token="xapp-A111-222-xyz",
            app=app,
            trace_enabled=True,
        )
        try:
            handler.client.wss_uri = "ws://localhost:3012/link"

            handler.connect()
            assert handler.client.is_connected() is True
            time.sleep(2)  # wait for the message receiver

            handler.client.send_message("foo")

            time.sleep(2)
            assert result["shortcut"] is True
            assert result["command"] is True
        finally:
            handler.client.close()
Ejemplo n.º 8
0
    def __init__(self, channel=None):
        """Initializes the Slack channel handler.

        Args:
            channel: Slack channel where logs are sent
        """
        # super(SlackChannelHandler, self).__init__()
        super().__init__()

        # set the channel
        self.set_channel(channel)
        if not self.channel:
            raise ValueError('Must supply a "channel" in the logging configuration.')

        # obtain access token
        access_token = os.environ.get('SLACK_BOT_TOKEN')
        if not access_token:
            raise ValueError('Environmental variable, "SLACK_BOT_TOKEN", is not set.')

        # obtain signing secret
        signing_secret = os.environ.get('SLACK_SIGNING_SECRET')
        if not signing_secret:
            raise ValueError('Environmental variable, "SLACK_SIGNING_SECRET", is not set.')

        # authenticate and get slack client
        app = App(token=access_token, signing_secret=signing_secret)
        self.client = app.client
Ejemplo n.º 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),
         )
Ejemplo n.º 10
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
Ejemplo n.º 11
0
 def test_listener_registration_error(self):
     app = App(signing_secret="valid", client=self.web_client)
     with pytest.raises(BoltError):
         app.action({
             "type": "invalid_type",
             "action_id": "a"
         })(self.simple_listener)
Ejemplo n.º 12
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
Ejemplo n.º 13
0
    def test_app_home_opened(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            installation_store=OrgAppInstallationStore(),
        )

        event_payload = {
            "token":
            "verification-token",
            "team_id":
            "T111",
            "enterprise_id":
            "E111",
            "api_app_id":
            "A111",
            "event": {
                "type": "app_home_opened",
                "user": "******",
                "channel": "D111",
                "tab": "messages",
                "event_ts": "1606810927.510671",
            },
            "type":
            "event_callback",
            "event_id":
            "Ev111",
            "event_time":
            1606810927,
            "authorizations": [{
                "enterprise_id": "E111",
                "team_id": None,
                "user_id": "W111",
                "is_bot": True,
                "is_enterprise_install": True,
            }],
            "is_ext_shared_channel":
            False,
        }

        result = Result()

        @app.event("app_home_opened")
        def handle_app_mention(body):
            assert body == event_payload
            result.called = True

        timestamp, body = str(int(time())), json.dumps(event_payload)
        request: BoltRequest = BoltRequest(body=body,
                                           headers=self.build_headers(
                                               timestamp, body))
        response = app.dispatch(request)
        assert response.status == 200
        # auth.test API call must be skipped
        assert self.mock_received_requests["/auth.test"] == 1
        sleep(1)  # wait a bit after auto ack()
        assert result.called is True
Ejemplo n.º 14
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
Ejemplo n.º 15
0
    def test_message(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            installation_store=OrgAppInstallationStore(),
        )

        event_payload = {
            "token": "verification-token",
            "team_id": "T111",
            "enterprise_id": "E111",
            "api_app_id": "A111",
            "event": {
                "client_msg_id": "0186b75a-2ad4-4f36-8ccc-18608b0ac5d1",
                "type": "message",
                "text": "<@W222>",
                "user": "******",
                "ts": "1606810819.000800",
                "team": "T111",
                "channel": "C111",
                "event_ts": "1606810819.000800",
                "channel_type": "channel",
            },
            "type": "event_callback",
            "event_id": "Ev111",
            "event_time": 1606810819,
            "authed_users": [],
            "authorizations": [
                {
                    "enterprise_id": "E111",
                    "team_id": None,
                    "user_id": "W222",
                    "is_bot": True,
                    "is_enterprise_install": True,
                }
            ],
            "is_ext_shared_channel": False,
            "event_context": "1-message-T111-C111",
        }

        result = Result()

        @app.event("message")
        def handle_app_mention(body):
            assert body == event_payload
            result.called = True

        timestamp, body = str(int(time())), json.dumps(event_payload)
        request: BoltRequest = BoltRequest(
            body=body, headers=self.build_headers(timestamp, body)
        )
        response = app.dispatch(request)
        assert response.status == 200
        # auth.test API call must be skipped
        assert_auth_test_count(self, 1)
        sleep(1)  # wait a bit after auto ack()
        assert result.called is True
Ejemplo n.º 16
0
def main(event, context):
    # Using SLACK_BOT_TOKEN environment variable
    app = App()
    slack_api_id = os.environ['SLACK_API_ID'].replace('-', '_')
    env_prefix = os.environ['ENV_PREFIX']
    base_url = os.environ['{}_SLACK_CONNECTOR_{}_GATEWAY_URL'.format(
        env_prefix, slack_api_id)]
    # Set Slack API base URL to the URL of slack-connector application gateway.
    app.client.base_url = "{}/".format(base_url)
    print("received message with id: {}".format(event["data"]["ID"]))
    print("Slack api base URL: {}".format(app.client.base_url))
    print("sending notification to channel: {}".format(
        os.environ['NOTIFICATION_SLACK_CHANNEL']))
    # Get cloud events data.
    msg = json.loads(base64.b64decode(event["data"]["Data"]))
    try:
        # Deliver message to the channel.
        result = app.client.chat_postMessage(
            channel=os.environ['NOTIFICATION_SLACK_CHANNEL'],
            text="oom found in <{}|{}> prowjob.".format(
                msg["url"], msg["job_name"]),
            username="******",
            icon_url=
            "https://www.stickpng.com/img/download/580b57fbd9996e24bc43bdf6",
            blocks=[{
                "type":
                "context",
                "elements": [{
                    "type": "mrkdwn",
                    "text": "OutOfMemory event"
                }]
            }, {
                "type": "header",
                "text": {
                    "type": "plain_text",
                    "text": "OOM event found"
                }
            }, {
                "type": "section",
                "text": {
                    "type":
                    "mrkdwn",
                    "text":
                    "@here, OutOfMemory event found in <{}|{}> prowjob.".
                    format(msg["url"], msg["job_name"])
                }
            }])
        assert result["ok"]
        print("sent notification for message id: {}".format(
            event["data"]["ID"]))
    except SlackApiError as e:
        assert result["ok"] is False
        print(f"Got an error: {e.response['error']}")
        print("failed sent notification for message id: {}".format(
            event["data"]["ID"]))
Ejemplo n.º 17
0
    def test_stable_auto_ack(self):
        app = App(client=self.web_client)

        @app.event("reaction_added")
        def handle_app_mention():
            raise Exception("Something wrong!")

        for _ in range(10):
            request: BoltRequest = BoltRequest(
                body=self.valid_reaction_added_body, mode="socket_mode")
            response = app.dispatch(request)
            assert response.status == 200
Ejemplo n.º 18
0
def create_app():
    app = App(token=os.environ.get("SLACK_BOT_TOKEN"),
              signing_secret=os.environ.get("SLACK_SIGNING_SECRET"))

    actions.set_routes(app)
    commands.set_routes(app)
    events.set_routes(app)
    messages.set_routes(app)
    shortcuts.set_routes(app)
    views.set_routes(app)

    return app
 def test_no_installation_store(self):
     self.web_client.token = valid_token
     app = App(
         client=self.web_client,
         signing_secret=self.signing_secret,
     )
     with pytest.raises(BoltError):
         app.default_tokens_revoked_event_listener()
     with pytest.raises(BoltError):
         app.default_app_uninstalled_event_listener()
     with pytest.raises(BoltError):
         app.enable_token_revocation_listeners()
Ejemplo n.º 20
0
    def test_self_events(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            authorize=authorize,
        )

        event_body = {
            "token": "verification_token",
            "team_id": "T_SOURCE",
            "enterprise_id": "E_SOURCE",
            "api_app_id": "A111",
            "event": {
                "type": "reaction_added",
                "user": "******",  # bot_user_id
                "item": {
                    "type": "message",
                    "channel": "C111",
                    "ts": "1599529504.000400",
                },
                "reaction": "heart_eyes",
                "item_user": "******",
                "event_ts": "1599616881.000800",
            },
            "type": "event_callback",
            "event_id": "Ev111",
            "event_time": 1599616881,
            "authorizations": [
                {
                    "enterprise_id": "E_INSTALLED",
                    "team_id": "T_INSTALLED",
                    "user_id": "W111",
                    "is_bot": True,
                    "is_enterprise_install": False,
                }
            ],
        }

        @app.event("reaction_added")
        def handle_app_mention(say):
            say("What's up?")

        timestamp, body = str(int(time())), json.dumps(event_body)
        request: BoltRequest = BoltRequest(
            body=body, headers=self.build_headers(timestamp, body)
        )
        response = app.dispatch(request)
        assert response.status == 200
        assert_auth_test_count(self, 1)
        sleep(1)  # wait a bit after auto ack()
        # The listener should not be executed
        assert self.mock_received_requests.get("/chat.postMessage") is None
Ejemplo n.º 21
0
    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
Ejemplo n.º 22
0
 def build_process_before_response_app(self, callback_id: str):
     app = App(
         client=self.web_client,
         signing_secret=self.signing_secret,
         process_before_response=True,
     )
     app.step(
         callback_id=callback_id,
         edit=[edit_ack, edit_lazy],
         save=[save_ack, save_lazy],
         execute=[execute_ack, execute_lazy],
     )
     return app
Ejemplo n.º 23
0
    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 self.mock_received_requests["/auth.test"] == 1
        sleep(1)  # wait a bit after auto ack()
        assert self.mock_received_requests["/chat.postMessage"] == 1
Ejemplo n.º 24
0
    def test_self_events(self):
        app = App(client=self.web_client)

        @app.event("reaction_added")
        def handle_app_mention(say):
            say("What's up?")

        request: BoltRequest = BoltRequest(body=event_body, mode="socket_mode")
        response = app.dispatch(request)
        assert response.status == 200
        assert_auth_test_count(self, 1)
        sleep(1)  # wait a bit after auto ack()
        # The listener should not be executed
        assert self.mock_received_requests.get("/chat.postMessage") is None
Ejemplo n.º 25
0
    def test_none_body(self):
        app = App(signing_secret="valid", client=self.web_client)

        req = BoltRequest(body=None, headers={}, mode="http")
        response = app.dispatch(req)
        # request verification failure
        assert response.status == 401
        assert response.body == '{"error": "invalid request"}'

        req = BoltRequest(body=None, headers={}, mode="socket_mode")
        response = app.dispatch(req)
        # request verification is skipped for Socket Mode
        assert response.status == 404
        assert response.body == '{"error": "unhandled request"}'
    def test_default(self):
        app = App(client=self.web_client, signing_secret=self.signing_secret)

        timestamp, body = str(int(time())), json.dumps(event_body)
        request: BoltRequest = BoltRequest(body=body,
                                           headers=self.build_headers(
                                               timestamp, body))
        response = app.dispatch(request)
        assert response.status == 200
        assert (
            response.body ==
            """{"challenge": "3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P"}"""
        )
        assert_auth_test_count(self, 0)
    def test_disabled(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            url_verification_enabled=False,
        )

        timestamp, body = str(int(time())), json.dumps(event_body)
        request: BoltRequest = BoltRequest(body=body,
                                           headers=self.build_headers(
                                               timestamp, body))
        response = app.dispatch(request)
        assert response.status == 404
        assert response.body == """{"error": "unhandled request"}"""
        assert_auth_test_count(self, 0)
Ejemplo n.º 28
0
    def test_message_subtypes_3(self):
        app = App(client=self.web_client, signing_secret=self.signing_secret)
        app._client = WebClient(token="uninstalled-revoked",
                                base_url=self.mock_api_server_base_url)

        @app.event("message")
        def handler1(event):
            assert event["subtype"] == "file_share"

        timestamp, body = str(int(time())), json.dumps(
            self.message_file_share_body)
        request: BoltRequest = BoltRequest(body=body,
                                           headers=self.build_headers(
                                               timestamp, body))
        response = app.dispatch(request)
        assert response.status == 200
    def test_default(self):
        app = App(client=self.web_client, signing_secret=self.signing_secret)

        @app.event("reaction_added")
        def handle_app_mention(say):
            say("What's up?")

        timestamp, body = str(int(time())), json.dumps(event_body)
        request: BoltRequest = BoltRequest(body=body,
                                           headers=self.build_headers(
                                               timestamp, body))
        response = app.dispatch(request)
        assert response.status == 200
        assert_auth_test_count(self, 1)
        sleep(1)  # wait a bit after auto ack()
        assert self.mock_received_requests.get("/chat.postMessage") == 1
Ejemplo n.º 30
0
    def test_ssl_check(self):
        app = App(client=self.web_client, signing_secret=self.signing_secret)

        timestamp, body = str(int(time())), "token=random&ssl_check=1"
        request: BoltRequest = BoltRequest(
            body=body,
            query={},
            headers={
                "content-type": ["application/x-www-form-urlencoded"],
                "x-slack-signature": [self.generate_signature(body, timestamp)],
                "x-slack-request-timestamp": [timestamp],
            },
        )
        response = app.dispatch(request)
        assert response.status == 200
        assert response.body == ""