def make_twilio_request(method, uri, **kwargs):
    """
    Make a request to Twilio. Throws an error
    """
    headers = kwargs.get("headers", {})
    headers["User-Agent"] = "twilio-python/%s" % twilio.__version__

    if method == "POST" and "Content-Type" not in headers:
        headers["Content-Type"] = "application/x-www-form-urlencoded"

    kwargs["headers"] = headers

    if "Accept" not in headers:
        headers["Accept"] = "application/json"
        uri = uri + ".json"

    resp = make_request(method, uri, **kwargs)

    if not resp.ok:
        try:
            error = json.loads(resp.content)
            message = "%s: %s" % (error["code"], error["message"])
        except:
            message = resp.content

        raise TwilioRestException(resp.status_code, resp.url, message)

    return resp
    def create_instance(self, body):
        """
        Create an InstanceResource via a POST to the List Resource

        :param dict body: Dictoionary of POST data
        """
        resp, instance = self.request("POST", self.uri, data=body)

        if resp.status_code != 201:
            raise TwilioRestException(resp.status,
                                      self.uri, "Resource not created")

        return self.load_instance(instance)
Esempio n. 3
0
def twilioSMS_unloggedSender(request, recipient, body, sender=settings.TWILIO_CALLER_ID, callBack=None):
	"""Sends an SMS message without logging it.

	:param request: The HTTP Request object
	:param recipient: The destination mobile phone number.
	:param body: The body of the message to be sent. The length of this MUST NOT be
		greater than 160 characters. An exception is raised if it is.
	:param sender: The "sender" of the SMS message. Note that this value MUST be a
		DoctorCom phone number (one that we own through our Twilio account).
		If it isn't, then urllib will raise an exception since Twilio will
		come back with HTTP status 400.
	:param callBack: The url to have Twilio call back to with the SMS delivery
			status. Default None.
	"""
	if (len(body) > 160):  # fragment?
		raise Exception('Message is too long: "%s"' % (body,))

	sms_resp = None
	try:
#		d = {
#			'From': sender,
#			'To': recipient,
#			'Body': body,
#			'Method': 'POST',
#			'StatusCallback': callBack or '',
#		}
#		auth, uri = client.auth, client.account_uri
#		resp = make_twilio_request('POST', uri + '/SMS/Messages', auth=auth, data=d)
#		sms_resp = json.loads(resp.content)
# 		2010-04-01 version
		sms_resp = client.sms.messages.create(body=body, to=recipient,
			from_=sender, status_callback=callBack)
	except TwilioRestException as re:
		msg = re.msg  # json.loads(re.msg)
		if (re.status == 400):
			logger.warn('%s: got HTTP400 from Twilio: %s' % 
					(str(request.session.session_key), msg))
		else:
			logger.error('%s: Got HTTP from Twilio: %s' % 
					(str(request.session.session_key), msg))

		# An error occurred, re-raise the exception
		raise TwilioRestException(re.status, re.uri, msg, re.code or 0)

	return sms_resp
Esempio n. 4
0
    def test_deactivate(self):

        # make our channel of the twilio ilk
        self.org.connect_twilio("TEST_SID", "TEST_TOKEN", self.admin)
        twilio_channel = self.org.channels.all().first()
        twilio_channel.channel_type = "T"
        twilio_channel.save()

        # mock an authentication failure during the release process
        with self.settings(IS_PROD=True):
            with patch("temba.tests.twilio.MockTwilioClient.MockPhoneNumbers.update") as mock_numbers:
                mock_numbers.side_effect = TwilioRestException(
                    401, "http://twilio", msg="Authentication Failure", code=20003
                )

                # releasing shouldn't blow up on auth failures
                twilio_channel.release()
                twilio_channel.refresh_from_db()
                self.assertFalse(twilio_channel.is_active)
Esempio n. 5
0
    def test_claim(self):
        self.login(self.admin)

        claim_twilio = reverse("channels.types.twilio.claim")

        # remove any existing channels
        self.org.channels.update(is_active=False)

        # make sure twilio is on the claim page
        response = self.client.get(reverse("channels.channel_claim"))
        self.assertContains(response, "Twilio")

        response = self.client.get(claim_twilio)
        self.assertEqual(response.status_code, 302)
        response = self.client.get(claim_twilio, follow=True)
        self.assertEqual(response.request["PATH_INFO"], reverse("orgs.org_twilio_connect"))

        # attach a Twilio accont to the org
        self.org.config = {ACCOUNT_SID: "account-sid", ACCOUNT_TOKEN: "account-token"}
        self.org.save()

        # hit the claim page, should now have a claim twilio link
        response = self.client.get(reverse("channels.channel_claim"))
        self.assertContains(response, claim_twilio)

        response = self.client.get(claim_twilio)
        self.assertIn("account_trial", response.context)
        self.assertFalse(response.context["account_trial"])

        with patch("temba.orgs.models.Org.get_twilio_client") as mock_get_twilio_client:
            mock_get_twilio_client.return_value = None

            response = self.client.get(claim_twilio)
            self.assertRedirects(response, reverse("orgs.org_twilio_connect"))

            mock_get_twilio_client.side_effect = TwilioRestException(
                401, "http://twilio", msg="Authentication Failure", code=20003
            )

            response = self.client.get(claim_twilio)
            self.assertRedirects(response, reverse("orgs.org_twilio_connect"))

        with patch("temba.tests.twilio.MockTwilioClient.MockAccounts.get") as mock_get:
            mock_get.return_value = MockTwilioClient.MockAccount("Trial")

            response = self.client.get(claim_twilio)
            self.assertIn("account_trial", response.context)
            self.assertTrue(response.context["account_trial"])

        with patch("temba.tests.twilio.MockTwilioClient.MockPhoneNumbers.search") as mock_search:
            search_url = reverse("channels.channel_search_numbers")

            # try making empty request
            response = self.client.post(search_url, {})
            self.assertEqual(response.json(), [])

            # try searching for US number
            mock_search.return_value = [MockTwilioClient.MockPhoneNumber("+12062345678")]
            response = self.client.post(search_url, {"country": "US", "area_code": "206"})
            self.assertEqual(response.json(), ["+1 206-234-5678", "+1 206-234-5678"])

            # try searching without area code
            response = self.client.post(search_url, {"country": "US", "area_code": ""})
            self.assertEqual(response.json(), ["+1 206-234-5678", "+1 206-234-5678"])

            mock_search.return_value = []
            response = self.client.post(search_url, {"country": "US", "area_code": ""})
            self.assertEqual(
                response.json()["error"], "Sorry, no numbers found, please enter another area code and try again."
            )

            # try searching for non-US number
            mock_search.return_value = [MockTwilioClient.MockPhoneNumber("+442812345678")]
            response = self.client.post(search_url, {"country": "GB", "area_code": "028"})
            self.assertEqual(response.json(), ["+44 28 1234 5678", "+44 28 1234 5678"])

            mock_search.return_value = []
            response = self.client.post(search_url, {"country": "GB", "area_code": ""})
            self.assertEqual(
                response.json()["error"], "Sorry, no numbers found, please enter another pattern and try again."
            )

        with patch("temba.tests.twilio.MockTwilioClient.MockPhoneNumbers.list") as mock_numbers:
            mock_numbers.return_value = [MockTwilioClient.MockPhoneNumber("+12062345678")]

            with patch("temba.tests.twilio.MockTwilioClient.MockShortCodes.list") as mock_short_codes:
                mock_short_codes.return_value = []

                response = self.client.get(claim_twilio)
                self.assertContains(response, "206-234-5678")

                # claim it
                response = self.client.post(claim_twilio, dict(country="US", phone_number="12062345678"))
                self.assertRedirects(response, reverse("public.public_welcome") + "?success")

                # make sure it is actually connected
                channel = Channel.objects.get(channel_type="T", org=self.org)
                self.assertEqual(
                    channel.role, Channel.ROLE_CALL + Channel.ROLE_ANSWER + Channel.ROLE_SEND + Channel.ROLE_RECEIVE
                )

                channel_config = channel.config
                self.assertEqual(channel_config[Channel.CONFIG_ACCOUNT_SID], "account-sid")
                self.assertEqual(channel_config[Channel.CONFIG_AUTH_TOKEN], "account-token")
                self.assertTrue(channel_config[Channel.CONFIG_APPLICATION_SID])
                self.assertTrue(channel_config[Channel.CONFIG_NUMBER_SID])

        # voice only number
        with patch("temba.tests.twilio.MockTwilioClient.MockPhoneNumbers.list") as mock_numbers:
            mock_numbers.return_value = [MockTwilioClient.MockPhoneNumber("+554139087835")]

            with patch("temba.tests.twilio.MockTwilioClient.MockShortCodes.list") as mock_short_codes:
                mock_short_codes.return_value = []
                Channel.objects.all().delete()

                response = self.client.get(claim_twilio)
                self.assertContains(response, "+55 41 3908-7835")

                # claim it
                response = self.client.post(claim_twilio, dict(country="BR", phone_number="554139087835"))
                self.assertRedirects(response, reverse("public.public_welcome") + "?success")

                # make sure it is actually connected
                channel = Channel.objects.get(channel_type="T", org=self.org)
                self.assertEqual(channel.role, Channel.ROLE_CALL + Channel.ROLE_ANSWER)

        with patch("temba.tests.twilio.MockTwilioClient.MockPhoneNumbers.list") as mock_numbers:
            mock_numbers.return_value = [MockTwilioClient.MockPhoneNumber("+4545335500")]

            with patch("temba.tests.twilio.MockTwilioClient.MockShortCodes.list") as mock_short_codes:
                mock_short_codes.return_value = []

                Channel.objects.all().delete()

                response = self.client.get(claim_twilio)
                self.assertContains(response, "45 33 55 00")
                self.assertEqual(mock_numbers.call_args_list[0][1], {"page_size": 1000})

                # claim it
                response = self.client.post(claim_twilio, dict(country="DK", phone_number="4545335500"))
                self.assertRedirects(response, reverse("public.public_welcome") + "?success")

                # make sure it is actually connected
                Channel.objects.get(channel_type="T", org=self.org)

        with patch("temba.tests.twilio.MockTwilioClient.MockPhoneNumbers.list") as mock_numbers:
            mock_numbers.return_value = []

            with patch("temba.tests.twilio.MockTwilioClient.MockShortCodes.list") as mock_short_codes:
                mock_short_codes.return_value = [MockTwilioClient.MockShortCode("8080")]
                Channel.objects.all().delete()

                self.org.timezone = "America/New_York"
                self.org.save()

                response = self.client.get(claim_twilio)
                self.assertContains(response, "8080")
                self.assertContains(response, 'class="country">US')  # we look up the country from the timezone

                # claim it
                response = self.client.post(claim_twilio, dict(country="US", phone_number="8080"))
                self.assertRedirects(response, reverse("public.public_welcome") + "?success")
                self.assertEqual(mock_numbers.call_args_list[0][1], {"page_size": 1000})

                # make sure it is actually connected
                Channel.objects.get(channel_type="T", org=self.org)

        twilio_channel = self.org.channels.all().first()
        # make channel support both sms and voice to check we clear both applications
        twilio_channel.role = Channel.ROLE_SEND + Channel.ROLE_RECEIVE + Channel.ROLE_ANSWER + Channel.ROLE_CALL
        twilio_channel.save()
        self.assertEqual("T", twilio_channel.channel_type)

        with self.settings(IS_PROD=True):
            with patch("temba.tests.twilio.MockTwilioClient.MockPhoneNumbers.update") as mock_numbers:
                # our twilio channel removal should fail on bad auth
                mock_numbers.side_effect = TwilioRestException(
                    401, "http://twilio", msg="Authentication Failure", code=20003
                )
                self.client.post(reverse("channels.channel_delete", args=[twilio_channel.pk]))
                self.assertIsNotNone(self.org.channels.all().first())

                # or other arbitrary twilio errors
                mock_numbers.side_effect = TwilioRestException(400, "http://twilio", msg="Twilio Error", code=123)
                self.client.post(reverse("channels.channel_delete", args=[twilio_channel.pk]))
                self.assertIsNotNone(self.org.channels.all().first())

                # now lets be successful
                mock_numbers.side_effect = None
                self.client.post(reverse("channels.channel_delete", args=[twilio_channel.pk]))
                self.assertIsNone(self.org.channels.filter(is_active=True).first())
                self.assertEqual(
                    mock_numbers.call_args_list[-1][1], dict(voice_application_sid="", sms_application_sid="")
                )
Esempio n. 6
0
 def side_effect():
     from twilio import TwilioRestException
     raise TwilioRestException('Test exception')
Esempio n. 7
0
 def create(self, to=None, from_=None, url=None, status_callback=None):
     from twilio import TwilioRestException
     raise TwilioRestException(403, 'http://twilio.com', code=20003)
Esempio n. 8
0
    def test_claim(self):
        self.login(self.admin)

        claim_twilio = reverse('channels.claim_twilio')

        # remove any existing channels
        self.org.channels.update(is_active=False, org=None)

        # make sure twilio is on the claim page
        response = self.client.get(reverse('channels.channel_claim'))
        self.assertContains(response, "Twilio")

        response = self.client.get(claim_twilio)
        self.assertEqual(response.status_code, 302)
        response = self.client.get(claim_twilio, follow=True)
        self.assertEqual(response.request['PATH_INFO'],
                         reverse('orgs.org_twilio_connect'))

        # attach a Twilio accont to the org
        self.org.config = json.dumps({
            ACCOUNT_SID: 'account-sid',
            ACCOUNT_TOKEN: 'account-token'
        })
        self.org.save()

        # hit the claim page, should now have a claim twilio link
        response = self.client.get(reverse('channels.channel_claim'))
        self.assertContains(response, claim_twilio)

        response = self.client.get(claim_twilio)
        self.assertIn('account_trial', response.context)
        self.assertFalse(response.context['account_trial'])

        with patch('temba.orgs.models.Org.get_twilio_client'
                   ) as mock_get_twilio_client:
            mock_get_twilio_client.return_value = None

            response = self.client.get(claim_twilio)
            self.assertRedirects(response, reverse('orgs.org_twilio_connect'))

            mock_get_twilio_client.side_effect = TwilioRestException(
                401, 'http://twilio', msg='Authentication Failure', code=20003)

            response = self.client.get(claim_twilio)
            self.assertRedirects(response, reverse('orgs.org_twilio_connect'))

        with patch(
                'temba.tests.MockTwilioClient.MockAccounts.get') as mock_get:
            mock_get.return_value = MockTwilioClient.MockAccount('Trial')

            response = self.client.get(claim_twilio)
            self.assertIn('account_trial', response.context)
            self.assertTrue(response.context['account_trial'])

        with patch('temba.tests.MockTwilioClient.MockPhoneNumbers.search'
                   ) as mock_search:
            search_url = reverse('channels.channel_search_numbers')

            # try making empty request
            response = self.client.post(search_url, {})
            self.assertEqual(response.json(), [])

            # try searching for US number
            mock_search.return_value = [
                MockTwilioClient.MockPhoneNumber('+12062345678')
            ]
            response = self.client.post(search_url, {
                'country': 'US',
                'area_code': '206'
            })
            self.assertEqual(response.json(),
                             ['+1 206-234-5678', '+1 206-234-5678'])

            # try searching without area code
            response = self.client.post(search_url, {
                'country': 'US',
                'area_code': ''
            })
            self.assertEqual(response.json(),
                             ['+1 206-234-5678', '+1 206-234-5678'])

            mock_search.return_value = []
            response = self.client.post(search_url, {
                'country': 'US',
                'area_code': ''
            })
            self.assertEqual(
                json.loads(response.content)['error'],
                "Sorry, no numbers found, please enter another area code and try again."
            )

            # try searching for non-US number
            mock_search.return_value = [
                MockTwilioClient.MockPhoneNumber('+442812345678')
            ]
            response = self.client.post(search_url, {
                'country': 'GB',
                'area_code': '028'
            })
            self.assertEqual(response.json(),
                             ['+44 28 1234 5678', '+44 28 1234 5678'])

            mock_search.return_value = []
            response = self.client.post(search_url, {
                'country': 'GB',
                'area_code': ''
            })
            self.assertEqual(
                json.loads(response.content)['error'],
                "Sorry, no numbers found, please enter another pattern and try again."
            )

        with patch('temba.tests.MockTwilioClient.MockPhoneNumbers.list'
                   ) as mock_numbers:
            mock_numbers.return_value = [
                MockTwilioClient.MockPhoneNumber('+12062345678')
            ]

            with patch('temba.tests.MockTwilioClient.MockShortCodes.list'
                       ) as mock_short_codes:
                mock_short_codes.return_value = []

                response = self.client.get(claim_twilio)
                self.assertContains(response, '206-234-5678')

                # claim it
                response = self.client.post(
                    claim_twilio, dict(country='US',
                                       phone_number='12062345678'))
                self.assertRedirects(
                    response,
                    reverse('public.public_welcome') + "?success")

                # make sure it is actually connected
                channel = Channel.objects.get(channel_type='T', org=self.org)
                self.assertEqual(
                    channel.role, Channel.ROLE_CALL + Channel.ROLE_ANSWER +
                    Channel.ROLE_SEND + Channel.ROLE_RECEIVE)

                channel_config = channel.config_json()
                self.assertEqual(channel_config[Channel.CONFIG_ACCOUNT_SID],
                                 'account-sid')
                self.assertEqual(channel_config[Channel.CONFIG_AUTH_TOKEN],
                                 'account-token')
                self.assertTrue(channel_config[Channel.CONFIG_APPLICATION_SID])
                self.assertTrue(channel_config[Channel.CONFIG_NUMBER_SID])

        # voice only number
        with patch('temba.tests.MockTwilioClient.MockPhoneNumbers.list'
                   ) as mock_numbers:
            mock_numbers.return_value = [
                MockTwilioClient.MockPhoneNumber('+554139087835')
            ]

            with patch('temba.tests.MockTwilioClient.MockShortCodes.list'
                       ) as mock_short_codes:
                mock_short_codes.return_value = []
                Channel.objects.all().delete()

                response = self.client.get(claim_twilio)
                self.assertContains(response, '+55 41 3908-7835')

                # claim it
                response = self.client.post(
                    claim_twilio,
                    dict(country='BR', phone_number='554139087835'))
                self.assertRedirects(
                    response,
                    reverse('public.public_welcome') + "?success")

                # make sure it is actually connected
                channel = Channel.objects.get(channel_type='T', org=self.org)
                self.assertEqual(channel.role,
                                 Channel.ROLE_CALL + Channel.ROLE_ANSWER)

        with patch('temba.tests.MockTwilioClient.MockPhoneNumbers.list'
                   ) as mock_numbers:
            mock_numbers.return_value = [
                MockTwilioClient.MockPhoneNumber('+4545335500')
            ]

            with patch('temba.tests.MockTwilioClient.MockShortCodes.list'
                       ) as mock_short_codes:
                mock_short_codes.return_value = []

                Channel.objects.all().delete()

                response = self.client.get(claim_twilio)
                self.assertContains(response, '45 33 55 00')

                # claim it
                response = self.client.post(
                    claim_twilio, dict(country='DK',
                                       phone_number='4545335500'))
                self.assertRedirects(
                    response,
                    reverse('public.public_welcome') + "?success")

                # make sure it is actually connected
                Channel.objects.get(channel_type='T', org=self.org)

        with patch('temba.tests.MockTwilioClient.MockPhoneNumbers.list'
                   ) as mock_numbers:
            mock_numbers.return_value = []

            with patch('temba.tests.MockTwilioClient.MockShortCodes.list'
                       ) as mock_short_codes:
                mock_short_codes.return_value = [
                    MockTwilioClient.MockShortCode('8080')
                ]
                Channel.objects.all().delete()

                self.org.timezone = 'America/New_York'
                self.org.save()

                response = self.client.get(claim_twilio)
                self.assertContains(response, '8080')
                self.assertContains(
                    response, 'class="country">US'
                )  # we look up the country from the timezone

                # claim it
                response = self.client.post(
                    claim_twilio, dict(country='US', phone_number='8080'))
                self.assertRedirects(
                    response,
                    reverse('public.public_welcome') + "?success")

                # make sure it is actually connected
                Channel.objects.get(channel_type='T', org=self.org)

        twilio_channel = self.org.channels.all().first()
        # make channel support both sms and voice to check we clear both applications
        twilio_channel.role = Channel.ROLE_SEND + Channel.ROLE_RECEIVE + Channel.ROLE_ANSWER + Channel.ROLE_CALL
        twilio_channel.save()
        self.assertEqual('T', twilio_channel.channel_type)

        with self.settings(IS_PROD=True):
            with patch('temba.tests.MockTwilioClient.MockPhoneNumbers.update'
                       ) as mock_numbers:
                # our twilio channel removal should fail on bad auth
                mock_numbers.side_effect = TwilioRestException(
                    401,
                    'http://twilio',
                    msg='Authentication Failure',
                    code=20003)
                self.client.post(
                    reverse('channels.channel_delete',
                            args=[twilio_channel.pk]))
                self.assertIsNotNone(self.org.channels.all().first())

                # or other arbitrary twilio errors
                mock_numbers.side_effect = TwilioRestException(
                    400, 'http://twilio', msg='Twilio Error', code=123)
                self.client.post(
                    reverse('channels.channel_delete',
                            args=[twilio_channel.pk]))
                self.assertIsNotNone(self.org.channels.all().first())

                # now lets be successful
                mock_numbers.side_effect = None
                self.client.post(
                    reverse('channels.channel_delete',
                            args=[twilio_channel.pk]))
                self.assertIsNone(self.org.channels.all().first())
                self.assertEqual(
                    mock_numbers.call_args_list[-1][1],
                    dict(voice_application_sid='', sms_application_sid=''))
Esempio n. 9
0
    def test_claim(self):

        self.login(self.admin)

        claim_twilio_ms = reverse('channels.claim_twilio_messaging_service')

        # remove any existing channels
        self.org.channels.all().delete()

        # make sure twilio is on the claim page
        response = self.client.get(reverse('channels.channel_claim'))
        self.assertContains(response, "Twilio")

        response = self.client.get(claim_twilio_ms)
        self.assertEqual(response.status_code, 302)
        response = self.client.get(claim_twilio_ms, follow=True)
        self.assertEqual(response.request['PATH_INFO'],
                         reverse('orgs.org_twilio_connect'))

        twilio_config = dict()
        twilio_config[ACCOUNT_SID] = 'account-sid'
        twilio_config[ACCOUNT_TOKEN] = 'account-token'
        twilio_config[APPLICATION_SID] = 'TwilioTestSid'

        self.org.config = json.dumps(twilio_config)
        self.org.save()

        response = self.client.get(reverse('channels.channel_claim'))
        self.assertContains(response, claim_twilio_ms)

        response = self.client.get(claim_twilio_ms)
        self.assertTrue('account_trial' in response.context)
        self.assertFalse(response.context['account_trial'])

        with patch('temba.orgs.models.Org.get_twilio_client'
                   ) as mock_get_twilio_client:
            mock_get_twilio_client.return_value = None

            response = self.client.get(claim_twilio_ms)
            self.assertRedirects(response, reverse('orgs.org_twilio_connect'))

            mock_get_twilio_client.side_effect = TwilioRestException(
                401, 'http://twilio', msg='Authentication Failure', code=20003)

            response = self.client.get(claim_twilio_ms)
            self.assertRedirects(response, reverse('orgs.org_twilio_connect'))

        with patch(
                'temba.tests.MockTwilioClient.MockAccounts.get') as mock_get:
            mock_get.return_value = MockTwilioClient.MockAccount('Trial')

            response = self.client.get(claim_twilio_ms)
            self.assertTrue('account_trial' in response.context)
            self.assertTrue(response.context['account_trial'])

        response = self.client.get(claim_twilio_ms)
        self.assertEqual(response.context['form'].fields['country'].choices,
                         list(TWILIO_SUPPORTED_COUNTRIES))
        self.assertContains(response, "icon-channel-twilio")

        response = self.client.post(claim_twilio_ms, dict())
        self.assertTrue(response.context['form'].errors)

        response = self.client.post(
            claim_twilio_ms,
            dict(country='US', messaging_service_sid='MSG-SERVICE-SID'))
        channel = self.org.channels.get()
        self.assertRedirects(
            response,
            reverse('channels.channel_configuration', args=[channel.pk]))
        self.assertEqual(channel.channel_type, "TMS")

        channel_config = channel.config_json()
        self.assertEqual(channel_config['messaging_service_sid'],
                         'MSG-SERVICE-SID')
        self.assertTrue(channel_config['account_sid'])
        self.assertTrue(channel_config['auth_token'])
Esempio n. 10
0
def make_twilio_request(method, uri, **kwargs):
    """
    Make a request to Twilio. Throws an error

    :return: a requests-like HTTP response
    :rtype: :class:`RequestsResponse`
    :raises TwilioRestException: if the response is a 400
        or 500-level response.
    """
    headers = kwargs.get("headers", {})

    user_agent = "twilio-python/%s (Python %s)" % (
        twilio.__version__,
        platform.python_version(),
    )
    headers["User-Agent"] = user_agent
    headers["Accept-Charset"] = "utf-8"

    if method == "POST" and "Content-Type" not in headers:
        headers["Content-Type"] = "application/x-www-form-urlencoded"

    kwargs["headers"] = headers

    if "Accept" not in headers:
        headers["Accept"] = "application/json"
        uri += ".json"

    resp = make_request(method, uri, **kwargs)

    if not resp.ok:
        try:
            error = json.loads(resp.content)
            code = error["code"]
            message = "%s: %s" % (code, error["message"])
        except:
            code = None
            message = resp.content

        def red(msg):
            return u("\033[31m\033[49m%s\033[0m") % msg

        def white(msg):
            return u("\033[37m\033[49m%s\033[0m") % msg

        def blue(msg):
            return u("\033[34m\033[49m%s\033[0m") % msg

        def orange(msg):
            return u("\033[33m\033[49m%s\033[0m") % msg

        def teal(msg):
            return u("\033[36m\033[49m%s\033[0m") % msg

        # If it makes sense to print a human readable error message, try to do
        # it. The one problem is that someone might catch this error and try to
        # display the message from it to an end user.
        if hasattr(sys.stderr, 'isatty') and sys.stderr.isatty():
            msg = red("\nHTTP Error. ")
            msg += white("Your request was:\n\n")
            msg += teal("%s %s" % (method, uri))
            msg += white("\n\nTwilio returned the following information:")
            msg += blue("\n\n" + str(message) + "\n")
            if code:
                msg += white("\nMore information may be available here:\n\n")
                msg += blue("https://www.twilio.com/docs/errors/%s" % code)
                msg += "\n\n"
        else:
            msg = message

        raise TwilioRestException(resp.status_code, resp.url, msg, code)

    return resp
Esempio n. 11
0
    def test_claim(self):

        self.login(self.admin)

        claim_twilio_ms = reverse("channels.types.twilio_messaging_service.claim")

        # remove any existing channels
        self.org.channels.all().delete()

        # make sure twilio is on the claim page
        response = self.client.get(reverse("channels.channel_claim"))
        self.assertContains(response, "Twilio")

        response = self.client.get(claim_twilio_ms)
        self.assertEqual(response.status_code, 302)
        response = self.client.get(claim_twilio_ms, follow=True)
        self.assertEqual(response.request["PATH_INFO"], reverse("orgs.org_twilio_connect"))

        twilio_config = dict()
        twilio_config[ACCOUNT_SID] = "account-sid"
        twilio_config[ACCOUNT_TOKEN] = "account-token"
        twilio_config[APPLICATION_SID] = "TwilioTestSid"

        self.org.config = twilio_config
        self.org.save()

        response = self.client.get(reverse("channels.channel_claim"))
        self.assertContains(response, claim_twilio_ms)

        response = self.client.get(claim_twilio_ms)
        self.assertIn("account_trial", response.context)
        self.assertFalse(response.context["account_trial"])

        with patch("temba.orgs.models.Org.get_twilio_client") as mock_get_twilio_client:
            mock_get_twilio_client.return_value = None

            response = self.client.get(claim_twilio_ms)
            self.assertRedirects(response, reverse("orgs.org_twilio_connect"))

            mock_get_twilio_client.side_effect = TwilioRestException(
                401, "http://twilio", msg="Authentication Failure", code=20003
            )

            response = self.client.get(claim_twilio_ms)
            self.assertRedirects(response, reverse("orgs.org_twilio_connect"))

        with patch("temba.tests.twilio.MockTwilioClient.MockAccounts.get") as mock_get:
            mock_get.return_value = MockTwilioClient.MockAccount("Trial")

            response = self.client.get(claim_twilio_ms)
            self.assertIn("account_trial", response.context)
            self.assertTrue(response.context["account_trial"])

        response = self.client.get(claim_twilio_ms)
        self.assertEqual(response.context["form"].fields["country"].choices, list(TWILIO_SUPPORTED_COUNTRIES))
        self.assertContains(response, "icon-channel-twilio")

        response = self.client.post(claim_twilio_ms, dict())
        self.assertTrue(response.context["form"].errors)

        response = self.client.post(claim_twilio_ms, dict(country="US", messaging_service_sid="MSG-SERVICE-SID"))
        channel = self.org.channels.get()
        self.assertRedirects(response, reverse("channels.channel_configuration", args=[channel.uuid]))
        self.assertEqual(channel.channel_type, "TMS")

        channel_config = channel.config
        self.assertEqual(channel_config["messaging_service_sid"], "MSG-SERVICE-SID")
        self.assertTrue(channel_config["account_sid"])
        self.assertTrue(channel_config["auth_token"])

        response = self.client.get(reverse("channels.channel_configuration", args=[channel.uuid]))
        self.assertContains(response, reverse("courier.tms", args=[channel.uuid, "receive"]))