Skip to content

Commit

Permalink
added Seznam SSO provider (#194)
Browse files Browse the repository at this point in the history
* add seznam example

* add info to README.md

* add SeznamSSO to test_providers

* add SeznamSSO

* add client_secret comment

* Organize imports (ruff)
  • Loading branch information
TomasKoutek committed Sep 21, 2024
1 parent 73e7467 commit 989ce0c
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ I tend to process Pull Requests faster when properly caffeinated 😉.
- Line (by Jimmy Yeh) - [jimmyyyeh](https://github.com/jimmyyyeh)
- LinkedIn (by Alessandro Pischedda) - [Cereal84](https://github.com/Cereal84)
- Yandex (by Akim Faskhutdinov) – [akimrx](https://github.com/akimrx)
- Seznam (by Tomas Koutek) - [TomasKoutek](https://github.com/TomasKoutek)

See [Contributing](#contributing) for a guide on how to contribute your own login provider.

Expand Down
39 changes: 39 additions & 0 deletions examples/seznam.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""Seznam Login Example"""

import os
import uvicorn
from fastapi import FastAPI
from fastapi import Request

from fastapi_sso.sso.seznam import SeznamSSO

CLIENT_ID = os.environ["CLIENT_ID"]
CLIENT_SECRET = os.environ["CLIENT_SECRET"]

app = FastAPI()

sso = SeznamSSO(
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
redirect_uri="http://localhost:5000/auth/callback",
allow_insecure_http=True,
)


@app.get("/auth/login")
async def auth_init():
"""Initialize auth and redirect"""
with sso:
return await sso.get_login_redirect()


@app.get("/auth/callback")
async def auth_callback(request: Request):
"""Verify login"""
with sso:
user = await sso.verify_and_process(request, params={"client_secret": CLIENT_SECRET}) # <- "client_secret" parameter is needed!
return user


if __name__ == "__main__":
uvicorn.run(app="examples.seznam:app", host="127.0.0.1", port=5000)
39 changes: 39 additions & 0 deletions fastapi_sso/sso/seznam.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""Seznam SSO Login Helper."""

from typing import TYPE_CHECKING, ClassVar, Optional

from fastapi_sso.sso.base import DiscoveryDocument, OpenID, SSOBase

if TYPE_CHECKING:
import httpx # pragma: no cover


# https://vyvojari.seznam.cz/oauth/doc


class SeznamSSO(SSOBase):
"""Class providing login via Seznam OAuth."""

provider = "seznam"
base_url = "https://login.szn.cz/api/v1"
scope: ClassVar = ["identity", "avatar"] # + ["contact-phone", "adulthood", "birthday", "gender"]

async def get_discovery_document(self) -> DiscoveryDocument:
"""Get document containing handy urls."""
return {
"authorization_endpoint": f"{self.base_url}/oauth/auth",
"token_endpoint": f"{self.base_url}/oauth/token",
"userinfo_endpoint": f"{self.base_url}/user",
}

async def openid_from_response(self, response: dict, session: Optional["httpx.AsyncClient"] = None) -> OpenID:
"""Return OpenID from user information provided by Seznam."""
return OpenID(
email=response.get("email"),
first_name=response.get("firstname"),
last_name=response.get("lastname"),
display_name=response.get("accountDisplayName"),
provider=self.provider,
id=response.get("oauth_user_id"),
picture=response.get("avatar_url"),
)
2 changes: 2 additions & 0 deletions tests/test_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from fastapi_sso.sso.linkedin import LinkedInSSO
from fastapi_sso.sso.twitter import TwitterSSO
from fastapi_sso.sso.yandex import YandexSSO
from fastapi_sso.sso.seznam import SeznamSSO

GenericProvider = create_provider(
name="generic",
Expand Down Expand Up @@ -51,6 +52,7 @@
LinkedInSSO,
TwitterSSO,
YandexSSO,
SeznamSSO,
)

# Run all tests for each of the listed providers
Expand Down

0 comments on commit 989ce0c

Please sign in to comment.