BackendJunsen / main.py
2nzi's picture
update
c7da95d verified
raw
history blame
3.75 kB
from fastapi import FastAPI, Depends, HTTPException, status, Response
from fastapi.middleware.cors import CORSMiddleware
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from firebase_admin import auth, credentials, firestore
import firebase_admin
import os
from dotenv import load_dotenv
# Charger les variables d'environnement depuis le fichier .env
load_dotenv()
# Récupérer les variables d'environnement pour initialiser Firebase
firebase_credentials = os.getenv("FIREBASE_CREDENTIALS")
# Vérification de la présence de la clé
if not firebase_credentials:
raise ValueError("La variable d'environnement FIREBASE_CREDENTIALS n'est pas définie.")
# Charger les informations de la clé Firebase
import json
try:
firebase_credentials_dict = json.loads(firebase_credentials)
if not isinstance(firebase_credentials_dict, dict):
raise ValueError("FIREBASE_CREDENTIALS n'est pas un JSON valide.")
except json.JSONDecodeError as e:
raise ValueError("FIREBASE_CREDENTIALS n'est pas un JSON valide.") from e
# Initialisation Firebase Admin
cred = credentials.Certificate(firebase_credentials_dict)
firebase_admin.initialize_app(cred)
db = firestore.client()
app = FastAPI()
# Configuration CORS
allowed_origins = [
"*"
]
app.add_middleware(
CORSMiddleware,
allow_origins=allowed_origins,
allow_credentials=True,
allow_methods=["POST", "GET"],
allow_headers=["*"]
)
# Fonction pour vérifier le token Firebase et récupérer le rôle depuis Firestore
def get_user(res: Response,
cred: HTTPAuthorizationCredentials = Depends(HTTPBearer(auto_error=False))):
if cred is None:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Bearer authentication required",
headers={'WWW-Authenticate': 'Bearer realm="auth_required"'},
)
try:
# Vérification et décodage du token Firebase
decoded_token = auth.verify_id_token(cred.credentials)
user_id = decoded_token['uid']
# Récupération du rôle de l'utilisateur depuis Firestore
user_doc = db.collection('users').document(user_id).get()
if not user_doc.exists:
raise HTTPException(status_code=401, detail="Utilisateur non trouvé dans Firestore")
# Extraction du rôle et ajout aux informations utilisateur
user_data = user_doc.to_dict()
user_role = user_data.get('role', 'user_extern') # Par défaut à 'user_extern' si le rôle n'existe pas
decoded_token['role'] = user_role
res.headers['WWW-Authenticate'] = 'Bearer realm="auth_required"'
return decoded_token
except Exception as err:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=f"Invalid authentication credentials. {err}",
headers={'WWW-Authenticate': 'Bearer error="invalid_token"'},
)
# Fonction de dépendance pour vérifier le rôle
def require_role(allowed_roles):
def role_checker(user_info=Depends(get_user)):
if user_info['role'] not in allowed_roles:
raise HTTPException(status_code=403, detail="Accès non autorisé")
return user_info
return role_checker
# Route publique
@app.get("/")
async def root():
return {"message": "This is the root."}
@app.get("/api/protected/user")
async def protected_user_route(user_info=Depends(get_user)):
return {"message": "Protected user route accessed successfully", "user_info": user_info}
@app.get("/api/protected/admin")
async def protected_admin_route(user_info=Depends(require_role(["admin"]))):
return {"message": "Protected admin route accessed successfully", "user_info": user_info}