11# SPDX-FileCopyrightText: 2023-2024 MTS PJSC
22# SPDX-License-Identifier: Apache-2.0
3- from typing import Annotated
3+ from typing import TYPE_CHECKING , Annotated
44
5- from fastapi import APIRouter , Depends
5+ from fastapi import APIRouter , Depends , HTTPException , status
6+ from fastapi .responses import RedirectResponse
67from fastapi .security import OAuth2PasswordRequestForm
78
89from syncmaster .backend .dependencies import Stub
910from syncmaster .backend .providers .auth import AuthProvider
11+ from syncmaster .backend .utils .state import validate_state
1012from syncmaster .errors .registration import get_error_responses
1113from syncmaster .errors .schemas .invalid_request import InvalidRequestSchema
1214from syncmaster .errors .schemas .not_authorized import NotAuthorizedSchema
1315from syncmaster .schemas .v1 .auth import AuthTokenSchema
1416
17+ if TYPE_CHECKING :
18+ from syncmaster .backend .providers .auth import (
19+ DummyAuthProvider ,
20+ KeycloakAuthProvider ,
21+ )
22+
1523router = APIRouter (
1624 prefix = "/auth" ,
1725 tags = ["Auth" ],
2028
2129
2230@router .post ("/token" )
23- async def login (
24- auth_provider : Annotated [AuthProvider , Depends (Stub (AuthProvider ))],
31+ async def token (
32+ auth_provider : Annotated ["DummyAuthProvider" , Depends (Stub (AuthProvider ))],
2533 form_data : OAuth2PasswordRequestForm = Depends (),
2634) -> AuthTokenSchema :
27- token = await auth_provider .get_token (
35+ token = await auth_provider .get_token_password_grant (
2836 grant_type = form_data .grant_type ,
2937 login = form_data .username ,
3038 password = form_data .password ,
@@ -33,3 +41,25 @@ async def login(
3341 client_secret = form_data .client_secret ,
3442 )
3543 return AuthTokenSchema .parse_obj (token )
44+
45+
46+ @router .get ("/callback" )
47+ async def auth_callback (
48+ code : str ,
49+ state : str ,
50+ auth_provider : Annotated ["KeycloakAuthProvider" , Depends (Stub (AuthProvider ))],
51+ ):
52+ if not validate_state (state ):
53+ raise HTTPException (
54+ status_code = status .HTTP_400_BAD_REQUEST ,
55+ detail = "Invalid state parameter" ,
56+ )
57+ token = await auth_provider .get_token_authorization_code_grant (
58+ code = code ,
59+ redirect_uri = auth_provider .settings .redirect_uri ,
60+ )
61+ access_token = token ["access_token" ]
62+ await auth_provider .get_current_user (access_token )
63+ response = RedirectResponse (url = "/" )
64+ response .set_cookie (key = "access_token" , value = access_token , httponly = True )
65+ return AuthTokenSchema .parse_obj (token )
0 commit comments