示例#1
0
    def payment_process(self):
        """Simulate the CyberSource payment process.

        Mirrors the way a user would behave when interacting with the payment
        flow. Contacts the ecommerce service directly to emulate the merchant
        notification sent by CyberSource.
        """
        self.auto_auth()

        self.api_client = LocustEdxRestApiClient(
            settings.data['ecommerce']['url']['api'],
            session=self.client,
            signing_key=settings.secrets['jwt']['secret_key'],
            issuer=settings.secrets['jwt']['issuer'],
            username=self._username,
            email=self._email,
        )

        # Emulate rendering of payment buttons
        self.api_client.payment.processors().get()

        # Emulate basket creation and payment
        order_id = self.cybersource_notification()

        # Emulate rendering of the receipt page
        self.api_client.orders(order_id).get(name='/api/v2/orders/:id/')
示例#2
0
    def payment_process(self):
        """Simulate the CyberSource payment process.

        Mirrors the way a user would behave when interacting with the payment
        flow. Contacts the ecommerce service directly to emulate the merchant
        notification sent by CyberSource.
        """
        self.auto_auth()

        self.api_client = LocustEdxRestApiClient(
            ECOMMERCE_API_URL,
            session=self.client,
            signing_key=ECOMMERCE_JWT_SECRET_KEY,
            issuer=ECOMMERCE_JWT_ISSUER,
            username=self._username,
            email=self._email,
        )

        # Emulate rendering of payment buttons
        self.api_client.payment.processors().get()

        # Emulate basket creation and payment
        order_id = self.cybersource_notification()

        # Emulate rendering of the receipt page
        self.api_client.orders(order_id).get(name='/api/v2/orders/:id/')
示例#3
0
    def payment_process(self):
        """Simulate the CyberSource payment process.

        Mirrors the way a user would behave when interacting with the payment
        flow. Contacts the ecommerce service directly to emulate the merchant
        notification sent by CyberSource.
        """
        self.auto_auth()

        self.api_client = LocustEdxRestApiClient(
            settings.data['ecommerce']['url']['api'],
            session=self.client,
            signing_key=settings.data['jwt']['secret_key'],
            issuer=settings.data['jwt']['issuer'],
            username=self._username,
            email=self._email,
        )

        # Emulate rendering of payment buttons
        self.api_client.payment.processors().get()

        # Emulate basket creation and payment
        order_id = self.cybersource_notification()

        # Emulate rendering of the receipt page
        self.api_client.orders(order_id).get(name='/api/v2/orders/:id/')
示例#4
0
 def get_credential_client(self):
     """ New property added for using LocustEdxRestApiClient.
     Default locust client will remain same for using auto_auth().
     """
     return LocustEdxRestApiClient(
         CREDENTIAL_API_URL,
         session=HttpSession(base_url=self.locust.host),
         jwt=self._get_token())
    def __init__(self):
        super(CourseDiscoveryLocust, self).__init__()

        access_token_endpoint = '{}/oauth2/access_token'.format(
            settings.secrets['oauth']['provider_url'].strip('/'))

        access_token, __ = LocustEdxRestApiClient.get_oauth_access_token(
            access_token_endpoint,
            settings.secrets['oauth']['client_id'],
            settings.secrets['oauth']['client_secret'],
        )

        api_url = self.host.strip('/')

        self.client = LocustEdxRestApiClient(
            api_url,
            session=HttpSession(base_url=self.host),
            oauth_access_token=access_token)
示例#6
0
 def get_credential_client(self):
     """ New property added for using LocustEdxRestApiClient.
     Default locust client will remain same for using auto_auth().
     """
     return LocustEdxRestApiClient(
         settings.data['credentials']['url']['api'],
         session=HttpSession(base_url=self.locust.host),
         jwt=self.get_access_token()
     )
示例#7
0
    def __init__(self):
        super(ProgramsUser, self).__init__()

        if not self.host:
            raise LocustError(
                'You must specify a base host, either in the host attribute in the Locust class, '
                'or on the command line using the --host option.')

        self.client = LocustEdxRestApiClient(
            PROGRAMS_API_URL,
            session=HttpSession(base_url=self.host),
            jwt=self._get_token())
示例#8
0
    def get_access_token():
        """ Returns the OAuth 2.0 access token for the Credentials Service.

        Returns:
            str: JWT
        """
        access_token_url = settings.secrets['oauth']['access_token_url']
        client_id = settings.secrets['oauth']['client_id']
        client_secret = settings.secrets['oauth']['client_secret']
        access_token, __ = LocustEdxRestApiClient.get_oauth_access_token(access_token_url, client_id, client_secret,
                                                                         token_type='jwt')
        return access_token
def get_ecom_worker_client():
    """
    Gets the ecommerce worker client

    Using the oauth credentials in the settings file, this method
    returns up the ecommerce work clients which enables a task to call
    the api on behalf of the ecommerce worker.

    Returns:
        LocustEdxRestApiClient: The ecommerce worker client
    """
    access_token_endpoint = '{}/oauth2/access_token'.format(
        settings.secrets['oauth']['provider_url'].strip('/'))

    access_token, __ = LocustEdxRestApiClient.get_oauth_access_token(
        access_token_endpoint,
        settings.secrets['oauth']['client_id'],
        settings.secrets['oauth']['client_secret'],
    )

    return LocustEdxRestApiClient(ECOMMERCE_HOST,
                                  session=HttpSession(base_url=ECOMMERCE_HOST),
                                  oauth_access_token=access_token)
示例#10
0
    def __init__(self):
        super(CourseDiscoveryLocust, self).__init__()

        access_token_endpoint = '{}/oauth2/access_token'.format(
            settings.data['oauth']['provider_url'].strip('/')
        )

        access_token, __ = LocustEdxRestApiClient.get_oauth_access_token(
            access_token_endpoint,
            settings.data['oauth']['client_id'],
            settings.data['oauth']['client_secret'],
        )

        api_url = '{}/api/v1/'.format(self.host.strip('/'))

        self.client = LocustEdxRestApiClient(
            api_url,
            session=HttpSession(base_url=self.host),
            oauth_access_token=access_token
        )
示例#11
0
class CybersourcePaymentTasks(AutoAuthTasks):
    def __init__(self, *args, **kwargs):
        super(CybersourcePaymentTasks, self).__init__(*args, **kwargs)
        self.ecommerce_service_url = settings.data['ecommerce']['url']['service']
        self.cybersource_secret_key = settings.secrets['ecommerce']['cybersource_secret_key']

    @task
    def payment_process(self):
        """Simulate the CyberSource payment process.

        Mirrors the way a user would behave when interacting with the payment
        flow. Contacts the ecommerce service directly to emulate the merchant
        notification sent by CyberSource.
        """
        self.auto_auth()

        self.api_client = LocustEdxRestApiClient(
            settings.data['ecommerce']['url']['api'],
            session=self.client,
            signing_key=settings.secrets['jwt']['secret_key'],
            issuer=settings.secrets['jwt']['issuer'],
            username=self._username,
            email=self._email,
        )

        # Emulate rendering of payment buttons
        self.api_client.payment.processors().get()

        # Emulate basket creation and payment
        order_id = self.cybersource_notification()

        # Emulate rendering of the receipt page
        self.api_client.orders(order_id).get(name='/api/v2/orders/:id/')

    def cybersource_notification(self):
        """Contact Otto's CyberSource notification endpoint."""
        basket_id, amount = self._get_basket_details()
        data = self._get_cybersource_notification_data(basket_id, amount)

        # This endpoint isn't part of the versioned API. It's also not protected
        # by JWT auth, so there's no need to use the API client here.
        url = '{}/payment/cybersource/notify/'.format(self.ecommerce_service_url)
        self.client.post(
            url,
            data=data,
            headers={'Content-Type': 'application/x-www-form-urlencoded'}
        )

        order_id = data['req_reference_number']

        return order_id

    def _get_basket_details(self):
        """Creates a basket and returns its ID and amount.

        Contacts Otto directly to create the user's basket.
        """
        basket = self.api_client.baskets.post({
            'products': [{'sku': settings.data['ecommerce']['paid_sku']}],
            'checkout': True,
            'payment_processor_name': 'cybersource'
        })
        return basket['id'], basket['payment_data']['payment_form_data']['amount']

    def _get_cybersource_notification_data(self, basket_id, amount):
        """Returns a dict simulating a CyberSource payment response."""
        order_id = basket_id + settings.data['ecommerce']['order']['offset']
        order_number = u'{prefix}-{order_id}'.format(
            prefix=settings.data['ecommerce']['order']['prefix'],
            order_id=order_id
        )

        notification = {
            'decision': 'ACCEPT',
            'req_reference_number': order_number,
            'transaction_id': '123456',
            'auth_amount': amount,
            'req_amount': amount,
            'req_tax_amount': '0.00',
            'req_currency': 'USD',
            'req_card_number': 'xxxxxxxxxxxx1111',
            'req_card_type': '001',
            'req_bill_to_forename': 'Ed',
            'req_bill_to_surname': 'Xavier',
            'req_bill_to_address_line1': '141 Portland Ave.',
            'req_bill_to_address_line2': '9th Floor',
            'req_bill_to_address_city': 'Cambridge',
            'req_bill_to_address_postal_code': '02141',
            'req_bill_to_address_state': 'MA',
            'req_bill_to_address_country': 'US'
        }

        notification['signed_field_names'] = ','.join(notification.keys())
        notification['signature'] = self._generate_cybersource_signature(
            self.cybersource_secret_key,
            notification
        )
        return notification

    def _generate_cybersource_signature(self, secret_key, data):
        """Generate a signature for the given data dict."""
        keys = data[u'signed_field_names'].split(u',')

        message = u','.join([u'{key}={value}'.format(key=key, value=data[key]) for key in keys])
        return sign(message, secret_key)
示例#12
0
class CybersourcePaymentTasks(AutoAuthTasks):
    def __init__(self, *args, **kwargs):
        super(CybersourcePaymentTasks, self).__init__(*args, **kwargs)
        self.ecommerce_service_url = ECOMMERCE_SERVICE_URL
        self.cybersource_secret_key = CYBERSOURCE_SECRET_KEY

    @task
    def payment_process(self):
        """Simulate the CyberSource payment process.

        Mirrors the way a user would behave when interacting with the payment
        flow. Contacts the ecommerce service directly to emulate the merchant
        notification sent by CyberSource.
        """
        self.auto_auth()

        self.api_client = LocustEdxRestApiClient(
            ECOMMERCE_API_URL,
            session=self.client,
            signing_key=ECOMMERCE_JWT_SECRET_KEY,
            issuer=ECOMMERCE_JWT_ISSUER,
            username=self._username,
            email=self._email,
        )

        # Emulate rendering of payment buttons
        self.api_client.payment.processors().get()

        # Emulate basket creation and payment
        order_id = self.cybersource_notification()

        # Emulate rendering of the receipt page
        self.api_client.orders(order_id).get(name='/api/v2/orders/:id/')

    def cybersource_notification(self):
        """Contact Otto's CyberSource notification endpoint."""
        basket_id, amount = self._get_basket_details()
        data = self._get_cybersource_notification_data(basket_id, amount)

        # This endpoint isn't part of the versioned API. It's also not protected
        # by JWT auth, so there's no need to use the API client here.
        url = '{}/payment/cybersource/notify/'.format(self.ecommerce_service_url)
        self.client.post(
            url,
            data=data,
            headers={'Content-Type': 'application/x-www-form-urlencoded'}
        )

        order_id = data['req_reference_number']

        return order_id

    def _get_basket_details(self):
        """Creates a basket and returns its ID and amount.

        Contacts Otto directly to create the user's basket.
        """
        basket = self.api_client.baskets.post({
            'products': [{'sku': PAID_SKU}],
            'checkout': True,
            'payment_processor_name': 'cybersource'
        })
        return basket['id'], basket['payment_data']['payment_form_data']['amount']

    def _get_cybersource_notification_data(self, basket_id, amount):
        """Returns a dict simulating a CyberSource payment response."""
        order_id = basket_id + ECOMMERCE_ORDER_OFFSET
        order_number = u'{prefix}-{order_id}'.format(
            prefix=ECOMMERCE_ORDER_PREFIX,
            order_id=order_id
        )

        notification = {
            'decision': 'ACCEPT',
            'req_reference_number': order_number,
            'transaction_id': '123456',
            'auth_amount': amount,
            'req_amount': amount,
            'req_tax_amount': '0.00',
            'req_currency': 'USD',
            'req_card_number': 'xxxxxxxxxxxx1111',
            'req_card_type': '001',
            'req_bill_to_forename': 'Ed',
            'req_bill_to_surname': 'Xavier',
            'req_bill_to_address_line1': '141 Portland Ave.',
            'req_bill_to_address_line2': '9th Floor',
            'req_bill_to_address_city': 'Cambridge',
            'req_bill_to_address_postal_code': '02141',
            'req_bill_to_address_state': 'MA',
            'req_bill_to_address_country': 'US'
        }

        notification['signed_field_names'] = ','.join(notification.keys())
        notification['signature'] = self._generate_cybersource_signature(
            self.cybersource_secret_key,
            notification
        )
        return notification

    def _generate_cybersource_signature(self, secret_key, data):
        """Generate a signature for the given data dict."""
        keys = data[u'signed_field_names'].split(u',')

        message = u','.join([u'{key}={value}'.format(key=key, value=data[key]) for key in keys])
        return sign(message, secret_key)