This repository has been archived on 2024-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
authentik/passbook/audit/models.py

82 lines
2.8 KiB
Python
Raw Normal View History

2018-11-23 16:05:41 +00:00
"""passbook audit models"""
from json import dumps, loads
2018-12-10 12:51:16 +00:00
from logging import getLogger
2018-11-23 16:05:41 +00:00
from django.conf import settings
2018-12-10 14:26:28 +00:00
from django.contrib.auth.models import AnonymousUser
from django.core.exceptions import ValidationError
2018-11-23 16:05:41 +00:00
from django.db import models
from django.utils.translation import gettext as _
from ipware import get_client_ip
2018-11-23 16:05:41 +00:00
from reversion import register
from passbook.lib.models import UUIDModel
LOGGER = getLogger(__name__)
2018-11-23 16:05:41 +00:00
@register()
class AuditEntry(UUIDModel):
"""An individual audit log entry"""
ACTION_LOGIN = 'login'
ACTION_LOGIN_FAILED = 'login_failed'
ACTION_LOGOUT = 'logout'
ACTION_AUTHORIZE_APPLICATION = 'authorize_application'
ACTION_SUSPICIOUS_REQUEST = 'suspicious_request'
ACTION_SIGN_UP = 'sign_up'
2018-12-10 13:26:10 +00:00
ACTION_PASSWORD_RESET = 'password_reset' # noqa
2018-12-10 13:21:42 +00:00
ACTION_INVITE_CREATED = 'invitation_created'
ACTION_INVITE_USED = 'invitation_used'
ACTIONS = (
(ACTION_LOGIN, ACTION_LOGIN),
(ACTION_LOGIN_FAILED, ACTION_LOGIN_FAILED),
(ACTION_LOGOUT, ACTION_LOGOUT),
(ACTION_AUTHORIZE_APPLICATION, ACTION_AUTHORIZE_APPLICATION),
(ACTION_SUSPICIOUS_REQUEST, ACTION_SUSPICIOUS_REQUEST),
(ACTION_SIGN_UP, ACTION_SIGN_UP),
(ACTION_PASSWORD_RESET, ACTION_PASSWORD_RESET),
(ACTION_INVITE_CREATED, ACTION_INVITE_CREATED),
(ACTION_INVITE_USED, ACTION_INVITE_USED),
)
2018-11-23 16:05:41 +00:00
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL)
action = models.TextField(choices=ACTIONS)
2018-11-23 16:05:41 +00:00
date = models.DateTimeField(auto_now_add=True)
app = models.TextField()
_context = models.TextField()
_context_cache = None
request_ip = models.GenericIPAddressField()
@property
def context(self):
"""Load context data and load json"""
if not self._context_cache:
self._context_cache = loads(self._context)
return self._context_cache
@staticmethod
def create(action, request, **kwargs):
"""Create AuditEntry from arguments"""
client_ip, _ = get_client_ip(request)
2018-12-10 14:26:28 +00:00
user = request.user
if isinstance(user, AnonymousUser):
user = kwargs.get('user', None)
entry = AuditEntry.objects.create(
action=action,
2018-12-10 14:26:28 +00:00
user=user,
2018-12-10 13:26:10 +00:00
# User 255.255.255.255 as fallback if IP cannot be determined
request_ip=client_ip or '255.255.255.255',
_context=dumps(kwargs))
LOGGER.debug("Logged %s from %s (%s)", action, request.user, client_ip)
return entry
2018-11-23 16:05:41 +00:00
def save(self, *args, **kwargs):
if not self._state.adding:
raise ValidationError("you may not edit an existing %s" % self._meta.model_name)
2018-11-23 16:05:41 +00:00
super().save(*args, **kwargs)
class Meta:
verbose_name = _('Audit Entry')
verbose_name_plural = _('Audit Entries')