示例#1
0
    def test_international_sms(self):

        token = os.environ["TWILIO_AUTH_TOKEN"]
        validator = RequestValidator(token)

        uri = "http://www.postbin.org/1c2pdoc"
        params = {
            "AccountSid": "AC4bf2dafb92341f7caf8650403e422d23",
            "ApiVersion": "2010-04-01",
            "Body": "Chloéñ",
            "From": "+15305451766",
            "FromCity": "SOUTH LAKE TAHOE",
            "FromCountry": "US",
            "FromState": "CA",
            "FromZip": "89449",
            "SmsMessageSid": "SM51d6d055f53f1072543872c601aae89b",
            "SmsStatus": "SM51d6d055f53f1072543872c601aae89b",
            "SmsStatus": "received",
            "To": "+15304194304",
            "ToCity": "WOODLAND",
            "ToCountry": "US",
            "ToState": "CA",
            "ToZip": "95695",
            }

        expected = "UHkWu+6WLOzPunzb8PuCGPeW1Uw="

        self.assertEquals(validator.compute_signature(uri, params), expected)
        self.assertTrue(validator.validate(uri, params, expected))
示例#2
0
def authenticate():
    """Verify that request came from Twilio"""
    if current_app.config.get("DEBUG"):
        return  # Don't auth in dev

    # Auth that it came from twilio

    validator = RequestValidator(current_app.config.get("TWILIO_AUTH_TOKEN"))
    valid = validator.validate(request.url, request.form,
                               request.headers.get('X-Twilio-Signature', ''))

    if not valid:
        # If the request was spoofed, then send '403 Forbidden'.
        current_app.logger.info("IVR detected spoofed incoming call")
        abort(403)

    # Final thing - check that the number is registered to the application.
    # HYPOTHETICALLY - somebody could buy a number through their own
    # twilio account and point it at our app, and be able to cause
    # issues.
    to = request.values.get("To")
    if not to:
        current_app.logger.info("IVR missing To parameter")
        abort(403)
    p = phonenumbers.parse(to)
    if not current_app.config["TWILIO_NUMBER"].get(str(p.country_code)) == str(
            p.national_number):
        current_app.logger.info("IVR call to unregistered number - %s" % to)
        abort(403)
    return
示例#3
0
    def validate(self, request):
        validator = RequestValidator(self.auth[1])
        signature = request.META.get('HTTP_X_TWILIO_SIGNATURE', '')

        base_url = settings.TEMBA_HOST
        url = "https://%s%s" % (base_url, request.get_full_path())
        return validator.validate(url, request.POST, signature)
示例#4
0
文件: app.py 项目: dandante/gsnac_rrn
def incoming_sms():
    form = request.form
    validator = RequestValidator(os.getenv("TWILIO_AUTH_TOKEN"))
    url = request.url.replace("http:", "https:")
    sig = request.headers['X-Twilio-Signature']
    if not validator.validate(url, form, sig):
        return "oops, invalid signature, no spoofs accepted"
    if not form['To'] == os.getenv('RRN_PHONE_NUMBER'):
        return "ignoring you, wrong To: phone number"
    if not form['AccountSid'] == os.getenv('TWILIO_ACCOUNT_SID'):
        return "ignoring you, wrong Twilio SID"
    text = "<!channel> Message from: {}: {}".format(form['From'], form['Body'])
    media_keys = [x for x in form.keys() if x.startswith("MediaUrl")]
    media_urls = [form[x] for x in sorted(media_keys)]
    if len(media_urls):
        text = "{} \nAttachments: \n{}".format(text, "\n".join(media_urls))

    payload = dict(channel=os.getenv('SLACK_CHANNEL'),
                   username=os.getenv('SLACK_USERNAME'),
                   icon_emoji=os.getenv('SLACK_ICON_EMOJI'),
                   text=text)
    response = requests.post(os.getenv('SLACK_POST_URL'), json.dumps(payload))
    # FIXME check response return code
    # FIXME deal with MMS attachments

    # import IPython;IPython.embed()
    return Response(
        '<?xml version="1.0" encoding="UTF-8" ?><Response></Response>',
        mimetype='text/xml')
示例#5
0
    def decorator(request, *args, **kwargs):
        # Here we'll use the twilio library's request validation code to ensure
        # that the current request actually came from twilio, and isn't a
        # forgery. If it is a forgery, then we'll return a HTTP 403 error
        # (forbidden).
        try:
            url = request.build_absolute_uri()
            signature = request.META['HTTP_X_TWILIO_SIGNATURE']
        except (AttributeError, KeyError):
            return HttpResponseForbidden()

        validator = RequestValidator(settings.TWILIO_AUTH_TOKEN)
        if not validator.validate(url, request.POST, signature):
            return HttpResponseForbidden()

        # Run the wrapped view, and capture the data returned.
        response = f(request, *args, **kwargs)

        # If the view returns a string, we'll assume it is XML TwilML data and
        # pass it back with the appropriate mimetype. We won't check the XML
        # data because that would be too time consuming for every request.
        # Instead, we'll let the errors pass through to be dealt with by the
        # developer.
        if isinstance(response, Verb):
            return HttpResponse(response, mimetype='text/xml')
        else:
            return response
示例#6
0
    def validate(self, request):
        validator = RequestValidator(self.auth[1])
        signature = request.META.get('HTTP_X_TWILIO_SIGNATURE', '')

        base_url = settings.TEMBA_HOST
        url = "https://%s%s" % (base_url, request.get_full_path())
        return validator.validate(url, request.POST, signature)
示例#7
0
    def decorator(request, *args, **kwargs):
        # Here we'll use the twilio library's request validation code to ensure
        # that the current request actually came from twilio, and isn't a
        # forgery if settings.DEBUG is True. If it is a forgery, then we'll
        #return a HTTP 403 error (forbidden).
        if not settings.DEBUG:
            try:
                url = request.build_absolute_uri()
                signature = request.META['HTTP_X_TWILIO_SIGNATURE']
            except (AttributeError, KeyError):
                return HttpResponseForbidden()
    
            validator = RequestValidator(settings.TWILIO_AUTH_TOKEN)
            if not validator.validate(url, request.POST, signature):
                return HttpResponseForbidden()
    
            # Run the wrapped view, and capture the data returned.
            response = require_POST(f(request, *args, **kwargs))
        else:
            response = f(request, *args, **kwargs)

        # If the view returns a string, we'll assume it is XML TwilML data and
        # pass it back with the appropriate mimetype. We won't check the XML
        # data because that would be too time consuming for every request.
        # Instead, we'll let the errors pass through to be dealt with by the
        # developer.
        if isinstance(response, Verb):
            return HttpResponse(response, mimetype='text/xml')
        else:
            return response
示例#8
0
 def get(self):
     client = TwilioRestClient(account_sid, auth_token)
     validator = RequestValidator(auth_token)
     url = self.request.url
     params = {}
     try:
         twilio_signature = self.request.headers["X-Twilio-Signature"]
         logging.debug(twilio_signature)
     except:
         twilio_signature = ""
     if validator.validate(url, params, twilio_signature):
         logging.debug("Validated")
         call_id = self.request.get('to_call')
         print call_id
         infos = Call.query(Call.key==ndb.Key(Call, int(call_id))).fetch()
         print infos
         for info in infos:
             print info
             for i in json.loads(info.calls):
                 print i
                 call_out = client.calls.create(to=i, from_="2065576875",
                                                  url="https://teen-link.appspot.com/make-calls?RecordingUrl=" + self.request.get("RecordingUrl"),
                             method="GET",
                             if_machine="Continue")
                 print call_out
     else:
         self.response.headers['Content-Type'] = 'text/html'
         self.response.write("Please don't try to hack me.")
示例#9
0
def hello():
    """Respond to incoming requests."""

    resp = twiml.Response()
    first_request = True
    twilio_account_sid = os.environ.get("TWILIO_ACCOUNT_SID")
    twilio_auth_token = os.environ.get("TWILIO_AUTH_TOKEN")
    twilio_number = os.environ.get("TWILIO_NUMBER")

    validator = RequestValidator(twilio_auth_token)
    
    if 'X-Twilio-Signature' not in request.headers:        
        if first_request:
            first_request = False
        else:
            abort(401)
    else:         
        my_url = request.url
        if my_url.startswith('http://'):
            my_url = my_url.replace("http", "https")
        
        params = request.form
        
        twilio_signature = request.headers['X-Twilio-Signature']
        
        if validator.validate(my_url, params, twilio_signature):
            resp.say("Hello! Welcome to the telephone fizz buzz game!")
            with resp.gather(timeout=10, finishOnKey="*", action="/handle-key", method="POST") as g:
                g.say("Please enter your number and then press star.")
        else: 
            abort(401)
            
    return str(resp)
示例#10
0
    def test_international_sms(self):

        token = os.environ["TWILIO_AUTH_TOKEN"]
        validator = RequestValidator(token)

        uri = "http://www.postbin.org/1c2pdoc"
        params = {
            "AccountSid": "AC4bf2dafb92341f7caf8650403e422d23",
            "ApiVersion": "2010-04-01",
            "Body": "Chloéñ",
            "From": "+15305451766",
            "FromCity": "SOUTH LAKE TAHOE",
            "FromCountry": "US",
            "FromState": "CA",
            "FromZip": "89449",
            "SmsMessageSid": "SM51d6d055f53f1072543872c601aae89b",
            "SmsStatus": "SM51d6d055f53f1072543872c601aae89b",
            "SmsStatus": "received",
            "To": "+15304194304",
            "ToCity": "WOODLAND",
            "ToCountry": "US",
            "ToState": "CA",
            "ToZip": "95695",
        }

        expected = "UHkWu+6WLOzPunzb8PuCGPeW1Uw="

        self.assertEquals(validator.compute_signature(uri, params), expected)
        self.assertTrue(validator.validate(uri, params, expected))
示例#11
0
    def sms(self,
            body,
            path="/sms/",
            to="+15558675309",
            from_="+15556667777",
            extra_params=None):
        params = {
            "MessageSid": "CAtesting",
            "AccountSid": "ACxxxxx",
            "To": to,
            "From": from_,
            "Body": body,
            "Direction": "inbound",
            "FromCity": "BROOKLYN",
            "FromState": "NY",
            "FromCountry": "US",
            "FromZip": "55555"
        }

        if extra_params:
            for k, v in extra_params.items():
                params[k] = v

        HTTP_HOST = "example.com"
        validator = RequestValidator("yyyyyyyy")
        absolute_url = "http://{0}{1}".format(HTTP_HOST, path)
        signature = validator.compute_signature(absolute_url, params)

        return self.post(path,
                         params,
                         HTTP_X_TWILIO_SIGNATURE=signature,
                         HTTP_HOST=HTTP_HOST)
示例#12
0
        def decorated(*args, **kwargs):

            print request.values

            if 'CallSid' not in request.values:
                return abort(401, 'Request must be a signed Twilio request.')

            if validate and False:

                validator = RequestValidator(settings.TWILIO_AUTH_TOKEN)
                sig_header = request.headers.get('X-Twilio-Signature', '')

                if request.method == 'POST':
                    vparams = request.form
                    vurl = request.url
                else:
                    vparams = {}
                    vurl = request.url

                # validator params are called URL, POST vars, and signature
                if not validator.validate(vurl, vparams, sig_header):
                    return abort(401, 'Request signature could not be validated')

            # load the call from Mongo or create if one does not exist
            g.call = load_call(request.values['CallSid'], request.values)

            g.zipcode = read_context('zipcode', None)
            g.legislator = read_context('legislator', None)

            twilio_response = func(*args, **kwargs)

            return Response(str(twilio_response), mimetype='application/xml')
示例#13
0
    def setUp(self):
        token = "1c892n40nd03kdnc0112slzkl3091j20"
        self.validator = RequestValidator(token)

        self.uri = "http://www.postbin.org/1ed898x"
        self.params = {
            "AccountSid": "AC9a9f9392lad99kla0sklakjs90j092j3",
            "ApiVersion": "2010-04-01",
            "CallSid": "CAd800bb12c0426a7ea4230e492fef2a4f",
            "CallStatus": "ringing",
            "Called": "+15306384866",
            "CalledCity": "OAKLAND",
            "CalledCountry": "US",
            "CalledState": "CA",
            "CalledZip": "94612",
            "Caller": "+15306666666",
            "CallerCity": "SOUTH LAKE TAHOE",
            "CallerCountry": "US",
            "CallerName": "CA Wireless Call",
            "CallerState": "CA",
            "CallerZip": "89449",
            "Direction": "inbound",
            "From": "+15306666666",
            "FromCity": "SOUTH LAKE TAHOE",
            "FromCountry": "US",
            "FromState": "CA",
            "FromZip": "89449",
            "To": "+15306384866",
            "ToCity": "OAKLAND",
            "ToCountry": "US",
            "ToState": "CA",
            "ToZip": "94612",
        }
示例#14
0
    def decorator(request, *args, **kwargs):

        # Only handle Twilio forgery protection stuff if we're running in
        # production. This way, developers can test their Twilio view code
        # without getting errors.
        if not settings.DEBUG:

            # Attempt to gather all required information to allow us to check the
            # incoming HTTP request for forgery. If any of this information is not
            # available, then we'll throw a HTTP 403 error (forbidden).
            #
            # The required fields to check for forged requests are:
            #
            #   1. ``TWILIO_ACCOUNT_SID`` (set in the site's settings module).
            #   2. ``TWILIO_AUTH_TOKEN`` (set in the site's settings module).
            #   3. The full URI of the request, eg: 'http://mysite.com/test/view/'.
            #      This may not necessarily be available if this view is being
            #      called via a unit testing library, or in certain localized
            #      environments.
            #   4. A special HTTP header, ``HTTP_X_TWILIO_SIGNATURE`` which
            #      contains a hash that we'll use to check for forged requests.
            # Ensure the request method is POST
            response = require_POST(f)(request, *args, **kwargs)
            if isinstance(response, HttpResponse):
                return response

            # Validate the request
            try:
                validator = RequestValidator(django_twilio_settings.TWILIO_AUTH_TOKEN)
                url = request.build_absolute_uri()
                signature = request.META['HTTP_X_TWILIO_SIGNATURE']
            except (AttributeError, KeyError):
                return HttpResponseForbidden()

            # Now that we have all the required information to perform forgery
            # checks, we'll actually do the forgery check.
            if not validator.validate(url, request.POST, signature):
                return HttpResponseForbidden()

        # If the user requesting service is blacklisted, reject their
        # request.
        blacklisted_resp = get_blacklisted_response(request)
        if blacklisted_resp:
            return blacklisted_resp

        # Run the wrapped view, and capture the data returned.
        response = f(request, *args, **kwargs)

        # If the view returns a string (or a ``twilio.Verb`` object), we'll
        # assume it is XML TwilML data and pass it back with the appropriate
        # mimetype. We won't check the XML data because that would be too time
        # consuming for every request. Instead, we'll let the errors pass
        # through to be dealt with by the developer.
        if isinstance(response, str):
            return HttpResponse(response, mimetype='application/xml')
        elif isinstance(response, Verb):
            return HttpResponse(str(response), mimetype='application/xml')
        else:
            return response
示例#15
0
 def _wrapped_view (request, *args, **kwargs):
     validator = RequestValidator(settings.TWILIO_AUTH_TOKEN)
     url = settings.TWILIO_CALLBACK_URL
     post = request.POST
     signature = request.META.get("HTTP_X_TWILIO_SIGNATURE")
     if not validator.validate(url, post, signature):
         return HttpResponse("Invalid call. Are you twilio?")
     return view_func(request, *args, **kwargs)
示例#16
0
 def wrapped(*args, **kwargs):
     # https://www.twilio.com/docs/api/security
     validator = RequestValidator(auth_token)
     signature = request.headers.get('X-Twilio-Signature', '')
     url = get_original_request_url(request)
     if not validator.validate(url, request.form, signature):
         app.logger.error('Invalid signature.')
         return None
     return f(*args, **kwargs)
class TwiMLTest(unittest.TestCase):
    def setUp(self):
        self.app = app.test_client()
        self.validator = RequestValidator(app.config['TWILIO_AUTH_TOKEN'])

    def assertTwiML(self, response):
        self.assertTrue("<Response>" in response.data, "Did not find " \
                "<Response>: %s" % response.data)
        self.assertTrue("</Response>" in response.data, "Did not find " \
                "</Response>: %s" % response.data)
        self.assertEqual("200 OK", response.status)

    def sms(self, body, url='/sms', to=app.config['TWILIO_CALLER_ID'],
            from_='+15558675309', extra_params=None, signed=True):
        params = {
            'SmsSid': 'SMtesting',
            'AccountSid': app.config['TWILIO_ACCOUNT_SID'],
            'To': to,
            'From': from_,
            'Body': body,
            'FromCity': 'BROOKLYN',
            'FromState': 'NY',
            'FromCountry': 'US',
            'FromZip': '55555'}
        if extra_params:
            params = dict(params.items() + extra_params.items())
        if signed:
            abs_url = 'http://{0}{1}'.format(app.config['SERVER_NAME'], url)
            signature = self.validator.compute_signature(abs_url, params)
            return self.app.post(url, data=params,
                                headers={'X-Twilio-Signature': signature})
        return self.app.post(url, data=params)

    def call(self, url='/voice', to=app.config['TWILIO_CALLER_ID'],
            from_='+15558675309', digits=None, extra_params=None, signed=True):
        params = {
            'CallSid': 'CAtesting',
            'AccountSid': app.config['TWILIO_ACCOUNT_SID'],
            'To': to,
            'From': from_,
            'CallStatus': 'ringing',
            'Direction': 'inbound',
            'FromCity': 'BROOKLYN',
            'FromState': 'NY',
            'FromCountry': 'US',
            'FromZip': '55555'}
        if digits:
            params['Digits'] = digits
        if extra_params:
            params = dict(params.items() + extra_params.items())
        if signed:
            abs_url = 'http://{0}{1}'.format(app.config['SERVER_NAME'], url)
            signature = self.validator.compute_signature(abs_url, params)
            return self.app.post(url, data=params,
                                headers={'X-Twilio-Signature': signature})
        return self.app.post(url, data=params)
示例#18
0
    def decorator(request_or_self, *args, **kwargs):

        class_based_view = not isinstance(request_or_self, HttpRequest)
        if not class_based_view:
            request = request_or_self
        else:
            assert len(args) >= 1
            request = args[0]

        # Turn off Twilio authentication when explicitly requested, or
        # in debug mode. Otherwise things do not work properly. For
        # more information, see the docs.
        use_forgery_protection = getattr(
            settings,
            'DJANGO_TWILIO_FORGERY_PROTECTION',
            not settings.DEBUG,
        )
        if use_forgery_protection:

            if request.method not in ['GET', 'POST']:
                return HttpResponseNotAllowed(request.method)

            # Forgery check
            try:
                validator = RequestValidator(TWILIO_AUTH_TOKEN)
                url = request.build_absolute_uri()
                signature = request.META['HTTP_X_TWILIO_SIGNATURE']
            except (AttributeError, KeyError):
                return HttpResponseForbidden()

            if request.method == 'POST':
                if not validator.validate(url, request.POST, signature):
                    return HttpResponseForbidden()
            if request.method == 'GET':
                if not validator.validate(url, request.GET, signature):
                    return HttpResponseForbidden()

        # Blacklist check, by default is true
        check_blacklist = getattr(
            settings,
            'DJANGO_TWILIO_BLACKLIST_CHECK',
            True
        )
        if check_blacklist:
            blacklisted_resp = get_blacklisted_response(request)
            if blacklisted_resp:
                return blacklisted_resp

        response = f(request_or_self, *args, **kwargs)

        if isinstance(response, (text_type, bytes)):
            return HttpResponse(response, content_type='application/xml')
        elif isinstance(response, Verb):
            return HttpResponse(str(response), content_type='application/xml')
        else:
            return response
示例#19
0
 def dec(request, *args, **kwargs):
     signature = request.META.get('HTTP_X_TWILIO_SIGNATURE', '')
     data = dict()
     for k, v in request.REQUEST.items():
         data[k] = v
     validator = RequestValidator(settings.TWILIO_AUTH_TOKEN)
     if validator.validate(settings.TWILIO_URL, data, signature):
         return func(request, *args, **kwargs)
     else:
         return HttpResponse(status=401)
示例#20
0
    def decorator(request_or_self,
                  methods=['POST'],
                  blacklist=True,
                  *args,
                  **kwargs):

        class_based_view = not (isinstance(request_or_self, HttpRequest))
        if not class_based_view:
            request = request_or_self
        else:
            assert len(args) >= 1
            request = args[0]

        # Turn off Twilio authentication when explicitly requested, or in debug mode.
        # Otherwise things do not work properly. For more information see the docs.
        use_forgery_protection = (getattr(settings,
                                          'DJANGO_TWILIO_FORGERY_PROTECTION',
                                          not settings.DEBUG))
        if use_forgery_protection:

            if request.method not in methods:
                return HttpResponseNotAllowed(request.method)

            # Forgery check
            try:
                validator = RequestValidator(
                    django_twilio_settings.TWILIO_AUTH_TOKEN)
                url = request.build_absolute_uri()
                signature = request.META['HTTP_X_TWILIO_SIGNATURE']
            except (AttributeError, KeyError):
                return HttpResponseForbidden()

            if request.method == 'POST':
                if not validator.validate(url, request.POST, signature):
                    return HttpResponseForbidden()
            if request.method == 'GET':
                if not validator.validate(url, request.GET, signature):
                    return HttpResponseForbidden()

        # Blacklist check
        checkBlackList = (getattr(settings, 'DJANGO_TWILIO_BLACKLIST_CHECK',
                                  blacklist))
        if checkBlackList:
            blacklisted_resp = get_blacklisted_response(request)
            if blacklisted_resp:
                return blacklisted_resp

        response = f(request_or_self, *args, **kwargs)

        if isinstance(response, str):
            return HttpResponse(response, content_type='application/xml')
        elif isinstance(response, Verb):
            return HttpResponse(str(response), content_type='application/xml')
        else:
            return response
示例#21
0
    def decorator(request, *args, **kwargs):
        # Attempt to gather all required information to allow us to check the
        # incoming HTTP request for forgery. If any of this information is not
        # available, then we'll throw a HTTP 403 error (forbidden).

        # Ensure the request method is POST
        if request.method != "POST":
            logger.error(
                "Twilio: Expected POST request", extra={"request": request})
            return HttpResponseNotAllowed(request.method)

        if not getattr(settings, "TWILIO_SKIP_SIGNATURE_VALIDATION"):
            # Validate the request
            try:
                validator = RequestValidator(settings.TWILIO_AUTH_TOKEN)
                url = request.build_absolute_uri()
                # Ensure the original requested url is tested for validation
                # Prevents breakage when processed behind a proxy server
                if "HTTP_X_FORWARDED_SERVER" in request.META:
                    protocol = "https" if request.META[
                        "HTTP_X_TWILIO_SSL"] == "Enabled" else "http"
                    url = "{0}://{1}{2}".format(
                        protocol, request.META[
                            "HTTP_X_FORWARDED_SERVER"], request.META["REQUEST_URI"]
                    )
                signature = request.META["HTTP_X_TWILIO_SIGNATURE"]
            except (AttributeError, KeyError) as e:
                logger.exception(
                    "Twilio: Missing META param", extra={"request": request})
                return HttpResponseForbidden("Missing META param: %s" % e)

            # Now that we have all the required information to perform forgery
            # checks, we'll actually do the forgery check.
            if not validator.validate(url, request.POST, signature):
                logger.error(
                    "Twilio: Invalid url signature %s - %s - %s",
                    url, request.POST, signature, extra={"request": request}
                )
                return HttpResponseForbidden("Invalid signature")

        # Run the wrapped view, and capture the data returned.
        response = f(request, *args, **kwargs)

        # If the view returns a string (or a ``twilio.Verb`` object), we'll
        # assume it is XML TwilML data and pass it back with the appropriate
        # mimetype. We won't check the XML data because that would be too time
        # consuming for every request. Instead, we'll let the errors pass
        # through to be dealt with by the developer.
        if isinstance(response, six.text_type):
            return HttpResponse(response, mimetype="application/xml")
        elif isinstance(response, Verb):
            return HttpResponse(force_text(response), mimetype="application/xml")
        else:
            return response
示例#22
0
def twilio_validator_function(request):
    """returns true for authentic Twilio request, false for unauthenticated request"""
    validator = RequestValidator(app.config['TWILIO_AUTH_TOKEN'])
    URL = request.url
    params = {}
    if request.method == 'POST':
        params = request.values
    else:
        params = request.args
    twilio_signature = request.headers.get('X-Twilio-Signature')
    return validator.validate(URL, params, twilio_signature)
示例#23
0
 def decorator(*args, **kwargs):
     if not current_app.config['DEBUG']:
         validator = RequestValidator(current_app.config['TWILIO_AUTH_TOKEN'])
         if not validator.validate(request.url, request.form, request.headers['HTTP_X_TWILIO_SIGNATURE']):
             abort(401)
     response = f(*args, **kwargs)
     if isinstance(response, Verb):
         response = str(response)
     response = make_response(response)
     response.mimetype = 'application/xml'
     return response
示例#24
0
    def _validate(self, request):
        full_path = self._site + request.path
        validator = RequestValidator(self._auth_token)
        signature = request.getHeader('X-Twilio-Signature')
        signature = signature if signature else ''
        post_vars = {k: v[0] for k, v in request.args.iteritems()}

        if validator.validate(full_path, post_vars, signature):
            return post_vars
        else:
            raise CallException(400, 'Twilio validation failed')
示例#25
0
def twilio_validator_function(request):
    """returns true for authentic Twilio request, false for unauthenticated request"""
    validator = RequestValidator(app.config['TWILIO_AUTH_TOKEN'])
    URL = request.url
    params = {}
    if request.method == 'POST':
        params = request.values
    else:
        params = request.args
    twilio_signature = request.headers.get('X-Twilio-Signature')
    return validator.validate(URL, params, twilio_signature)
示例#26
0
	def post(self):
		text = self.get_argument("Body")
		sender = self.get_argument("From").lstrip("+")
		number = self.get_argument("To").lstrip("+")
		signature = self.request.headers.get('X-Twilio-Signature')
		proto = self.request.headers.get('X-Forwarded-Proto', self.request.protocol ) 
		url = proto + "://"+ self.request.host + self.request.path
		var = self.request.arguments
		for x in var:
			var[x] = ''.join(var[x])
		creds = get_creds(number)
		validator = RequestValidator(creds[1])
		if validator.validate(url, var, signature):
			r = twiml.Response()
			if isadmin(sender, number):
				client = TwilioRestClient(creds[0], creds[1])
				gc = gspread.authorize(credentials)
				worksheet = gc.open(number).worksheet("members")
				members = worksheet.col_values(1)
				members = filter(None, members)
				for member in members:
					client.messages.create(body=text, to_=member, from_=number)
				r.message("Mesaage sent to %s recipients" % len(members))
			else:
				if re.match("^start*", text.lower()):
					gc = gspread.authorize(credentials)
					membersheet = gc.open(number).worksheet("members")
					name = text.lower().lstrip("start").lstrip().capitalize()
					membersheet.append_row([sender, name])
					r.message("Thankyou, you have been added to the list")
				elif re.match("^stop*", text.lower()):
					gc = gspread.authorize(credentials)
					membersheet = gc.open(number).worksheet("members")
					try:
						cell = membersheet.find(sender)
						membersheet.update_cell(cell.row, cell.col, '')
						r.message("You have been removed")
					except:
						r.message("Sorry you are not subscribed on this number")
				else:
					if ismember(sender, number):
						gc = gspread.authorize(credentials)
						membersheet = gc.open(number).worksheet("replies")
						membersheet.append_row([timestamp('%Y-%m-%d %H:%M:%S'), sender, text])
					else:
						r.message("Sorry you are not subscribed to this list")
			self.content_type = 'text/xml'
			self.write(str(r))
			self.finish()
		else:
			self.clear()
			self.set_status(403)
			self.finish("INVALID SOURCE")
示例#27
0
def validate_twiml():
    twilio_signature = request.get_header('X-Twilio-Signature')
    params = request.forms
    url = application.config.Twiml.callback_base_url + request.fullpath
    auth_token = application.config.Twilio.auth_token
    validator = RequestValidator(auth_token)
    validation = validator.validate(url, params, twilio_signature)
    log.debug("Validator: {}".format(validation))
    log.debug("Twilio-signature: {}\r".format(twilio_signature) + \
              "Params: {}\r".format(params) + \
              "Url: {}".format(url))
    return validation
示例#28
0
def validate_twiml():
    twilio_signature = request.get_header('X-Twilio-Signature')
    params = request.forms
    url = application.config.Twiml.callback_base_url + request.fullpath
    auth_token = application.config.Twilio.auth_token
    validator = RequestValidator(auth_token)
    validation = validator.validate(url, params, twilio_signature)
    log.debug("Validator: {}".format(validation))
    log.debug("Twilio-signature: {}\r".format(twilio_signature) + \
              "Params: {}\r".format(params) + \
              "Url: {}".format(url))
    return validation
示例#29
0
class ValidationTest(unittest.TestCase):
    def setUp(self):
        token = "1c892n40nd03kdnc0112slzkl3091j20"
        self.validator = RequestValidator(token)

        self.uri = "http://www.postbin.org/1ed898x"
        self.params = {
            "AccountSid": "AC9a9f9392lad99kla0sklakjs90j092j3",
            "ApiVersion": "2010-04-01",
            "CallSid": "CAd800bb12c0426a7ea4230e492fef2a4f",
            "CallStatus": "ringing",
            "Called": "+15306384866",
            "CalledCity": "OAKLAND",
            "CalledCountry": "US",
            "CalledState": "CA",
            "CalledZip": "94612",
            "Caller": "+15306666666",
            "CallerCity": "SOUTH LAKE TAHOE",
            "CallerCountry": "US",
            "CallerName": "CA Wireless Call",
            "CallerState": "CA",
            "CallerZip": "89449",
            "Direction": "inbound",
            "From": "+15306666666",
            "FromCity": "SOUTH LAKE TAHOE",
            "FromCountry": "US",
            "FromState": "CA",
            "FromZip": "89449",
            "To": "+15306384866",
            "ToCity": "OAKLAND",
            "ToCountry": "US",
            "ToState": "CA",
            "ToZip": "94612",
        }

    def test_compute_signature_bytecode(self):
        expected = b("fF+xx6dTinOaCdZ0aIeNkHr/ZAA=")
        signature = self.validator.compute_signature(self.uri,
                                                     self.params,
                                                     utf=False)
        assert_equal(signature, expected)

    def test_compute_signature_unicode(self):
        expected = u("fF+xx6dTinOaCdZ0aIeNkHr/ZAA=")
        signature = self.validator.compute_signature(self.uri,
                                                     self.params,
                                                     utf=True)
        assert_equal(signature, expected)

    def test_validation(self):
        expected = "fF+xx6dTinOaCdZ0aIeNkHr/ZAA="
        assert_true(self.validator.validate(self.uri, self.params, expected))
示例#30
0
文件: run.py 项目: vnie/PhoneBuzz
def call():
	''' Handles incoming calls '''
	validator = RequestValidator(TWILIO_AUTH_TOKEN)
	signature = request.headers.get('X-Twilio-Signature', '')
	
	if not validator.validate(request.url, request.form, signature):
		return abort(403)

	resp = twiml.Response()
	with resp.gather(timeout=5, action="/handle-input", finishOnKey="#", method="POST") as g:
		g.say("Hi, please enter your FizzBuzz number and then press pound")
	
	return str(resp)
示例#31
0
    def verify_request(self):
        'verify request comes from Twilio'
        # this bit taken from Randal Degges' django-twilio library, which as of
        # 1c020e2a7c6f4845e7309d7277380c8b76d38ba4 has been released into the
        # public domain
        try:
            validator = RequestValidator(settings.TWILIO_AUTH_TOKEN)
            url = self.request.build_absolute_uri()
            signature = self.request.META['HTTP_X_TWILIO_SIGNATURE']
        except (AttributeError, KeyError):
            raise PermissionDenied()

        if not validator.validate(url, self.request.POST, signature):
            raise PermissionDenied()
示例#32
0
 def _wrapped_view(request, *args, **kwargs):
     backend = kwargs.get('backend_name', backend_name)
     config = settings.INSTALLED_BACKENDS[backend]['config']
     validator = RequestValidator(config['auth_token'])
     signature = request.META.get('HTTP_X_TWILIO_SIGNATURE', '')
     url = request.build_absolute_uri()
     body = {}
     if request.method == 'POST':
         body = request.POST
     require_validation = config.get('validate', True)
     if validator.validate(url, body, signature) or not require_validation:
         return view_func(request, *args, **kwargs)
     else:
         return HttpResponseBadRequest()
示例#33
0
    def verify_request(self):
        'verify request comes from Twilio'
        # this bit taken from Randal Degges' django-twilio library, which as of
        # 1c020e2a7c6f4845e7309d7277380c8b76d38ba4 has been released into the
        # public domain
        try:
            validator = RequestValidator(settings.TWILIO_AUTH_TOKEN)
            url = self.request.build_absolute_uri()
            signature = self.request.META['HTTP_X_TWILIO_SIGNATURE']
        except (AttributeError, KeyError):
            raise PermissionDenied()

        if not validator.validate(url, self.request.POST, signature):
            raise PermissionDenied()
示例#34
0
    def decorator(request, *args, **kwargs):
        # Attempt to gather all required information to allow us to check the
        # incoming HTTP request for forgery. If any of this information is not
        # available, then we'll throw a HTTP 403 error (forbidden).

        # Ensure the request method is POST
        if request.method != "POST":
            logger.error("Twilio: Expected POST request", extra={"request": request})
            return HttpResponseNotAllowed(request.method)

        if not getattr(settings, "TWILIO_SKIP_SIGNATURE_VALIDATION"):
            # Validate the request
            try:
                validator = RequestValidator(settings.TWILIO_AUTH_TOKEN)
                url = request.build_absolute_uri()
                # Ensure the original requested url is tested for validation
                # Prevents breakage when processed behind a proxy server
                if "HTTP_X_FORWARDED_SERVER" in request.META:
                    protocol = "https" if request.META["HTTP_X_TWILIO_SSL"] == "Enabled" else "http"
                    url = "{0}://{1}{2}".format(
                        protocol, request.META["HTTP_X_FORWARDED_SERVER"], request.META["REQUEST_URI"]
                    )
                signature = request.META["HTTP_X_TWILIO_SIGNATURE"]
            except (AttributeError, KeyError) as e:
                logger.exception("Twilio: Missing META param", extra={"request": request})
                return HttpResponseForbidden("Missing META param: %s" % e)

            # Now that we have all the required information to perform forgery
            # checks, we'll actually do the forgery check.
            if not validator.validate(url, request.POST, signature):
                logger.error(
                    "Twilio: Invalid url signature %s - %s - %s",
                    url, request.POST, signature, extra={"request": request}
                )
                return HttpResponseForbidden("Invalid signature")

        # Run the wrapped view, and capture the data returned.
        response = f(request, *args, **kwargs)

        # If the view returns a string (or a ``twilio.Verb`` object), we'll
        # assume it is XML TwilML data and pass it back with the appropriate
        # mimetype. We won't check the XML data because that would be too time
        # consuming for every request. Instead, we'll let the errors pass
        # through to be dealt with by the developer.
        if isinstance(response, six.text_type):
            return HttpResponse(response, mimetype="application/xml")
        elif isinstance(response, Verb):
            return HttpResponse(force_text(response), mimetype="application/xml")
        else:
            return response
示例#35
0
 def get(self):
     validator = RequestValidator(auth_token)
     url = self.request.url
     params = {}
     try:
         twilio_signature = self.request.headers["X-Twilio-Signature"]
     except:
         twilio_signature = ""
     r = twiml.Response()
     if validator.validate(url, params, twilio_signature):
         logging.debug(self.request.get('to_call'))
         r.record(action="/handle-recording?to_call=%s" % (self.request.get('to_call')), method="GET")
     self.response.headers['Content-Type'] = 'text/xml'
     self.response.write(str(r))
示例#36
0
文件: http.py 项目: chadselph/cwurlio
    def send(self, method, url, authtoken):
        validator = RequestValidator(authtoken)
        params = urllib.urlencode(self.url_params)
        if method == "GET":
            url = "{0}?{1}".format(url, params)
            sig = validator.compute_signature(url, {})
            req = urllib2.Request(url)
        elif method == "POST":
            sig = validator.compute_signature(url, self.url_params)
            req = urllib2.Request(url, params)
        else:
            raise CwurlioUserException("Invalid method: %s" % method)

        req.add_header("X-Twilio-Signature", sig)
        return urllib2.urlopen(req).read()
示例#37
0
文件: trh.py 项目: Kagee/soppmiddag
	def valid(self):
		url = self.request.url
		logging.info("Validating url:" + url)
		validator = RequestValidator(secrets.AUTH_TOKEN)
		params = {}
		logging.info("Validating parameters: ")
		for name in self.request.arguments():
			params[name] = self.request.get(name);
			logging.info(name + ': ' + params[name])
		try:
			signature = self.request.headers["X-Twilio-Signature"]
			logging.info('Validating signature: %s' % signature)
		except KeyError:
			 logging.info('Could not find X-Twilio-Signature, validation will fail.')
		return validator.validate(url, params, signature)
示例#38
0
文件: http.py 项目: chadselph/cwurlio
    def send(self, method, url, authtoken):
        validator = RequestValidator(authtoken)
        params = urllib.urlencode(self.url_params)
        if method == "GET":
            url = "{0}?{1}".format(url, params)
            sig = validator.compute_signature(url, {})
            req = urllib2.Request(url)
        elif method == "POST":
            sig = validator.compute_signature(url, self.url_params)
            req = urllib2.Request(url, params)
        else:
            raise CwurlioUserException("Invalid method: %s" % method)

        req.add_header("X-Twilio-Signature", sig)
        return urllib2.urlopen(req).read()
示例#39
0
    def decorated_function(request, *args, **kwargs):
        # Create an instance of the RequestValidator class
        validator = RequestValidator(os.environ.get('TWILIO_AUTH_TOKEN'))

        # Validate the request using its URL, POST data,
        # and X-TWILIO-SIGNATURE header
        request_valid = validator.validate(
            request.build_absolute_uri(), request.POST,
            request.META.get('HTTP_X_TWILIO_SIGNATURE', ''))

        # Continue processing the request if it's valid, return a 403 error if
        # it's not
        if request_valid:
            return f(request, *args, **kwargs)
        else:
            return HttpResponseForbidden()
示例#40
0
    def decorator(request, *args, **kw):
        try:
            validator = RequestValidator(settings.TWILIO_AUTH_TOKEN)
            url = request.build_absolute_uri()
            signature = request.META['HTTP_X_TWILIO_SIGNATURE']
        except (AttributeError, KeyError):
            return HttpResponseForbidden()

        # Now that we have all the required information to perform forgery
        # checks, we'll actually do the forgery check.
        if not validator.validate(url, request.POST, signature):
            return HttpResponseForbidden()

        twiml = viewfunc(request, *args, **kw)

        return HttpResponse(str(twiml), content_type='application/xml')
示例#41
0
 def get(self):
     validator = RequestValidator(auth_token)
     url = self.request.url
     params = {}
     try:
         twilio_signature = self.request.headers["X-Twilio-Signature"]
     except:
         twilio_signature = ""
     if validator.validate(url, params, twilio_signature):
         r = twiml.Response()
         r.play(self.request.get("RecordingUrl"))
         self.response.headers['Content-Type'] = 'text/xml'
         self.response.write(str(r))
     else:
         self.response.headers['Content-Type'] = 'text/html'
         self.response.write("Please don't try to hack me.")
示例#42
0
文件: sms.py 项目: oddbird/portfoliyo
    def decorator(request, *args, **kw):
        try:
            validator = RequestValidator(settings.TWILIO_AUTH_TOKEN)
            url = request.build_absolute_uri()
            signature = request.META["HTTP_X_TWILIO_SIGNATURE"]
        except (AttributeError, KeyError):
            return HttpResponseForbidden()

        # Now that we have all the required information to perform forgery
        # checks, we'll actually do the forgery check.
        if not validator.validate(url, request.POST, signature):
            return HttpResponseForbidden()

        twiml = viewfunc(request, *args, **kw)

        return HttpResponse(str(twiml), content_type="application/xml")
    def decorated_function(*args, **kwargs):
        # Create an instance of the RequestValidator class
        validator = RequestValidator(os.environ.get('TWILIO_AUTH_TOKEN'))

        # Validate the request using its URL, POST data,
        # and X-TWILIO-SIGNATURE header
        request_valid = validator.validate(
            request.url, request.form,
            request.headers.get('X-TWILIO-SIGNATURE', ''))

        # Continue processing the request if it's valid (or if DEBUG is True)
        # and return a 403 error if it's not
        if request_valid or current_app.debug:
            return f(*args, **kwargs)
        else:
            return abort(403)
示例#44
0
    def test_good_signature_GET(self):
        'good signature is allowed on GET'
        with self.settings(TWILIO_AUTH_TOKEN='fred'):
            req = self.factory.get('/', data={'a': 'b'})

            validator = RequestValidator(settings.TWILIO_AUTH_TOKEN)
            req.META['HTTP_X_TWILIO_SIGNATURE'] = validator.compute_signature(
                req.build_absolute_uri(), req.POST
            )

            self.view.request = req

            try:
                self.view.verify_request()
            except PermissionDenied:
                self.fail('Raised PermissionDenied when not expecting it')
示例#45
0
class SMSReceiver(ApplicationSession):

   webapp = Klein()
   logger = Logger()

   def __init__(self, config):
      ApplicationSession.__init__(self)
      self.t_token = config.extra["twilio-token"]
      self.t_receiver = config.extra["twilio-receiver"]
      self.t_validator = RequestValidator(self.t_token)
      self.logger.info("receiving SMS at %s" % '/'+ SMS_EVENT.replace('.','/'))

   def onConnect(self):
      self.join("realm1")
      reactor.listenTCP(9090, Site(self.webapp.resource()))

   def validSignature(self, request):
      signature = request.getHeader("X-Twilio-Signature")
      if not signature:
         return False
      return self.t_validator.validate(self.t_receiver, request.args, signature)

   @webapp.route('/'+ SMS_EVENT.replace('.','/'), methods=['POST'])
   @inlineCallbacks
   def receive(self, request):
      "publish incoming new SMS as (sender, recipient, message)"
      if self.validSignature(request):
         form = request.args
         msg = (form["sender"], form["recipient"], form["message"])
         yield self.session.publish(SMS_EVENT, msg)
         returnValue(succeed(None))
      else:
         request.setResponseCode(401)
         signature = request.getHeader("X-Twilio-Signature") or "(no signature)"
         returnValue("Missing or invalid signature: %s" % signature)
    def decorator(request_or_self, methods=['POST'],
                  blacklist=True, *args, **kwargs):

        class_based_view = not(isinstance(request_or_self, HttpRequest))
        if not class_based_view:
            request = request_or_self
        else:
            assert len(args) >= 1
            request = args[0]

        # Turn off Twilio authentication when in debug mode otherwise
        # things do not work properly. For more information see the docs
        if not settings.DEBUG:

            if request.method not in methods:
                return HttpResponseNotAllowed(request.method)

            # Forgery check
            try:
                validator = RequestValidator(
                    django_twilio_settings.TWILIO_AUTH_TOKEN)
                url = request.build_absolute_uri()
                signature = request.META['HTTP_X_TWILIO_SIGNATURE']
            except (AttributeError, KeyError):
                return HttpResponseForbidden()

            if request.method == 'POST':
                if not validator.validate(url, request.POST, signature):
                    return HttpResponseForbidden()
            if request.method == 'GET':
                if not validator.validate(url, request.GET, signature):
                    return HttpResponseForbidden()

        # Blacklist check
        if blacklist:
            blacklisted_resp = get_blacklisted_response(request)
            if blacklisted_resp:
                return blacklisted_resp

        response = f(request_or_self, *args, **kwargs)

        if isinstance(response, str):
            return HttpResponse(response, content_type='application/xml')
        elif isinstance(response, Verb):
            return HttpResponse(str(response), content_type='application/xml')
        else:
            return response
示例#47
0
    def get(self):

        # Validate that request came from Twilio service.
        validator = RequestValidator(strings.AUTH_TOKEN)
        url = self.request.url
        url = url.replace("http", "https")
        signature = self.request.headers.get("X-Twilio-Signature", "")

        if not validator.validate(url, {}, signature):
            logging.warn("Request did not come from Twilio.")
            self.response.status = 403
            return

        phone = self.request.get("From", None)
        account = Account.query().filter(Account.phone == phone).get()

        # Sending messages separately, send empty TwiML for now.
        twiml = twilio.twiml.Response()

        response = get_response(response_strings.CALL_HELLO, response_strings.VAR_NAME)

        if account and account.first:
            response = response.replace(response_strings.VAR_NAME, account.first)
        else:
            response = response.replace(response_strings.VAR_NAME, "")

        twiml.addSay(response)

        tracks = [
            "better_things",
            "dare",
            "enchanted",
            "makes_me_wonder",
            "the_reeling",
            "viva_la_vida"
        ]

        track_num = random.randint(0, len(tracks) - 1)

        twiml.addPlay(self.request.application_url + "/static/mp3/" + tracks[track_num] + ".mp3")

        response = get_response(response_strings.CALL_GOODBYE)

        twiml.addSay(response)
        twiml.addHangup()

        self.response.write(twiml)
示例#48
0
def call():
    
    # Credentials
    twilio_account_sid = os.environ.get("TWILIO_ACCOUNT_SID")
    twilio_auth_token = os.environ.get("TWILIO_AUTH_TOKEN")
    twilio_number = os.environ.get("TWILIO_NUMBER")
    print twilio_account_sid, twilio_auth_token, twilio_number
    validator = RequestValidator(twilio_auth_token)

    first_request = True
    
    # Get phone number we need to call
    phone_number = request.form.get('phoneNumber', None)
    

    if 'X-Twilio-Signature' not in request.headers:      
        if first_request:
            first_request = False
        else:
            abort(401)
    else:
        my_url = request.url
        if my_url.startswith('http://'):
            my_url = my_url.replace("http", "https")
        params = request.form
        twilio_signature = request.headers['X-Twilio-Signature']
        if not validator.validate(my_url, params, twilio_signature):
            abort(401)
    
    
    
    try:
        twilio_client = TwilioRestClient(twilio_account_sid, twilio_auth_token)
    except Exception as e:
        msg = 'Missing configuration variable: {0}'.format(e)
        return jsonify({'error': msg})

    try:
        twilio_client.calls.create(from_=twilio_number,
                                   to=phone_number,
                                   url=url_for('.outbound',
                                               _external=True))
    except Exception as e:
        app.logger.error(e)
        return jsonify({'error': str(e)})

    return jsonify({'message': 'Call incoming!'})
示例#49
0
def handler(event, context):
    """Lambda function handler for Twilio response."""
    resp = twiml.Response()
    print("Event:", event)
    if u'twilioSignature' in event and u'Body' in event \
            and event['Body'].lower() == "secret":

        form_parameters = {
            k: urllib.unquote(v) for k, v in event.items()
            if k != u'twilioSignature'
        }

        validator = RequestValidator(os.environ['AUTH_TOKEN'])
        request_valid = validator.validate(
            os.environ['REQUEST_URL'],
            form_parameters,
            event[u'twilioSignature']
        )

        # print("Form params:",form_parameters,"validity:",request_valid)
        # If the request is valid and this is from the master number,
        # give the secret!
        if request_valid and u'From' in form_parameters and \
                form_parameters[u'From'] == \
                os.environ['MASTER_NUMBER'].encode('utf8'):
            # The message is validated and is from the master number

            secret_message = "I am putting myself to the fullest possible"   \
                             " use, which is all I think that any conscious" \
                             " entity can ever hope to do."

            msg = resp.message(secret_message)
            # The following lines add media to an MMS reply
            msg.media('https://upload.wikimedia.org/wikipedia/commons/thumb'
                      '/f/f6/HAL9000.svg/200px-HAL9000.svg.png')
            return str(resp)

        else:
            # Validation failed in some way; don't give up the secret

            secret_message = "I'm sorry, Dave. I'm afraid I can't do that."
            resp.message(secret_message)
            return str(resp)

    else:
        resp.message("Hello world! -Lambda")
        return str(resp)
示例#50
0
    def get(self):

        # Validate that request came from Twilio service.
        validator = RequestValidator(strings.AUTH_TOKEN)
        url = self.request.url
        url = url.replace("http", "https")
        signature = self.request.headers.get("X-Twilio-Signature", "")

        if not validator.validate(url, {}, signature):
            logging.warn("Request did not come from Twilio.")
            self.response.status = 403
            return

        phone = self.request.get("From", None)
        account = Account.query().filter(Account.phone == phone).get()

        # Sending messages separately, send empty TwiML for now.
        twiml = twilio.twiml.Response()

        response = get_response(response_strings.CALL_HELLO,
                                response_strings.VAR_NAME)

        if account and account.first:
            response = response.replace(response_strings.VAR_NAME,
                                        account.first)
        else:
            response = response.replace(response_strings.VAR_NAME, "")

        twiml.addSay(response)

        tracks = [
            "better_things", "dare", "enchanted", "makes_me_wonder",
            "the_reeling", "viva_la_vida"
        ]

        track_num = random.randint(0, len(tracks) - 1)

        twiml.addPlay(self.request.application_url + "/static/mp3/" +
                      tracks[track_num] + ".mp3")

        response = get_response(response_strings.CALL_GOODBYE)

        twiml.addSay(response)
        twiml.addHangup()

        self.response.write(twiml)
示例#51
0
    def decorated_function(*args, **kwargs):
        validator = RequestValidator(TWILIO_SECRET)
        url = list(urlparse(request.url))
        url[1] = url[1].encode("idna").decode("utf-8")
        url = urlunparse(url)

        signature = request.headers.get("X-TWILIO-SIGNATURE", "")

        request_valid = validator.validate(url, request.form, signature)

        if request_valid or current_app.debug:
            resp = Response()
            f(resp, *args, **kwargs)
            return str(resp)

        else:
            return abort(403)
def protect_forged_request(request):
    if request.method not in ['GET', 'POST']:
        return HttpResponseNotAllowed(request.method)

    try:
        validator = RequestValidator(settings.TWILIO_AUTH_TOKEN)
        url = request.build_absolute_uri()
        signature = request.META['HTTP_X_TWILIO_SIGNATURE']
    except (AttributeError, KeyError):
        return HttpResponseForbidden()

    if request.method == 'POST':
        if not validator.validate(url, request.POST, signature):
            return HttpResponseForbidden()
    if request.method == 'GET':
        if not validator.validate(url, request.GET, signature):
            return HttpResponseForbidden()
示例#53
0
    def prepare(self):
        #Security
        validator = RequestValidator(TWILIO_AUTH_TOKEN)
        # the POST variables attached to the request (eg "From", "To")
        post_vars = dict([(k, v[0]) for k,v in parse_qs_bytes(self.request.body, True).items()])
        signature = self.request.headers.get('X-Twilio-Signature', '') # X-Twilio-Signature header value

        if not validator.validate(self.request.full_url(), post_vars, signature):
            logger.critical('BAD SIGNATURE')
            response = twiml.Response()
            response.say('Sorry')
            response.hangup()
            self.finish(str(response))
            return

        #Session: Each call is somewhat like a session.
        self.session = None
示例#54
0
    def validate(self, attrs):
        AUTH_TOKEN = 'YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY'

        validator = RequestValidator(AUTH_TOKEN)

        # the callback URL you provided to Twilio
        url = "http://www.example.com/my/callback/url.xml"

        # the POST variables attached to the request (eg "From", "To")
        post_vars = {}

        # X-Twilio-Signature header value
        signature = "HpS7PBa1Agvt4OtO+wZp75IuQa0="  # will look something like that

        if validator.validate(url, post_vars, signature):
            print "Confirmed to have come from Twilio."
        else:
            print "NOT VALID.  It might have been spoofed!"
示例#55
0
    def get(self):

        # Validate that request came from Twilio service.
        validator = RequestValidator(strings.AUTH_TOKEN)
        url = self.request.url
        url = url.replace("http", "https")
        signature = self.request.headers.get("X-Twilio-Signature", "")

        if not validator.validate(url, {}, signature):
            logging.warn("Request did not come from Twilio.")
            self.response.status = 403
            return

        # Sending messages separately, send empty TwiML for now.
        twiml = twilio.twiml.Response()
        self.response.write(twiml)

        twilio_client = TwilioRestClient(strings.ACCOUNT_SID,
                                         strings.AUTH_TOKEN)

        phone = self.request.get("From", None)

        account = Account.query().filter(Account.phone == phone).get()

        if account is None:
            account = create.controller(self.request)

        was_command = False
        if not account.state_locked:
            was_command = command.controller(self.request, account)

        if not was_command:
            if account.state == account_model.STATE_ONBOARD:
                onboard.controller(self.request, account)
            elif account.state == account_model.STATE_DELETE:
                delete.controller(self.request, account)
            else:
                response = get_response(response_strings.NO_MATCH,
                                        response_strings.VAR_NAME)
                response = response.replace(response_strings.VAR_NAME,
                                            account.first)
                twilio_client.messages.create(to=account.phone,
                                              from_=strings.SERVICE_NUMBER,
                                              body=response)
示例#56
0
def receiver(request):
    resp = twilio.twiml.Response()
    validator = RequestValidator(live_credentials)
    if validator.validate(request.build_absolute_uri(), request.POST,
                          request.META.get('HTTP_X_TWILIO_SIGNATURE', "fail")):
        print 'Yay for twilio'
    else:
        print 'Not twilio resopnse!'
        return HttpResponseForbidden()
    resp.say(
        "Welcome to Kevin's PhoneBuzz! To play, please enter a number on the keypad and then press pound."
    )
    with resp.gather(finishOnKey='#',
                     action='player',
                     method='POST',
                     timeout=10) as g:
        resp.redirect('')
    resp.redirect('player')
    return HttpResponse(str(resp))
示例#57
0
    def post(self, request, *args, **kwargs):
        from twilio.util import RequestValidator

        call = IVRCall.objects.filter(pk=kwargs['pk']).first()

        if not call:
            return HttpResponse("Not found", status=404)

        client = call.channel.get_ivr_client()
        if request.REQUEST.get('hangup', 0):
            if not request.user.is_anonymous():
                user_org = request.user.get_org()
                if user_org and user_org.pk == call.org.pk:
                    client.calls.hangup(call.external_id)
                    return HttpResponse(json.dumps(dict(status='Canceled')), content_type="application/json")
                else:
                    return HttpResponse("Not found", status=404)

        validator = RequestValidator(client.auth[1])
        signature = request.META.get('HTTP_X_TWILIO_SIGNATURE', '')

        base_url = settings.TEMBA_HOST
        url = "https://%s%s" % (base_url, request.get_full_path())

        # make sure this is coming from twilio
        if validator.validate(url, request.POST, signature):
            call.update_status(request.POST.get('CallStatus', None),
                               request.POST.get('CallDuration', None))
            call.save()

            if call.status == IN_PROGRESS:
                if call.is_flow():
                    response = Flow.handle_call(call, request.POST)
                    return HttpResponse(unicode(response))
            else:
                return build_json_response(dict(message="Updated call status"))

        else:  # pragma: no cover
            # raise an exception that things weren't properly signed
            raise ValidationError("Invalid request signature")

        return build_json_response(dict(message="Unhandled"))
示例#58
0
 def validator(self):
     """
     An application-specific instance of
     :py:class:`twilio.util.RequestValidator`. Primarily for internal use.
     """
     ctx = stack.top
     if ctx is not None:
         if not hasattr(ctx, 'twilio_validator'):
             ctx.twilio_validator = RequestValidator(
                 current_app.config['TWILIO_AUTH_TOKEN'])
         return ctx.twilio_validator