Commit 7f451c88 by Will Daly

Merge pull request #8681 from edx/will/credit-provider-integration-fixups

Credit provider integration fixups
parents 0bc2c42e da982341
......@@ -89,7 +89,7 @@ def from_timestamp(timestamp):
If the timestamp cannot be converted, returns None instead.
"""
try:
return datetime.utcfromtimestamp(timestamp).replace(tzinfo=UTC)
return datetime.utcfromtimestamp(int(timestamp)).replace(tzinfo=UTC)
except (ValueError, TypeError):
return None
......
......@@ -190,6 +190,15 @@ class CreditProviderViewTests(UrlResetMixin, TestCase):
response = self._credit_provider_callback(request_uuid, "approved", timestamp=timestamp)
self.assertEqual(response.status_code, 403)
def test_credit_provider_callback_handles_string_timestamp(self):
request_uuid = self._create_credit_request_and_get_uuid(self.USERNAME, self.COURSE_KEY)
# Simulate a callback from the credit provider with a timestamp
# encoded as a string instead of an integer.
timestamp = str(to_timestamp(datetime.datetime.now(pytz.UTC)))
response = self._credit_provider_callback(request_uuid, "approved", timestamp=timestamp)
self.assertEqual(response.status_code, 200)
def test_credit_provider_callback_is_idempotent(self):
request_uuid = self._create_credit_request_and_get_uuid(self.USERNAME, self.COURSE_KEY)
......
......@@ -13,6 +13,7 @@ from django.http import (
Http404
)
from django.views.decorators.http import require_POST
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
from opaque_keys.edx.keys import CourseKey
......@@ -127,6 +128,7 @@ def create_credit_request(request, provider_id):
@require_POST
@csrf_exempt
def credit_provider_callback(request, provider_id):
"""
Callback end-point used by credit providers to approve or reject
......@@ -150,8 +152,9 @@ def credit_provider_callback(request, provider_id):
* status (string): Either "approved" or "rejected".
* timestamp (int): The datetime at which the POST request was made, represented
* timestamp (int or string): The datetime at which the POST request was made, represented
as the number of seconds since January 1, 1970 00:00:00 UTC.
If the timestamp is a string, it will be converted to an integer.
* signature (string): A digital signature of the request parameters,
created using a secret key shared with the credit provider.
......@@ -257,7 +260,8 @@ def _validate_timestamp(timestamp_value, provider_id):
Check that the timestamp of the request is recent.
Arguments:
timestamp (int): Number of seconds since Jan. 1, 1970 UTC.
timestamp (int or string): Number of seconds since Jan. 1, 1970 UTC.
If specified as a string, it will be converted to an integer.
provider_id (unicode): Identifier for the credit provider.
Returns:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment