Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f9a9ed1f0 |
@@ -6,10 +6,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0),
|
||||
and this project adheres to
|
||||
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [1.0.5] - 2025-03-06
|
||||
- add allowlist for URL paths to nginx ingress
|
||||
- allow customizing log levels per logger
|
||||
|
||||
## [1.0.4] - 2024-09-11
|
||||
- serve static files
|
||||
|
||||
|
||||
@@ -63,13 +63,6 @@ number and date.
|
||||
3. Commit and push to `main`.
|
||||
4. Update the `production` tag and push it.
|
||||
|
||||
## Environment variables
|
||||
|
||||
| variable | usage |
|
||||
| --- | --- |
|
||||
| `LOG_LEVEL` | Sets the log level for the root logger, i.e. the default. Defaults to `INFO`. |
|
||||
| `LOG_LEVELS` | A JSON object that can be used to set log levels for specific loggers, e.g. `{"satosa.backends.saml2": "DEBUG"}`. Defaults to `{}`. |
|
||||
|
||||
## Contributing
|
||||
|
||||
This project is intended to be community-driven, so please, do not hesitate to
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ services:
|
||||
BASE_URL: https://satosa.traefik.me
|
||||
GUNICORN_CMD_ARGS: --workers=2
|
||||
TEST_E2E: 1
|
||||
#TEST_E2E_PC: 1
|
||||
#TEST_E2E_AC: 1
|
||||
OIDC_DB_URI: redis://redis/0
|
||||
CLIENT_DB_JSON: |
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import datetime
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
@@ -30,8 +29,6 @@ class RequestJSONFormatter(json_log_formatter.JSONFormatter):
|
||||
url += f"?{record.args['q']}"
|
||||
|
||||
return {
|
||||
"logger": record.name,
|
||||
"level": record.levelname,
|
||||
"remote_ip": record.args["h"],
|
||||
"method": record.args["m"],
|
||||
"path": url,
|
||||
@@ -40,7 +37,7 @@ class RequestJSONFormatter(json_log_formatter.JSONFormatter):
|
||||
"user_agent": record.args["a"],
|
||||
"referer": record.args["f"],
|
||||
"duration_in_ms": record.args["M"],
|
||||
"pid": record.process,
|
||||
"poppid": record.process,
|
||||
}
|
||||
|
||||
|
||||
@@ -58,23 +55,11 @@ class DefaultJSONFormatter(json_log_formatter.JSONFormatter):
|
||||
payload: dict[str, str | int | float] = super().json_record(
|
||||
message, extra, record
|
||||
)
|
||||
payload["logger"] = record.name
|
||||
payload["level"] = record.levelname
|
||||
payload["pid"] = record.process
|
||||
return payload
|
||||
|
||||
|
||||
class NoPingFilter(logging.Filter):
|
||||
"""
|
||||
Filters out /ping requests from the access log.
|
||||
"""
|
||||
|
||||
def filter(self, record: logging.LogRecord) -> bool:
|
||||
return not( record.args.get("m", "") == "GET"
|
||||
and record.args.get("U", "") == "/ping"
|
||||
and str(record.args.get("s", "")) == "200" )
|
||||
|
||||
|
||||
bind = ["0.0.0.0:8000"]
|
||||
name = "satosa"
|
||||
python_path = "/app"
|
||||
@@ -91,9 +76,6 @@ accesslog = "-"
|
||||
errorlog = "-"
|
||||
loglevel = os.environ.get("LOG_LEVEL", "INFO")
|
||||
|
||||
loglevels_json = os.environ.get("LOG_LEVELS", "{}")
|
||||
loglevels = json.loads(loglevels_json)
|
||||
|
||||
logconfig_dict = {
|
||||
"version": 1,
|
||||
"disable_existing_loggers": True,
|
||||
@@ -113,24 +95,7 @@ logconfig_dict = {
|
||||
"handlers": ["json_request"],
|
||||
"propagate": False,
|
||||
"qualname": "gunicorn.access",
|
||||
"filters": [NoPingFilter()],
|
||||
},
|
||||
"satosa.base": {
|
||||
"level": "INFO",
|
||||
},
|
||||
"satosa.state": {
|
||||
"level": "INFO",
|
||||
},
|
||||
"satosa.proxy_server": {
|
||||
"level": "INFO",
|
||||
},
|
||||
"satosa.routing": {
|
||||
"level": "INFO",
|
||||
},
|
||||
"satosa.frontends.ping": {
|
||||
"level": "INFO",
|
||||
},
|
||||
**{k: {"level": v.upper()} for k, v in loglevels.items()},
|
||||
},
|
||||
"formatters": {
|
||||
"json_request": {
|
||||
|
||||
@@ -9,8 +9,7 @@ satosa:
|
||||
BASE_URL: https://renater.agentconnect.gouv.fr
|
||||
GUNICORN_CMD_ARGS: --workers=3
|
||||
|
||||
LOG_LEVEL: INFO
|
||||
LOG_LEVELS: '{ "satosa.backends.saml2": "DEBUG" }'
|
||||
LOG_LEVEL: debug
|
||||
|
||||
SAML2_DISCOVERY_URL: https://discovery.renater.fr/agentconnect/
|
||||
SAML2_METADATA_URL: https://pub.federation.renater.fr/metadata/renater/main/main-idps-renater-metadata.xml
|
||||
|
||||
@@ -9,8 +9,7 @@ satosa:
|
||||
BASE_URL: https://oidc2fer-staging.beta.numerique.gouv.fr
|
||||
GUNICORN_CMD_ARGS: --workers=3
|
||||
|
||||
LOG_LEVEL: DEBUG
|
||||
LOG_LEVELS: '{ "satosa.backends.saml2": "DEBUG" }'
|
||||
LOG_LEVEL: debug
|
||||
|
||||
SAML2_DISCOVERY_URL: https://discovery.renater.fr/test/
|
||||
SAML2_METADATA_URL: https://pub.federation.renater.fr/metadata/test/preview/preview-idps-test-metadata.xml
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{{- if .Values.ingress.enabled -}}
|
||||
{{- $fullName := include "oidc2fer.fullname" . -}}
|
||||
{{- $port := .Values.satosa.service.port -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
@@ -34,15 +33,13 @@ spec:
|
||||
- host: {{ .Values.ingress.host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .Values.ingress.paths }}
|
||||
- path: {{ .path | quote }}
|
||||
pathType: {{ .pathType }}
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ $fullName }}-satosa
|
||||
name: {{ include "oidc2fer.satosa.fullname" . }}
|
||||
port:
|
||||
number: {{ $port }}
|
||||
{{- end }}
|
||||
number: {{ .Values.satosa.service.port }}
|
||||
{{- with .Values.ingress.customBackends }}
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
|
||||
@@ -33,9 +33,7 @@ ingress:
|
||||
enabled: false
|
||||
className: null
|
||||
host: oidc2fer.example.com
|
||||
paths:
|
||||
- path: '/$|^/\.well-known/openid-configuration$|^/images/|^/Saml2/|^/OIDC/|^/ping$'
|
||||
pathType: ImplementationSpecific # enables regex matching
|
||||
path: /
|
||||
## @param ingress.hosts Additional host to configure for the Ingress
|
||||
hosts: []
|
||||
# - chart-example.local
|
||||
@@ -50,9 +48,6 @@ ingress:
|
||||
## @param ingress.customBackends Add custom backends to ingress
|
||||
customBackends: []
|
||||
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/use-regex: "true"
|
||||
|
||||
## @section satosa
|
||||
|
||||
satosa:
|
||||
|
||||
@@ -75,26 +75,26 @@ def test_oidc_to_renater_student_not_allowed(page: Page):
|
||||
expect(page.locator("pre")).to_contain_text('"error":"access_denied"')
|
||||
|
||||
|
||||
def pro_connect_login(page: Page, email):
|
||||
def agent_connect_login(page: Page, email):
|
||||
page.goto("https://fsa1v2.integ01.dev-agentconnect.fr/")
|
||||
page.get_by_role("button", name="S’identifier avec ProConnect").click()
|
||||
page.get_by_label("Connexion à AgentConnect").click()
|
||||
page.get_by_label("Email professionnel").fill(email)
|
||||
page.get_by_test_id("interaction-connection-button").click()
|
||||
|
||||
|
||||
def pro_connect_to_renater(
|
||||
def agent_connect_to_renater(
|
||||
page: Page,
|
||||
login="enseignant1",
|
||||
expected_email="georges.grospieds@formation.renater.fr",
|
||||
expected_given_name="Georges",
|
||||
expected_usual_name="Grospieds",
|
||||
):
|
||||
pro_connect_login(page, email=expected_email)
|
||||
agent_connect_login(page, email=expected_email)
|
||||
renater_wayf(page)
|
||||
renater_test_idp(page, login=login)
|
||||
|
||||
expect(page.locator("body")).to_contain_text(expected_email)
|
||||
text = page.inner_text("#userinfo")
|
||||
text = page.inner_text("#json")
|
||||
result = json.loads(text)
|
||||
assert {
|
||||
"uid": f"{login}@test-renater.fr",
|
||||
@@ -106,22 +106,22 @@ def pro_connect_to_renater(
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
"TEST_E2E_PC" not in os.environ, reason="Depends on staging deployment"
|
||||
"TEST_E2E_AC" not in os.environ, reason="Depends on staging deployment"
|
||||
)
|
||||
def test_pro_connect_to_renater_keeps_sub(browser: Browser):
|
||||
def test_agent_connect_to_renater_keeps_sub(browser: Browser):
|
||||
with browser.new_context().new_page() as page:
|
||||
result1 = pro_connect_to_renater(page)
|
||||
result1 = agent_connect_to_renater(page)
|
||||
with browser.new_context().new_page() as page:
|
||||
result2 = pro_connect_to_renater(page)
|
||||
result2 = agent_connect_to_renater(page)
|
||||
|
||||
assert result1["sub"] == result2["sub"]
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
"TEST_E2E_PC" not in os.environ, reason="Depends on staging deployment"
|
||||
"TEST_E2E_AC" not in os.environ, reason="Depends on staging deployment"
|
||||
)
|
||||
def test_pro_connect_to_renater_student_not_allowed(page: Page):
|
||||
pro_connect_login(page, email="jean.dupont@formation.renater.fr")
|
||||
def test_agent_connect_to_renater_student_not_allowed(page: Page):
|
||||
agent_connect_login(page, email="jean.dupont@formation.renater.fr")
|
||||
renater_wayf(page)
|
||||
renater_test_idp(page, login="etudiant1")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user