Exemplo n.º 1
0
    def test_get_required_empty_claims(self):
        """
            Test getting the claims that are required and empty.

            Expected Result: Only the names of claims that are not optional, but have no value are returned.
        """

        easyjwt = EasyJWT(self.key)

        # Assert there is an optional, empty claim. This claim is not included in the output.
        self.assertIsNone(easyjwt.not_before_date)
        self.assertTrue(easyjwt._is_optional_claim('nbf'))

        # Set an optional claim. This claim is not included in the output.
        easyjwt.expiration_date = self.expiration_date
        self.assertTrue(easyjwt._is_optional_claim('exp'))

        # Create a non-optional claim and set a value. This claim is not included in the output.
        easyjwt.required = True
        self.assertTrue(easyjwt._is_claim('required'))

        # Create a non-optional, empty claim. This claim is included in the output.
        required_empty_claim = 'required_empty'
        easyjwt.required_empty = None
        self.assertTrue(easyjwt._is_claim(required_empty_claim))

        self.assertSetEqual({required_empty_claim},
                            easyjwt._get_required_empty_claims())
Exemplo n.º 2
0
    def test_algorithms_supported(self):
        """
            Test that the algorithms in the enum are actually supported.

            Expected result: All algorithms specified in the enum can encode and decode the token.
        """

        key = 'abcdefghijklmnopqrstuvwxyz'

        # noinspection PyTypeChecker
        for algorithm in list(Algorithm):

            # Set the algorithm on the class so it is used for decoding.
            EasyJWT.algorithm = algorithm

            easyjwt_creation = EasyJWT(key)

            # Encode the token with the current algorithm.
            token = easyjwt_creation.create()
            self.assertEqual(algorithm,
                             easyjwt_creation.algorithm,
                             msg=f'Algorithm {algorithm} not set on token')
            self.assertIsNotNone(
                token,
                msg=f'Failed to encode token with algorithm {algorithm}')

            # Decode the token with the current algorithm.
            easyjwt_verification = EasyJWT.verify(token, key)
            self.assertEqual(algorithm,
                             easyjwt_verification.algorithm,
                             msg=f'Algorithm {algorithm} not set on token')
            self.assertIsNotNone(
                easyjwt_verification,
                msg=f'Failed to decode token with algorithm {algorithm}')
Exemplo n.º 3
0
    def test_restore_claim_set_with_optional_claims(self):
        """
            Test restoring a claim set if optional claims are given.

            Expected Result: The values in the claim set are correctly mapped to their respective instance variables.
                             The date values are converted to `datetime` objects.
        """

        # Prepare a claim set. The dates must be included as a timestamp (seconds since the epoch).
        exp_timestamp = int(
            self.expiration_date.replace(tzinfo=timezone.utc).timestamp())
        iat_timestamp = int(
            self.issued_at_date.replace(tzinfo=timezone.utc).timestamp())
        nbf_timestamp = int(
            self.not_before_date.replace(tzinfo=timezone.utc).timestamp())
        claim_set = dict(
            _easyjwt_class='EasyJWT',
            aud=self.audience,
            exp=exp_timestamp,
            iat=iat_timestamp,
            iss=self.issuer,
            jti=self.JWT_ID,
            nbf=nbf_timestamp,
            sub=self.subject,
        )

        easyjwt = EasyJWT(self.key)
        easyjwt._restore_claim_set(claim_set)
        self.assertEqual(self.audience, easyjwt.audience)
        self.assertEqual(self.expiration_date, easyjwt.expiration_date)
        self.assertEqual(self.issued_at_date, easyjwt.issued_at_date)
        self.assertEqual(self.issuer, easyjwt.issuer)
        self.assertEqual(self.JWT_ID, easyjwt.JWT_ID)
        self.assertEqual(self.not_before_date, easyjwt.not_before_date)
        self.assertEqual(self.subject, easyjwt.subject)
Exemplo n.º 4
0
    def test_get_claim_set_with_optional_claims(self):
        """
            Test getting the claim set if optional claims are set.

            Expected Result: A dictionary with the entries for the class and the optional claims is returned.
        """

        claim_set = dict(
            _easyjwt_class='EasyJWT',
            aud=self.audience,
            exp=self.expiration_date,
            iat=self.issued_at_date,
            iss=self.issuer,
            jti=self.JWT_ID,
            nbf=self.not_before_date,
            sub=self.subject,
        )

        easyjwt = EasyJWT(self.key)
        easyjwt.audience = self.audience
        easyjwt.expiration_date = self.expiration_date
        easyjwt.issued_at_date = self.issued_at_date
        easyjwt.issuer = self.issuer
        easyjwt.JWT_ID = self.JWT_ID
        easyjwt.not_before_date = self.not_before_date
        easyjwt.subject = self.subject

        self.assertDictEqual(claim_set, easyjwt._get_claim_set())
Exemplo n.º 5
0
    def test_get_class_name(self):
        """
            Test getting the name of the class.

            Expected Result: `EasyJWT`
        """

        easyjwt = EasyJWT(self.key)
        self.assertEqual('EasyJWT', easyjwt._get_class_name())
Exemplo n.º 6
0
    def test_create_success_lenient_verification(self):
        """
            Test creating a token with strict verification disabled.

            Expected Result: A token is created successfully. The create token can be decoded.
        """

        EasyJWT.strict_verification = False

        easyjwt = EasyJWT(self.key)
        easyjwt.expiration_date = self.expiration_date
        easyjwt.issuer = self.issuer
        easyjwt.JWT_ID = self.JWT_ID
        easyjwt.not_before_date = self.not_before_date
        easyjwt.subject = self.subject

        token = easyjwt.create()
        self.assertIsNotNone(token)

        self.assertIsNotNone(easyjwt.issued_at_date)

        claim_set = decode(token,
                           self.key,
                           algorithms=easyjwt._get_decode_algorithms())
        self.assertIsNotNone(claim_set)
Exemplo n.º 7
0
    def test_verify_claim_set_success_without_optional_claims(self):
        """
            Test verifying a valid claim set not containing optional claims.

            Expected result: `True`
        """

        easyjwt = EasyJWT(self.key)

        claim_set = easyjwt._get_claim_set()
        self.assertTrue(easyjwt._verify_claim_set(claim_set))
Exemplo n.º 8
0
    def test_get_claim_names_strict_verification(self):
        """
            Test getting the set of claim names with strict verification enabled.

            Expected Result: A set with the claim names for the `EasyJWT` class and all optional claims returned.
        """

        claim_names = {
            '_easyjwt_class', 'aud', 'exp', 'iat', 'iss', 'jti', 'nbf', 'sub'
        }
        easyjwt = EasyJWT(self.key)
        self.assertSetEqual(claim_names, easyjwt._get_claim_names())
Exemplo n.º 9
0
    def test_get_claim_set_lenient_verification(self):
        """
            Test getting the claim set with strict verification disabled.

            Expected Result: The `_easyjwt_class` claim is not included.
        """

        EasyJWT.strict_verification = False
        claim_set = dict()

        easyjwt = EasyJWT(self.key)
        self.assertDictEqual(claim_set, easyjwt._get_claim_set())
Exemplo n.º 10
0
    def test_str(self):
        """
            Test converting the object to a string.

            Expected Result: The token is returned as if `create()` had been called.
        """

        easyjwt = EasyJWT(self.key)

        # Note: If this assertion ever fails it might be because the issued-at date is set within `create()` and the
        # difference between the two calls is too large.
        self.assertEqual(easyjwt.create(), str(easyjwt))
Exemplo n.º 11
0
    def test_claim_names_and_claim_set_keys_equal(self):
        """
            Assert that the set of claim names is exactly the same as the set of claim set keys (if empty claims are
            included).

            Expected Result: The set of claim names equals the set of claim set keys.
        """

        easyjwt = EasyJWT(self.key)
        claim_names = easyjwt._get_claim_names()
        claim_set = easyjwt._get_claim_set(with_empty_claims=True)
        self.assertSetEqual(claim_names, set(claim_set.keys()))
Exemplo n.º 12
0
    def test_get_claim_set_without_optional_claims_and_without_empty_claims(
            self):
        """
            Test getting the claim set without getting empty claims if optional claims are not set.

            Expected Result: A dictionary with the entry for the class is returned. Optional claims are not included.
        """

        claim_set = dict(_easyjwt_class='EasyJWT', )

        easyjwt = EasyJWT(self.key)
        self.assertDictEqual(claim_set,
                             easyjwt._get_claim_set(with_empty_claims=False))
Exemplo n.º 13
0
    def test_verify_failure_invalid_issued_at(self):
        """
            Test verifying a token with an invalid issued-at date.

            Expected Result: An `InvalidIssuedAtError` is raised.
        """

        easyjwt_creation = EasyJWT(self.key)
        # noinspection PyTypeChecker
        token = easyjwt_creation.create(issued_at='NaN')

        with self.assertRaises(InvalidIssuedAtError):
            easyjwt_verification = EasyJWT.verify(token, self.key)
            self.assertIsNone(easyjwt_verification)
Exemplo n.º 14
0
    def test_verify_failure_invalid_audience_no_audience_expected(self):
        """
            Test verifying a token with an audience claim, but without expecting one when verifying the token.

            Expected Result: An `InvalidAudienceError` is raised.
        """

        easyjwt_creation = EasyJWT(self.key)
        easyjwt_creation.audience = self.audience
        token = easyjwt_creation.create()

        with self.assertRaises(InvalidAudienceError):
            easyjwt_verification = EasyJWT.verify(token, self.key)
            self.assertIsNone(easyjwt_verification)
Exemplo n.º 15
0
    def test_verify_claim_set_failure_class_missing(self):
        """
            Test verifying a claim set with a missing class claim.

            Expected result: An `UnspecifiedClassError` error is raised.
        """

        # Remove the class claim from the claim set.
        easyjwt = EasyJWT(self.key)
        claim_set = easyjwt._get_claim_set()
        del claim_set['_easyjwt_class']

        with self.assertRaises(UnspecifiedClassError):
            easyjwt._verify_claim_set(claim_set)
Exemplo n.º 16
0
    def test_verify_failure_invalid_signature(self):
        """
            Test verifying a token using an invalid key.

            Expected Result: An `InvalidSignatureError` error is raised.
        """

        easyjwt_creation = EasyJWT(self.key)
        token = easyjwt_creation.create()

        key = 'invalid-' + self.key
        with self.assertRaises(InvalidSignatureError):
            easyjwt_verification = EasyJWT.verify(token, key)
            self.assertIsNone(easyjwt_verification)
Exemplo n.º 17
0
    def test_registered_claim_subject(self):
        """
            Test the registered claim ``sub``.

            Expected Result: The field is an optional claim and correctly mapped to the claim name and vice versa.
        """
        instance_var_name = 'subject'
        claim_name = 'sub'

        self.assertTrue(EasyJWT._is_claim(instance_var_name))
        self.assertTrue(EasyJWT._is_optional_claim(claim_name))
        self.assertEqual(instance_var_name,
                         EasyJWT._map_claim_name_to_instance_var(claim_name))
        self.assertEqual(
            claim_name,
            EasyJWT._map_instance_var_to_claim_name(instance_var_name))
Exemplo n.º 18
0
    def test_verify_failure_expired_token(self):
        """
            Test verifying an expired token.

            Expected Result: An `ExpiredTokenError` error is raised.
        """

        easyjwt_creation = EasyJWT(self.key)
        easyjwt_creation.expiration_date = self.expiration_date - timedelta(
            minutes=30)

        token = easyjwt_creation.create()

        with self.assertRaises(ExpiredTokenError):
            easyjwt_verification = EasyJWT.verify(token, self.key)
            self.assertIsNone(easyjwt_verification)
Exemplo n.º 19
0
    def test_verify_failure_not_yet_valid_token(self):
        """
            Test verifying a token that is not yet valid.

            Expected Result: An `ImmatureTokenError` error is raised.
        """

        easyjwt_creation = EasyJWT(self.key)
        easyjwt_creation.not_before_date = self.not_before_date + timedelta(
            minutes=15)

        token = easyjwt_creation.create()

        with self.assertRaises(ImmatureTokenError):
            easyjwt_verification = EasyJWT.verify(token, self.key)
            self.assertIsNone(easyjwt_verification)
Exemplo n.º 20
0
    def test_is_optional_claim_easyjwt_class(self):
        """
            Test if the claim for the `EasyJWT` class is optional.

            Expected Result: `False`
        """

        self.assertFalse(EasyJWT._is_optional_claim('_easyjwt_class'))
Exemplo n.º 21
0
    def test_verify_failure_invalid_audience_no_audience_in_token(self):
        """
            Test verifying a token without an audience claim, but expecting one.

            Expected Result: An `InvalidClaimSetError` is raised.
        """

        easyjwt_creation = EasyJWT(self.key)
        token = easyjwt_creation.create()

        with self.assertRaises(InvalidClaimSetError) as exception_cm:
            easyjwt_verification = EasyJWT.verify(token,
                                                  self.key,
                                                  audience=self.audience)
            self.assertIsNone(easyjwt_verification)

        self.assertIn('audience', exception_cm.exception.missing_claims)
Exemplo n.º 22
0
    def test_verify_failure_missing_issuer(self):
        """
            Test verifying a token without giving an issuer.

            Expected Result: An `InvalidIssuerError` is raised.
        """

        easyjwt_creation = EasyJWT(self.key)
        token = easyjwt_creation.create()

        with self.assertRaises(InvalidClaimSetError) as exception_cm:
            easyjwt_verification = EasyJWT.verify(token,
                                                  self.key,
                                                  issuer=self.issuer)
            self.assertIsNone(easyjwt_verification)

        self.assertSetEqual({'issuer'}, exception_cm.exception.missing_claims)
Exemplo n.º 23
0
    def test_verify_failure_invalid_issuer(self):
        """
            Test verifying a token with an invalid issuer.

            Expected Result: An `InvalidIssuerError` is raised.
        """

        easyjwt_creation = EasyJWT(self.key)
        easyjwt_creation.issuer = self.issuer
        token = easyjwt_creation.create()

        invalid_issuer = 'Impersonating ' + self.issuer
        with self.assertRaises(InvalidIssuerError):
            easyjwt_verification = EasyJWT.verify(token,
                                                  self.key,
                                                  issuer=invalid_issuer)
            self.assertIsNone(easyjwt_verification)
Exemplo n.º 24
0
    def test_verify_failure_invalid_audience_wrong_type(self):
        """
            Test verifying a token with an audience claim, but giving an audience of a wrong type.

            Expected Result: An `InvalidAudienceError` is raised.
        """

        easyjwt_creation = EasyJWT(self.key)
        easyjwt_creation.audience = self.audience
        token = easyjwt_creation.create()

        with self.assertRaises(InvalidAudienceError):
            # noinspection PyTypeChecker
            easyjwt_verification = EasyJWT.verify(token,
                                                  self.key,
                                                  audience=42.1337)
            self.assertIsNone(easyjwt_verification)
Exemplo n.º 25
0
    def test_verify_claim_set_failure_class_wrong(self):
        """
            Test verifying a claim set with a faulty value in the class claim.

            Expected result: An `InvalidClassError` error with an explaining message is raised.
        """

        # Manipulate the class claim in the claim set.
        easyjwt = EasyJWT(self.key)
        claim_set = easyjwt._get_claim_set()
        claim_set['_easyjwt_class'] = 'InheritedEasyJWT'

        with self.assertRaises(InvalidClassError) as exception_cm:
            easyjwt._verify_claim_set(claim_set)

        self.assertEqual('Expected class EasyJWT. Got class InheritedEasyJWT',
                         str(exception_cm.exception))
Exemplo n.º 26
0
    def test_verify_claim_set_failure_claims_unexpected(self):
        """
            Test verifying a claim set with unexpected claims.

            Expected result: An `InvalidClaimSetError` error with an explaining message is raised.
        """

        easyjwt = EasyJWT(self.key)

        # Add a claim to the claim set.
        claim_set = easyjwt._get_claim_set()
        claim_set['user_id'] = 42

        with self.assertRaises(InvalidClaimSetError) as exception_cm:
            easyjwt._verify_claim_set(claim_set)

        self.assertEqual('Missing claims: {}. Unexpected claims: {user_id}',
                         str(exception_cm.exception))
Exemplo n.º 27
0
    def test_create_failure_missing_required_claims(self):
        """
            Test creating a token if required claims are empty.

            Expected Result: An `MissingRequiredClaimsError` error is raised.
        """

        # Unset the claim for the EasyJWT class which is always required.
        easyjwt = EasyJWT(self.key)
        easyjwt._easyjwt_class = None
        self.assertTrue(easyjwt._is_claim('_easyjwt_class'))

        with self.assertRaises(MissingRequiredClaimsError) as exception_cm:
            token = easyjwt.create()
            self.assertIsNone(token)

        self.assertEqual('Required empty claims: {_easyjwt_class}',
                         str(exception_cm.exception))
Exemplo n.º 28
0
    def test_restore_claim_set_without_optional_claims(self):
        """
            Test restoring a claim set if optional claims are not given.

            Expected Result: The values in the claim set are mapped to their respective instance variables. Optional
                             claims are empty, without causing an error.
        """

        claim_set = dict(_easyjwt_class='EasyJWT', )

        easyjwt = EasyJWT(self.key)
        easyjwt._restore_claim_set(claim_set)
        self.assertIsNone(easyjwt.audience)
        self.assertIsNone(easyjwt.expiration_date)
        self.assertIsNone(easyjwt.issued_at_date)
        self.assertIsNone(easyjwt.issuer)
        self.assertIsNone(easyjwt.JWT_ID)
        self.assertIsNone(easyjwt.not_before_date)
        self.assertIsNone(easyjwt.subject)
Exemplo n.º 29
0
    def test_get_restore_method_for_claim_none(self):
        """
            Test getting the restore method for a claim that has no such method.

            Expected Result: `None`.
        """

        restore_method = EasyJWT._get_restore_method_for_claim(
            'claim_with_no_restore_method')
        self.assertIsNone(restore_method)
Exemplo n.º 30
0
    def test_get_restore_method_for_claim_not_before_date(self):
        """
            Test getting the restore method for the not-before date.

            Expected Result: The method `restoration.restore_timestamp_to_datetime()` is returned.
        """

        restore_method = EasyJWT._get_restore_method_for_claim(
            'not_before_date')
        self.assertEqual(restore_timestamp_to_datetime, restore_method)