From 7dd08476c8b964171f20d36fec6bae8e53fd76bd Mon Sep 17 00:00:00 2001 From: Yasser Tahiri Date: Sun, 25 Jun 2023 00:07:14 +0400 Subject: [PATCH 1/7] =?UTF-8?q?=E2=9E=95=20update=20dependencies?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5a354c2a..47d34803 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,9 +46,9 @@ classifiers = [ ] dependencies = [ - "fastapi >=0.65.2,<0.99.0", + "fastapi >=0.65.2,<0.200.0", "pyjwt[crypto] >=2.6.0,<3.0.0", - "pydantic >=1.7.4,!=1.8,!=1.8.1,<2.0.0", + "pydantic >=2.0.3" ] dynamic = ["version"] From 27fbc8c0917839e4d717d2e48780ab5ee48023d8 Mon Sep 17 00:00:00 2001 From: Yasser Tahiri Date: Sun, 25 Jun 2023 00:21:28 +0400 Subject: [PATCH 2/7] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor=20`BaseSettin?= =?UTF-8?q?gs`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- authx/_internal/_session.py | 41 +++++++++++++++++++++++++++++++++++++ authx/config.py | 3 ++- authx/schema.py | 7 +++---- 3 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 authx/_internal/_session.py diff --git a/authx/_internal/_session.py b/authx/_internal/_session.py new file mode 100644 index 00000000..f2805033 --- /dev/null +++ b/authx/_internal/_session.py @@ -0,0 +1,41 @@ +from datetime import timedelta +from typing import Callable, Optional +from uuid import uuid4 + +from pydantic_settings import BaseSettings + + +def genSessionId() -> str: + return uuid4().hex + + +settings = {"sessionIdGenerator": genSessionId} + + +class Config(BaseSettings): + redisURL: str = "redis://localhost:6379/0" + settings: dict = settings + sessionIdName: str = "ssid" + expireTime: timedelta = timedelta(hours=6) + + def genSessionId(self) -> str: + return self.settings["sessionIdGenerator"]() + + +config = Config() + + +def basicConfig( + redisURL: Optional[str] = "", + sessionIdName: Optional[str] = "", + sessionIdGenerator: Optional[Callable[[], str]] = None, + expireTime: Optional[timedelta] = None, +): + if redisURL: + config.redisURL = redisURL + if sessionIdName: + config.sessionIdName = sessionIdName + if sessionIdGenerator: + config.settings["sessionIdGenerator"] = sessionIdGenerator + if expireTime: + config.expireTime = expireTime diff --git a/authx/config.py b/authx/config.py index 9f23b3ca..a302c8de 100644 --- a/authx/config.py +++ b/authx/config.py @@ -2,7 +2,8 @@ from typing import List, Optional, Sequence from jwt.algorithms import get_default_algorithms, requires_cryptography -from pydantic import BaseSettings, Field +from pydantic import Field +from pydantic_settings import BaseSettings from authx.exceptions import BadConfigurationError from authx.types import AlgorithmType, HTTPMethods, SameSitePolicy, StringOrSequence, TokenLocations diff --git a/authx/schema.py b/authx/schema.py index 862f1952..7a2b5b6b 100644 --- a/authx/schema.py +++ b/authx/schema.py @@ -2,7 +2,7 @@ from hmac import compare_digest from typing import Any, Dict, List, Optional, Sequence -from pydantic import BaseModel, Extra, Field, ValidationError, validator +from pydantic import BaseModel, ConfigDict, Field, ValidationError, validator from authx._internal._utils import get_now, get_now_ts, get_uuid from authx.exceptions import ( @@ -18,6 +18,8 @@ class TokenPayload(BaseModel): + model_config = ConfigDict(extra='allow') + jti: Optional[str] = Field(default_factory=get_uuid) iss: Optional[str] = None sub: Optional[str] = None @@ -30,9 +32,6 @@ class TokenPayload(BaseModel): scopes: Optional[List[str]] = None fresh: bool = False - class Config: - extra = Extra.allow - @property def _additional_fields(self): return set(self.__dict__) - set(self.__fields__) From e0c36e52b2d755db9f5e5b11509a72770ab8585d Mon Sep 17 00:00:00 2001 From: Yasser Tahiri Date: Sun, 25 Jun 2023 00:28:19 +0400 Subject: [PATCH 3/7] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20remove=20deprecated=20?= =?UTF-8?q?=20`parse=5Fobj`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- authx/schema.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/authx/schema.py b/authx/schema.py index 7a2b5b6b..0de95645 100644 --- a/authx/schema.py +++ b/authx/schema.py @@ -108,11 +108,13 @@ def decode( cls, token: str, key: str, - algorithms: Sequence[AlgorithmType] = ["HS256"], + algorithms: Sequence[AlgorithmType] = None, audience: Optional[StringOrSequence] = None, issuer: Optional[str] = None, verify: bool = True, ) -> "TokenPayload": + if algorithms is None: + algorithms = ["HS256"] payload = decode_token( token=token, key=key, @@ -121,7 +123,7 @@ def decode( issuer=issuer, verify=verify, ) - return cls.parse_obj(payload) + return cls.model_validate(payload) class RequestToken(BaseModel): @@ -133,7 +135,7 @@ class RequestToken(BaseModel): def verify( self, key: str, - algorithms: Sequence[AlgorithmType] = ["HS256"], + algorithms: Sequence[AlgorithmType] = None, audience: Optional[StringOrSequence] = None, issuer: Optional[str] = None, verify_jwt: bool = True, @@ -141,6 +143,8 @@ def verify( verify_csrf: bool = True, verify_fresh: bool = False, ) -> TokenPayload: + if algorithms is None: + algorithms = ["HS256"] # JWT Base Verification try: decoded_token = decode_token( @@ -152,7 +156,7 @@ def verify( issuer=issuer, ) # Parse payload - payload = TokenPayload.parse_obj(decoded_token) + payload = TokenPayload.model_validate(decoded_token) except JWTDecodeError as e: raise JWTDecodeError(*e.args) from e except ValidationError as e: From cc599cb27b7bc42ca583ff11236f679142697247 Mon Sep 17 00:00:00 2001 From: Yasser Tahiri Date: Sun, 25 Jun 2023 01:19:50 +0400 Subject: [PATCH 4/7] =?UTF-8?q?=F0=9F=90=9B=20fix=20argument=20issue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- authx/schema.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/authx/schema.py b/authx/schema.py index 0de95645..2cea37b3 100644 --- a/authx/schema.py +++ b/authx/schema.py @@ -38,7 +38,7 @@ def _additional_fields(self): @property def extra_dict(self): - return self.dict(include=self._additional_fields) + return self.model_dump(include=self._additional_fields) @property def issued_at(self) -> datetime.datetime: @@ -108,13 +108,11 @@ def decode( cls, token: str, key: str, - algorithms: Sequence[AlgorithmType] = None, + algorithms: Sequence[AlgorithmType] = ["HS256"], audience: Optional[StringOrSequence] = None, issuer: Optional[str] = None, verify: bool = True, ) -> "TokenPayload": - if algorithms is None: - algorithms = ["HS256"] payload = decode_token( token=token, key=key, @@ -135,7 +133,7 @@ class RequestToken(BaseModel): def verify( self, key: str, - algorithms: Sequence[AlgorithmType] = None, + algorithms: Sequence[AlgorithmType] = ["HS256"], audience: Optional[StringOrSequence] = None, issuer: Optional[str] = None, verify_jwt: bool = True, @@ -143,8 +141,6 @@ def verify( verify_csrf: bool = True, verify_fresh: bool = False, ) -> TokenPayload: - if algorithms is None: - algorithms = ["HS256"] # JWT Base Verification try: decoded_token = decode_token( From 23c0d6c9a3938b1ea5302f97a304b3095929c09c Mon Sep 17 00:00:00 2001 From: Yasser Tahiri Date: Sun, 25 Jun 2023 01:25:41 +0400 Subject: [PATCH 5/7] =?UTF-8?q?=F0=9F=91=B7=20Integrate=20`mypy`=20in=20CI?= =?UTF-8?q?=20(Thanks=20Doctor)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d306ce76..b46cf6d4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,6 +25,8 @@ jobs: - uses: pre-commit/action@v3.0.0 with: extra_args: --all-files --verbose + - name: Mypy check + run: bash scripts/mypy.sh test: name: test on python ${{ matrix.python-version }} runs-on: ubuntu-latest From 6116744c6fba9b19bba8139535bbcfa0021c275b Mon Sep 17 00:00:00 2001 From: Yasser Tahiri Date: Sun, 15 Oct 2023 04:04:52 +0100 Subject: [PATCH 6/7] fix dependencies --- requirements/pyproject.txt | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/requirements/pyproject.txt b/requirements/pyproject.txt index 4a31b23f..87b63bb1 100644 --- a/requirements/pyproject.txt +++ b/requirements/pyproject.txt @@ -4,22 +4,28 @@ # # pip-compile --extra=all --output-file=requirements/pyproject.txt pyproject.toml # -anyio==4.0.0 - # via starlette +annotated-types==0.6.0 + # via pydantic +anyio==3.7.1 + # via + # fastapi + # starlette cffi==1.16.0 # via cryptography cryptography==41.0.4 # via pyjwt -fastapi==0.98.0 +fastapi==0.103.2 # via authx (pyproject.toml) idna==3.4 # via anyio pycparser==2.21 # via cffi -pydantic==1.10.13 +pydantic==2.4.2 # via # authx (pyproject.toml) # fastapi +pydantic-core==2.10.1 + # via pydantic pyjwt[crypto]==2.8.0 # via authx (pyproject.toml) sniffio==1.3.0 @@ -27,4 +33,7 @@ sniffio==1.3.0 starlette==0.27.0 # via fastapi typing-extensions==4.8.0 - # via pydantic + # via + # fastapi + # pydantic + # pydantic-core From fe8d036a1c605d6da548ab65003732f7af50c422 Mon Sep 17 00:00:00 2001 From: Capi Etheriel Date: Tue, 28 Nov 2023 19:54:05 -0300 Subject: [PATCH 7/7] further fix dependencies (#496) --- requirements/docs.txt | 16 ++++++++-------- requirements/linting.txt | 12 ++++++------ requirements/optional.txt | 2 +- requirements/pyproject.txt | 8 +++++--- requirements/testing.in | 3 ++- requirements/testing.txt | 31 ++++++++++++++++++------------- scripts/requirements.sh | 0 7 files changed, 40 insertions(+), 32 deletions(-) mode change 100644 => 100755 scripts/requirements.sh diff --git a/requirements/docs.txt b/requirements/docs.txt index 7b04c838..7a53b48d 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -4,13 +4,13 @@ # # pip-compile --output-file=requirements/docs.txt requirements/docs.in # -babel==2.13.0 +babel==2.13.1 # via mkdocs-material beautifulsoup4==4.12.2 # via mkdocs-mermaid2-plugin certifi==2023.7.22 # via requests -charset-normalizer==3.3.0 +charset-normalizer==3.3.2 # via requests click==8.1.7 # via @@ -36,9 +36,9 @@ jinja2==3.1.2 # -r requirements/docs.in # mkdocs # mkdocs-material -jsbeautifier==1.14.9 +jsbeautifier==1.14.11 # via mkdocs-mermaid2-plugin -markdown==3.5 +markdown==3.5.1 # via # markdown-include # mdx-include @@ -63,9 +63,9 @@ mkdocs==1.5.3 # mkdocs-mermaid2-plugin mkdocs-markdownextradata-plugin==0.2.5 # via -r requirements/docs.in -mkdocs-material==9.4.6 +mkdocs-material==9.4.8 # via -r requirements/docs.in -mkdocs-material-extensions==1.2 +mkdocs-material-extensions==1.3 # via mkdocs-material mkdocs-mermaid2-plugin==1.1.1 # via -r requirements/docs.in @@ -81,7 +81,7 @@ pygments==2.16.1 # via # mkdocs-material # rich -pymdown-extensions==10.3 +pymdown-extensions==10.3.1 # via # -r requirements/docs.in # mkdocs-material @@ -123,7 +123,7 @@ typer[all]==0.7.0 # typer-cli typer-cli==0.0.13 # via -r requirements/docs.in -urllib3==2.0.6 +urllib3==2.0.7 # via requests watchdog==3.0.0 # via mkdocs diff --git a/requirements/linting.txt b/requirements/linting.txt index b6cc148d..27ab40cf 100644 --- a/requirements/linting.txt +++ b/requirements/linting.txt @@ -4,7 +4,7 @@ # # pip-compile --output-file=requirements/linting.txt requirements/linting.in # -black==23.9.1 +black==23.10.1 # via -r requirements/linting.in cfgv==3.4.0 # via pre-commit @@ -12,11 +12,11 @@ click==8.1.7 # via black distlib==0.3.7 # via virtualenv -filelock==3.12.4 +filelock==3.13.1 # via virtualenv -identify==2.5.30 +identify==2.5.31 # via pre-commit -mypy==1.6.0 +mypy==1.6.1 # via -r requirements/linting.in mypy-extensions==1.0.0 # via @@ -38,13 +38,13 @@ pyupgrade==3.15.0 # via -r requirements/linting.in pyyaml==6.0.1 # via pre-commit -ruff==0.0.292 +ruff==0.1.4 # via -r requirements/linting.in tokenize-rt==5.2.0 # via pyupgrade typing-extensions==4.8.0 # via mypy -virtualenv==20.24.5 +virtualenv==20.24.6 # via pre-commit # The following packages are considered to be unsafe in a requirements file: diff --git a/requirements/optional.txt b/requirements/optional.txt index 7640c11a..aec1b38f 100644 --- a/requirements/optional.txt +++ b/requirements/optional.txt @@ -8,7 +8,7 @@ async-timeout==4.0.3 # via redis ecdsa==0.18.0 # via python-jose -prometheus-client==0.17.1 +prometheus-client==0.18.0 # via -r requirements/optional.in pyasn1==0.5.0 # via diff --git a/requirements/pyproject.txt b/requirements/pyproject.txt index 87b63bb1..5dcd55ec 100644 --- a/requirements/pyproject.txt +++ b/requirements/pyproject.txt @@ -12,9 +12,9 @@ anyio==3.7.1 # starlette cffi==1.16.0 # via cryptography -cryptography==41.0.4 +cryptography==41.0.5 # via pyjwt -fastapi==0.103.2 +fastapi==0.104.1 # via authx (pyproject.toml) idna==3.4 # via anyio @@ -27,7 +27,9 @@ pydantic==2.4.2 pydantic-core==2.10.1 # via pydantic pyjwt[crypto]==2.8.0 - # via authx (pyproject.toml) + # via + # authx (pyproject.toml) + # pyjwt sniffio==1.3.0 # via anyio starlette==0.27.0 diff --git a/requirements/testing.in b/requirements/testing.in index 5660ba07..f7b1620f 100644 --- a/requirements/testing.in +++ b/requirements/testing.in @@ -2,10 +2,11 @@ pytest pytest-asyncio pytest-cov httpx +anyio<4 requests SQLAlchemy itsdangerous websockets uvicorn uvloop -freezegun \ No newline at end of file +freezegun diff --git a/requirements/testing.txt b/requirements/testing.txt index 495ee712..ec20d132 100644 --- a/requirements/testing.txt +++ b/requirements/testing.txt @@ -4,28 +4,34 @@ # # pip-compile --output-file=requirements/testing.txt requirements/testing.in # -anyio==4.0.0 - # via httpcore +anyio==3.7.1 + # via + # -r requirements/testing.in + # httpx certifi==2023.7.22 # via # httpcore # httpx # requests -charset-normalizer==3.3.0 +charset-normalizer==3.3.2 # via requests click==8.1.7 # via uvicorn coverage[toml]==7.3.2 - # via pytest-cov + # via + # coverage + # pytest-cov freezegun==1.2.2 # via -r requirements/testing.in +greenlet==3.0.1 + # via sqlalchemy h11==0.14.0 # via # httpcore # uvicorn -httpcore==0.18.0 +httpcore==1.0.1 # via httpx -httpx==0.25.0 +httpx==0.25.1 # via -r requirements/testing.in idna==3.4 # via @@ -40,7 +46,7 @@ packaging==23.2 # via pytest pluggy==1.3.0 # via pytest -pytest==7.4.2 +pytest==7.4.3 # via # -r requirements/testing.in # pytest-asyncio @@ -58,17 +64,16 @@ six==1.16.0 sniffio==1.3.0 # via # anyio - # httpcore # httpx -sqlalchemy==2.0.22 +sqlalchemy==2.0.23 # via -r requirements/testing.in typing-extensions==4.8.0 # via sqlalchemy -urllib3==2.0.6 +urllib3==2.0.7 # via requests -uvicorn==0.23.2 +uvicorn==0.24.0.post1 # via -r requirements/testing.in -uvloop==0.18.0 +uvloop==0.19.0 # via -r requirements/testing.in -websockets==11.0.3 +websockets==12.0 # via -r requirements/testing.in diff --git a/scripts/requirements.sh b/scripts/requirements.sh old mode 100644 new mode 100755