Beispiel #1
0
def test_signed_payload(mocker, contract_number):
    """
    A valid payload should be signed appropriately
    """
    order = B2BOrderFactory.create(contract_number=contract_number)
    transaction_uuid = "hex"

    now = now_in_utc()
    now_mock = mocker.patch("b2b_ecommerce.api.now_in_utc",
                            autospec=True,
                            return_value=now)
    product_version = order.product_version
    product = product_version.product

    mocker.patch(
        "b2b_ecommerce.api.uuid.uuid4",
        autospec=True,
        return_value=mocker.MagicMock(hex=transaction_uuid),
    )
    receipt_url = "https://example.com/base_url/receipt/"
    cancel_url = "https://example.com/base_url/cancel/"
    payload = generate_b2b_cybersource_sa_payload(order=order,
                                                  receipt_url=receipt_url,
                                                  cancel_url=cancel_url)
    signature = payload.pop("signature")
    assert generate_cybersource_sa_signature(payload) == signature
    signed_field_names = payload["signed_field_names"].split(",")
    assert signed_field_names == sorted(payload.keys())

    total_price = order.total_price
    assert payload == {
        "access_key": CYBERSOURCE_ACCESS_KEY,
        "amount": str(total_price),
        "currency": "USD",
        "item_0_code": "enrollment_code",
        "item_0_name":
        f"Enrollment codes for {product_version.description}"[:254],
        "item_0_quantity": order.num_seats,
        "item_0_sku":
        f"enrollment_code-{str(product.content_type)}-{product.content_object.id}",
        "item_0_tax_amount": "0",
        "item_0_unit_price": str(total_price),
        "line_item_count": 1,
        "locale": "en-us",
        "reference_number": order.reference_number,
        "override_custom_receipt_page": receipt_url,
        "override_custom_cancel_page": cancel_url,
        "profile_id": CYBERSOURCE_PROFILE_ID,
        "signed_date_time": now.strftime(ISO_8601_FORMAT),
        "signed_field_names": ",".join(signed_field_names),
        "transaction_type": "sale",
        "transaction_uuid": transaction_uuid,
        "unsigned_field_names": "",
        "merchant_defined_data1": order.contract_number or "",
    }
    now_mock.assert_called_once_with()
Beispiel #2
0
def gen_fake_receipt_data(order=None):
    """
    Helper function to generate a fake signed piece of data
    """
    data = {}
    for _ in range(10):
        data[FAKE.text()] = FAKE.text()
    keys = sorted(data.keys())
    data["signed_field_names"] = ",".join(keys)
    data["unsigned_field_names"] = ""
    data["req_reference_number"] = order.reference_number if order else ""
    data["signature"] = generate_cybersource_sa_signature(data)
    return data
Beispiel #3
0
def gen_fake_receipt_data(order=None):
    """
    Helper function to generate a fake signed piece of data
    """
    data = {}
    for _ in range(10):
        data[FAKE.text()] = FAKE.text()
    keys = sorted(data.keys())
    data['signed_field_names'] = ",".join(keys)
    data['unsigned_field_names'] = ''
    data['req_reference_number'] = make_reference_id(order) if order else ''
    data['signature'] = generate_cybersource_sa_signature(data)
    return data
Beispiel #4
0
def test_has_signature(settings, mocker):
    """
    If the payload has a valid signature, it should pass the permissions test
    """
    settings.CYBERSOURCE_SECURITY_KEY = "fake"

    payload = {"a": "b", "c": "d", "e": "f"}
    keys = sorted(payload.keys())
    payload["signed_field_names"] = ",".join(keys)
    payload["signature"] = generate_cybersource_sa_signature(payload)

    request = mocker.MagicMock(data=payload)
    assert IsSignedByCyberSource().has_permission(request,
                                                  mocker.MagicMock()) is True
Beispiel #5
0
    def test_signed_payload(self):
        """
        A valid payload should be signed appropriately
        """
        course_run, user = create_purchasable_course_run()
        order = create_unfulfilled_order(course_run.edx_course_key, user)
        username = '******'
        transaction_uuid = 'hex'
        fake_user_ip = "194.100.0.1"

        now = now_in_utc()

        with patch('ecommerce.api.get_social_username', autospec=True, return_value=username):
            with patch('ecommerce.api.now_in_utc', autospec=True, return_value=now) as now_mock:
                with patch('ecommerce.api.uuid.uuid4', autospec=True, return_value=MagicMock(hex=transaction_uuid)):
                    payload = generate_cybersource_sa_payload(order, 'dashboard_url', fake_user_ip)
        signature = payload.pop('signature')
        assert generate_cybersource_sa_signature(payload) == signature
        signed_field_names = payload['signed_field_names'].split(',')
        assert signed_field_names == sorted(payload.keys())
        quoted_course_key = quote_plus(course_run.edx_course_key)

        assert payload == {
            'access_key': CYBERSOURCE_ACCESS_KEY,
            'amount': str(order.total_price_paid),
            'consumer_id': username,
            'currency': 'USD',
            'item_0_code': 'course',
            'item_0_name': '{}'.format(course_run.title),
            'item_0_quantity': 1,
            'item_0_sku': '{}'.format(course_run.edx_course_key),
            'item_0_tax_amount': '0',
            'item_0_unit_price': str(order.total_price_paid),
            'line_item_count': 1,
            'locale': 'en-us',
            'override_custom_cancel_page': 'dashboard_url?status=cancel&course_key={}'.format(quoted_course_key),
            'override_custom_receipt_page': "dashboard_url?status=receipt&course_key={}".format(quoted_course_key),
            'reference_number': make_reference_id(order),
            'profile_id': CYBERSOURCE_PROFILE_ID,
            'signed_date_time': now.strftime(ISO_8601_FORMAT),
            'signed_field_names': ','.join(signed_field_names),
            'transaction_type': 'sale',
            'transaction_uuid': transaction_uuid,
            'unsigned_field_names': '',
            'merchant_defined_data1': 'course',
            'merchant_defined_data2': '{}'.format(course_run.title),
            'merchant_defined_data3': '{}'.format(course_run.edx_course_key),
            "customer_ip_address": fake_user_ip if fake_user_ip else None,
        }
        assert now_mock.called
    def test_has_signature(self):
        """
        If the payload has a valid signature, it should pass the permissions test
        """
        payload = {
            'a': 'b',
            'c': 'd',
            'e': 'f',
        }
        keys = sorted(payload.keys())
        payload['signed_field_names'] = ','.join(keys)
        payload['signature'] = generate_cybersource_sa_signature(payload)

        request = MagicMock(data=payload)
        assert IsSignedByCyberSource().has_permission(request, MagicMock()) is True
Beispiel #7
0
 def has_permission(self, request, view):
     """
     Returns true if request params are signed by CyberSource
     """
     signature = generate_cybersource_sa_signature(request.data)
     if request.data['signature'] == signature:
         return True
     else:
         log.error(
             "Cybersource signature failed: we expected %s but we got %s. Payload: %s",
             signature,
             request.data['signature'],
             request.data,
         )
         return False
Beispiel #8
0
 def has_permission(self, request, view):
     """
     Returns true if request params are signed by CyberSource
     """
     signature = generate_cybersource_sa_signature(request.data)
     if request.data["signature"] == signature:
         return True
     else:
         log.error(
             "Cybersource signature failed: we expected %s but we got %s. Payload: %s",
             signature,
             request.data["signature"],
             request.data,
         )
         return False
Beispiel #9
0
    def test_signed_payload(self):
        """
        A valid payload should be signed appropriately
        """
        course_run, user = create_purchasable_course_run()
        order = create_unfulfilled_order(course_run.edx_course_key, user)
        username = '******'
        transaction_uuid = 'hex'

        now = now_in_utc()

        with patch('ecommerce.api.get_social_username', autospec=True, return_value=username):
            with patch('ecommerce.api.now_in_utc', autospec=True, return_value=now) as now_mock:
                with patch('ecommerce.api.uuid.uuid4', autospec=True, return_value=MagicMock(hex=transaction_uuid)):
                    payload = generate_cybersource_sa_payload(order, 'dashboard_url')
        signature = payload.pop('signature')
        assert generate_cybersource_sa_signature(payload) == signature
        signed_field_names = payload['signed_field_names'].split(',')
        assert signed_field_names == sorted(payload.keys())
        quoted_course_key = quote_plus(course_run.edx_course_key)

        assert payload == {
            'access_key': CYBERSOURCE_ACCESS_KEY,
            'amount': str(order.total_price_paid),
            'consumer_id': username,
            'currency': 'USD',
            'item_0_code': 'course',
            'item_0_name': '{}'.format(course_run.title),
            'item_0_quantity': 1,
            'item_0_sku': '{}'.format(course_run.edx_course_key),
            'item_0_tax_amount': '0',
            'item_0_unit_price': str(order.total_price_paid),
            'line_item_count': 1,
            'locale': 'en-us',
            'override_custom_cancel_page': 'dashboard_url?status=cancel&course_key={}'.format(quoted_course_key),
            'override_custom_receipt_page': "dashboard_url?status=receipt&course_key={}".format(quoted_course_key),
            'reference_number': make_reference_id(order),
            'profile_id': CYBERSOURCE_PROFILE_ID,
            'signed_date_time': now.strftime(ISO_8601_FORMAT),
            'signed_field_names': ','.join(signed_field_names),
            'transaction_type': 'sale',
            'transaction_uuid': transaction_uuid,
            'unsigned_field_names': '',
            'merchant_defined_data1': 'course',
            'merchant_defined_data2': '{}'.format(course_run.title),
            'merchant_defined_data3': '{}'.format(course_run.edx_course_key),
        }
        assert now_mock.called
Beispiel #10
0
    def test_valid_signature(self):
        """
        Signature is made up of a ordered key value list signed using HMAC 256 with a security key
        """
        payload = {
            'x': 'y',
            'abc': 'def',
            'key': 'value',
            'signed_field_names': 'abc,x',
        }
        signature = generate_cybersource_sa_signature(payload)

        message = ','.join('{}={}'.format(key, payload[key]) for key in ['abc', 'x'])

        digest = hmac.new(
            CYBERSOURCE_SECURITY_KEY.encode('utf-8'),
            msg=message.encode('utf-8'),
            digestmod=hashlib.sha256,
        ).digest()

        assert b64encode(digest).decode('utf-8') == signature
Beispiel #11
0
    def test_valid_signature(self):
        """
        Signature is made up of a ordered key value list signed using HMAC 256 with a security key
        """
        payload = {
            'x': 'y',
            'abc': 'def',
            'key': 'value',
            'signed_field_names': 'abc,x',
        }
        signature = generate_cybersource_sa_signature(payload)

        message = ','.join('{}={}'.format(key, payload[key]) for key in ['abc', 'x'])

        digest = hmac.new(
            CYBERSOURCE_SECURITY_KEY.encode('utf-8'),
            msg=message.encode('utf-8'),
            digestmod=hashlib.sha256,
        ).digest()

        assert b64encode(digest).decode('utf-8') == signature
Beispiel #12
0
    def test_signed_payload(self):
        """
        A valid payload should be signed appropriately
        """
        course_run, user = create_purchasable_course_run()
        order = create_unfulfilled_order(course_run.edx_course_key, user)
        username = '******'
        transaction_uuid = 'hex'

        now = datetime.utcnow()

        with patch('ecommerce.api.get_social_username', autospec=True, return_value=username):
            with patch('ecommerce.api.datetime', autospec=True, utcnow=MagicMock(return_value=now)):
                with patch('ecommerce.api.uuid.uuid4', autospec=True, return_value=MagicMock(hex=transaction_uuid)):
                    payload = generate_cybersource_sa_payload(order)
        signature = payload.pop('signature')
        assert generate_cybersource_sa_signature(payload) == signature
        signed_field_names = payload['signed_field_names'].split(',')
        assert signed_field_names == sorted(payload.keys())

        assert payload == {
            'access_key': CYBERSOURCE_ACCESS_KEY,
            'amount': str(order.total_price_paid),
            'consumer_id': username,
            'currency': 'USD',
            'locale': 'en-us',
            'override_custom_cancel_page': 'https://micromasters.mit.edu?cancel',
            'override_custom_receipt_page': "https://micromasters.mit.edu?receipt",
            'reference_number': make_reference_id(order),
            'profile_id': CYBERSOURCE_PROFILE_ID,
            'signed_date_time': now.strftime(ISO_8601_FORMAT),
            'signed_field_names': ','.join(signed_field_names),
            'transaction_type': 'sale',
            'transaction_uuid': transaction_uuid,
            'unsigned_field_names': '',
        }