Операции 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
. См. Любой из плагинов act_as для вдохновения о том, как достигнуть этого.
В контроллерах вам нужно будет не забыть добавить @thing.modifier = @current_user
перед попыткой сохранения.
Должен быть какой-то способ проверки данных (т.е. запись контрольных сумм записей MD5)
Что касается контрольной суммы ... операции? Вы можете переопределить inspect для последовательной печати строки, содержащей всю информацию в записи, а затем сгенерировать контрольную сумму для этого. Пока вы это делаете, можете также добавить его в журнал аудита как часть методов записи в журнал.
Некоторые данные должны быть однократной записи (т. Е. Приложение может создать запись в журнале аудита, но впоследствии этот журнал нельзя редактировать или удалять из приложения)
Запись каждого журнала доступа в виде отдельного файла с детерминированным именем ("/logs/audits/#{class}/#{id}/#{timestamp}"
) и удаление разрешения на запись после его сохранения. File.chmod(0555, access_log_file)
Изменения в связанных объектах, вероятно, должны регистрироваться на протяжении всего вложения. Например, добавление CustodyLog к фрагменту Evidence должно иметь журнал для себя, журнал для его Evidence и журнал для родительского Case. Это необходимо для того, чтобы отметка времени последнего обновления для Case точно отражала реальное последнее обновление, а не только последний раз, когда сами данные модели Case изменялись.
Что касается 4-го требования. Это автоматически попадет в мое решение в первую очередь, если вы будете использовать accepts_nested_attributes_for в любом из ваших вложенных отношений. И: autosave => true для отношений принадлежащих к.
Если вы сохраняете контрольные суммы в журналах аудита, вы можете добавить проверку в метод before_save, чтобы убедиться, что объект, над которым вы работаете, не был подделан. Просто проверив последний журнал аудита для объекта и сопоставив контрольные суммы.