audit: add cleanse_dict function to ensure no passwords end in logs
This commit is contained in:
parent
21ba969072
commit
96a6ac85df
|
@ -12,6 +12,7 @@ from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
from django.views.debug import CLEANSED_SUBSTITUTE, HIDDEN_SETTINGS
|
||||||
from guardian.shortcuts import get_anonymous_user
|
from guardian.shortcuts import get_anonymous_user
|
||||||
from structlog import get_logger
|
from structlog import get_logger
|
||||||
|
|
||||||
|
@ -20,6 +21,22 @@ from passbook.lib.utils.http import get_client_ip
|
||||||
LOGGER = get_logger()
|
LOGGER = get_logger()
|
||||||
|
|
||||||
|
|
||||||
|
def cleanse_dict(source: Dict[Any, Any]) -> Dict[Any, Any]:
|
||||||
|
"""Cleanse a dictionary, recursively"""
|
||||||
|
final_dict = {}
|
||||||
|
for key, value in source.items():
|
||||||
|
try:
|
||||||
|
if HIDDEN_SETTINGS.search(key):
|
||||||
|
final_dict[key] = CLEANSED_SUBSTITUTE
|
||||||
|
else:
|
||||||
|
final_dict[key] = value
|
||||||
|
except TypeError:
|
||||||
|
final_dict[key] = value
|
||||||
|
if isinstance(value, dict):
|
||||||
|
final_dict[key] = cleanse_dict(value)
|
||||||
|
return final_dict
|
||||||
|
|
||||||
|
|
||||||
def sanitize_dict(source: Dict[Any, Any]) -> Dict[Any, Any]:
|
def sanitize_dict(source: Dict[Any, Any]) -> Dict[Any, Any]:
|
||||||
"""clean source of all Models that would interfere with the JSONField.
|
"""clean source of all Models that would interfere with the JSONField.
|
||||||
Models are replaced with a dictionary of {
|
Models are replaced with a dictionary of {
|
||||||
|
@ -107,7 +124,7 @@ class Event(models.Model):
|
||||||
)
|
)
|
||||||
if not app:
|
if not app:
|
||||||
app = getmodule(stack()[_inspect_offset][0]).__name__
|
app = getmodule(stack()[_inspect_offset][0]).__name__
|
||||||
cleaned_kwargs = sanitize_dict(kwargs)
|
cleaned_kwargs = cleanse_dict(sanitize_dict(kwargs))
|
||||||
event = Event(action=action.value, app=app, context=cleaned_kwargs)
|
event = Event(action=action.value, app=app, context=cleaned_kwargs)
|
||||||
return event
|
return event
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ from django.views.decorators.clickjacking import xframe_options_sameorigin
|
||||||
from django.views.generic import TemplateView, View
|
from django.views.generic import TemplateView, View
|
||||||
from structlog import get_logger
|
from structlog import get_logger
|
||||||
|
|
||||||
from passbook.audit.models import sanitize_dict
|
from passbook.audit.models import cleanse_dict
|
||||||
from passbook.core.views.utils import PermissionDeniedView
|
from passbook.core.views.utils import PermissionDeniedView
|
||||||
from passbook.flows.exceptions import EmptyFlowException, FlowNonApplicableException
|
from passbook.flows.exceptions import EmptyFlowException, FlowNonApplicableException
|
||||||
from passbook.flows.models import Flow, FlowDesignation, Stage
|
from passbook.flows.models import Flow, FlowDesignation, Stage
|
||||||
|
@ -162,7 +162,7 @@ class FlowExecutorView(View):
|
||||||
LOGGER.debug(
|
LOGGER.debug(
|
||||||
"f(exec): User passed all stages",
|
"f(exec): User passed all stages",
|
||||||
flow_slug=self.flow.slug,
|
flow_slug=self.flow.slug,
|
||||||
context=sanitize_dict(self.plan.context),
|
context=cleanse_dict(self.plan.context),
|
||||||
)
|
)
|
||||||
return self._flow_done()
|
return self._flow_done()
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ class ChangeFlowInitView(LoginRequiredMixin, View):
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
plan = FlowPlanner(stage.change_flow).plan(
|
plan = FlowPlanner(stage.change_flow).plan(
|
||||||
request, {PLAN_CONTEXT_PENDING_USER: request.user,}
|
request, {PLAN_CONTEXT_PENDING_USER: request.user}
|
||||||
)
|
)
|
||||||
request.session[SESSION_KEY_PLAN] = plan
|
request.session[SESSION_KEY_PLAN] = plan
|
||||||
return redirect_with_qs(
|
return redirect_with_qs(
|
||||||
|
|
Reference in New Issue