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.http import HttpRequest
|
||||
from django.utils.translation import gettext as _
|
||||
from django.views.debug import CLEANSED_SUBSTITUTE, HIDDEN_SETTINGS
|
||||
from guardian.shortcuts import get_anonymous_user
|
||||
from structlog import get_logger
|
||||
|
||||
|
@ -20,6 +21,22 @@ from passbook.lib.utils.http import get_client_ip
|
|||
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]:
|
||||
"""clean source of all Models that would interfere with the JSONField.
|
||||
Models are replaced with a dictionary of {
|
||||
|
@ -107,7 +124,7 @@ class Event(models.Model):
|
|||
)
|
||||
if not app:
|
||||
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)
|
||||
return event
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ from django.views.decorators.clickjacking import xframe_options_sameorigin
|
|||
from django.views.generic import TemplateView, View
|
||||
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.flows.exceptions import EmptyFlowException, FlowNonApplicableException
|
||||
from passbook.flows.models import Flow, FlowDesignation, Stage
|
||||
|
@ -162,7 +162,7 @@ class FlowExecutorView(View):
|
|||
LOGGER.debug(
|
||||
"f(exec): User passed all stages",
|
||||
flow_slug=self.flow.slug,
|
||||
context=sanitize_dict(self.plan.context),
|
||||
context=cleanse_dict(self.plan.context),
|
||||
)
|
||||
return self._flow_done()
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ class ChangeFlowInitView(LoginRequiredMixin, View):
|
|||
raise Http404
|
||||
|
||||
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
|
||||
return redirect_with_qs(
|
||||
|
|
Reference in a new issue