Skip to content

Commit

Permalink
python-jose is removed from project.optional-dependency.
Browse files Browse the repository at this point in the history
in security, the tokens' encode and decode now uses pyjwt.
  • Loading branch information
liwen authored and provinzkraut committed Aug 15, 2024
1 parent f80b4d3 commit 07a69c8
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 23 deletions.
17 changes: 11 additions & 6 deletions litestar/security/jwt/token.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
from datetime import datetime, timezone
from typing import TYPE_CHECKING, Any

from jose import JWSError, JWTError, jwt
import jwt
from jwt import InvalidTokenError, PyJWTError

from litestar.exceptions import ImproperlyConfiguredException, NotAuthorizedException

Expand Down Expand Up @@ -86,7 +87,10 @@ def decode(cls, encoded_token: str, secret: str | dict[str, str], algorithm: str
NotAuthorizedException: If the token is invalid.
"""
try:
payload = jwt.decode(token=encoded_token, key=secret, algorithms=[algorithm], options={"verify_aud": False})
payload = jwt.decode(jwt=encoded_token,
key=secret,
algorithms=[algorithm],
options={"verify_aud": False})
exp = datetime.fromtimestamp(payload.pop("exp"), tz=timezone.utc)
iat = datetime.fromtimestamp(payload.pop("iat"), tz=timezone.utc)
field_names = {f.name for f in dataclasses.fields(Token)}
Expand All @@ -95,7 +99,7 @@ def decode(cls, encoded_token: str, secret: str | dict[str, str], algorithm: str
for key in extra_fields:
extras[key] = payload.pop(key)
return cls(exp=exp, iat=iat, **payload, extras=extras)
except (KeyError, JWTError, ImproperlyConfiguredException) as e:
except (KeyError, PyJWTError, ImproperlyConfiguredException) as e:
raise NotAuthorizedException("Invalid token") from e

def encode(self, secret: str, algorithm: str) -> str:
Expand All @@ -113,7 +117,8 @@ def encode(self, secret: str, algorithm: str) -> str:
"""
try:
return jwt.encode(
claims={k: v for k, v in asdict(self).items() if v is not None}, key=secret, algorithm=algorithm
)
except (JWTError, JWSError) as e:
payload={k: v for k, v in asdict(self).items() if v is not None},
key=secret,
algorithm=algorithm)
except (PyJWTError, InvalidTokenError) as e:
raise ImproperlyConfiguredException("Failed to encode token") from e
29 changes: 15 additions & 14 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,20 @@ classifiers = [
"Topic :: Software Development :: Libraries :: Python Modules",
]
dependencies = [
"anyio>=3",
"httpx>=0.22",
"exceptiongroup; python_version < \"3.11\"",
"importlib-metadata; python_version < \"3.10\"",
"importlib-resources>=5.12.0; python_version < \"3.9\"",
"msgspec>=0.18.2",
"multidict>=6.0.2",
"polyfactory>=2.6.3",
"pyyaml",
"typing-extensions",
"click",
"rich>=13.0.0",
"rich-click",
"anyio>=3",
"httpx>=0.22",
"exceptiongroup; python_version < \"3.11\"",
"importlib-metadata; python_version < \"3.10\"",
"importlib-resources>=5.12.0; python_version < \"3.9\"",
"msgspec>=0.18.2",
"multidict>=6.0.2",
"polyfactory>=2.6.3",
"pyyaml",
"typing-extensions",
"click",
"rich>=13.0.0",
"rich-click",
"pyjwt>=2.8.0",
]
description = "Litestar - A production-ready, highly performant, extensible ASGI API Framework"
keywords = ["api", "rest", "asgi", "litestar", "starlite"]
Expand Down Expand Up @@ -83,7 +84,7 @@ full = [
"litestar[annotated-types,attrs,brotli,cli,cryptography,jinja,jwt,mako,minijinja,opentelemetry,piccolo,picologging,prometheus,pydantic,redis,sqlalchemy,standard,structlog]",
]
jinja = ["jinja2>=3.1.2"]
jwt = ["python-jose", "cryptography"]
jwt = ["pyjwt", "cryptography"]
mako = ["mako>=1.2.4"]
minijinja = ["minijinja>=1.0.0"]
opentelemetry = ["opentelemetry-instrumentation-asgi"]
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/test_security/test_jwt/test_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
from typing import Any, Dict, Optional
from uuid import uuid4

import jwt
import pytest
from hypothesis import given
from hypothesis.strategies import datetimes
from jose import jwt

from litestar.exceptions import ImproperlyConfiguredException, NotAuthorizedException
from litestar.security.jwt import Token
Expand Down Expand Up @@ -150,7 +150,7 @@ def test_extra_fields() -> None:
"exp": (datetime.now(timezone.utc) + timedelta(seconds=30)),
}
token_secret = secrets.token_hex()
encoded_token = jwt.encode(claims=raw_token, key=token_secret, algorithm="HS256")
encoded_token = jwt.encode(payload=raw_token, key=token_secret, algorithm="HS256")
token = Token.decode(encoded_token=encoded_token, secret=token_secret, algorithm="HS256")
assert "azp" in token.extras
assert "email" in token.extras
Expand All @@ -161,6 +161,6 @@ def test_extra_fields() -> None:
"exp": (datetime.now(timezone.utc) + timedelta(seconds=30)),
}
token_secret = secrets.token_hex()
encoded_token = jwt.encode(claims=raw_token, key=token_secret, algorithm="HS256")
encoded_token = jwt.encode(payload=raw_token, key=token_secret, algorithm="HS256")
token = Token.decode(encoded_token=encoded_token, secret=token_secret, algorithm="HS256")
assert token.extras == {}

0 comments on commit 07a69c8

Please sign in to comment.