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

84 lines
2.9 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
2021-12-13 00:20:48 +08:00
from felicity.database.base_class import DBModel
2021-05-06 21:48:09 +08:00
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']
2021-10-01 15:37:34 +08:00
except (KeyError, TypeError):
2021-09-06 02:05:20 +08:00
updated_by_uid = None
2021-10-01 15:37:34 +08:00
self.user_id = updated_by_uid if updated_by_uid else None
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)
2021-10-01 15:37:34 +08:00
if state_after:
to_delete = []
for key in state_after.keys():
if state_after[key] == state_before[key]:
to_delete.append(key)
2021-09-06 02:05:20 +08:00
2021-10-01 15:37:34 +08:00
for _key in to_delete:
del state_after[_key]
del state_before[_key]
2021-09-06 02:05:20 +08:00
2021-10-01 15:37:34 +08:00
if len(state_after.keys()) == 1:
if list(state_after.keys())[0] == 'updated_at':
return
2021-10-01 15:37:34 +08:00
state_after = json.dumps(state_after) if state_after else json.dumps({})
state_before = json.dumps(state_before) if state_before else json.dumps({})
2021-09-06 02:05:20 +08:00
2021-05-06 21:48:09 +08:00
connection.execute(
self.__table__.insert(),
2021-10-07 15:17:20 +08:00
[
{
2021-12-13 00:20:48 +08:00
'user_id': self.user_id,
'target_type': self.target_type,
'target_id': self.target_id,
'action': self.action,
'state_before': state_before,
'state_after': state_after,
2021-10-07 15:17:20 +08:00
}
]
2021-12-13 00:20:48 +08:00
)