fastapi-sso 0.18.0__py3-none-any.whl → 0.20.0__py3-none-any.whl

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.
fastapi_sso/__init__.py CHANGED
@@ -18,6 +18,7 @@ from .sso.linkedin import LinkedInSSO
18
18
  from .sso.microsoft import MicrosoftSSO
19
19
  from .sso.naver import NaverSSO
20
20
  from .sso.notion import NotionSSO
21
+ from .sso.soundcloud import SoundcloudSSO
21
22
  from .sso.spotify import SpotifySSO
22
23
  from .sso.twitter import TwitterSSO
23
24
 
@@ -38,6 +39,7 @@ __all__ = [
38
39
  "OpenID",
39
40
  "SSOBase",
40
41
  "SSOLoginError",
42
+ "SoundcloudSSO",
41
43
  "SpotifySSO",
42
44
  "TwitterSSO",
43
45
  "create_provider",
fastapi_sso/sso/base.py CHANGED
@@ -341,6 +341,8 @@ class SSOBase:
341
341
  response = RedirectResponse(login_uri, 303)
342
342
  if self.uses_pkce:
343
343
  response.set_cookie("pkce_code_verifier", str(self._pkce_code_verifier))
344
+ if state is not None:
345
+ response.set_cookie("sso_state", state)
344
346
  return response
345
347
 
346
348
  @overload
@@ -402,6 +404,14 @@ class SSOBase:
402
404
  )
403
405
  raise SSOLoginError(400, "'code' parameter was not found in callback request")
404
406
  self._state = request.query_params.get("state")
407
+ if self._state is None and self.requires_state:
408
+ raise SSOLoginError(400, "'state' parameter was not found in callback request")
409
+ if self._state is not None:
410
+ sso_state = request.cookies.get("sso_state")
411
+ if sso_state is None and self.requires_state:
412
+ raise SSOLoginError(401, "State cookie not found")
413
+ if sso_state is not None and sso_state != self._state:
414
+ raise SSOLoginError(401, "Invalid state")
405
415
  pkce_code_verifier: Optional[str] = None
406
416
  if self.uses_pkce:
407
417
  pkce_code_verifier = request.cookies.get("pkce_code_verifier")
fastapi_sso/sso/kakao.py CHANGED
@@ -15,6 +15,10 @@ class KakaoSSO(SSOBase):
15
15
  scop: ClassVar = ["openid"]
16
16
  version = "v2"
17
17
 
18
+ @property
19
+ def _extra_query_params(self) -> dict:
20
+ return {"client_secret": self.client_secret}
21
+
18
22
  async def get_discovery_document(self) -> DiscoveryDocument:
19
23
  return {
20
24
  "authorization_endpoint": "https://kauth.kakao.com/oauth/authorize",
fastapi_sso/sso/naver.py CHANGED
@@ -15,6 +15,10 @@ class NaverSSO(SSOBase):
15
15
  scope: ClassVar[list[str]] = []
16
16
  additional_headers: ClassVar = {"accept": "application/json"}
17
17
 
18
+ @property
19
+ def _extra_query_params(self) -> dict:
20
+ return {"client_secret": self.client_secret}
21
+
18
22
  async def get_discovery_document(self) -> DiscoveryDocument:
19
23
  return {
20
24
  "authorization_endpoint": "https://nid.naver.com/oauth2.0/authorize",
fastapi_sso/sso/seznam.py CHANGED
@@ -18,6 +18,10 @@ class SeznamSSO(SSOBase):
18
18
  base_url = "https://login.szn.cz/api/v1"
19
19
  scope: ClassVar = ["identity", "avatar"] # + ["contact-phone", "adulthood", "birthday", "gender"]
20
20
 
21
+ @property
22
+ def _extra_query_params(self) -> dict:
23
+ return {"client_secret": self.client_secret}
24
+
21
25
  async def get_discovery_document(self) -> DiscoveryDocument:
22
26
  """Get document containing handy urls."""
23
27
  return {
@@ -0,0 +1,38 @@
1
+ """Soundcloud SSO Login Helper."""
2
+
3
+ from typing import TYPE_CHECKING, ClassVar, Optional
4
+
5
+ from fastapi_sso.sso.base import DiscoveryDocument, OpenID, SSOBase
6
+
7
+ if TYPE_CHECKING:
8
+ import httpx # pragma: no cover
9
+
10
+
11
+ class SoundcloudSSO(SSOBase):
12
+ """Class providing login via Soundcloud OAuth."""
13
+
14
+ provider = "soundcloud"
15
+ scope: ClassVar = ["openid"]
16
+
17
+ @property
18
+ def _extra_query_params(self) -> dict:
19
+ return {"client_secret": self.client_secret}
20
+
21
+ async def get_discovery_document(self) -> DiscoveryDocument:
22
+ """Get document containing handy urls."""
23
+ return {
24
+ "authorization_endpoint": "https://secure.soundcloud.com/authorize",
25
+ "token_endpoint": "https://secure.soundcloud.com/oauth/token",
26
+ "userinfo_endpoint": "https://api.soundcloud.com/me",
27
+ }
28
+
29
+ async def openid_from_response(self, response: dict, session: Optional["httpx.AsyncClient"] = None) -> OpenID:
30
+ """Return OpenID from user information provided by Soundcloud."""
31
+ return OpenID(
32
+ id=str(response.get("id")),
33
+ first_name=response.get("first_name"),
34
+ last_name=response.get("last_name"),
35
+ display_name=response.get("username"),
36
+ picture=response.get("avatar_url"),
37
+ provider=self.provider,
38
+ )
@@ -1,8 +1,9 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: fastapi-sso
3
- Version: 0.18.0
3
+ Version: 0.20.0
4
4
  Summary: FastAPI plugin to enable SSO to most common providers (such as Facebook login, Google login and login via Microsoft Office 365 Account)
5
5
  License: MIT
6
+ License-File: LICENSE.md
6
7
  Keywords: fastapi,sso,oauth,google,facebook,spotify,linkedin
7
8
  Author: Tomas Votava
8
9
  Author-email: info@tomasvotava.eu
@@ -14,6 +15,7 @@ Classifier: Programming Language :: Python :: 3.10
14
15
  Classifier: Programming Language :: Python :: 3.11
15
16
  Classifier: Programming Language :: Python :: 3.12
16
17
  Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
17
19
  Requires-Dist: fastapi (>=0.80)
18
20
  Requires-Dist: httpx (>=0.23.0)
19
21
  Requires-Dist: oauthlib (>=3.1.0)
@@ -65,6 +67,16 @@ Quick links for the eager ones:
65
67
 
66
68
  ## Security Notice
67
69
 
70
+ ### Version `0.19.0` Update: OAuth `state` Validation Fix
71
+
72
+ A critical OAuth login CSRF vulnerability caused by missing `state` validation was
73
+ reported by [@davidbors-snyk](https://github.com/davidbors-snyk) (Snyk Security Labs)
74
+ in [#266](https://github.com/tomasvotava/fastapi-sso/issues/266) and has been resolved
75
+ in version `0.19.0`.
76
+
77
+ Starting with `fastapi-sso==1.0.0`, OAuth `state` will be backed by a pluggable server-side store
78
+ (in-memory by default, with support for external stores such as `Redis`).
79
+
68
80
  ### Version `0.16.0` Update: Race Condition Bug Fix & Context Manager Change
69
81
 
70
82
  A race condition bug in the login flow that could, in rare cases, allow one user
@@ -145,6 +157,7 @@ I tend to process Pull Requests faster when properly caffeinated 😉.
145
157
  - Seznam (by Tomas Koutek) - [TomasKoutek](https://github.com/TomasKoutek)
146
158
  - Discord (by Kaelian Baudelet) - [afi-dev](https://github.com/afi-dev)
147
159
  - Bitbucket (by Kaelian Baudelet) - [afi-dev](https://github.com/afi-dev)
160
+ - Soundcloud (by John) - [john-9474](https://github.com/john-9474)
148
161
 
149
162
  See [Contributing](#contributing) for a guide on how to contribute your own login provider.
150
163
 
@@ -1,8 +1,8 @@
1
- fastapi_sso/__init__.py,sha256=2xdjBYKS18YTwHRsOCTibfL9xRxBZLVe03waEiMVNhg,1120
1
+ fastapi_sso/__init__.py,sha256=erTb2pUMF0QR0VsmHhUX1HsbAVm0ZToXAeIq-7vJxkQ,1183
2
2
  fastapi_sso/pkce.py,sha256=DhxoJrBIUxDlhAmy5tAoSIBts1WsyQ5KGqLbvDQER1w,767
3
3
  fastapi_sso/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  fastapi_sso/sso/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- fastapi_sso/sso/base.py,sha256=s3SBUfjZcP17sIhVLK8pV1BK65zjt18nlC_g36FmGLw,22676
5
+ fastapi_sso/sso/base.py,sha256=juAQMbXJ19-EnbtkWP2bIBhRUrX6vbzdV_eKBicMh0o,23249
6
6
  fastapi_sso/sso/bitbucket.py,sha256=pqMBDNhVR5rqda3yq5HCXsJzBFZBH2Df6SMIve6btYY,2109
7
7
  fastapi_sso/sso/discord.py,sha256=iJzR17XyPq8YJWwht083yPyCrEtLOHD3E1HGxDSgUtQ,1786
8
8
  fastapi_sso/sso/facebook.py,sha256=JaGCT2v56iRRQlnoZ5OSsB19677gyMU7U5dZTjVE_mc,1368
@@ -11,18 +11,19 @@ fastapi_sso/sso/generic.py,sha256=I3qvR1pwNuxJG2GbDcjIvnNdnYO4tD8NAiLz2H-Bj5E,26
11
11
  fastapi_sso/sso/github.py,sha256=Ol0W6vjmErY8M9XlMCH9nbKsnZfXeOClDNx3oUX52_c,1754
12
12
  fastapi_sso/sso/gitlab.py,sha256=EA-1p2Iklh5W-TrBhCFAeupxuUZJ4RPMNKRfUS5fq6U,2701
13
13
  fastapi_sso/sso/google.py,sha256=LIBV-nEoH2CTJCpINVu7jEfPqRlPQCAPSWK4MKBgsM0,1399
14
- fastapi_sso/sso/kakao.py,sha256=qcsNUXbVTdyb_0V2CHTqplG82ftbnJ1uMB_GenEaiG0,905
14
+ fastapi_sso/sso/kakao.py,sha256=MeKSW6t-o-x2JajW71FeJGT_MmYYcWpn03cURjJA7XA,1016
15
15
  fastapi_sso/sso/line.py,sha256=F6XmXO5RBllGV5U0mhujEiJ4GsZKwzoabLfi-l54lwM,1233
16
16
  fastapi_sso/sso/linkedin.py,sha256=ju5evL8SR_-AjbLT2zUjliXlFARRxBpdP1EGsLKeBl0,1525
17
17
  fastapi_sso/sso/microsoft.py,sha256=xFA3ngVz6JS9Eg5zIQfYR6TnJuR1ZLOLGXOSbEbJCJE,1954
18
- fastapi_sso/sso/naver.py,sha256=mMiHfHlpdamAJ-O7BmagtJGCeQIlptGDI-jot1O4RVc,1143
18
+ fastapi_sso/sso/naver.py,sha256=snBtYMJEbCxsAjRYObmj899D75ogPPPOh5n9AmHwHjo,1254
19
19
  fastapi_sso/sso/notion.py,sha256=YWGBUhN-CFTEpjIgkkEUS5JmGawyhJE57XB4Q9nFOD4,1334
20
- fastapi_sso/sso/seznam.py,sha256=HGI01QPBYslv_b6Lq3oTL2UWPnNLPu45y3rgTdDqxpU,1383
20
+ fastapi_sso/sso/seznam.py,sha256=c15JNxdIGJOLXJS_4-vA42rb6MazlQKL1oclQ536MsQ,1494
21
+ fastapi_sso/sso/soundcloud.py,sha256=y7EpNUslTep60hfl0Pk_NE1-qAvKbvocEAYxofLSABM,1336
21
22
  fastapi_sso/sso/spotify.py,sha256=FvX2N91Bi3wgKRwdU1sWo-zA0s3wYJCiCYA05ebXweE,1244
22
23
  fastapi_sso/sso/twitter.py,sha256=1kMjFdh-OT1b5bJvY3tWfl-BRBv2hVZ6L_liLAvNML8,1249
23
24
  fastapi_sso/sso/yandex.py,sha256=8jKkh-na62lwsaBW7Pvj6VC6WlR0RMg8KrSNlr2Hj8o,1507
24
25
  fastapi_sso/state.py,sha256=9RKMrFGjeN4Ab-3var81QV-gpcBlnNy152WYbxTUGVY,300
25
- fastapi_sso-0.18.0.dist-info/LICENSE.md,sha256=5NVQtYs6liDtYdWM4VObWmTTKaK0k9C9txx5pLPJSyQ,1093
26
- fastapi_sso-0.18.0.dist-info/METADATA,sha256=5E3Hn1f4FDZOHR5rRAJQ37o6Uevv3G9G97ae1FOLLKo,7185
27
- fastapi_sso-0.18.0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
28
- fastapi_sso-0.18.0.dist-info/RECORD,,
26
+ fastapi_sso-0.20.0.dist-info/METADATA,sha256=YBESyXezOtH2-ZJz8-YpUWuNUXTe7kFa4-9w3hbMkZ0,7838
27
+ fastapi_sso-0.20.0.dist-info/WHEEL,sha256=kJCRJT_g0adfAJzTx2GUMmS80rTJIVHRCfG0DQgLq3o,88
28
+ fastapi_sso-0.20.0.dist-info/licenses/LICENSE.md,sha256=5NVQtYs6liDtYdWM4VObWmTTKaK0k9C9txx5pLPJSyQ,1093
29
+ fastapi_sso-0.20.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.1.1
2
+ Generator: poetry-core 2.3.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any