Skip to content

Commit

Permalink
[DOP-23149] Replace python-jose with authlib.jose
Browse files Browse the repository at this point in the history
  • Loading branch information
dolfinus committed Jan 9, 2025
1 parent 06df16e commit daee7bc
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 19 deletions.
20 changes: 11 additions & 9 deletions horizon/backend/utils/jwt.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
# SPDX-FileCopyrightText: 2023-2025 MTS PJSC
# SPDX-License-Identifier: Apache-2.0

from jose import ExpiredSignatureError, JWTError, jwt
from authlib.jose import JsonWebToken
from authlib.jose.errors import ExpiredTokenError, JoseError

from horizon.commons.exceptions import AuthorizationError


def sign_jwt(payload: dict, secret_key: str, security_algorithm: str) -> str:
jwt = JsonWebToken([security_algorithm])
return jwt.encode(
payload,
secret_key,
algorithm=security_algorithm,
)
header={"alg": security_algorithm},
payload=payload,
key=secret_key,
).decode("utf-8")


def decode_jwt(token: str, secret_key: str, security_algorithm: str) -> dict:
jwt = JsonWebToken([security_algorithm])
try:
result = jwt.decode(
token,
secret_key,
algorithms=[security_algorithm],
key=secret_key,
)
if "exp" not in result:
raise ExpiredSignatureError("Missing expiration time in token")
raise ExpiredTokenError("Missing expiration time in token")

return result
except JWTError as e:
except JoseError as e:
raise AuthorizationError("Invalid token") from e
5 changes: 3 additions & 2 deletions horizon/client/auth/access_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@

from __future__ import annotations

from authlib.jose import jwt
from authlib.jose.errors import ExpiredTokenError
from authlib.oauth2.auth import OAuth2Token as AuthlibToken
from jose import ExpiredSignatureError, jwt
from pydantic import AnyHttpUrl, BaseModel, validator
from typing_extensions import Literal

Expand Down Expand Up @@ -55,5 +56,5 @@ def fetch_token_kwargs(self, base_url: AnyHttpUrl) -> dict[str, str]:
def _validate_token(cls, value):
token_decoded = jwt.decode(value, key="NONE", options={"verify_signature": False})
if "exp" not in token_decoded:
raise ExpiredSignatureError("Missing expiration time in token")
raise ExpiredTokenError("Missing expiration time in token")
return value
8 changes: 4 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ backend = [
"pydantic-settings",
"devtools",
"passlib",
"authlib",
]
postgres = [
"asyncpg",
Expand Down
8 changes: 4 additions & 4 deletions tests/test_client/test_auth/test_access_token.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
from __future__ import annotations

import pytest
from jose import ExpiredSignatureError, JWTError
from authlib.jose.errors import ExpiredTokenError, JoseError

from horizon.client.auth import AccessToken

pytestmark = [pytest.mark.client_sync, pytest.mark.client]


def test_access_token_constructor_expired(access_token_expired: AccessToken):
with pytest.raises(ExpiredSignatureError):
with pytest.raises(ExpiredTokenError):
AccessToken(token=access_token_expired)


def test_access_token_constructor_no_expiration_time(access_token_no_expiration_time: AccessToken):
with pytest.raises(ExpiredSignatureError):
with pytest.raises(ExpiredTokenError):
AccessToken(token=access_token_no_expiration_time)


def test_access_token_constructor_malformed(access_token_malformed: AccessToken):
with pytest.raises(JWTError):
with pytest.raises(JoseError):
AccessToken(token=access_token_malformed)

0 comments on commit daee7bc

Please sign in to comment.