diff --git a/.env.testing b/.env.testing index 79ef30d43b..1f1ff04701 100644 --- a/.env.testing +++ b/.env.testing @@ -20,6 +20,8 @@ DEMARCHES_SIMPLIFIEES_ENROLLMENT_PROCEDURE_ID_v3=44682 DEMARCHES_SIMPLIFIEES_RIB_OFFERER_PROCEDURE_ID=30417 DEMARCHES_SIMPLIFIEES_RIB_VENUE_PROCEDURE_ID=30415 DEMARCHES_SIMPLIFIEES_USER_URL=https://www.demarches-simplifiees.fr/commencer/test/e08b6650-3dfd-4d7d-ad2c-3933f1477eb7 +EDUCONNECT_IDP_SSO_URL=https://pr4.educonnect.phm.education.gouv.fr/idp/profile/SAML2/POST/SSO +EDUCONNECT_IDP_SLO_URL=https://pr4.educonnect.phm.education.gouv.fr/idp/profile/SAML2/POST/SLO FIREBASE_DYNAMIC_LINKS_URL=https://passcultureapptesting.page.link GCP_BUCKET_NAME=pass-culture-app-projet-test-testing-assets GCP_ENCRYPTED_BUCKET_NAME=passculture-metier-ehp-testing-idcheck diff --git a/helm/pcapi/values.testing.yaml b/helm/pcapi/values.testing.yaml index 70cf9f5f16..7d2ec4bc4d 100644 --- a/helm/pcapi/values.testing.yaml +++ b/helm/pcapi/values.testing.yaml @@ -424,6 +424,14 @@ secrets: version: 4 - name: EAC_API_KEY version: 1 + - name: EDUCONNECT_IDP_CERTIFICATE + version: 1 + - name: EDUCONNECT_IDP_METADATA + version: 1 + - name: EDUCONNECT_SP_CERTIFICATE + version: 1 + - name: EDUCONNECT_SP_PRIVATE_KEY + version: 1 - name: EXPORT_TOKEN version: 2 - name: FLASK_SECRET diff --git a/requirements.txt b/requirements.txt index 16d7656709..85147c7697 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,6 +17,7 @@ Flask-Cors==3.0.9 Flask-JWT-Extended==4.0.0 Flask-Limiter==1.4 Flask-Login==0.5.0 +flask-saml2==0.3.0 Flask-Script==2.0.6 Flask-SQLAlchemy==2.4.4 freezegun==0.3.12 diff --git a/src/pcapi/app.py b/src/pcapi/app.py index 798cca7055..24a928c935 100644 --- a/src/pcapi/app.py +++ b/src/pcapi/app.py @@ -5,6 +5,7 @@ from pcapi import settings from pcapi.admin.install import install_admin_template_filters from pcapi.admin.install import install_admin_views +from pcapi.connectors.educonnect_service_provider import EduconnectServiceProvider from pcapi.flask_app import admin from pcapi.flask_app import app from pcapi.flask_app import db @@ -46,6 +47,9 @@ def install_login_manager() -> None: app.register_blueprint(adage_iframe, url_prefix="/adage-iframe") app.register_blueprint(cloud_task_api) + educonnectSP = EduconnectServiceProvider() + app.register_blueprint(educonnectSP.create_blueprint(), url_prefix="/saml/") + if __name__ == "__main__": port = settings.FLASK_PORT if settings.IS_DEV and settings.DEBUG_ACTIVATED: diff --git a/src/pcapi/connectors/educonnect_service_provider.py b/src/pcapi/connectors/educonnect_service_provider.py new file mode 100644 index 0000000000..8d18a50971 --- /dev/null +++ b/src/pcapi/connectors/educonnect_service_provider.py @@ -0,0 +1,10 @@ +from flask import url_for +from flask_saml2.sp import ServiceProvider + + +class EduconnectServiceProvider(ServiceProvider): + def get_logout_return_url(self) -> str: + return url_for("index", _external=True) + + def get_default_login_return_url(self) -> str: + return url_for("index", _external=True) diff --git a/src/pcapi/flask_app.py b/src/pcapi/flask_app.py index 62b3970e67..a0688ba16e 100644 --- a/src/pcapi/flask_app.py +++ b/src/pcapi/flask_app.py @@ -151,6 +151,26 @@ def add_security_headers(response: flask.wrappers.Response) -> flask.wrappers.Re app.config["JWT_SECRET_KEY"] = settings.JWT_SECRET_KEY app.config["RATELIMIT_STORAGE_URL"] = settings.REDIS_URL + +app.config["SAML2_SP"] = { + "certificate": settings.EDUCONNECT_SP_CERTIFICATE, + "private_key": settings.EDUCONNECT_SP_PRIVATE_KEY, +} + +app.config["SAML2_IDENTITY_PROVIDERS"] = [ + { + "CLASS": "flask_saml2.sp.idphandler.IdPHandler", + "OPTIONS": { + "display_name": "Educonnect", + "entity_id": settings.EDUCONNECT_IDP_METADATA, + "sso_url": settings.EDUCONNECT_IDP_SSO_URL, + "slo_url": settings.EDUCONNECT_IDP_SLO_URL, + "certificate": settings.EDUCONNECT_IDP_CERTIFICATE, + }, + }, +] + + jwt = JWTManager(app) rate_limiter.init_app(app) diff --git a/src/pcapi/settings.py b/src/pcapi/settings.py index 71368c9e5f..7012fbbd81 100644 --- a/src/pcapi/settings.py +++ b/src/pcapi/settings.py @@ -329,3 +329,11 @@ # NOTION NOTION_TOKEN = os.environ.get("NOTION_TOKEN", "") + +# EDUCONNECT +EDUCONNECT_SP_CERTIFICATE = os.environ.get("EDUCONNECT_SP_CERTIFICATE", None) +EDUCONNECT_SP_PRIVATE_KEY = os.environ.get("EDUCONNECT_SP_PRIVATE_KEY", None) +EDUCONNECT_IDP_CERTIFICATE = os.environ.get("EDUCONNECT_IDP_CERTIFICATE", None) +EDUCONNECT_IDP_METADATA = os.environ.get("EDUCONNECT_IDP_METADATA", None) +EDUCONNECT_IDP_SSO_URL = os.environ.get("EDUCONNECT_IDP_SSO_URL", None) +EDUCONNECT_IDP_SLO_URL = os.environ.get("EDUCONNECT_IDP_SLO_URL", None)