Merge pull request #8681 from edx/will/credit-provider-integration-fixups
Credit provider integration fixups
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user