Skip to content

Commit b6f8ede

Browse files
feat: is_authenticated request logging + cleanup (ietf-tools#7893)
* chore: nginx log is s, not ms * chore: log seconds from gunicorn too * chore: drop X-Real-IP header / log * style: Black * style: single -> double quotes * feat: add is-authenticated header * feat: log is-authenticated header * chore: update nginx-auth.conf to match
1 parent 061c89f commit b6f8ede

6 files changed

Lines changed: 60 additions & 31 deletions

File tree

ietf/middleware.py

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,45 +17,61 @@ def sql_log_middleware(get_response):
1717
def sql_log(request):
1818
response = get_response(request)
1919
for q in connection.queries:
20-
if re.match('(update|insert)', q['sql'], re.IGNORECASE):
21-
log(q['sql'])
20+
if re.match("(update|insert)", q["sql"], re.IGNORECASE):
21+
log(q["sql"])
2222
return response
23+
2324
return sql_log
2425

26+
2527
class SMTPExceptionMiddleware(object):
2628
def __init__(self, get_response):
2729
self.get_response = get_response
30+
2831
def __call__(self, request):
2932
return self.get_response(request)
33+
3034
def process_exception(self, request, exception):
3135
if isinstance(exception, smtplib.SMTPException):
3236
(extype, value, tb) = log_smtp_exception(exception)
33-
return render(request, 'email_failed.html',
34-
{'exception': extype, 'args': value, 'traceback': "".join(tb)} )
37+
return render(
38+
request,
39+
"email_failed.html",
40+
{"exception": extype, "args": value, "traceback": "".join(tb)},
41+
)
3542
return None
3643

44+
3745
class Utf8ExceptionMiddleware(object):
3846
def __init__(self, get_response):
3947
self.get_response = get_response
48+
4049
def __call__(self, request):
4150
return self.get_response(request)
51+
4252
def process_exception(self, request, exception):
4353
if isinstance(exception, OperationalError):
4454
extype, e, tb = exc_parts()
4555
if e.args[0] == 1366:
4656
log("Database 4-byte utf8 exception: %s: %s" % (extype, e))
47-
return render(request, 'utf8_4byte_failed.html',
48-
{'exception': extype, 'args': e.args, 'traceback': "".join(tb)} )
57+
return render(
58+
request,
59+
"utf8_4byte_failed.html",
60+
{"exception": extype, "args": e.args, "traceback": "".join(tb)},
61+
)
4962
return None
5063

64+
5165
def redirect_trailing_period_middleware(get_response):
5266
def redirect_trailing_period(request):
5367
response = get_response(request)
5468
if response.status_code == 404 and request.path.endswith("."):
5569
return HttpResponsePermanentRedirect(request.path.rstrip("."))
5670
return response
71+
5772
return redirect_trailing_period
5873

74+
5975
def unicode_nfkc_normalization_middleware(get_response):
6076
def unicode_nfkc_normalization(request):
6177
"""Do Unicode NFKC normalization to turn ligatures into individual characters.
@@ -65,9 +81,21 @@ def unicode_nfkc_normalization(request):
6581
There are probably other elements of a request which may need this normalization
6682
too, but let's put that in as it comes up, rather than guess ahead.
6783
"""
68-
request.META["PATH_INFO"] = unicodedata.normalize('NFKC', request.META["PATH_INFO"])
69-
request.path_info = unicodedata.normalize('NFKC', request.path_info)
84+
request.META["PATH_INFO"] = unicodedata.normalize(
85+
"NFKC", request.META["PATH_INFO"]
86+
)
87+
request.path_info = unicodedata.normalize("NFKC", request.path_info)
7088
response = get_response(request)
7189
return response
90+
7291
return unicode_nfkc_normalization
73-
92+
93+
94+
def is_authenticated_header_middleware(get_response):
95+
"""Middleware to add an is-authenticated header to the response"""
96+
def add_header(request):
97+
response = get_response(request)
98+
response["X-Datatracker-Is-Authenticated"] = "yes" if request.user.is_authenticated else "no"
99+
return response
100+
101+
return add_header

ietf/settings.py

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -401,24 +401,25 @@ def skip_unreadable_post(record):
401401

402402

403403
MIDDLEWARE = [
404-
'django.middleware.csrf.CsrfViewMiddleware',
405-
'corsheaders.middleware.CorsMiddleware', # see docs on CORS_REPLACE_HTTPS_REFERER before using it
406-
'django.middleware.common.CommonMiddleware',
407-
'django.contrib.sessions.middleware.SessionMiddleware',
408-
'django.contrib.auth.middleware.AuthenticationMiddleware',
409-
'django.contrib.messages.middleware.MessageMiddleware',
410-
'django.middleware.http.ConditionalGetMiddleware',
411-
'simple_history.middleware.HistoryRequestMiddleware',
404+
"django.middleware.csrf.CsrfViewMiddleware",
405+
"corsheaders.middleware.CorsMiddleware", # see docs on CORS_REPLACE_HTTPS_REFERER before using it
406+
"django.middleware.common.CommonMiddleware",
407+
"django.contrib.sessions.middleware.SessionMiddleware",
408+
"django.contrib.auth.middleware.AuthenticationMiddleware",
409+
"django.contrib.messages.middleware.MessageMiddleware",
410+
"django.middleware.http.ConditionalGetMiddleware",
411+
"simple_history.middleware.HistoryRequestMiddleware",
412412
# comment in this to get logging of SQL insert and update statements:
413-
#'ietf.middleware.sql_log_middleware',
414-
'ietf.middleware.SMTPExceptionMiddleware',
415-
'ietf.middleware.Utf8ExceptionMiddleware',
416-
'ietf.middleware.redirect_trailing_period_middleware',
417-
'django_referrer_policy.middleware.ReferrerPolicyMiddleware',
418-
'django.middleware.clickjacking.XFrameOptionsMiddleware',
419-
'django.middleware.security.SecurityMiddleware',
420-
# 'csp.middleware.CSPMiddleware',
421-
'ietf.middleware.unicode_nfkc_normalization_middleware',
413+
#"ietf.middleware.sql_log_middleware",
414+
"ietf.middleware.SMTPExceptionMiddleware",
415+
"ietf.middleware.Utf8ExceptionMiddleware",
416+
"ietf.middleware.redirect_trailing_period_middleware",
417+
"django_referrer_policy.middleware.ReferrerPolicyMiddleware",
418+
"django.middleware.clickjacking.XFrameOptionsMiddleware",
419+
"django.middleware.security.SecurityMiddleware",
420+
#"csp.middleware.CSPMiddleware",
421+
"ietf.middleware.unicode_nfkc_normalization_middleware",
422+
"ietf.middleware.is_authenticated_header_middleware",
422423
]
423424

424425
ROOT_URLCONF = 'ietf.urls'

ietf/utils/jsonlogger.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ def add_fields(self, log_record, record, message_dict):
2323
log_record.setdefault("referer", record.args["f"])
2424
log_record.setdefault("user_agent", record.args["a"])
2525
log_record.setdefault("len_bytes", record.args["B"])
26-
log_record.setdefault("duration_ms", record.args["M"])
26+
log_record.setdefault("duration_s", record.args["L"]) # decimal seconds
2727
log_record.setdefault("host", record.args["{host}i"])
2828
log_record.setdefault("x_request_start", record.args["{x-request-start}i"])
29-
log_record.setdefault("x_real_ip", record.args["{x-real-ip}i"])
3029
log_record.setdefault("x_forwarded_for", record.args["{x-forwarded-for}i"])
3130
log_record.setdefault("x_forwarded_proto", record.args["{x-forwarded-proto}i"])
3231
log_record.setdefault("cf_connecting_ip", record.args["{cf-connecting-ip}i"])
3332
log_record.setdefault("cf_connecting_ipv6", record.args["{cf-connecting-ipv6}i"])
3433
log_record.setdefault("cf_ray", record.args["{cf-ray}i"])
34+
log_record.setdefault("is_authenticated", record.args["{x-datatracker-is-authenticated}i"])

k8s/nginx-auth.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ server {
3232
proxy_set_header Connection close;
3333
proxy_set_header X-Request-Start "t=$${keepempty}msec";
3434
proxy_set_header X-Forwarded-For $${keepempty}proxy_add_x_forwarded_for;
35-
proxy_set_header X-Real-IP $${keepempty}remote_addr;
35+
proxy_hide_header X-Datatracker-Is-Authenticated; # hide this from the outside world
3636
proxy_pass http://localhost:8000;
3737
# Set timeouts longer than Cloudflare proxy limits
3838
proxy_connect_timeout 60; # nginx default (Cf = 15)

k8s/nginx-datatracker.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ server {
2121
proxy_set_header Connection close;
2222
proxy_set_header X-Request-Start "t=$${keepempty}msec";
2323
proxy_set_header X-Forwarded-For $${keepempty}proxy_add_x_forwarded_for;
24-
proxy_set_header X-Real-IP $${keepempty}remote_addr;
24+
proxy_hide_header X-Datatracker-Is-Authenticated; # hide this from the outside world
2525
proxy_pass http://localhost:8000;
2626
# Set timeouts longer than Cloudflare proxy limits
2727
proxy_connect_timeout 60; # nginx default (Cf = 15)

k8s/nginx-logging.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ log_format ietfjson escape=json
99
'"method":"$${keepempty}request_method",'
1010
'"status":"$${keepempty}status",'
1111
'"len_bytes":"$${keepempty}body_bytes_sent",'
12-
'"duration_ms":"$${keepempty}request_time",'
12+
'"duration_s":"$${keepempty}request_time",'
1313
'"referer":"$${keepempty}http_referer",'
1414
'"user_agent":"$${keepempty}http_user_agent",'
1515
'"x_forwarded_for":"$${keepempty}http_x_forwarded_for",'

0 commit comments

Comments
 (0)