示例#1
0
 def decorated_function(*args, **kwargs):
     timestamp = request.headers['X-Slack-Request-Timestamp']
     signature = request.headers['X-Slack-Signature']
     if abs(time.time() - float(timestamp)) > 60 * 3:
         raise SlackApiError("cannnnno", response=HTTPStatus.REQUEST_TIMEOUT)
     get_form_body = MultiDict(request.form)
     hashed_signature = generate_signature(get_form_body, timestamp)
     if compare_signature(hashed_signature, signature):
         return func(*args, **kwargs)
     else:
         raise SlackApiError("Cannnot verify signature", response=HTTPStatus.FORBIDDEN)
示例#2
0
    def send_response(self,
                      response_url: Optional[str] = None,
                      **kwargs: Optional[Any]):

        req_args = dict(
            # contents of messenger[UserDict]
            **self,
            # any other API fields
            **kwargs)

        if self.client._event_loop is None:
            self.client._event_loop = self.client._get_event_loop()

        api_url = response_url or self.response_url

        future = asyncio.ensure_future(self.client._request(
            http_verb='POST', api_url=api_url, req_args=dict(json=req_args)),
                                       loop=self.client._get_event_loop())

        res = self.client._event_loop.run_until_complete(future)
        status = res['status_code']

        if status != 200:
            raise SlackApiError(
                message='Failed to send response_url: {}: status={}'.format(
                    api_url, status),
                response=res)

        return True
示例#3
0
 def mock_users_info(user):
     if user == bill_user_id:
         resp = mocker.Mock()
         resp.data = {'user': slack_user}
         return resp
     else:
         raise SlackApiError('bla bla bla', "'error': 'user_not_found'")
示例#4
0
def test_monitor_job_error():
    mock_client = WebClient()
    mock_client.chat_postMessage = MagicMock(side_effect=SlackApiError(message="", response={}))

    client = utils.client.create(**CONFIG["my_instance_name"])
    project = client.projects.by_resource_id(CONFIG["projects"]["minimal_schema_mapping"])
    op = project.unified_dataset().refresh(asynchronous=True)

    with pytest.raises(HTTPError):
        notifications.slack.monitor_job(
            tamr=client,
            slack_client=mock_client,
            channel="#test_tbox_messaging",
            operation=0,
            poll_interval_seconds=0.01,
        )

    with pytest.raises(SlackApiError):
        notifications.slack.monitor_job(
            tamr=client,
            slack_client=mock_client,
            channel="#fake_channel_name",
            operation=op,
            poll_interval_seconds=0.01,
        )
示例#5
0
 def schedule_message(self, channel, message, timestamp, as_user=True):
     try:
         scheduled_message = self.time_travel_slack_client.chat_scheduleMessage(
             channel=channel,
             text=message,
             post_at=timestamp,
             as_user=as_user
         )
         if scheduled_message['ok'] is True:
             return True
         else:
             raise SlackApiError("Message Not Send")
     except SlackApiError as err:
         raise SlackApiError('', MessageTemplate(
             "Error Sending Scheduled Message",
             time=time.time()
         ).get_template())
示例#6
0
    def test_retryafterslack_policy(self):
        mock = MagicMock(
            side_effect=SlackApiError(message="x", response=self.Responce()))
        policy = RetryAfterSlack(3)

        loop = asyncio.new_event_loop()
        with self.assertRaises(RetryAfterError):
            loop.run_until_complete(policy.execute(lambda: mock()))
示例#7
0
 def post_message(self, channel_id, message):
     try:
         scheduled_message = self.time_travel_slack_client.chat_postMessage(
             channel=channel_id,
             text="",
             as_user=True,
             blocks=message
         )
         if scheduled_message['ok'] is True:
             return True
         else:
             raise SlackApiError("Message Not Send")
     except SlackApiError as err:
         raise SlackApiError('', MessageTemplate(
             "Error Sending Scheduled Message",
             time=time.time()
         ).get_template())
示例#8
0
    async def _perform_http_request(
            self, *, body: Dict[str, any],
            headers: Dict[str, str]) -> WebhookResponse:
        """Performs an HTTP request and parses the response.
        :param url: a complete URL to send data (e.g., https://hooks.slack.com/XXX)
        :param body: request body data
        :param headers: complete set of request headers
        :return: API response
        """
        body = json.dumps(body)
        headers["Content-Type"] = "application/json;charset=utf-8"

        if self.logger.level <= logging.DEBUG:
            self.logger.debug(
                f"Sending a request - url: {self.url}, body: {body}, headers: {headers}"
            )
        session: Optional[ClientSession] = None
        use_running_session = self.session and not self.session.closed
        if use_running_session:
            session = self.session
        else:
            session = aiohttp.ClientSession(
                timeout=aiohttp.ClientTimeout(total=self.timeout),
                auth=self.auth,
                trust_env=self.trust_env_in_session,
            )

        try:
            request_kwargs = {
                "headers": headers,
                "data": body,
                "ssl": self.ssl,
                "proxy": self.proxy,
            }
            async with session.request("POST", self.url,
                                       **request_kwargs) as res:
                response_body = {}
                try:
                    response_body = await res.text()
                except aiohttp.ContentTypeError:
                    self._logger.debug(
                        f"No response data returned from the following API call: {self.url}."
                    )
                except json.decoder.JSONDecodeError as e:
                    message = f"Failed to parse the response body: {str(e)}"
                    raise SlackApiError(message, res)

                resp = WebhookResponse(
                    url=self.url,
                    status_code=res.status,
                    body=response_body,
                    headers=res.headers,
                )
                _debug_log_response(self.logger, resp)
                return resp
        finally:
            if not use_running_session:
                await session.close()
示例#9
0
    def send_response(self,
                      response_url: Optional[str] = None,
                      **kwargs: Optional[Any]):
        """
        This method is used to send a message via the response_url rathern
        than using the api.slack.com endpoints.

        Parameters
        ----------
        response_url: str
            The message will be POST to this URL; originates from a message received
            from api.slack.com

        Other Parameters
        ----------------
        Any other kwargs are passed as content into the message.

        Raises
        ------
        SlackApiError upon error sending; HTTP status code other
        than 200.

        Returns
        -------
        True if the message was sent without error (HTTP code 200).

        Notes
        -----
        Ideally this method should be a part of the `slackclient` BaseClient class to avoid
        using the internals of the client instance.  TODO: open issue with that repo.
        """
        req_args = dict(
            # contents of messenger[UserDict]
            **self,
            # any other API fields
            **kwargs)

        if self.client._event_loop is None:
            self.client._event_loop = _get_event_loop()

        api_url = response_url or self.response_url

        future = asyncio.ensure_future(self.client._request(
            http_verb='POST', api_url=api_url, req_args=dict(json=req_args)),
                                       loop=_get_event_loop())

        res = self.client._event_loop.run_until_complete(future)
        status = res['status_code']

        if status != 200:
            raise SlackApiError(
                message='Failed to send response_url: {}: status={}'.format(
                    api_url, status),
                response=res)

        return True
示例#10
0
def test_send_message_raise_error_true():
    mock_client = WebClient()
    mock_client.chat_postMessage = MagicMock(side_effect=SlackApiError(message="", response={}))

    with pytest.raises(SlackApiError):
        notifications.slack.send_message(
            slack_client=mock_client,
            channel="#fake_channel_name",
            message="This is a test message.",
        )
def test_get_invalid_permissions_icon_url(mock_webclient):
    class FakeResponse:
        data = {"error": "missing_scope", "needed": "users:read"}

    fake_error = SlackApiError("message", FakeResponse())
    mock_webclient().users_list.side_effect = fake_error
    manager = SlackMessageManager(sender_token="Fake",
                                  sender_name="test_invalid_bot")
    url = manager._get_icon_url()
    assert url is None
示例#12
0
    def test_call_with_failure(self, slack_client_class_mock):
        slack_client_mock = mock.Mock()
        slack_client_class_mock.return_value = slack_client_mock
        expected_exception = SlackApiError(message='foo', response='bar')
        slack_client_mock.api_call = mock.Mock(side_effect=expected_exception)

        test_token = 'test_token'
        test_slack_conn_id = 'test_slack_conn_id'
        slack_hook = SlackHook(token=test_token, slack_conn_id=test_slack_conn_id)
        test_method = 'test_method'
        test_api_params = {'key1': 'value1', 'key2': 'value2'}

        with self.assertRaises(SlackApiError):
            slack_hook.call(test_method, test_api_params)
def test_get_invalid_unknown_slack_error_icon_url(mock_webclient):
    class FakeResponse:
        data = {"error": "unknown", "needed": "unknown"}

    fake_error = SlackApiError("mocked error", FakeResponse())
    mock_webclient().users_list.side_effect = fake_error
    manager = SlackMessageManager(sender_token="Fake",
                                  sender_name="test_invalid_bot")
    with pytest.raises(SlackApiError) as excinfo:
        manager._get_icon_url()
    assert excinfo.value.response.data == {
        "error": "unknown",
        "needed": "unknown"
    }
示例#14
0
def test_slack_error_raises(mock_client, mock_post):
    """A SlackSendError on slack failure."""
    # Actual error example: {'ok': False, 'error': 'channel_not_found'}
    mock_post.side_effect = SlackApiError(response={'error': 'bang bang'},
                                          message="bang bang msg")
    context = Context({
        'slackToken': 'in your dreams',
        'slackChannel': '#blah',
        'slackText': 'this is :boom: text'
    })

    with pytest.raises(SlackSendError) as err_info:
        send.run_step(context)

    assert str(err_info.value) == "bang bang"
async def _request_with_session(
    *,
    current_session: Optional[ClientSession],
    timeout: int,
    logger: Logger,
    http_verb: str,
    api_url: str,
    req_args: dict,
) -> Dict[str, any]:
    """Submit the HTTP request with the running session or a new session.
    Returns:
        A dictionary of the response data.
    """
    session = None
    use_running_session = current_session and not current_session.closed
    if use_running_session:
        session = current_session
    else:
        session = aiohttp.ClientSession(
            timeout=aiohttp.ClientTimeout(total=timeout),
            auth=req_args.pop("auth", None),
        )

    response = None
    try:
        async with session.request(http_verb, api_url, **req_args) as res:
            data = {}
            try:
                data = await res.json()
            except aiohttp.ContentTypeError:
                logger.debug(
                    f"No response data returned from the following API call: {api_url}."
                )
            except json.decoder.JSONDecodeError as e:
                message = f"Failed to parse the response body: {str(e)}"
                raise SlackApiError(message, res)

            response = {
                "data": data,
                "headers": res.headers,
                "status_code": res.status,
            }
    finally:
        if not use_running_session:
            await session.close()
    return response
示例#16
0
    async def users_profile_get(self, *, user: str) -> SlackResponse:
        step = self._step
        self._step = (self._step + 1) % 4

        if step == 0:
            raise ClientConnectionError()
        elif step == 1:
            return await super().users_profile_get(user=user)
        elif step == 2:
            response = self.build_slack_response({
                "ok": False,
                "error": "ratelimited"
            })
            raise SlackApiError("test exception", response)
        elif step == 3:
            return await super().users_profile_get(user=user)
        else:
            raise NotImplementedError("invalid step number")
async def test_setup_slackApiError(hass: HomeAssistant, caplog: LogCaptureFixture):
    """Test setup slack notify with SlackApiError exception."""
    config = DEFAULT_CONFIG

    with patch(
        MODULE_PATH + ".aiohttp_client",
        **{"async_get_clientsession.return_value": Mock()},
    ), patch(MODULE_PATH + ".WebClient", return_value=(client := AsyncMock())):

        client.auth_test.side_effect = [err := SlackApiError("msg", "resp")]
        await async_setup_component(hass, notify.DOMAIN, config)
        await hass.async_block_till_done()
        assert hass.services.has_service(notify.DOMAIN, SERVICE_NAME) is False
        caplog_records_slack = filter_log_records(caplog)
        assert len(caplog_records_slack) == 1
        record = caplog_records_slack[0]
        assert record.levelno == logging.ERROR
        assert err.__class__.__qualname__ in record.message
示例#18
0
    def test_call_with_failure(self, slack_client_class_mock):
        slack_client_mock = mock.Mock()
        slack_client_class_mock.return_value = slack_client_mock
        slack_response = mock.Mock()
        slack_client_mock.api_call.return_value = slack_response
        expected_exception = SlackApiError(message='foo', response='bar')
        slack_response.validate = mock.Mock(side_effect=expected_exception)

        test_token = 'test_token'
        test_slack_conn_id = 'test_slack_conn_id'
        slack_hook = SlackHook(token=test_token,
                               slack_conn_id=test_slack_conn_id)
        test_method = 'test_method'
        test_api_params = {'key1': 'value1', 'key2': 'value2'}

        try:
            slack_hook.call(test_method, test_api_params)
            self.fail()
        except AirflowException as exc:
            self.assertIn("foo", str(exc))
            self.assertIn("bar", str(exc))
示例#19
0
    def test__call_slack(self):
        ok = {"ok": True, "data": "foobar"}

        warning = {"ok": True, "warning": "bad", "data": "foobar"}

        self.mock_slack.api_call.return_value = ok
        assert self.cache._call_slack("some_method") == ok
        self.mock_slack.api_call.assert_called_with("some_method")
        assert self.cache._call_slack("some_method", json={"foo": "bar"}) == ok
        self.mock_slack.api_call.assert_called_with("some_method",
                                                    json={"foo": "bar"})

        self.mock_slack.api_call.return_value = warning
        with self._caplog.at_level(logging.WARNING):
            assert self.cache._call_slack("some_method") == warning
        assert 'raised a warning' in self._caplog.text

        self.mock_slack.api_call.side_effect = SlackApiError("foo",
                                                             response={
                                                                 "ok": False,
                                                                 "error": "foo"
                                                             })
        with pytest.raises(SlackApiError):
            self.cache._call_slack("some_method")
示例#20
0
def slack_api_error(mocker):
    return SlackApiError("Failed Slack call", mocker.Mock())