feat(auth): init Authlib + provider LinkedIn (config env) (#88)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,12 @@ USERS_DB_PATH=./users.sqlite
|
||||
SECRET_KEY= # à générer : python -c "import secrets; print(secrets.token_hex(32))"
|
||||
APP_BASE_URL=http://localhost:8050
|
||||
|
||||
# Connexion LinkedIn (OpenID Connect) — créer une app sur le LinkedIn Developer Portal,
|
||||
# activer "Sign In with LinkedIn using OpenID Connect", déclarer le redirect URI
|
||||
# {APP_BASE_URL}/auth/linkedin/callback
|
||||
LINKEDIN_CLIENT_ID=
|
||||
LINKEDIN_CLIENT_SECRET=
|
||||
|
||||
# Brevo — envoi des emails transactionnels (vérification email, reset mot de passe)
|
||||
BREVO_API_KEY= # clé API transactionnelle Brevo
|
||||
BREVO_TEMPLATE_VERIFY_ID= # ID numérique du template "vérification d'adresse"
|
||||
|
||||
@@ -25,6 +25,7 @@ dependencies = [
|
||||
"brevo-python==5.0.0rc1",
|
||||
"flask-wtf",
|
||||
"email-validator",
|
||||
"authlib",
|
||||
"flask-cors>=6.0.2",
|
||||
"flask-smorest>=0.46.0",
|
||||
"marshmallow>=3.20.0",
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import os
|
||||
|
||||
from authlib.integrations.flask_client import OAuth
|
||||
from flask import Flask
|
||||
|
||||
LINKEDIN_DISCOVERY_URL = (
|
||||
"https://www.linkedin.com/oauth/.well-known/openid-configuration"
|
||||
)
|
||||
|
||||
oauth = OAuth()
|
||||
|
||||
|
||||
def init_oauth(app: Flask) -> None:
|
||||
oauth.init_app(app)
|
||||
oauth.register(
|
||||
name="linkedin",
|
||||
client_id=os.getenv("LINKEDIN_CLIENT_ID"),
|
||||
client_secret=os.getenv("LINKEDIN_CLIENT_SECRET"),
|
||||
server_metadata_url=LINKEDIN_DISCOVERY_URL,
|
||||
client_kwargs={"scope": "openid profile email"},
|
||||
)
|
||||
@@ -6,6 +6,7 @@ from flask_wtf.csrf import CSRFProtect
|
||||
|
||||
from src.auth import db, mailer
|
||||
from src.auth.models import load_user
|
||||
from src.auth.oauth import init_oauth
|
||||
from src.utils import DEVELOPMENT, logger
|
||||
|
||||
_csrf: CSRFProtect | None = None
|
||||
@@ -47,6 +48,8 @@ def init_auth(app: Flask) -> None:
|
||||
|
||||
app.register_blueprint(auth_bp)
|
||||
|
||||
init_oauth(app)
|
||||
|
||||
_csrf = CSRFProtect(app)
|
||||
|
||||
if not os.getenv("BREVO_API_KEY"):
|
||||
@@ -54,3 +57,9 @@ def init_auth(app: Flask) -> None:
|
||||
"BREVO_API_KEY non défini : les emails d'auth échoueront. "
|
||||
"Définissez les variables BREVO_* dans .env pour envoyer des emails."
|
||||
)
|
||||
|
||||
if not os.getenv("LINKEDIN_CLIENT_ID"):
|
||||
logger.warning(
|
||||
"LINKEDIN_CLIENT_ID non défini : la connexion LinkedIn échouera. "
|
||||
"Définissez LINKEDIN_CLIENT_ID / LINKEDIN_CLIENT_SECRET dans .env."
|
||||
)
|
||||
|
||||
@@ -19,6 +19,9 @@ def app(users_db_path, monkeypatch):
|
||||
from src.auth.setup import init_auth
|
||||
|
||||
monkeypatch.setenv("SECRET_KEY", "test-secret-key")
|
||||
monkeypatch.setenv("LINKEDIN_CLIENT_ID", "test-client-id")
|
||||
monkeypatch.setenv("LINKEDIN_CLIENT_SECRET", "test-client-secret")
|
||||
monkeypatch.setenv("APP_BASE_URL", "http://localhost:8050")
|
||||
app = Flask(__name__)
|
||||
app.config["WTF_CSRF_ENABLED"] = False
|
||||
init_auth(app)
|
||||
|
||||
Reference in New Issue
Block a user