def test_decode_error(self): # Update the payload to ensure a validation error self.payload['exp'] = 0 token = generate_jwt_token(self.payload) with mock.patch('ecommerce.extensions.api.handlers.logger') as patched_log: with self.assertRaises(jwt.InvalidTokenError): jwt_decode_handler(token) patched_log.exception.assert_called_once_with('JWT decode failed!')
def test_decode_error(self): # Update the payload to ensure a validation error self.payload['exp'] = 0 token = generate_jwt_token(self.payload) with mock.patch( 'ecommerce.extensions.api.handlers.logger') as patched_log: with self.assertRaises(jwt.InvalidTokenError): jwt_decode_handler(token) patched_log.exception.assert_called_once_with('JWT decode failed!')
def test_decode_success_with_multiple_issuers(self): settings.JWT_AUTH['JWT_ISSUERS'] = ISSUERS for issuer in ISSUERS: self.payload['iss'] = issuer token = generate_jwt_token(self.payload) self.assertEqual(jwt_decode_handler(token), self.payload)
def test_decode_error_invalid_token(self, mock_logger): """ Invalid token will fail both multiple-issuers and the fallback of edx-drf-extensions jwt_decode_handler. """ # Update the payload to ensure a validation error payload = generate_jwt_payload(self.user, issuer_name='test-issuer-2') payload['exp'] = 0 token = generate_jwt_token(payload, 'test-secret-key-2') with self.assertRaises(jwt.InvalidTokenError): jwt_decode_handler(token) mock_logger.exception.assert_called_with('Custom config JWT decode failed!') mock_logger.info.assert_has_calls(calls=[ mock.call('Failed to use ecommerce multiple issuer jwt_decode_handler.', exc_info=True), mock.call('Failed to use edx-drf-extensions jwt_decode_handler.', exc_info=True), ])
def test_decode_error_invalid_token(self, mock_logger): """ Should fail ``_ecommerce_jwt_decode_handler_multiple_issuers`` due to invalid token, not because it is not configured properly. """ # Update the payload to ensure a validation error payload = generate_jwt_payload(self.user, issuer_name='test-issuer-2') payload['exp'] = 0 token = generate_jwt_token(payload, 'test-secret-key-2') with self.assertRaisesMessage( jwt.InvalidTokenError, ("All combinations of JWT issuers with updated config failed to validate the token. " "Wrong secret_key for issuer test-issuer. Invalid token found using issuer test-issuer-2." )): jwt_decode_handler(token) mock_logger.exception.assert_called_with( 'Custom config JWT decode failed!') mock_logger.info.assert_called_with( 'Failed to use ecommerce multiple issuer jwt_decode_handler.', exc_info=True, )
def get_decoded_jwt_discount_from_request(): request = crum.get_current_request() # We use a get request for display on the basket page, # and we use a post request for submitting payment. if request.method == 'GET': discount_jwt = request.GET.get('discount_jwt') else: discount_jwt = request.POST.get('discount_jwt') if not discount_jwt: return None return jwt_decode_handler(discount_jwt)
def test_decode_success_edx_drf_extensions(self, mock_multiple_issuer_decoder, mock_set_custom_metric): """ Should pass using the edx-drf-extensions jwt_decode_handler. This would happen if ``_ecommerce_jwt_decode_handler_multiple_issuers`` should fail (e.g. using asymmetric tokens). """ mock_multiple_issuer_decoder.side_effect = jwt.InvalidTokenError() first_issuer = settings.JWT_AUTH['JWT_ISSUERS'][0] payload = generate_jwt_payload(self.user, issuer_name=first_issuer['ISSUER']) token = generate_jwt_token(payload, first_issuer['SECRET_KEY']) self.assertDictContainsSubset(payload, jwt_decode_handler(token)) mock_set_custom_metric.assert_called_with('ecom_jwt_decode_handler', 'edx-drf-extensions')
def test_decode_success_edx_drf_extensions(self, mock_set_custom_metric): """ Should pass using the edx-drf-extensions jwt_decode_handler. This would happen with the combination of the JWT_ISSUERS configured in the way that edx-drf-extensions is expected, and using the secret-key of the first configured issuer. """ first_issuer = settings.JWT_AUTH['JWT_ISSUERS'][0] payload = generate_jwt_payload(self.user, issuer_name=first_issuer['ISSUER']) token = generate_jwt_token(payload, first_issuer['SECRET_KEY']) self.assertDictContainsSubset(payload, jwt_decode_handler(token)) mock_set_custom_metric.assert_called_with('ecom_jwt_decode_handler', 'edx-drf-extensions')
def test_decode_success_multiple_issuers(self, mock_logger, mock_set_custom_metric): """ Should pass using ``_ecommerce_jwt_decode_handler_multiple_issuers``. This would happen with the combination of the JWT_ISSUERS configured in the way that edx-drf-extensions is expected, but when the token was generated from the second (or third+) issuer. """ non_first_issuer = settings.JWT_AUTH['JWT_ISSUERS'][2] payload = generate_jwt_payload(self.user, issuer_name=non_first_issuer['ISSUER']) token = generate_jwt_token(payload, non_first_issuer['SECRET_KEY']) self.assertDictContainsSubset(payload, jwt_decode_handler(token)) mock_set_custom_metric.assert_called_with('ecom_jwt_decode_handler', 'ecommerce-multiple-issuers') mock_logger.exception.assert_not_called() mock_logger.warning.assert_not_called() mock_logger.error.assert_not_called() mock_logger.info.assert_not_called()
def test_decode_success_with_multiple_signing_keys(self): settings.JWT_AUTH['JWT_SECRET_KEYS'] = SIGNING_KEYS for signing_key in SIGNING_KEYS: token = generate_jwt_token(self.payload, signing_key) self.assertEqual(jwt_decode_handler(token), self.payload)
def test_decode_success(self): self.assertEqual(jwt_decode_handler(self.jwt), self.payload)
def post(self, request, *args, **kwargs): user = request.user email = user.email customer_id = user.tracking_context['customer_id'] customer = stripe.Customer.retrieve(customer_id) user_basket = Basket.objects.filter(owner=request.user, status="Commited").last() if user_basket: user_basket.strategy = Selector().strategy(user=self.request.user) else: return Response({ "message": "No item found in cart.", "status": False, "result": {}, "status_code": 400 }) if waffle.flag_is_active( request, DYNAMIC_DISCOUNT_FLAG) and user_basket.lines.count() > 0: discount_lms_url = get_lms_url('/api/discounts/') lms_discount_client = EdxRestApiClient( discount_lms_url, jwt=request.site.siteconfiguration.access_token) ck = user_basket.lines.first().product.course_id user_id = user_basket.owner.lms_user_id response = lms_discount_client.course(ck).get() jwt = jwt_decode_handler(response.get('jwt')) if jwt['discount_applicable']: offers = Applicator().get_offers(user_basket, request.user, request) user_basket.strategy = request.strategy discount_benefit = DynamicPercentageDiscountBenefit() percentage = jwt['discount_percent'] discount_benefit.apply(user_basket, 'dynamic_discount_condition', offers[0], discount_percent=percentage) Applicator().apply(user_basket, self.request.user, self.request) if user_basket.status == "Commited": total_amount = int(user_basket.total_incl_tax) if total_amount > 0: try: with transaction.atomic(): payment_response = self.make_stripe_payment_for_mobile( None, user_basket) response = {"total_amount": payment_response.total, "transaction_id": payment_response.transaction_id, \ "currency": payment_response.currency, "client_secret": payment_response.client_secret} # Freezing basket to prevent student from getting enrolled to possibily unpaid courses user_basket.status = Basket.FROZEN user_basket.save() return Response({ "message": "Payment completed.", "status": True, "result": response, "status_code": 200 }) except Exception as e: logger.exception(e) msg = 'Attempts to handle payment for basket ' + str( user_basket.id) + ' failed.' return Response({ "message": msg, "status": False, "result": {}, "status_code": 400 }) else: return Response({ "message": "Total amount must be greater than 0.", "status": False, "result": {}, "status_code": 400 }) else: return Response({ "message": "No item found in cart.", "status": False, "result": {}, "status_code": 400 })