예제 #1
0
    def validate(self, data):
        token = data['token']

        payload = _check_payload(token=token)
        user = _check_user(payload=payload)

        # Get and check 'orig_iat'
        orig_iat = payload.get('orig_iat')

        if orig_iat is None:
            msg = _('orig_iat field not found in token.')
            raise serializers.ValidationError(msg)

        # Verify expiration
        refresh_limit = \
            api_settings.JWT_REFRESH_EXPIRATION_DELTA.total_seconds()

        expiration_timestamp = orig_iat + refresh_limit
        now_timestamp = unix_epoch()

        if now_timestamp > expiration_timestamp:
            msg = _('Refresh has expired.')
            raise serializers.ValidationError(msg)

        new_payload = JSONWebTokenAuthentication.jwt_create_payload(user)
        new_payload['orig_iat'] = orig_iat

        return {
            'token':
            JSONWebTokenAuthentication.jwt_encode_payload(new_payload),
            'user': user,
            'issued_at': new_payload.get('iat', unix_epoch())
        }
예제 #2
0
def test_valid_token__returns_new_token(call_auth_refresh_endpoint, user):
    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    payload["exp"] = payload["iat"] + 100  # add 100 seconds to issued at time
    auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

    refresh_response = call_auth_refresh_endpoint(auth_token)
    refresh_token = refresh_response.json()["token"]
    assert refresh_token != auth_token
예제 #3
0
 def _create_authenticated_client(user):
     payload = JSONWebTokenAuthentication.jwt_create_payload(user)
     token = JSONWebTokenAuthentication.jwt_encode_payload(payload)
     api_client.credentials(
         HTTP_AUTHORIZATION="{prefix} {token}".format(
             prefix=api_settings.JWT_AUTH_HEADER_PREFIX, token=token
         )
     )
     return api_client
예제 #4
0
def test_refresh_limit_expired__returns_validation_error(
        call_auth_refresh_endpoint, user):
    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    payload["orig_iat"] = 0  # beginning of time
    auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

    expected_output = {"non_field_errors": [_("Refresh has expired.")]}

    response = call_auth_refresh_endpoint(auth_token)
    assert response.json() == expected_output
예제 #5
0
def test_valid_token__returns_new_token_with_new_token_id(
        call_auth_refresh_endpoint, user):
    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

    refresh_response = call_auth_refresh_endpoint(auth_token)
    refresh_token = refresh_response.json()["token"]
    refresh_token_payload = JSONWebTokenAuthentication.jwt_decode_token(
        refresh_token)
    assert refresh_token_payload["jti"] != str(payload["jti"])
    def test_auth_refresh__valid_token__returns_new_token(self):
        payload = JSONWebTokenAuthentication.jwt_create_payload(
            self.active_user)
        payload[
            'exp'] = payload['iat'] + 100  # add 100 seconds to issued at time
        auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

        refresh_response = call_auth_refresh_endpoint(self.client, auth_token)
        refresh_token = refresh_response.json()['token']
        self.assertNotEqual(refresh_token, auth_token)
def test_token_with_invalid_username_returns_validation_error(
        user, call_auth_verify_endpoint):
    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    payload["username"] = "******"
    auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

    expected_output = {"non_field_errors": [_("User doesn't exist.")]}

    verify_response = call_auth_verify_endpoint(auth_token)
    assert verify_response.json() == expected_output
def test_token_without_username_returns_validation_error(
        user, call_auth_verify_endpoint):
    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    payload.pop("username")
    auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

    expected_output = {"non_field_errors": [_("Invalid token.")]}

    verify_response = call_auth_verify_endpoint(auth_token)

    assert verify_response.json() == expected_output
예제 #9
0
def test_valid_token__returns_new_token_preserving_token_id_for_first_refresh(
        call_auth_refresh_endpoint, user):
    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)
    assert "orig_jti" not in payload

    refresh_response = call_auth_refresh_endpoint(auth_token)
    refresh_token = refresh_response.json()["token"]
    refresh_token_payload = JSONWebTokenAuthentication.jwt_decode_token(
        refresh_token)
    assert refresh_token_payload["orig_jti"] == str(payload["jti"])
예제 #10
0
def test_valid_token__returns_new_token_preserving_original_token_id_for_subsequent_refreshes(
        call_auth_refresh_endpoint, user):
    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    payload["orig_jti"] = uuid.uuid4()
    auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

    refresh_response = call_auth_refresh_endpoint(auth_token)
    refresh_token = refresh_response.json()["token"]
    refresh_token_payload = JSONWebTokenAuthentication.jwt_decode_token(
        refresh_token)
    assert refresh_token_payload["orig_jti"] == str(payload["orig_jti"])
예제 #11
0
    def test_auth_refresh__expired_token__returns_validation_error(self):
        payload = JSONWebTokenAuthentication.jwt_create_payload(
            self.active_user)
        payload['iat'] = 0
        payload['exp'] = 1
        auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

        expected_output = {'non_field_errors': [_('Token has expired.')]}

        refresh_response = call_auth_refresh_endpoint(self.client, auth_token)
        self.assertEqual(refresh_response.json(), expected_output)
예제 #12
0
def test_expired_token__returns_validation_error(call_auth_refresh_endpoint,
                                                 user):
    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    payload["iat"] = 0
    payload["exp"] = 1
    auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

    expected_output = {"non_field_errors": [_("Token has expired.")]}

    refresh_response = call_auth_refresh_endpoint(auth_token)
    assert refresh_response.json() == expected_output
def test_expired_token_returns_validation_error(user,
                                                call_auth_verify_endpoint):
    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    payload["iat"] = 0  # beginning of time
    payload["exp"] = 1  # one second after beginning of time
    auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

    expected_output = {"non_field_errors": [_("Token has expired.")]}

    verify_response = call_auth_verify_endpoint(auth_token)
    assert verify_response.json() == expected_output
def test_token_for_inactive_user_returns_validation_error(
        create_user, call_auth_verify_endpoint):
    inactive_user = create_user(username="******",
                                password="******",
                                is_active=False)
    payload = JSONWebTokenAuthentication.jwt_create_payload(inactive_user)
    auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

    expected_output = {"non_field_errors": [_("User account is disabled.")]}

    verify_response = call_auth_verify_endpoint(auth_token)
    assert verify_response.json() == expected_output
예제 #15
0
    def test_auth_verify__expired_token__returns_validation_error(self):

        payload = JSONWebTokenAuthentication.jwt_create_payload(
            self.active_user)
        payload['iat'] = 0  # beginning of time
        payload['exp'] = 1  # one second after beginning of time
        auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

        expected_output = {'non_field_errors': [_('Token has expired.')]}

        verify_response = call_auth_verify_endpoint(self.client, auth_token)
        self.assertEqual(verify_response.json(), expected_output)
예제 #16
0
    def test_auth_verify__token_with_invalid_username__returns_validation_error(
            self):
        # create token with invalid username
        payload = JSONWebTokenAuthentication.jwt_create_payload(
            self.active_user)
        payload['username'] = "******"
        auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

        expected_output = {'non_field_errors': [_("User doesn't exist.")]}

        verify_response = call_auth_verify_endpoint(self.client, auth_token)
        self.assertEqual(verify_response.json(), expected_output)
예제 #17
0
def test_view_returns_401_for_corrupt_signature(api_client, user):
    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    token = JSONWebTokenAuthentication.jwt_encode_payload(payload) + "x"
    api_client.credentials(HTTP_AUTHORIZATION="Bearer " + token)

    expected_output = {"detail": _("Error decoding token.")}

    url = reverse("test-view")
    response = api_client.get(url)

    assert response.status_code == status.HTTP_401_UNAUTHORIZED
    assert response.json() == expected_output
예제 #18
0
    def validate(self, data):
        user = data["user"]

        payload = JSONWebTokenAuthentication.jwt_create_payload(user)
        check_user(payload)

        token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

        return {
            "user": user,
            "token": token,
            "issued_at": payload.get('iat', unix_epoch())
        }
def test_create_or_update_blacklist_entry(user, create_authenticated_client):
    url = reverse('blacklist-list')
    api_client = create_authenticated_client(user)

    # Create a different token to try to blacklist twice
    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

    api_client.post(url, data={"token": token})
    assert BlacklistedToken.objects.count() == 1

    api_client.post(url, data={"token": token})
    assert BlacklistedToken.objects.count() == 1
예제 #20
0
    def test_auth_verify__token_without_username__returns_validation_error(
            self):
        # create token without username field
        payload = JSONWebTokenAuthentication.jwt_create_payload(
            self.active_user)
        del payload['username']
        auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

        expected_output = {'non_field_errors': [_('Invalid token.')]}

        verify_response = call_auth_verify_endpoint(self.client, auth_token)

        self.assertEqual(verify_response.json(), expected_output)
def test_token_without_required_token_id_returns_validation_error(
    monkeypatch, user, call_auth_verify_endpoint
):
    monkeypatch.setattr(api_settings, "JWT_TOKEN_ID", "require")
    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    payload.pop("jti")
    auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

    expected_output = {"non_field_errors": [_("Invalid token.")]}

    verify_response = call_auth_verify_endpoint(auth_token)

    assert verify_response.json() == expected_output
def test_token_is_blocked_by_id(user, monkeypatch, id_setting):
    monkeypatch.setattr(api_settings, "JWT_TOKEN_ID", id_setting)
    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

    expiration = timezone.now() + timedelta(days=1)
    BlacklistedToken(
        token_id=payload['jti'],
        expires_at=expiration,
        user=user,
    ).save()

    assert BlacklistedToken.is_blocked(token, payload) is True
예제 #23
0
    def test_auth_verify__token_for_inactive_user__returns_validation_error(
            self):
        # create token with invalid username
        payload = JSONWebTokenAuthentication.jwt_create_payload(
            self.inactive_user)
        auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

        expected_output = {
            'non_field_errors': [_('User account is disabled.')]
        }

        verify_response = call_auth_verify_endpoint(self.client, auth_token)
        self.assertEqual(verify_response.json(), expected_output)
def test_token_is_not_blocked_by_value_when_ids_required(user, monkeypatch):
    monkeypatch.setattr(api_settings, "JWT_TOKEN_ID", "require")
    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

    expiration = timezone.now() + timedelta(days=1)
    BlacklistedToken(
        token=token,
        expires_at=expiration,
        user=user,
    ).save()

    assert BlacklistedToken.is_blocked(token, payload) is False
예제 #25
0
def test_without_orig_iat_in_payload__returns_validation_error(
        call_auth_refresh_endpoint, user):
    # create token without orig_iat in payload
    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    del payload["orig_iat"]
    auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

    expected_output = {
        "non_field_errors": [_("orig_iat field not found in token.")]
    }

    response = call_auth_refresh_endpoint(auth_token)
    assert response.json() == expected_output
예제 #26
0
def test_blacklisted_token__returns_validation_error(
        call_auth_refresh_endpoint, user):
    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)
    BlacklistedToken.objects.create(
        token=auth_token,
        user=user,
        expires_at=timezone.now() - timedelta(days=7),
    )

    expected_output = {"non_field_errors": [_("Token is blacklisted.")]}

    refresh_response = call_auth_refresh_endpoint(auth_token)
    assert refresh_response.json() == expected_output
예제 #27
0
    def test_auth_refresh__without_orig_iat_in_payload__returns_validation_error(
            self):
        # create token without orig_iat in payload
        payload = JSONWebTokenAuthentication.jwt_create_payload(
            self.active_user)
        del payload['orig_iat']
        auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

        expected_output = {
            'non_field_errors': [_('orig_iat field not found in token.')]
        }

        response = call_auth_refresh_endpoint(self.client, auth_token)
        self.assertEqual(response.json(), expected_output)
예제 #28
0
def test_view_returns_401_for_bogus_issued_at(api_client, user):
    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    payload["iat"] = 'banana'
    token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

    api_client.credentials(HTTP_AUTHORIZATION="Bearer " + token)

    expected_output = {"detail": _("Invalid token.")}

    url = reverse("test-view")
    response = api_client.get(url)

    assert response.status_code == status.HTTP_401_UNAUTHORIZED
    assert response.json() == expected_output
예제 #29
0
def test_view_returns_401_when_username_does_not_exist(api_client, user):
    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    payload["username"] = "******"
    token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

    api_client.credentials(HTTP_AUTHORIZATION="Bearer " + token)

    expected_output = {"detail": _("Invalid token.")}

    url = reverse("test-view")
    response = api_client.get(url)

    assert response.status_code == status.HTTP_401_UNAUTHORIZED
    assert response.json() == expected_output
예제 #30
0
def test_with_JWT_ALLOW_REFRESH_disabled__returns_validation_error(
        monkeypatch, call_auth_refresh_endpoint, user):
    monkeypatch.setattr(api_settings, "JWT_ALLOW_REFRESH", False)

    payload = JSONWebTokenAuthentication.jwt_create_payload(user)
    payload["exp"] = payload["iat"] + 100  # add 100 seconds to issued at time
    auth_token = JSONWebTokenAuthentication.jwt_encode_payload(payload)

    expected_output = {
        "non_field_errors": ["orig_iat field not found in token."]
    }

    refresh_response = call_auth_refresh_endpoint(auth_token)

    assert refresh_response.json() == expected_output