Аудит и моделирование управления жизненным циклом для экземпляров и их ассоциаций? - PullRequest
0 голосов
/ 24 октября 2009

Я пытаюсь написать приложение для отслеживания запросов по судебным делам. Основной моделью является Case, который has_many Предметы, Ключевые слова, Заметки и Доказательства (которые, в свою очередь, has_many CustodyLogs). Поскольку заявка связана с правовыми вопросами, существуют некоторые необычные требования:

  • Операции CRUD должны регистрироваться, включая информацию о том, какой была операция, кем был актер и когда произошла операция
  • Должен быть какой-то способ проверки данных (т.е. запись контрольных сумм записей MD5)
  • Некоторые данные должны быть однократной записи (т. Е. Приложение может создать запись журнала аудита, но этот журнал не может быть отредактирован или удален из приложения после этого)
  • Изменения в связанных объектах, вероятно, должны регистрироваться на протяжении всего вложения. Например, добавление CustodyLog к фрагменту Evidence должно иметь журнал для себя, журнал для его Evidence и журнал для родительского Case. Это делается для того, чтобы отметка времени последнего обновления для Case точно отражала реальное последнее обновление, а не только последний раз, когда сами данные модели Case изменялись.

У меня есть кое-что из этого, но я столкнулся с проблемой. Аутентификация обрабатывается внешней веб-службой единого входа, поэтому единственное видение идентификатора вошедшего в систему пользователя находится в переменной запроса. Если я включу ведение журнала аудита в модель, например, с помощью обратного вызова, я могу быть совершенно уверен, что все изменения данных записываются в журнал, но модель не имеет видимости для переменных запроса, поэтому я не могу зарегистрировать идентификатор пользователя. Это также гарантирует, что изменения в конечный автомат (в настоящее время использующий плагин state_machine) регистрируются.

Если, с другой стороны, я помещаю журнал аудита в контроллер приложения, я теряю способность быть уверенным, что все операции CRUD регистрируются (например, код в модели Case, вызывающий Subject.create, не будет войти) Я также думаю, что потерял бы изменения состояния.

Есть ли способ быть уверенным, что все операции CRUD регистрируются по всему дереву ассоциации, так что записывается идентификатор пользователя вошедшего в систему пользователя?

1 Ответ

0 голосов
/ 24 октября 2009

Операции 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, чтобы убедиться, что объект, над которым вы работаете, не был подделан. Просто проверив последний журнал аудита для объекта и сопоставив контрольные суммы.

...