def test_supported_jwt_version(self, jwt_version): """ Verifies the JWT is decoded successfully with different supported versions in the token. """ jwt_payload = generate_latest_version_payload(self.user, version=jwt_version) token = generate_jwt_token(jwt_payload) self.assertDictEqual(jwt_decode_handler(token), jwt_payload)
def test_supported_jwt_version(self, jwt_version): """ Verifies the JWT is decoded successfully with different supported versions in the token. """ jwt_payload = generate_latest_version_payload(self.user, version=jwt_version) token = generate_jwt_token(jwt_payload) self.assertDictEqual(jwt_decode_handler(token), jwt_payload)
def test_required_claims(self, claim): """ Verify that tokens that do not carry 'exp' or 'iat' claims are rejected """ # Deletes required claim from payload del self.payload[claim] token = generate_jwt_token(self.payload) with self.assertRaises(jwt.MissingRequiredClaimError): # Decode to see if MissingRequiredClaimError exception is raised or not jwt_decode_handler(token)
def test_get_decoded_jwt_from_existing_cookie(self): user = UserFactory() payload = generate_latest_version_payload(user) jwt = generate_jwt_token(payload) expected_decoded_jwt = jwt_decode_handler(jwt) mock_request_with_cookie = mock.Mock(COOKIES={'edx-jwt-cookie': jwt}) decoded_jwt = cookies.get_decoded_jwt(mock_request_with_cookie) self.assertEqual(expected_decoded_jwt, decoded_jwt)
def test_valid_token_multiple_valid_issuers(self, jwt_issuer): """ Validates that a valid token is properly decoded given a list of multiple valid issuers """ # Verify that each valid issuer is properly matched against the valid issuers list # and used to decode the token that was generated using said valid issuer data self.payload['iss'] = jwt_issuer['ISSUER'] token = generate_jwt_token(self.payload, jwt_issuer['SECRET_KEY']) self.assertEqual(jwt_decode_handler(token), self.payload)
def test_valid_token_multiple_valid_issuers(self, jwt_issuer): """ Validates that a valid token is properly decoded given a list of multiple valid issuers """ # Verify that each valid issuer is properly matched against the valid issuers list # and used to decode the token that was generated using said valid issuer data self.payload['iss'] = jwt_issuer['ISSUER'] token = generate_jwt_token(self.payload, jwt_issuer['SECRET_KEY']) self.assertEqual(jwt_decode_handler(token), self.payload)
def test_get_decoded_jwt_from_existing_cookie(self): user = UserFactory() payload = generate_latest_version_payload(user) jwt = generate_jwt_token(payload) expected_decoded_jwt = jwt_decode_handler(jwt) mock_request_with_cookie = mock.Mock(COOKIES={'edx-jwt-cookie': jwt}) decoded_jwt = cookies.get_decoded_jwt(mock_request_with_cookie) self.assertEquals(expected_decoded_jwt, decoded_jwt)
def test_lms_user_id_from_jwt_cookie(self): """ Ensures the lms_user_id can be pulled from the jwt cookie. """ user = self.create_user() self.assertIsNone(user.lms_user_id) payload = generate_latest_version_payload(user, scopes=['user_id']) payload['user_id'] = 'test-lms-user-id' jwt = generate_jwt_token(payload) mock_request_with_cookie = mock.Mock(COOKIES={'edx-jwt-cookie': jwt}) with mock.patch('ecommerce.core.models.crum.get_current_request', return_value=mock_request_with_cookie): self.assertEqual(user.lms_user_id, 'test-lms-user-id')
def test_upgrade(self): """ Verifies the JWT is upgraded when an old (starting) version is provided. """ jwt_payload = generate_unversioned_payload(self.user) token = generate_jwt_token(jwt_payload) upgraded_payload = generate_latest_version_payload(self.user, version='1.0.0') # Keep time-related values constant for full-proof comparison. upgraded_payload['iat'], upgraded_payload['exp'] = jwt_payload['iat'], jwt_payload['exp'] self.assertDictEqual(jwt_decode_handler(token), upgraded_payload)
def test_unsupported_jwt_version(self): """ Verifies the function logs decode failures, and raises an InvalidTokenError if the token version is not supported. """ with mock.patch('edx_rest_framework_extensions.auth.jwt.decoder.logger') as patched_log: with self.assertRaises(jwt.InvalidTokenError): token = generate_jwt_token(self.payload) jwt_decode_handler(token) msg = "Token decode failed due to unsupported JWT version number [%s]" patched_log.info.assert_any_call(msg, '1.1.0')
def test_unsupported_jwt_version(self): """ Verifies the function logs decode failures, and raises an InvalidTokenError if the token version is not supported. """ with mock.patch('edx_rest_framework_extensions.auth.jwt.decoder.logger' ) as patched_log: with self.assertRaises(jwt.InvalidTokenError): token = generate_jwt_token(self.payload) jwt_decode_handler(token) msg = "Token decode failed due to unsupported JWT version number [%s]" patched_log.info.assert_any_call(msg, '1.1.0')
def set_jwt_cookie(self, system_wide_role='admin', context='some_context'): """ Set jwt token in cookies """ role_data = '{system_wide_role}'.format( system_wide_role=system_wide_role) if context is not None: role_data += ':{context}'.format(context=context) payload = generate_unversioned_payload(self.user) payload.update({'roles': [role_data]}) jwt_token = generate_jwt_token(payload) self.client.cookies[jwt_cookie_name()] = jwt_token
def _jwt_token_from_role_context_pairs(user, role_context_pairs): """ Generates a new JWT token with roles assigned from pairs of (role name, context). """ roles = [] for role, context in role_context_pairs: role_data = f'{role}' if context is not None: role_data += f':{context}' roles.append(role_data) payload = generate_unversioned_payload(user) payload.update({'roles': roles}) return generate_jwt_token(payload)
def test_upgrade(self): """ Verifies the JWT is upgraded when an old (starting) version is provided. """ jwt_payload = generate_unversioned_payload(self.user) token = generate_jwt_token(jwt_payload) upgraded_payload = generate_latest_version_payload(self.user, version='1.0.0') # Keep time-related values constant for full-proof comparison. upgraded_payload['iat'], upgraded_payload['exp'] = jwt_payload[ 'iat'], jwt_payload['exp'] self.assertDictEqual(jwt_decode_handler(token), upgraded_payload)
def test_get_decoded_jwt_from_request_from_auth_attr(self, mock_decoder): """ A dcoded jwt should be returned from the request auth if it is not set on the cookie. """ payload = generate_unversioned_payload(self.request.user) payload.update({ "roles": [ "some_new_role_name:some_context" ] }) jwt_token = generate_jwt_token(payload) self.request.auth = jwt_token get_decoded_jwt_from_request(self.request) mock_decoder.assert_called_once()
def get_request_with_jwt_cookie(self, system_wide_role=None, context=None): """ Set jwt token in cookies. """ payload = generate_unversioned_payload(self.user) if system_wide_role: payload.update({ 'roles': [ '{system_wide_role}:{context}'.format(system_wide_role=system_wide_role, context=context) ] }) jwt_token = generate_jwt_token(payload) request = RequestFactory().get('/') request.COOKIES[jwt_cookie_name()] = jwt_token return request
def test_get_decoded_jwt_from_request(self, mock_decoder): """ A decoded jwt should be returned from request if it exists """ payload = generate_unversioned_payload(self.request.user) payload.update({ "roles": [ "some_new_role_name:some_context" ] }) jwt_token = generate_jwt_token(payload) self.request.COOKIES[jwt_cookie_name()] = jwt_token get_decoded_jwt_from_request(self.request) mock_decoder.assert_called_once()
def test_get_decoded_jwt_from_auth(self, is_jwt_authentication): """ Verify get_decoded_jwt_from_auth returns the appropriate value. """ # Mock out the `is_jwt_authenticated` method authentication.is_jwt_authenticated = lambda request: is_jwt_authentication user = factories.UserFactory() payload = generate_latest_version_payload(user) jwt = generate_jwt_token(payload) mock_request_with_cookie = mock.Mock(COOKIES={}, auth=jwt) expected_decoded_jwt = jwt_decode_handler( jwt) if is_jwt_authentication else None decoded_jwt = authentication.get_decoded_jwt_from_auth( mock_request_with_cookie) self.assertEqual(expected_decoded_jwt, decoded_jwt)
def test_failure_invalid_issuer(self): """ Verifies the function logs decode failures, and raises an InvalidTokenError if the token cannot be decoded """ # Create tokens using each invalid issuer and attempt to decode them against # the valid issuers list, which won't work with mock.patch('edx_rest_framework_extensions.auth.jwt.decoder.logger') as patched_log: with self.assertRaises(jwt.InvalidTokenError): self.payload['iss'] = 'invalid-issuer' signing_key = 'invalid-secret-key' # Generate a token using the invalid issuer data token = generate_jwt_token(self.payload, signing_key) # Attempt to decode the token against the entries in the valid issuers list, # which will fail with an InvalidTokenError jwt_decode_handler(token) patched_log.exception.assert_any_call("Token verification failed.")
def test_failure_invalid_issuer(self): """ Verifies the function logs decode failures, and raises an InvalidTokenError if the token cannot be decoded """ # Create tokens using each invalid issuer and attempt to decode them against # the valid issuers list, which won't work with mock.patch('edx_rest_framework_extensions.auth.jwt.decoder.logger' ) as patched_log: with self.assertRaises(jwt.InvalidTokenError): self.payload['iss'] = 'invalid-issuer' signing_key = 'invalid-secret-key' # Generate a token using the invalid issuer data token = generate_jwt_token(self.payload, signing_key) # Attempt to decode the token against the entries in the valid issuers list, # which will fail with an InvalidTokenError jwt_decode_handler(token) patched_log.exception.assert_any_call("Token verification failed.")
def test_failure_invalid_issuer(self): """ Verifies the function logs decode failures with invalid issuer, and raises an InvalidTokenError if the token cannot be decoded """ # Create tokens using each invalid issuer and attempt to decode them against # the valid issuers list, which won't work with mock.patch('edx_rest_framework_extensions.auth.jwt.decoder.logger' ) as patched_log: with self.assertRaises(jwt.InvalidTokenError): self.payload['iss'] = 'invalid-issuer' # signing key of None will use the default valid signing key valid_signing_key = None # Generate a token using the invalid issuer data token = generate_jwt_token(self.payload, valid_signing_key) # Attempt to decode the token against the entries in the valid issuers list, # which will fail with an InvalidTokenError jwt_decode_handler(token) msg = "Token decode failed due to mismatched issuer [%s]" patched_log.info.assert_any_call(msg, 'invalid-issuer')
def setUp(self): super().setUp() self.user = UserFactory() self.payload = generate_latest_version_payload(self.user) self.jwt = generate_jwt_token(self.payload)
def setUp(self): super(JWTDecodeHandlerTests, self).setUp() self.user = UserFactory() self.payload = generate_latest_version_payload(self.user) self.jwt = generate_jwt_token(self.payload)
def setUp(self): super(JWTDecodeHandlerTests, self).setUp() self.user = UserFactory() self.payload = generate_latest_version_payload(self.user) self.jwt = generate_jwt_token(self.payload)
def test_supported_jwt_version_not_specified(self): """ Verifies the JWT is decoded successfully when the JWT_SUPPORTED_VERSION setting is not specified. """ token = generate_jwt_token(self.payload) self.assertDictEqual(jwt_decode_handler(token), self.payload)
def _get_test_jwt_token(self): """ Returns a user and jwt token """ user = factories.UserFactory() payload = generate_latest_version_payload(user) jwt_token = generate_jwt_token(payload) return jwt_token
def test_supported_jwt_version_not_specified(self): """ Verifies the JWT is decoded successfully when the JWT_SUPPORTED_VERSION setting is not specified. """ token = generate_jwt_token(self.payload) self.assertDictEqual(jwt_decode_handler(token), self.payload)
def _set_encoded_jwt_in_cookies(client, payload): """ JWT-encodes the given payload and sets it in the client's cookies. """ client.cookies[jwt_cookie_name()] = generate_jwt_token(payload)