76 lines
1.8 KiB
Python
76 lines
1.8 KiB
Python
import secrets
|
|
from logging import getLogger
|
|
|
|
from fastapi import APIRouter
|
|
from sqlmodel import select
|
|
|
|
from apps.esia.sign import get_url
|
|
from apps.users.models import User
|
|
from clients import clients as c
|
|
from database import AsyncSessionDep
|
|
from shared import exceptions as e
|
|
from shared.redis import client as cache
|
|
|
|
from . import schema as s
|
|
|
|
logger = getLogger(__name__)
|
|
router = APIRouter(
|
|
prefix='/esia',
|
|
tags=[
|
|
'ESIA',
|
|
],
|
|
)
|
|
|
|
|
|
@router.get('/login', response_model=s.LoginURL)
|
|
async def login():
|
|
url = get_url()
|
|
return s.LoginURL(url=url)
|
|
|
|
|
|
@router.post('/callback')
|
|
async def callback(session: AsyncSessionDep, code: str):
|
|
token = None
|
|
for i in range(3):
|
|
try:
|
|
token = await c.esia_api.access_token(code)
|
|
break
|
|
except Exception:
|
|
logger.warning(
|
|
'Error occurred while accessing ESI API. Retrying...'
|
|
)
|
|
if i == 2:
|
|
raise
|
|
|
|
if token is None:
|
|
raise e.BadRequestException
|
|
|
|
esia_user = await c.esia_api.get_user_info(
|
|
token.access_token, token.id_token
|
|
)
|
|
|
|
try:
|
|
vita_user = await c.vitacore_api.findBySnils(esia_user.snils)
|
|
patId = vita_user.patId
|
|
except e.UnknownException:
|
|
raise e.BadRequestException(detail='Patient not found') from None
|
|
|
|
existing_user_stmt = select(User).where(User.vita_id == patId).limit(1)
|
|
existing_user = (
|
|
await session.execute(existing_user_stmt)
|
|
).scalar_one_or_none()
|
|
|
|
if existing_user is None:
|
|
user = User(vita_id=patId)
|
|
session.add(user)
|
|
await session.commit()
|
|
await session.refresh(user)
|
|
|
|
else:
|
|
user = existing_user
|
|
|
|
access_token = secrets.token_urlsafe(32)
|
|
await cache.set(access_token, f'user:{user.id}')
|
|
|
|
return s.Token(access_token=access_token)
|