usso 0.24.18__tar.gz → 0.25.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. {usso-0.24.18/src/usso.egg-info → usso-0.25.0}/PKG-INFO +1 -2
  2. {usso-0.24.18 → usso-0.25.0}/pyproject.toml +1 -2
  3. {usso-0.24.18 → usso-0.25.0}/src/usso/async_session.py +1 -2
  4. usso-0.25.0/src/usso/core.py +174 -0
  5. usso-0.25.0/src/usso/fastapi/auth_middleware.py +87 -0
  6. {usso-0.24.18 → usso-0.25.0}/src/usso/session.py +1 -1
  7. {usso-0.24.18 → usso-0.25.0/src/usso.egg-info}/PKG-INFO +1 -2
  8. {usso-0.24.18 → usso-0.25.0}/src/usso.egg-info/requires.txt +0 -1
  9. usso-0.24.18/src/usso/core.py +0 -113
  10. usso-0.24.18/src/usso/fastapi/auth_middleware.py +0 -186
  11. {usso-0.24.18 → usso-0.25.0}/LICENSE.txt +0 -0
  12. {usso-0.24.18 → usso-0.25.0}/README.md +0 -0
  13. {usso-0.24.18 → usso-0.25.0}/setup.cfg +0 -0
  14. {usso-0.24.18 → usso-0.25.0}/src/usso/__init__.py +0 -0
  15. {usso-0.24.18 → usso-0.25.0}/src/usso/api.py +0 -0
  16. {usso-0.24.18 → usso-0.25.0}/src/usso/async_api.py +0 -0
  17. {usso-0.24.18 → usso-0.25.0}/src/usso/b64tools.py +0 -0
  18. {usso-0.24.18 → usso-0.25.0}/src/usso/django/__init__.py +0 -0
  19. {usso-0.24.18 → usso-0.25.0}/src/usso/django/middleware.py +0 -0
  20. {usso-0.24.18 → usso-0.25.0}/src/usso/exceptions.py +0 -0
  21. {usso-0.24.18 → usso-0.25.0}/src/usso/fastapi/__init__.py +0 -0
  22. {usso-0.24.18 → usso-0.25.0}/src/usso/fastapi/integration.py +0 -0
  23. {usso-0.24.18 → usso-0.25.0}/src/usso/package_data.dat +0 -0
  24. {usso-0.24.18 → usso-0.25.0}/src/usso.egg-info/SOURCES.txt +0 -0
  25. {usso-0.24.18 → usso-0.25.0}/src/usso.egg-info/dependency_links.txt +0 -0
  26. {usso-0.24.18 → usso-0.25.0}/src/usso.egg-info/entry_points.txt +0 -0
  27. {usso-0.24.18 → usso-0.25.0}/src/usso.egg-info/top_level.txt +0 -0
  28. {usso-0.24.18 → usso-0.25.0}/tests/test_api.py +0 -0
  29. {usso-0.24.18 → usso-0.25.0}/tests/test_core.py +0 -0
  30. {usso-0.24.18 → usso-0.25.0}/tests/test_simple.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: usso
3
- Version: 0.24.18
3
+ Version: 0.25.0
4
4
  Summary: A plug-and-play client for integrating universal single sign-on (SSO) with Python frameworks, enabling secure and seamless authentication across microservices.
5
5
  Author-email: Mahdi Kiani <mahdikiany@gmail.com>
6
6
  Maintainer-email: Mahdi Kiani <mahdikiany@gmail.com>
@@ -42,7 +42,6 @@ Classifier: Programming Language :: Python :: 3 :: Only
42
42
  Requires-Python: >=3.9
43
43
  Description-Content-Type: text/markdown
44
44
  License-File: LICENSE.txt
45
- Requires-Dist: peppercorn
46
45
  Requires-Dist: pydantic>=2
47
46
  Requires-Dist: requests>=2.26.0
48
47
  Requires-Dist: pyjwt[crypto]
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "usso"
7
- version = "0.24.18"
7
+ version = "0.25.0"
8
8
  description = "A plug-and-play client for integrating universal single sign-on (SSO) with Python frameworks, enabling secure and seamless authentication across microservices."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -28,7 +28,6 @@ classifiers = [
28
28
  "Programming Language :: Python :: 3 :: Only",
29
29
  ]
30
30
  dependencies = [
31
- "peppercorn", # Example main dependency
32
31
  "pydantic>=2",
33
32
  "requests>=2.26.0",
34
33
  "pyjwt[crypto]",
@@ -2,7 +2,6 @@ from contextlib import asynccontextmanager
2
2
  from datetime import datetime, timedelta
3
3
 
4
4
  import aiohttp
5
- from fastapi import params
6
5
  import jwt
7
6
 
8
7
 
@@ -76,7 +75,7 @@ class AsyncUssoSession:
76
75
  if not self.access_token:
77
76
  # Get a new token if none exists or it has expired
78
77
  token_data = await self._refresh()
79
- self.access_token = token_data["access_token"]
78
+ self.access_token = token_data.get("access_token")
80
79
 
81
80
  # Update headers with the new access token
82
81
  if self.session:
@@ -0,0 +1,174 @@
1
+ import logging
2
+ import os
3
+ import uuid
4
+ from functools import lru_cache
5
+ from typing import Optional, Tuple
6
+
7
+ import cachetools.func
8
+ import jwt
9
+ from pydantic import BaseModel, model_validator
10
+ from singleton import Singleton
11
+
12
+ from . import b64tools
13
+ from .exceptions import USSOException
14
+
15
+ logger = logging.getLogger("usso")
16
+
17
+
18
+ class UserData(BaseModel):
19
+ user_id: str
20
+ workspace_id: str | None = None
21
+ workspace_ids: list[str] = []
22
+ token_type: str = "access"
23
+
24
+ email: str | None = None
25
+ phone: str | None = None
26
+ username: str | None = None
27
+
28
+ authentication_method: str | None = None
29
+ is_active: bool = False
30
+
31
+ jti: str | None = None
32
+ data: dict | None = None
33
+
34
+ token: str | None = None
35
+
36
+ @property
37
+ def uid(self) -> uuid.UUID:
38
+ user_id = self.user_id
39
+
40
+ if user_id.startswith("u_"):
41
+ user_id = user_id[2:]
42
+ if 22 <= len(user_id) <= 24:
43
+ user_id = b64tools.b64_decode_uuid(user_id)
44
+
45
+ return uuid.UUID(user_id)
46
+
47
+ @property
48
+ def b64id(self) -> uuid.UUID:
49
+ return b64tools.b64_encode_uuid_strip(self.uid)
50
+
51
+
52
+ def get_authorization_scheme_param(
53
+ authorization_header_value: str | None,
54
+ ) -> tuple[str, str]:
55
+ if not authorization_header_value:
56
+ return "", ""
57
+ scheme, _, param = authorization_header_value.partition(" ")
58
+ return scheme, param
59
+
60
+
61
+ def decode_token(key, token: str, algorithms=["RS256"], **kwargs) -> dict:
62
+ try:
63
+ decoded = jwt.decode(token, key, algorithms=algorithms)
64
+ decoded["token"] = token
65
+ return UserData(**decoded)
66
+ except jwt.exceptions.ExpiredSignatureError:
67
+ if kwargs.get("raise_exception", True):
68
+ raise USSOException(status_code=401, error="expired_signature")
69
+ except jwt.exceptions.InvalidSignatureError:
70
+ if kwargs.get("raise_exception", True):
71
+ raise USSOException(status_code=401, error="invalid_signature")
72
+ except jwt.exceptions.InvalidAlgorithmError:
73
+ if kwargs.get("raise_exception", True):
74
+ raise USSOException(status_code=401, error="invalid_algorithm")
75
+ except jwt.exceptions.InvalidIssuedAtError:
76
+ if kwargs.get("raise_exception", True):
77
+ raise USSOException(status_code=401, error="invalid_issued_at")
78
+ except jwt.exceptions.InvalidTokenError:
79
+ if kwargs.get("raise_exception", True):
80
+ raise USSOException(status_code=401, error="invalid_token")
81
+ except jwt.exceptions.InvalidKeyError:
82
+ if kwargs.get("raise_exception", True):
83
+ raise USSOException(status_code=401, error="invalid_key")
84
+ except USSOException as e:
85
+ if kwargs.get("raise_exception", True):
86
+ raise e
87
+ except Exception as e:
88
+ if kwargs.get("raise_exception", True):
89
+ raise USSOException(status_code=401, error="error", message=str(e))
90
+ logger.error(e)
91
+
92
+
93
+ @lru_cache
94
+ def get_jwk_keys(jwk_url: str) -> jwt.PyJWKClient:
95
+ return jwt.PyJWKClient(jwk_url, headers={"User-Agent": "usso-python"})
96
+
97
+
98
+ def decode_token_jwk(jwk_url: str, token: str, **kwargs) -> UserData | None:
99
+ """Return the user associated with a token value."""
100
+ try:
101
+ jwk_client = get_jwk_keys(jwk_url)
102
+ signing_key = jwk_client.get_signing_key_from_jwt(token)
103
+ return decode_token(signing_key.key, token, **kwargs)
104
+ except USSOException as e:
105
+ if kwargs.get("raise_exception", True):
106
+ raise e
107
+ logger.error(e)
108
+ except Exception as e:
109
+ if kwargs.get("raise_exception", True):
110
+ raise USSOException(
111
+ status_code=401,
112
+ error="error",
113
+ message=str(e),
114
+ )
115
+ logger.error(e)
116
+
117
+
118
+ class JWTConfig(BaseModel):
119
+ jwk_url: str | None = None
120
+ secret: str | None = None
121
+ type: str = "RS256"
122
+ header: dict[str, str] = {"type": "Cookie", "name": "usso_access_token"}
123
+
124
+ def __hash__(self):
125
+ return hash(self.model_dump_json())
126
+
127
+ @model_validator(mode="before")
128
+ def validate_secret(cls, data: dict):
129
+ if not data.get("jwk_url") and not data.get("secret"):
130
+ raise ValueError("Either jwk_url or secret must be provided")
131
+ return data
132
+
133
+ @classmethod
134
+ @cachetools.func.ttl_cache(maxsize=128, ttl=10 * 60)
135
+ def get_jwk_keys(cls, jwk_url):
136
+ return get_jwk_keys(jwk_url)
137
+
138
+ @cachetools.func.ttl_cache(maxsize=128, ttl=10 * 60)
139
+ def decode(self, token: str):
140
+ if self.jwk_url:
141
+ return decode_token_jwk(self.jwk_url, token)
142
+ return decode_token(self.secret, token, algorithms=[self.type])
143
+
144
+
145
+ class Usso(metaclass=Singleton):
146
+ def __init__(self, jwks_url: str | None = None):
147
+ if jwks_url is None:
148
+ jwks_url = os.getenv("USSO_JWKS_URL")
149
+ self.jwks_url = jwks_url
150
+
151
+ def get_jwk_keys(self):
152
+ return get_jwk_keys(self.jwks_url)
153
+
154
+ def get_authorization_scheme_param(
155
+ self, authorization_header_value: Optional[str]
156
+ ) -> Tuple[str, str]:
157
+ return get_authorization_scheme_param(authorization_header_value)
158
+
159
+ def user_data_from_token(self, token: str, **kwargs) -> UserData | None:
160
+ """Return the user associated with a token value."""
161
+ user_data = decode_token_jwk(self.jwks_url, token, **kwargs)
162
+ if user_data.token_type.lower() != kwargs.get("token_type", "access"):
163
+ raise USSOException(status_code=401, error="invalid_token_type")
164
+ return user_data
165
+
166
+ def user_data_from_token_none(self, token: str, **kwargs) -> UserData | None:
167
+ try:
168
+ return self.user_data_from_token(token, **kwargs)
169
+ except USSOException:
170
+ # logger.error(str(e))
171
+ return None
172
+ except Exception:
173
+ # logger.error(str(e))
174
+ return None
@@ -0,0 +1,87 @@
1
+ import json
2
+ import logging
3
+ import os
4
+
5
+ from fastapi import Request, WebSocket
6
+ from starlette.status import HTTP_401_UNAUTHORIZED
7
+
8
+ from usso.exceptions import USSOException
9
+
10
+ from ..core import JWTConfig, UserData
11
+ from .integration import get_request_token
12
+
13
+ logger = logging.getLogger("usso")
14
+
15
+
16
+ class Usso:
17
+
18
+ def __init__(
19
+ self,
20
+ jwt_config: (
21
+ str | dict | JWTConfig | list[str] | list[dict] | list[JWTConfig] | None
22
+ ) = None,
23
+ ):
24
+ if jwt_config is None:
25
+ self.jwk_url = os.getenv("USSO_JWK_URL")
26
+ self.jwt_configs = [JWTConfig(jwk_url=self.jwk_url)]
27
+ return
28
+
29
+ def _get_config(jwt_config):
30
+ if isinstance(jwt_config, str):
31
+ jwt_config = json.loads(jwt_config)
32
+ if isinstance(jwt_config, dict):
33
+ jwt_config = JWTConfig(**jwt_config)
34
+ return jwt_config
35
+
36
+ if isinstance(jwt_config, str | dict | JWTConfig):
37
+ jwt_config = [_get_config(jwt_config)]
38
+ elif isinstance(jwt_config, list):
39
+ jwt_config = [_get_config(j) for j in jwt_config]
40
+
41
+ # self.jwk_url = jwt_config
42
+ self.jwt_configs = jwt_config
43
+
44
+ def user_data_from_token(self, token: str, **kwargs) -> UserData | None:
45
+ """Return the user associated with a token value."""
46
+ exp = None
47
+ for jwk_config in self.jwt_configs:
48
+ try:
49
+ return jwk_config.decode(token)
50
+ except USSOException as e:
51
+ exp = e
52
+
53
+ if kwargs.get("raise_exception", True):
54
+ if exp:
55
+ raise exp
56
+ raise USSOException(
57
+ status_code=HTTP_401_UNAUTHORIZED,
58
+ error="unauthorized",
59
+ )
60
+
61
+ async def jwt_access_security(self, request: Request, **kwargs) -> UserData | None:
62
+ """Return the user associated with a token value."""
63
+ token = get_request_token(request)
64
+ if token:
65
+ return self.user_data_from_token(token)
66
+
67
+ if kwargs.get("raise_exception", True):
68
+ raise USSOException(
69
+ status_code=HTTP_401_UNAUTHORIZED,
70
+ error="unauthorized",
71
+ )
72
+ return None
73
+
74
+ async def jwt_access_security_ws(
75
+ self, websocket: WebSocket, **kwargs
76
+ ) -> UserData | None:
77
+ """Return the user associated with a token value."""
78
+ token = get_request_token(websocket)
79
+ if token:
80
+ return self.user_data_from_token(token)
81
+
82
+ if kwargs.get("raise_exception", True):
83
+ raise USSOException(
84
+ status_code=HTTP_401_UNAUTHORIZED,
85
+ error="unauthorized",
86
+ )
87
+ return None
@@ -69,7 +69,7 @@ class UssoSession:
69
69
  if exp < datetime.now():
70
70
  self.access_token = None
71
71
  if not self.access_token:
72
- self.access_token = self._refresh()["access_token"]
72
+ self.access_token = self._refresh().get("access_token")
73
73
  self.session.headers.update(
74
74
  {"Authorization": f"Bearer {self.access_token}"}
75
75
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: usso
3
- Version: 0.24.18
3
+ Version: 0.25.0
4
4
  Summary: A plug-and-play client for integrating universal single sign-on (SSO) with Python frameworks, enabling secure and seamless authentication across microservices.
5
5
  Author-email: Mahdi Kiani <mahdikiany@gmail.com>
6
6
  Maintainer-email: Mahdi Kiani <mahdikiany@gmail.com>
@@ -42,7 +42,6 @@ Classifier: Programming Language :: Python :: 3 :: Only
42
42
  Requires-Python: >=3.9
43
43
  Description-Content-Type: text/markdown
44
44
  License-File: LICENSE.txt
45
- Requires-Dist: peppercorn
46
45
  Requires-Dist: pydantic>=2
47
46
  Requires-Dist: requests>=2.26.0
48
47
  Requires-Dist: pyjwt[crypto]
@@ -1,4 +1,3 @@
1
- peppercorn
2
1
  pydantic>=2
3
2
  requests>=2.26.0
4
3
  pyjwt[crypto]
@@ -1,113 +0,0 @@
1
- import logging
2
- import os
3
- import uuid
4
- from functools import lru_cache
5
- from typing import Optional, Tuple
6
-
7
- import jwt
8
- from pydantic import BaseModel
9
- from singleton import Singleton
10
-
11
- from . import b64tools
12
- from .exceptions import USSOException
13
-
14
- logger = logging.getLogger("usso")
15
-
16
-
17
- class UserData(BaseModel):
18
- user_id: str
19
- email: str | None = None
20
- phone: str | None = None
21
- authentication_method: str | None = None
22
- is_active: bool = False
23
- jti: str | None = None
24
- data: dict | None = None
25
- token: str | None = None
26
-
27
- @property
28
- def uid(self) -> uuid.UUID:
29
- user_id = self.user_id
30
-
31
- if user_id.startswith("u_"):
32
- user_id = user_id[2:]
33
- if 22 <= len(user_id) <= 24:
34
- user_id = b64tools.b64_decode_uuid(user_id)
35
-
36
- return uuid.UUID(user_id)
37
-
38
- @property
39
- def b64id(self) -> uuid.UUID:
40
- return b64tools.b64_encode_uuid_strip(self.uid)
41
-
42
-
43
- class Usso(metaclass=Singleton):
44
- def __init__(self, jwks_url: str | None = None):
45
- if jwks_url is None:
46
- jwks_url = os.getenv("USSO_JWKS_URL")
47
- self.jwks_url = jwks_url
48
-
49
- @lru_cache
50
- def get_jwks_keys(self):
51
- return jwt.PyJWKClient(
52
- self.jwks_url,
53
- headers={
54
- "User-Agent": "usso-python",
55
- },
56
- )
57
-
58
- def get_authorization_scheme_param(
59
- self,
60
- authorization_header_value: Optional[str],
61
- ) -> Tuple[str, str]:
62
- if not authorization_header_value:
63
- return "", ""
64
- scheme, _, param = authorization_header_value.partition(" ")
65
- return scheme, param
66
-
67
- def decode_token(self, key, token: str, **kwargs) -> dict:
68
- try:
69
- decoded = jwt.decode(token, key, algorithms=["RS256"])
70
- if decoded["token_type"] != "access":
71
- raise USSOException(status_code=401, error="invalid_token_type")
72
- decoded["token"] = token
73
- return UserData(**decoded)
74
- except jwt.exceptions.ExpiredSignatureError:
75
- if kwargs.get("raise_exception", True):
76
- raise USSOException(status_code=401, error="expired_signature")
77
- except jwt.exceptions.InvalidSignatureError:
78
- if kwargs.get("raise_exception", True):
79
- raise USSOException(status_code=401, error="invalid_signature")
80
- except jwt.exceptions.InvalidAlgorithmError:
81
- if kwargs.get("raise_exception", True):
82
- raise USSOException(status_code=401, error="invalid_algorithm")
83
- except jwt.exceptions.InvalidIssuedAtError:
84
- if kwargs.get("raise_exception", True):
85
- raise USSOException(status_code=401, error="invalid_issued_at")
86
- except jwt.exceptions.InvalidTokenError:
87
- if kwargs.get("raise_exception", True):
88
- raise USSOException(status_code=401, error="invalid_token")
89
- except jwt.exceptions.InvalidKeyError:
90
- if kwargs.get("raise_exception", True):
91
- raise USSOException(status_code=401, error="invalid_key")
92
- except USSOException as e:
93
- if kwargs.get("raise_exception", True):
94
- raise e
95
- except Exception as e:
96
- if kwargs.get("raise_exception", True):
97
- raise USSOException(status_code=401, error="error", message=str(e))
98
- logger.error(e)
99
-
100
- def user_data_from_token(self, token: str, **kwargs) -> UserData | None:
101
- """Return the user associated with a token value."""
102
- try:
103
- jwks_client = self.get_jwks_keys()
104
- signing_key = jwks_client.get_signing_key_from_jwt(token)
105
- return self.decode_token(signing_key.key, token, **kwargs)
106
- except Exception as e:
107
- if kwargs.get("raise_exception", True):
108
- raise USSOException(
109
- status_code=401,
110
- error="error",
111
- message=str(e),
112
- )
113
- logger.error(e)
@@ -1,186 +0,0 @@
1
- import json
2
- import logging
3
- import os
4
-
5
- import cachetools.func
6
- import jwt
7
- from fastapi import Request, WebSocket
8
- from pydantic import BaseModel, model_validator
9
- from starlette.status import HTTP_401_UNAUTHORIZED
10
-
11
- from usso.core import UserData
12
- from usso.exceptions import USSOException
13
-
14
- logger = logging.getLogger("usso")
15
-
16
-
17
- class JWTConfig(BaseModel):
18
- jwk_url: str | None = None
19
- secret: str | None = None
20
- type: str = "RS256"
21
- header: dict[str, str] = {"type": "Cookie", "name": "usso_access_token"}
22
-
23
- def __hash__(self):
24
- return hash(self.model_dump_json())
25
-
26
- @model_validator(mode="before")
27
- def validate_secret(cls, data: dict):
28
- if not data.get("jwk_url") and not data.get("secret"):
29
- raise ValueError("Either jwk_url or secret must be provided")
30
- return data
31
-
32
- @classmethod
33
- @cachetools.func.ttl_cache(maxsize=128, ttl=10 * 60)
34
- def get_jwk_keys(cls, jwk_url):
35
- return jwt.PyJWKClient(
36
- jwk_url,
37
- headers={
38
- "User-Agent": "usso-python",
39
- },
40
- )
41
-
42
- @cachetools.func.ttl_cache(maxsize=128, ttl=10 * 60)
43
- def decode(self, token: str):
44
- if self.jwk_url:
45
- jwk_client = self.get_jwk_keys(self.jwk_url)
46
- signing_key = jwk_client.get_signing_key_from_jwt(token)
47
- return jwt.decode(token, signing_key.key, algorithms=[self.type])
48
-
49
- return jwt.decode(token, self.secret, algorithms=[self.type])
50
-
51
-
52
- class Usso:
53
-
54
- def __init__(self, jwt_config: str | dict | JWTConfig | None = None):
55
- if jwt_config is None:
56
- self.jwk_url = os.getenv("USSO_JWK_URL")
57
- return
58
-
59
- if isinstance(jwt_config, str):
60
- jwt_config = json.loads(jwt_config)
61
- if isinstance(jwt_config, dict):
62
- jwt_config = JWTConfig(**jwt_config)
63
-
64
- self.jwk_url = jwt_config
65
- self.jwt_config = jwt_config
66
-
67
- def get_authorization_scheme_param(
68
- self,
69
- authorization_header_value: str | None,
70
- ) -> tuple[str, str]:
71
- if not authorization_header_value:
72
- return "", ""
73
- scheme, _, param = authorization_header_value.partition(" ")
74
- return scheme, param
75
-
76
- def decode_token(self, key, token: str, **kwargs) -> dict:
77
- try:
78
- decoded = jwt.decode(token, key, algorithms=["RS256"])
79
- if decoded["token_type"] != "access":
80
- raise USSOException(status_code=401, error="invalid_token_type")
81
- decoded["token"] = token
82
- return UserData(**decoded)
83
- except jwt.exceptions.ExpiredSignatureError:
84
- if kwargs.get("raise_exception", True):
85
- raise USSOException(status_code=401, error="expired_signature")
86
- except jwt.exceptions.InvalidSignatureError:
87
- if kwargs.get("raise_exception", True):
88
- raise USSOException(status_code=401, error="invalid_signature")
89
- except jwt.exceptions.InvalidAlgorithmError:
90
- if kwargs.get("raise_exception", True):
91
- raise USSOException(status_code=401, error="invalid_algorithm")
92
- except jwt.exceptions.InvalidIssuedAtError:
93
- if kwargs.get("raise_exception", True):
94
- raise USSOException(status_code=401, error="invalid_issued_at")
95
- except jwt.exceptions.InvalidTokenError:
96
- if kwargs.get("raise_exception", True):
97
- raise USSOException(status_code=401, error="invalid_token")
98
- except jwt.exceptions.InvalidKeyError:
99
- if kwargs.get("raise_exception", True):
100
- raise USSOException(status_code=401, error="invalid_key")
101
- except USSOException as e:
102
- if kwargs.get("raise_exception", True):
103
- raise e
104
- except Exception as e:
105
- if kwargs.get("raise_exception", True):
106
- raise USSOException(status_code=401, error="error", message=str(e))
107
- logger.error(e)
108
-
109
- def user_data_from_token(self, token: str, **kwargs) -> UserData | None:
110
- """Return the user associated with a token value."""
111
- try:
112
- decoded = self.jwk_url.decode(token)
113
- if decoded["token_type"] != "access":
114
- raise USSOException(status_code=401, error="invalid_token_type")
115
- decoded["token"] = token
116
- return UserData(**decoded)
117
- except jwt.exceptions.ExpiredSignatureError:
118
- if kwargs.get("raise_exception", True):
119
- raise USSOException(status_code=401, error="expired_signature")
120
- except jwt.exceptions.InvalidSignatureError:
121
- if kwargs.get("raise_exception", True):
122
- raise USSOException(status_code=401, error="invalid_signature")
123
- except jwt.exceptions.InvalidAlgorithmError:
124
- if kwargs.get("raise_exception", True):
125
- raise USSOException(status_code=401, error="invalid_algorithm")
126
- except jwt.exceptions.InvalidIssuedAtError:
127
- if kwargs.get("raise_exception", True):
128
- raise USSOException(status_code=401, error="invalid_issued_at")
129
- except jwt.exceptions.InvalidTokenError:
130
- if kwargs.get("raise_exception", True):
131
- raise USSOException(status_code=401, error="invalid_token")
132
- except jwt.exceptions.InvalidKeyError:
133
- if kwargs.get("raise_exception", True):
134
- raise USSOException(status_code=401, error="invalid_key")
135
- except KeyError as e:
136
- if kwargs.get("raise_exception", True):
137
- raise USSOException(status_code=401, error="key_error", message=str(e))
138
- except USSOException as e:
139
- if kwargs.get("raise_exception", True):
140
- raise e
141
- except Exception as e:
142
- if kwargs.get("raise_exception", True):
143
- raise USSOException(status_code=401, error="error", message=str(e))
144
- logger.error(e)
145
-
146
- async def jwt_access_security(self, request: Request) -> UserData | None:
147
- """Return the user associated with a token value."""
148
- kwargs = {}
149
- authorization = request.headers.get("Authorization")
150
- if authorization:
151
- scheme, credentials = self.get_authorization_scheme_param(authorization)
152
- if scheme.lower() == "bearer":
153
- token = credentials
154
- return self.user_data_from_token(token, **kwargs)
155
-
156
- cookie_token = request.cookies.get("usso_access_token")
157
- if cookie_token:
158
- return self.user_data_from_token(cookie_token, **kwargs)
159
-
160
- if kwargs.get("raise_exception", True):
161
- raise USSOException(
162
- status_code=HTTP_401_UNAUTHORIZED,
163
- error="unauthorized",
164
- )
165
- return None
166
-
167
- async def jwt_access_security_ws(self, websocket: WebSocket) -> UserData | None:
168
- """Return the user associated with a token value."""
169
- kwargs = {}
170
- authorization = websocket.headers.get("Authorization")
171
- if authorization:
172
- scheme, credentials = self.get_authorization_scheme_param(authorization)
173
- if scheme.lower() == "bearer":
174
- token = credentials
175
- return self.user_data_from_token(token, **kwargs)
176
-
177
- cookie_token = websocket.cookies.get("usso_access_token")
178
- if cookie_token:
179
- return self.user_data_from_token(cookie_token, **kwargs)
180
-
181
- if kwargs.get("raise_exception", True):
182
- raise USSOException(
183
- status_code=HTTP_401_UNAUTHORIZED,
184
- error="unauthorized",
185
- )
186
- return None
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes