Skip to content

Commit 58175ce

Browse files
authored
Log HTTP referer and origin (#1429)
1 parent a2dcfad commit 58175ce

File tree

2 files changed

+41
-33
lines changed

2 files changed

+41
-33
lines changed

src/server/_common.py

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ def log_info_with_request(message, **kwargs):
6868
remote_addr=request.remote_addr,
6969
real_remote_addr=get_real_ip_addr(request),
7070
user_agent=request.user_agent.string,
71+
referrer=request.referrer or request.origin,
7172
api_key=resolve_auth_token(),
7273
user_id=(current_user and current_user.id),
7374
**kwargs
@@ -114,19 +115,7 @@ def before_request_execute():
114115
user = current_user
115116
api_key = resolve_auth_token()
116117

117-
# TODO: replace this next call with: log_info_with_request("Received API request")
118-
get_structured_logger("server_api").info(
119-
"Received API request",
120-
method=request.method,
121-
url=request.url,
122-
form_args=request.form,
123-
req_length=request.content_length,
124-
remote_addr=request.remote_addr,
125-
real_remote_addr=get_real_ip_addr(request),
126-
user_agent=request.user_agent.string,
127-
api_key=api_key,
128-
user_id=(user and user.id)
129-
)
118+
log_info_with_request("Received API request")
130119

131120
if not _is_public_route() and api_key and not user:
132121
# if this is a privleged endpoint, and an api key was given but it does not look up to a user, raise exception:
@@ -150,28 +139,10 @@ def after_request_execute(response):
150139
# Convert to milliseconds
151140
total_time *= 1000
152141

153-
api_key = resolve_auth_token()
154-
155142
update_key_last_time_used(current_user)
156143

157-
# TODO: replace this next call with: log_info_with_request_and_response("Served API request", response, elapsed_time_ms=total_time)
158-
get_structured_logger("server_api").info(
159-
"Served API request",
160-
method=request.method,
161-
url=request.url,
162-
form_args=request.form,
163-
req_length=request.content_length,
164-
remote_addr=request.remote_addr,
165-
real_remote_addr=get_real_ip_addr(request),
166-
user_agent=request.user_agent.string,
167-
api_key=api_key,
168-
values=request.values.to_dict(flat=False),
169-
blueprint=request.blueprint,
170-
endpoint=request.endpoint,
171-
response_status=response.status,
172-
content_length=response.calculate_content_length(),
173-
elapsed_time_ms=total_time,
174-
)
144+
log_info_with_request_and_response("Served API request", response, elapsed_time_ms=total_time)
145+
175146
return response
176147

177148

tests/server/test_validate.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def setUp(self):
2626
app.config["TESTING"] = True
2727
app.config["WTF_CSRF_ENABLED"] = False
2828
app.config["DEBUG"] = False
29+
self.client = app.test_client()
2930

3031
def test_require_all(self):
3132
with self.subTest("all given"):
@@ -60,3 +61,39 @@ def test_require_any(self):
6061
with self.subTest("one options given with is empty but ok"):
6162
with app.test_request_context("/?abc="):
6263
self.assertTrue(require_any(request, "abc", empty=True))
64+
65+
def test_origin_headers(self):
66+
with self.subTest("referer only"):
67+
with self.assertLogs("server_api", level='INFO') as logs:
68+
self.client.get("/signal_dashboard_status", headers={
69+
"Referer": "https://test.com/test"
70+
})
71+
output = logs.output
72+
self.assertEqual(len(output), 2) # [before_request, after_request]
73+
self.assertIn("Received API request", output[0])
74+
self.assertIn("\"referrer\": \"https://test.com/test\"", output[0])
75+
self.assertIn("Served API request", output[1])
76+
self.assertIn("\"referrer\": \"https://test.com/test\"", output[1])
77+
with self.subTest("origin only"):
78+
with self.assertLogs("server_api", level='INFO') as logs:
79+
self.client.get("/signal_dashboard_status", headers={
80+
"Origin": "https://test.com"
81+
})
82+
output = logs.output
83+
self.assertEqual(len(output), 2) # [before_request, after_request]
84+
self.assertIn("Received API request", output[0])
85+
self.assertIn("\"referrer\": \"https://test.com\"", output[0])
86+
self.assertIn("Served API request", output[1])
87+
self.assertIn("\"referrer\": \"https://test.com\"", output[1])
88+
with self.subTest("referer overrides origin"):
89+
with self.assertLogs("server_api", level='INFO') as logs:
90+
self.client.get("/signal_dashboard_status", headers={
91+
"Referer": "https://test.com/test",
92+
"Origin": "https://test.com"
93+
})
94+
output = logs.output
95+
self.assertEqual(len(output), 2) # [before_request, after_request]
96+
self.assertIn("Received API request", output[0])
97+
self.assertIn("\"referrer\": \"https://test.com/test\"", output[0])
98+
self.assertIn("Served API request", output[1])
99+
self.assertIn("\"referrer\": \"https://test.com/test\"", output[1])

0 commit comments

Comments
 (0)