必须记录 CRUD 操作,包括操作是什么、参与者是谁以及操作发生的时间
这可以通过 ActiveRecord::Callbacks 和 attr_accessor 字段来解决。
在需要记录的任何模型中添加以下内容。
attr_accessor :modifier_id, :modifier
valiadate :valid_user
before_validate :populate_modifier
before_save :write_save_attempted_to_audit_log
after_save :write_save_completed_to_audit_log
def populate_modifier
self.modifier = User.find_by_id(modifier_id) unless modifier
end
def valid_user
unless modifier
errors.add(:modifiers_user_id, "Unknown user attempted to modify this record")
write_unauthorized_modification_to_audit_log
end
end
def write_save_attempted_to_audit_log
# announce that user is attempting to save a record with timestamp to audit log
# use ActiveRecord::Dirty.changes to show the change the might be made
end
def write_save_competed_to_audit_log
# announce that user has successfully changed the record with timestamp to audit log
end
def write_unauthorized_modification
# announce that a change was attempted without a user
end
因为您可能会在一些模型中使用它,所以您可以将其抽象为插件,并仅在需要时通过方法调用(如audit_changes
. 请参阅任何acts_as 插件以获取有关如何完成此操作的灵感。
在控制器中,您需要记住@thing.modifier = @current_user
在尝试保存之前添加。
需要有某种方法来验证数据(即记录记录的 MD5 校验和)
至于校验和......操作?您可以覆盖检查以以一致的方式打印包含记录中所有信息的字符串,然后为此生成校验和。当您使用它时,不妨将其添加到审计日志中,作为写入日志方法的一部分。
一些数据应该是一次性写入的(即应用程序可以创建一个审计日志条目,但此后不能在应用程序内编辑或删除该日志)
将每个访问日志写入具有确定性名称 ( "/logs/audits/#{class}/#{id}/#{timestamp}"
) 的单独文件,并在保存后删除写入权限。File.chmod(0555, access_log_file)
可能应该在整个嵌套过程中记录对关联对象的更改。例如,将 CustodyLog 添加到一个 Evidence 应该有一个日志用于它自己,一个日志用于它的 Evidence,一个日志用于父案例。这是为了确保 Case 的上次更新时间戳准确地反映了真实的上次更新,而不仅仅是 Case 模型数据本身更改的上次时间。
至于第四个要求。如果您在任何嵌套关系上使用accepts_nested_attributes_for,这将首先自动进入我的解决方案。并且 :autosave => true 用于 belongs_to 关系。
如果您将校验和保存到审计日志中,您可以在 before_save 方法中进行检查,以确保您正在处理的对象未被篡改。只需检查对象的最新审计日志并匹配校验和即可。