Skip to content

Commit

Permalink
new-feature(auth): BI-5509 custom endpoints for Yandex OAuth (#527)
Browse files Browse the repository at this point in the history
  • Loading branch information
ForrestGump authored Jul 5, 2024
1 parent 908f2aa commit c59ba3e
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 24 deletions.
9 changes: 8 additions & 1 deletion lib/dl_auth_api_lib/dl_auth_api_lib/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
from dl_api_commons.aio.middlewares.request_id import RequestId
from dl_api_commons.aio.middlewares.tracing import TracingService
from dl_api_commons.aio.typing import AIOHTTPMiddleware
from dl_auth_api_lib.settings import AuthAPISettings
from dl_auth_api_lib.oauth.yandex import YandexOAuthClient
from dl_auth_api_lib.settings import (
AuthAPISettings,
register_auth_client,
)
from dl_auth_api_lib.views import yandex as yandex_views
from dl_core.aio.ping_view import PingView

Expand Down Expand Up @@ -53,3 +57,6 @@ def create_app(self) -> web.Application:
app["clients"] = self._settings.auth_clients

return app


register_auth_client("yandex", YandexOAuthClient)
34 changes: 27 additions & 7 deletions lib/dl_auth_api_lib/dl_auth_api_lib/oauth/yandex.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
from base64 import b64encode
from typing import Any
from typing import (
Any,
Optional,
)
import urllib.parse

import aiohttp
import attr
import pydantic
from typing_extensions import Self

from dl_auth_api_lib.oauth.base import BaseOAuth
from dl_auth_api_lib.settings import YandexOAuthClient
from dl_auth_api_lib.settings import BaseOAuthClient


_AUTH_URL: str = "https://oauth.yandex.ru/authorize?"
_TOKEN_URL: str = "https://oauth.yandex.ru/token"


class YandexOAuthClient(BaseOAuthClient):
auth_type: str = "yandex"

client_id: str
client_secret: str
redirect_uri: str
scope: Optional[str] = pydantic.Field(default=None)
auth_url: str = pydantic.Field(default=_AUTH_URL)
token_url: str = pydantic.Field(default=_TOKEN_URL)


@attr.s
Expand All @@ -16,9 +35,8 @@ class YandexOAuth(BaseOAuth):
client_secret: str = attr.ib()
redirect_uri: str = attr.ib()
scope: str | None = attr.ib(default=None)

_AUTH_URL: str = "https://oauth.yandex.ru/authorize?"
_TOKEN_URL: str = "https://oauth.yandex.ru/token"
auth_url: str = attr.ib(default=_AUTH_URL)
token_url: str = attr.ib(default=_TOKEN_URL)

def get_auth_uri(self) -> str:
params = {
Expand All @@ -27,7 +45,7 @@ def get_auth_uri(self) -> str:
"response_type": "code",
"scope": self.scope,
}
uri = self._AUTH_URL + urllib.parse.urlencode({k: v for k, v in params.items() if v is not None})
uri = self.auth_url + urllib.parse.urlencode({k: v for k, v in params.items() if v is not None})
return uri

async def get_auth_token(self, code: str) -> dict[str, Any]:
Expand All @@ -38,7 +56,7 @@ async def get_auth_token(self, code: str) -> dict[str, Any]:
"grant_type": "authorization_code",
"code": code,
}
async with session.post(self._TOKEN_URL, data=token_data) as resp:
async with session.post(self.token_url, data=token_data) as resp:
token_response = await resp.json()
return token_response

Expand All @@ -49,6 +67,8 @@ def from_settings(cls, settings: YandexOAuthClient) -> Self:
client_secret=settings.client_secret,
redirect_uri=settings.redirect_uri,
scope=settings.scope,
auth_url=settings.auth_url,
token_url=settings.token_url,
)

def _get_session_headers(self) -> dict[str, str]:
Expand Down
19 changes: 7 additions & 12 deletions lib/dl_auth_api_lib/dl_auth_api_lib/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from typing import (
Annotated,
Any,
Optional,
Type,
)

Expand All @@ -29,13 +28,14 @@ def factory(cls, data: Any) -> "BaseOAuthClient":
return config_class.model_validate(data)


class YandexOAuthClient(BaseOAuthClient):
auth_type: str = "yandex"
_REGISTRY: dict[str, type[BaseOAuthClient]] = {}

client_id: str
client_secret: str
redirect_uri: str
scope: Optional[str] = pydantic.Field(default=None)

def register_auth_client(
name: str,
auth_type: type[BaseOAuthClient],
) -> None:
_REGISTRY[name] = auth_type


class AuthAPISettings(pydantic_settings.BaseSettings):
Expand Down Expand Up @@ -63,8 +63,3 @@ def settings_customise_sources(
),
init_settings,
)


_REGISTRY = {
"yandex": YandexOAuthClient,
}
15 changes: 11 additions & 4 deletions lib/dl_auth_api_lib/dl_auth_api_lib_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@
)
from dl_api_commons.client.common import DLCommonAPIClient
from dl_auth_api_lib.app import OAuthApiAppFactory
from dl_auth_api_lib.settings import (
AuthAPISettings,
YandexOAuthClient,
)
from dl_auth_api_lib.oauth.yandex import YandexOAuthClient
from dl_auth_api_lib.settings import AuthAPISettings
from dl_testing.utils import get_default_aiohttp_session


Expand Down Expand Up @@ -66,6 +64,15 @@ def oauth_app_settings(monkeypatch, config_path):
client_id="app_metrica",
redirect_uri="localhost",
),
custom_conn=dict(
auth_type="yandex",
conn_type="custom_conn",
client_id="custom_conn",
client_secret="pass321",
redirect_uri="localhost",
auth_url="https://oauth.yandex.com/authorize?",
token_url="https://oauth.yandex.com/token",
),
)
)
yield settings
Expand Down
4 changes: 4 additions & 0 deletions lib/dl_auth_api_lib/dl_auth_api_lib_tests/unit/test_yandex.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
"app_metrica",
"https://oauth.yandex.ru/authorize?client_id=app_metrica&redirect_uri=localhost&response_type=code",
),
(
"custom_conn",
"https://oauth.yandex.com/authorize?client_id=custom_conn&redirect_uri=localhost&response_type=code",
),
],
)
async def test_yandex_uri(oauth_app_client, conn_type, resp_uri):
Expand Down

0 comments on commit c59ba3e

Please sign in to comment.