Skip to content

Commit

Permalink
Merge branch 'master' into fix-jsonfield
Browse files Browse the repository at this point in the history
* master:
  Remove default_app_config configuration
  Fix lint entry in tox.ini
  Drop Django 2.2 support.
  [pre-commit.ci] pre-commit autoupdate
  Fix small typo
  Add mask_fields argument in register (jazzband#310)
  Use pre-commit as lint command
  Add black and isort to .pre-commit-config.yaml
  Replace assertTrue with assertEqual
  enable use of replica database (jazzband#359)
  • Loading branch information
barrachri committed May 8, 2022
2 parents aaec783 + e39fab3 commit 23ae65b
Show file tree
Hide file tree
Showing 19 changed files with 267 additions and 160 deletions.
15 changes: 14 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1 +1,14 @@
repos: []
---
repos:
- repo: https://github.com/psf/black
rev: 22.3.0
hooks:
- id: black
language_version: python3.8
args:
- "--target-version"
- "py37"
- repo: https://github.com/PyCQA/isort
rev: 5.10.1
hooks:
- id: isort
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changes

#### Improvements
- feat: enable use of replica database (delegating the choice to `DATABASES_ROUTER`) ([#359](https://github.com/jazzband/django-auditlog/pull/359))
- Add `mask_fields` argument in `register` to mask sensitive information when logging ([#3710](https://github.com/jazzband/django-auditlog/pull/310))
- Django: Drop 2.2 support. `django_jsonfield_backport` is not required anymore ([#370](https://github.com/jazzband/django-auditlog/pull/370))
- Remove `default_app_config` configuration ([#372](https://github.com/jazzband/django-auditlog/pull/372))

#### Important notes
- LogEntry no longer save to same database instance is using

## 1.0.0 (2022-01-24)

### Final
Expand Down
2 changes: 0 additions & 2 deletions auditlog/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,3 @@
except DistributionNotFound:
# package is not installed
pass

default_app_config = "auditlog.apps.AuditlogConfig"
21 changes: 20 additions & 1 deletion auditlog/diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,19 @@ def get_field_value(obj, field):
return value


def mask_str(value: str) -> str:
"""
Masks the first half of the input string to remove sensitive data.
:param value: The value to mask.
:type value: str
:return: The masked version of the string.
:rtype: str
"""
mask_limit = int(len(value) / 2)
return "*" * mask_limit + value[mask_limit:]


def model_instance_diff(old, new, fields_to_check=None):
"""
Calculates the differences between two model instances. One of the instances may be ``None`` (i.e., a newly
Expand Down Expand Up @@ -150,7 +163,13 @@ def model_instance_diff(old, new, fields_to_check=None):
new_value = get_field_value(new, field)

if old_value != new_value:
diff[field.name] = (smart_str(old_value), smart_str(new_value))
if model_fields and field.name in model_fields["mask_fields"]:
diff[field.name] = (
mask_str(smart_str(old_value)),
mask_str(smart_str(new_value)),
)
else:
diff[field.name] = (smart_str(old_value), smart_str(new_value))

if len(diff) == 0:
diff = None
Expand Down
5 changes: 2 additions & 3 deletions auditlog/migrations/0004_logentry_detailed_object_repr.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from django.db import migrations
from django_jsonfield_backport.models import JSONField
from django.db import migrations, models


class Migration(migrations.Migration):
Expand All @@ -12,6 +11,6 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name="logentry",
name="additional_data",
field=JSONField(null=True, blank=True),
field=models.JSONField(null=True, blank=True),
),
]
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from django.db import migrations
from django_jsonfield_backport.models import JSONField
from django.db import migrations, models


class Migration(migrations.Migration):
Expand All @@ -12,6 +11,8 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name="logentry",
name="additional_data",
field=JSONField(null=True, verbose_name="additional data", blank=True),
field=models.JSONField(
null=True, verbose_name="additional data", blank=True
),
),
]
7 changes: 4 additions & 3 deletions auditlog/migrations/0009_alter_logentry_additional_data.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from django.db import migrations
from django_jsonfield_backport.models import JSONField
from django.db import migrations, models


class Migration(migrations.Migration):
Expand All @@ -12,6 +11,8 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name="logentry",
name="additional_data",
field=JSONField(blank=True, null=True, verbose_name="additional data"),
field=models.JSONField(
blank=True, null=True, verbose_name="additional data"
),
),
]
11 changes: 2 additions & 9 deletions auditlog/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from django.utils import formats, timezone
from django.utils.encoding import smart_str
from django.utils.translation import gettext_lazy as _
from django_jsonfield_backport.models import JSONField


class LogEntryManager(models.Manager):
Expand Down Expand Up @@ -67,13 +66,7 @@ def log_create(self, instance, **kwargs):
content_type=kwargs.get("content_type"),
object_pk=kwargs.get("object_pk", ""),
).delete()
# save LogEntry to same database instance is using
db = instance._state.db
return (
self.create(**kwargs)
if db is None or db == ""
else self.using(db).create(**kwargs)
)
return self.create(**kwargs)
return None

def get_for_object(self, instance):
Expand Down Expand Up @@ -228,7 +221,7 @@ class Action:
blank=True, null=True, verbose_name=_("remote address")
)
timestamp = models.DateTimeField(auto_now_add=True, verbose_name=_("timestamp"))
additional_data = JSONField(
additional_data = models.JSONField(
blank=True, null=True, verbose_name=_("additional data")
)

Expand Down
6 changes: 6 additions & 0 deletions auditlog/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def register(
include_fields: Optional[List[str]] = None,
exclude_fields: Optional[List[str]] = None,
mapping_fields: Optional[Dict[str, str]] = None,
mask_fields: Optional[List[str]] = None,
):
"""
Register a model with auditlog. Auditlog will then track mutations on this model's instances.
Expand All @@ -48,6 +49,7 @@ def register(
:param include_fields: The fields to include. Implicitly excludes all other fields.
:param exclude_fields: The fields to exclude. Overrides the fields to include.
:param mapping_fields: Mapping from field names to strings in diff.
:param mask_fields: The fields to mask for sensitive info.
"""

Expand All @@ -57,6 +59,8 @@ def register(
exclude_fields = []
if mapping_fields is None:
mapping_fields = {}
if mask_fields is None:
mask_fields = []

def registrar(cls):
"""Register models for a given class."""
Expand All @@ -67,6 +71,7 @@ def registrar(cls):
"include_fields": include_fields,
"exclude_fields": exclude_fields,
"mapping_fields": mapping_fields,
"mask_fields": mask_fields,
}
self._connect_signals(cls)

Expand Down Expand Up @@ -114,6 +119,7 @@ def get_model_fields(self, model: ModelBase):
"include_fields": list(self._registry[model]["include_fields"]),
"exclude_fields": list(self._registry[model]["exclude_fields"]),
"mapping_fields": dict(self._registry[model]["mapping_fields"]),
"mask_fields": list(self._registry[model]["mask_fields"]),
}

def _connect_signals(self, model):
Expand Down
1 change: 0 additions & 1 deletion auditlog_tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
default_app_config = "auditlog_tests.apps.AuditlogTestConfig"
12 changes: 12 additions & 0 deletions auditlog_tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ class SimpleMappingModel(models.Model):
history = AuditlogHistoryField()


@auditlog.register(mask_fields=["address"])
class SimpleMaskedModel(models.Model):
"""
A simple model used for register's mask_fields kwarg
"""

address = models.CharField(max_length=100)
text = models.TextField()

history = AuditlogHistoryField()


class AdditionalDataIncludedModel(models.Model):
"""
A model where get_additional_data is defined which allows for logging extra
Expand Down
1 change: 0 additions & 1 deletion auditlog_tests/test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"django.contrib.sessions",
"django.contrib.admin",
"django.contrib.staticfiles",
"django_jsonfield_backport",
"auditlog",
"auditlog_tests",
]
Expand Down
Loading

0 comments on commit 23ae65b

Please sign in to comment.