felicity-lims/backend/felicity_lims/felicity/apps/audit/models.py

75 lines
2.5 KiB
Python
Raw Normal View History

2021-09-06 02:05:20 +08:00
import json
import logging
2021-05-06 21:48:09 +08:00
from sqlalchemy import Column, Integer, String, UnicodeText
from felicity.apps import DBModel
2021-09-06 02:05:20 +08:00
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
2021-05-06 21:48:09 +08:00
class AuditLog(DBModel):
"""Model an audit log of user actions"""
user_id = Column(Integer, doc="The ID of the user who made the change")
target_type = Column(String(100), nullable=False, doc="The table name of the altered object")
target_id = Column(Integer, doc="The ID of the altered object")
action = Column(Integer, doc="Create (1), update (2), or delete (3)")
state_before = Column(UnicodeText, doc="Stores a JSON string representation of a dict containing the altered "
"column names and original values")
state_after = Column(UnicodeText, doc="Stores a JSON string representation of a dict containing the altered "
"column names and new values")
def __init__(self, target_type, target_id, action, state_before, state_after):
2021-09-06 02:05:20 +08:00
self.state_after = state_after
2021-05-06 21:48:09 +08:00
self.target_type = target_type
self.target_id = target_id
self.action = action
self.state_before = state_before
2021-09-06 02:05:20 +08:00
if isinstance(state_after, str):
state_after = json.loads(state_after)
try:
updated_by_uid = state_after['updated_by_uid']
except KeyError:
updated_by_uid = None
self.user_id = updated_by_uid # current user id
2021-05-06 21:48:09 +08:00
def __repr__(self):
return '<AuditLog %r: %r -> %r>' % (self.user_id, self.target_type, self.action)
def save(self, connection):
2021-09-06 02:05:20 +08:00
state_after = self.state_after
if isinstance(state_after, str):
state_after = json.loads(state_after)
state_before = self.state_before
if isinstance(state_before, str):
state_before = json.loads(state_before)
to_delete = []
for key in state_after.keys():
if state_after[key] == state_before[key]:
to_delete.append(key)
for _key in to_delete:
del state_after[_key]
del state_before[_key]
state_after = json.dumps(state_after)
state_before = json.dumps(state_before)
2021-05-06 21:48:09 +08:00
connection.execute(
self.__table__.insert(),
user_id=self.user_id,
target_type=self.target_type,
target_id=self.target_id,
action=self.action,
2021-09-06 02:05:20 +08:00
state_before=state_before,
state_after=state_after
2021-05-06 21:48:09 +08:00
)