Skip to content

Commit 8f6a439

Browse files
Refactor and tests (#14) (#15)
* Added tests, start refactor work on signals * Update get_request_info function to work with dict objects, which would allow changing and inserting various fields easier * Added a message formatter that will take our siem_data (created by updated function above) and format it as a valid json string, while stripping the open and closing brackets. * Updated the signals handlers so that they use our new methods (defined above) * Added tests for all the above * variable name update * Tests and refactor for middlewares * Rename middlewares.py -> middleware.py * Since name changed, needs updated here also * Prevent error when user refresh logout page * Add optional django-ipware integration Co-authored-by: Andre Engelbrecht <[email protected]>
1 parent 7a9de57 commit 8f6a439

File tree

6 files changed

+563
-99
lines changed

6 files changed

+563
-99
lines changed

auditing/__init__.py

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,38 @@
66
from django.dispatch import receiver
77
from django.conf import settings
88

9-
from . utils import get_request_info
9+
from .utils import get_request_info, format_log_message
1010

1111

1212
logger = logging.getLogger(__name__)
1313

14-
USER_FIELD = getattr(settings, 'AUDIT_USERNAME_FIELD', 'username')
15-
1614

1715
@receiver(user_logged_in)
18-
def login_logger(sender, request, **kwargs):
19-
_msg = '"Django Login successful", "username": "{}", {}'
20-
logger.info(_msg.format(request.POST[USER_FIELD],
21-
get_request_info(request)))
16+
def login_logger(sender, **kwargs):
17+
msg_data = get_request_info(kwargs['request'])
18+
msg_data['username'] = kwargs['user'].get_username()
19+
logger.info('"Django Login successful", {}'.format(
20+
format_log_message(msg_data)))
2221

2322

2423
@receiver(user_login_failed)
25-
def login_failed_logger(sender, request, **kwargs):
26-
_msg = '"Django Login failed", "username": "{}", {}'
27-
logger.warn(_msg.format(request.POST[USER_FIELD],
28-
get_request_info(request)))
24+
def login_failed_logger(sender, **kwargs):
25+
USER_FIELD = getattr(settings, 'AUDIT_USERNAME_FIELD', 'username')
26+
msg_data = get_request_info(kwargs['request'])
27+
msg_data['username'] = kwargs['credentials'][USER_FIELD]
28+
logger.warn('"Django Login failed", {}'.format(
29+
format_log_message(msg_data)))
2930

3031

3132
@receiver(user_logged_out)
32-
def logout_logger(sender, request, **kwargs):
33-
_msg = '"Django Logout successful", "username": "{}", {}'
34-
logger.info(_msg.format(request.user,
35-
get_request_info(request)))
33+
def logout_logger(sender, **kwargs):
34+
msg_data = get_request_info(kwargs['request'])
35+
user = kwargs.get('user', None)
36+
37+
if user is not None:
38+
msg_data['username'] = user.get_username()
39+
logger.info('"Django Logout successful", {}'.format(
40+
format_log_message(msg_data)))
41+
else:
42+
logger.debug('"Django Logout failed", {}'.format(
43+
format_log_message(msg_data)))

auditing/middleware.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import logging
2+
import json
3+
4+
from django.conf import settings
5+
from . utils import get_request_info, format_log_message
6+
7+
8+
logger = logging.getLogger(__name__)
9+
10+
11+
# AUDITING_REQUEST_RESPONSE_KEYS_REGEX = getattr(settings,
12+
# 'AUDITING_REQUEST_RESPONSE_KEYS_REGEX',
13+
# r'(HTTP_COOKIE|HTTP_USER_|SERVER_NAME|CSRF_|QUERY_|REMOTE_)')
14+
15+
# Assume all codes, and only remove or ignore the ones that are not to be
16+
# analyzed
17+
AUDIT_RESPONSE_STATUS_IGNORED = getattr(settings,
18+
'AUDIT_RESPONSE_STATUS_IGNORED',
19+
(200, 201, 202, 301, 302))
20+
21+
AUDIT_REQUEST_POST_IGNORED = getattr(settings,
22+
'AUDIT_REQUEST_POST_IGNORED',
23+
('password', 'password1', 'password2'))
24+
25+
26+
def http_headers_logging_middleware(get_response):
27+
28+
def middleware(request):
29+
msg_data = get_request_info(request)
30+
31+
# Remove any sensitive POST data that we don't want in the logs
32+
if request.method == 'POST':
33+
post_data = request.POST.copy()
34+
for k in AUDIT_REQUEST_POST_IGNORED:
35+
post_data.pop(k, None)
36+
msg_data['post'] = post_data
37+
38+
msg = '"Http Request POST", {}'.format(format_log_message(msg_data))
39+
logger.debug(msg)
40+
41+
resp = get_response(request)
42+
43+
if resp.status_code not in AUDIT_RESPONSE_STATUS_IGNORED:
44+
msg_data['status'] = resp.status_code
45+
msg = '"Http Response", {}'.format(format_log_message(msg_data))
46+
logger.error(msg)
47+
48+
# Add response headers to data
49+
msg_data.update(resp.items())
50+
51+
# Add response cookies
52+
msg_data['Resp-Cookies'] = resp.cookies.output()
53+
54+
# Finally create a debug log message
55+
msg_data.update({
56+
'method': request.method,
57+
'status': resp.status_code,
58+
})
59+
60+
msg = '"Http Response", {}'.format(format_log_message(msg_data))
61+
logger.debug(msg)
62+
63+
return resp
64+
65+
return middleware

auditing/middlewares.py

Lines changed: 0 additions & 68 deletions
This file was deleted.

0 commit comments

Comments
 (0)