partner-core/integration_api.py

75 lines
3.1 KiB
Python

from fastapi import FastAPI, HTTPException, status, Depends, Request
from sqlmodel import Session, select
from typing import Optional
from datetime import datetime, timedelta
import jwt
from jwt.exceptions import InvalidTokenError
from pydantic import BaseModel
from sql_models import Sale
from helpers_bff import get_db, AUTH_DB_ENGINE # Assuming these are the correct imports
app = FastAPI()
# Конфигурация для интеграционного API токена
INTEGRATION_SECRET_KEY = "your-integration-super-secret-key" # Смените это на безопасный ключ!
INTEGRATION_ALGORITHM = "HS256"
INTEGRATION_TOKEN_EXPIRE_MINUTES = 60 * 24 # 24 часа
class IntegrationTokenData(BaseModel):
client_id: str
class SaleCreate(BaseModel):
cost: float
crediting: float
ref_id: int
sale_id: str
company_id: int
sale_date: datetime = datetime.utcnow()
def create_integration_access_token(data: dict, expires_delta: timedelta = None):
to_encode = data.copy()
if expires_delta:
expire = datetime.utcnow() + expires_delta
else:
expire = datetime.utcnow() + timedelta(minutes=INTEGRATION_TOKEN_EXPIRE_MINUTES)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, INTEGRATION_SECRET_KEY, algorithm=INTEGRATION_ALGORITHM)
return encoded_jwt
async def verify_integration_token(request: Request):
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate integration credentials",
headers={"WWW-Authenticate": "Bearer"},
)
auth_header = request.headers.get("Authorization")
if not auth_header or not auth_header.startswith("Bearer "):
raise credentials_exception
token = auth_header.replace("Bearer ", "").strip()
try:
payload = jwt.decode(token, INTEGRATION_SECRET_KEY, algorithms=[INTEGRATION_ALGORITHM])
client_id: str = payload.get("client_id")
if client_id is None:
raise credentials_exception
# Здесь вы можете добавить логику для проверки client_id, например, из базы данных
except InvalidTokenError:
raise credentials_exception
return True # Токен действителен
@app.post("/sale", status_code=status.HTTP_201_CREATED)
async def upload_sale(sale_data: SaleCreate, db: Session = Depends(get_db), verified: bool = Depends(verify_integration_token)):
if not verified:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Not authorized")
db_sale = Sale(cost=sale_data.cost, crediting=sale_data.crediting, ref=sale_data.ref_id, sale_id=sale_data.sale_id, company_id=sale_data.company_id, sale_date=sale_data.sale_date)
db.add(db_sale)
db.commit()
db.refresh(db_sale)
return {"message": "Sale uploaded successfully", "sale_id": db_sale.id}
@app.get("/generate-integration-token")
async def generate_token_endpoint(client_id: str):
token_data = {"client_id": client_id}
token = create_integration_access_token(token_data)
return {"access_token": token, "token_type": "bearer"}