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
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
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
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() # 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 = "%s://%s%s" % ( protocol, request.META['HTTP_X_FORWARDED_SERVER'], request.META['REQUEST_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