summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormontezdesousa <79287829+montezdesousa@users.noreply.github.com>2024-05-14 14:19:23 +0100
committerGitHub <noreply@github.com>2024-05-14 13:19:23 +0000
commit07693784fb4222c3c174e8004876daad40787ee6 (patch)
tree1dc092d5a92edb0e5afbacaf3242de112a7a8215
parent88cdd75a6d14f3f0143c5b8dcc94417c0968b02d (diff)
[BugFix] - Replace python-jose by PyJWT (#6407)
* fix: replace python-jose by PyJWT * add unit test * add unit test --------- Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com>
-rw-r--r--openbb_platform/core/openbb_core/app/service/hub_service.py10
-rw-r--r--openbb_platform/core/poetry.lock84
-rw-r--r--openbb_platform/core/pyproject.toml2
-rw-r--r--openbb_platform/core/tests/app/service/test_hub_service.py34
4 files changed, 57 insertions, 73 deletions
diff --git a/openbb_platform/core/openbb_core/app/service/hub_service.py b/openbb_platform/core/openbb_core/app/service/hub_service.py
index 419eef955dd..3448eb8d52c 100644
--- a/openbb_platform/core/openbb_core/app/service/hub_service.py
+++ b/openbb_platform/core/openbb_core/app/service/hub_service.py
@@ -4,9 +4,7 @@ from typing import Optional
from warnings import warn
from fastapi import HTTPException
-from jose import JWTError
-from jose.exceptions import ExpiredSignatureError
-from jose.jwt import decode, get_unverified_header
+from jwt import ExpiredSignatureError, PyJWTError, decode, get_unverified_header
from openbb_core.app.model.abstract.error import OpenBBError
from openbb_core.app.model.credentials import Credentials
from openbb_core.app.model.hub.hub_session import HubSession
@@ -139,7 +137,7 @@ class HubService:
if not token:
raise OpenBBError("Platform personal access token not found.")
- self.check_token_expiration(token)
+ self._check_token_expiration(token)
response = post(
url=self._base_url + "/sdk/login",
@@ -259,7 +257,7 @@ class HubService:
return settings
@staticmethod
- def check_token_expiration(token: str) -> None:
+ def _check_token_expiration(token: str) -> None:
"""Check token expiration, raises exception if expired."""
try:
header_data = get_unverified_header(token)
@@ -271,5 +269,5 @@ class HubService:
)
except ExpiredSignatureError as e:
raise OpenBBError("Platform personal access token expired.") from e
- except JWTError as e:
+ except PyJWTError as e:
raise OpenBBError("Failed to decode Platform token.") from e
diff --git a/openbb_platform/core/poetry.lock b/openbb_platform/core/poetry.lock
index 80094cd46e1..44a2f785be9 100644
--- a/openbb_platform/core/poetry.lock
+++ b/openbb_platform/core/poetry.lock
@@ -322,24 +322,6 @@ files = [
]
[[package]]
-name = "ecdsa"
-version = "0.18.0"
-description = "ECDSA cryptographic signature library (pure python)"
-optional = false
-python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
-files = [
- {file = "ecdsa-0.18.0-py2.py3-none-any.whl", hash = "sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd"},
- {file = "ecdsa-0.18.0.tar.gz", hash = "sha256:190348041559e21b22a1d65cee485282ca11a6f81d503fddb84d5017e9ed1e49"},
-]
-
-[package.dependencies]
-six = ">=1.9.0"
-
-[package.extras]
-gmpy = ["gmpy"]
-gmpy2 = ["gmpy2"]
-
-[[package]]
name = "exceptiongroup"
version = "1.2.0"
description = "Backport of PEP 654 (exception groups)"
@@ -841,17 +823,6 @@ sentry = ["django", "sentry-sdk"]
test = ["coverage", "flake8", "freezegun (==0.3.15)", "mock (>=2.0.0)", "pylint", "pytest", "pytest-timeout"]
[[package]]
-name = "pyasn1"
-version = "0.5.1"
-description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)"
-optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
-files = [
- {file = "pyasn1-0.5.1-py2.py3-none-any.whl", hash = "sha256:4439847c58d40b1d0a573d07e3856e95333f1976294494c325775aeca506eb58"},
- {file = "pyasn1-0.5.1.tar.gz", hash = "sha256:6d391a96e59b23130a5cfa74d6fd7f388dbbe26cc8f1edf39fdddf08d9d6676c"},
-]
-
-[[package]]
name = "pydantic"
version = "2.6.4"
description = "Data validation using Python type hints"
@@ -962,6 +933,23 @@ files = [
typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
[[package]]
+name = "pyjwt"
+version = "2.8.0"
+description = "JSON Web Token implementation in Python"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "PyJWT-2.8.0-py3-none-any.whl", hash = "sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320"},
+ {file = "PyJWT-2.8.0.tar.gz", hash = "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de"},
+]
+
+[package.extras]
+crypto = ["cryptography (>=3.4.0)"]
+dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"]
+docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"]
+tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"]
+
+[[package]]
name = "pytest"
version = "7.4.4"
description = "pytest: simple powerful testing with Python"
@@ -1060,27 +1048,6 @@ files = [
cli = ["click (>=5.0)"]
[[package]]
-name = "python-jose"
-version = "3.3.0"
-description = "JOSE implementation in Python"
-optional = false
-python-versions = "*"
-files = [
- {file = "python-jose-3.3.0.tar.gz", hash = "sha256:55779b5e6ad599c6336191246e95eb2293a9ddebd555f796a65f838f07e5d78a"},
- {file = "python_jose-3.3.0-py2.py3-none-any.whl", hash = "sha256:9b1376b023f8b298536eedd47ae1089bcdb848f1535ab30555cd92002d78923a"},
-]
-
-[package.dependencies]
-ecdsa = "!=0.15"
-pyasn1 = "*"
-rsa = "*"
-
-[package.extras]
-cryptography = ["cryptography (>=3.4.0)"]
-pycrypto = ["pyasn1", "pycrypto (>=2.6.0,<2.7.0)"]
-pycryptodome = ["pyasn1", "pycryptodome (>=3.3.1,<4.0.0)"]
-
-[[package]]
name = "python-multipart"
version = "0.0.7"
description = "A streaming multipart parser for Python"
@@ -1130,7 +1097,6 @@ files = [
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
- {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
@@ -1187,20 +1153,6 @@ socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
[[package]]
-name = "rsa"
-version = "4.9"
-description = "Pure-Python RSA implementation"
-optional = false
-python-versions = ">=3.6,<4"
-files = [
- {file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"},
- {file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"},
-]
-
-[package.dependencies]
-pyasn1 = ">=0.1.3"
-
-[[package]]
name = "ruff"
version = "0.1.15"
description = "An extremely fast Python linter and code formatter, written in Rust."
@@ -1722,4 +1674,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p
[metadata]
lock-version = "2.0"
python-versions = "^3.8"
-content-hash = "c58b1fc15e472b1609a4194d44da6cd35fc78748cd0931a874bebf441fe8c8ba"
+content-hash = "3431ad81cc2788032dfa6b3b7b12d705da384ecc9c592c7663da3d36d885e021"
diff --git a/openbb_platform/core/pyproject.toml b/openbb_platform/core/pyproject.toml
index 2f6467930f7..4832836ca77 100644
--- a/openbb_platform/core/pyproject.toml
+++ b/openbb_platform/core/pyproject.toml
@@ -13,7 +13,6 @@ websockets = "^12.0"
pandas = ">=1.5.3"
html5lib = "^1.1"
fastapi = "^0.104.1"
-python-jose = "^3.3.0"
uuid7 = "^0.1.0"
posthog = "^3.3.1"
python-multipart = "^0.0.7"
@@ -23,6 +22,7 @@ importlib-metadata = "^6.8.0"
python-dotenv = "^1.0.0"
aiohttp = "^3.9.5"
ruff = "^0.1.6"
+pyjwt = "^2.8.0"
[tool.poetry.group.dev.dependencies]
pytest = "^7.0.0"
diff --git a/openbb_platform/core/tests/app/service/test_hub_service.py b/openbb_platform/core/tests/app/service/test_hub_service.py
index db2030d561e..37cab472d22 100644
--- a/openbb_platform/core/tests/app/service/test_hub_service.py
+++ b/openbb_platform/core/tests/app/service/test_hub_service.py
@@ -5,9 +5,11 @@
from pathlib import Path
+from time import time
from unittest.mock import MagicMock, patch
import pytest
+from jwt import encode
from openbb_core.app.service.hub_service import (
Credentials,
HubService,
@@ -308,3 +310,35 @@ def test_platform2hub():
assert user_settings.features_keys["API_FRED_KEY"] == "fred"
assert user_settings.features_keys["benzinga_api_key"] == "benzinga"
assert "some_api_key" not in user_settings.features_keys
+
+
+@pytest.mark.parametrize(
+ "token, message",
+ [
+ # valid
+ (
+ encode(
+ {"some": "payload", "exp": int(time()) + 100},
+ "secret",
+ algorithm="HS256",
+ ),
+ None,
+ ),
+ # expired
+ (
+ encode(
+ {"some": "payload", "exp": int(time())}, "secret", algorithm="HS256"
+ ),
+ "Platform personal access token expired.",
+ ),
+ # invalid
+ ("invalid_token", "Failed to decode Platform token."),
+ ],
+)
+def test__check_token_expiration(token, message):
+ """Test check token expiration function."""
+ if message:
+ with pytest.raises(OpenBBError, match=message):
+ HubService._check_token_expiration(token)
+ else:
+ HubService._check_token_expiration(token)