* work on Issue 26: Auditing access to file revisions
* reworked operation logging git-svn-id: http://redmine-dmsf.googlecode.com/svn/trunk/redmine_dmsf@158 5e329b0b-a2ee-ea63-e329-299493fc886d
This commit is contained in:
parent
ecbc773a55
commit
a1f7cc2fa7
@ -138,13 +138,8 @@ class DmsfController < ApplicationController
|
||||
flash[:error] = l(:error_user_has_not_right_delete_file)
|
||||
end
|
||||
end
|
||||
unless deleted_folders.empty?
|
||||
Rails.logger.info "#{Time.now} from #{request.remote_ip}/#{request.env["HTTP_X_FORWARDED_FOR"]}: #{User.current.login} deleted folders from project #{@project.identifier}:"
|
||||
deleted_folders.each {|f| Rails.logger.info "\t#{f.dmsf_path_str}:"}
|
||||
end
|
||||
unless deleted_files.empty?
|
||||
Rails.logger.info "#{Time.now} from #{request.remote_ip}/#{request.env["HTTP_X_FORWARDED_FOR"]}: #{User.current.login} deleted files from project #{@project.identifier}:"
|
||||
deleted_files.each {|f| Rails.logger.info "\t#{f.dmsf_path_str}:"}
|
||||
deleted_files.each {|f| log_activity(f, "deleted")}
|
||||
DmsfMailer.deliver_files_deleted(User.current, deleted_files)
|
||||
end
|
||||
if failed_entries.empty?
|
||||
@ -171,7 +166,6 @@ class DmsfController < ApplicationController
|
||||
@folder.user = User.current
|
||||
if @folder.save
|
||||
flash[:notice] = l(:notice_folder_created)
|
||||
Rails.logger.info "#{Time.now} from #{request.remote_ip}/#{request.env["HTTP_X_FORWARDED_FOR"]}: #{User.current.login} created folder #{@project.identifier}://#{@folder.dmsf_path_str}"
|
||||
redirect_to({:controller => "dmsf", :action => "show", :id => @project, :folder_id => @folder})
|
||||
else
|
||||
@pathfolder = @parent
|
||||
@ -192,7 +186,6 @@ class DmsfController < ApplicationController
|
||||
@pathfolder = copy_folder(@folder)
|
||||
@folder.attributes = params[:dmsf_folder]
|
||||
if @folder.save
|
||||
Rails.logger.info "#{Time.now} from #{request.remote_ip}/#{request.env["HTTP_X_FORWARDED_FOR"]}: #{User.current.login} updated folder #{@project.identifier}://#{@folder.dmsf_path_str}"
|
||||
flash[:notice] = l(:notice_folder_details_were_saved)
|
||||
redirect_to :controller => "dmsf", :action => "show", :id => @project, :folder_id => @folder
|
||||
else
|
||||
@ -205,7 +198,6 @@ class DmsfController < ApplicationController
|
||||
if !@delete_folder.nil?
|
||||
if @delete_folder.delete
|
||||
flash[:notice] = l(:notice_folder_deleted)
|
||||
Rails.logger.info "#{Time.now} from #{request.remote_ip}/#{request.env["HTTP_X_FORWARDED_FOR"]}: #{User.current.login} deleted folder #{@project.identifier}://#{@delete_folder.dmsf_path_str}"
|
||||
else
|
||||
flash[:error] = l(:error_folder_is_not_empty)
|
||||
end
|
||||
@ -249,6 +241,10 @@ class DmsfController < ApplicationController
|
||||
|
||||
private
|
||||
|
||||
def log_activity(file, action)
|
||||
Rails.logger.info "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')} #{User.current.login}@#{request.remote_ip}/#{request.env['HTTP_X_FORWARDED_FOR']}: #{action} dmsf://#{file.project.identifier}/#{file.id}"
|
||||
end
|
||||
|
||||
def email_entries(selected_folders, selected_files)
|
||||
zip = DmsfZip.new
|
||||
zip_entries(zip, selected_folders, selected_files)
|
||||
@ -262,9 +258,12 @@ class DmsfController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
Rails.logger.info "#{Time.now} from #{request.remote_ip}/#{request.env["HTTP_X_FORWARDED_FOR"]}: #{User.current.login} emailed from project #{@project.identifier}:"
|
||||
selected_folders.each {|folder| Rails.logger.info "\tFolder #{folder}"} unless selected_folders.nil?
|
||||
selected_files.each {|file| Rails.logger.info "\tFile #{file}"} unless selected_files.nil?
|
||||
zip.files.each do |f|
|
||||
log_activity(f,"emailing zip")
|
||||
audit = DmsfFileRevisionAccess.new(:user_id => User.current.id, :dmsf_file_revision_id => f.last_revision.id,
|
||||
:action => DmsfFileRevisionAccess::EmailAction)
|
||||
audit.save!
|
||||
end
|
||||
|
||||
@email_params = {"zipped_content" => ziped_content}
|
||||
render :action => "email_entries"
|
||||
@ -276,9 +275,12 @@ class DmsfController < ApplicationController
|
||||
zip = DmsfZip.new
|
||||
zip_entries(zip, selected_folders, selected_files)
|
||||
|
||||
Rails.logger.info "#{Time.now} from #{request.remote_ip}/#{request.env["HTTP_X_FORWARDED_FOR"]}: #{User.current.login} downloaded from project #{@project.identifier}:"
|
||||
selected_folders.each {|folder| Rails.logger.info "\tFolder #{folder}"} unless selected_folders.nil?
|
||||
selected_files.each {|file| Rails.logger.info "\tFile #{file}"} unless selected_files.nil?
|
||||
zip.files.each do |f|
|
||||
log_activity(f,"download zip")
|
||||
audit = DmsfFileRevisionAccess.new(:user_id => User.current.id, :dmsf_file_revision_id => f.last_revision.id,
|
||||
:action => DmsfFileRevisionAccess::DownloadAction)
|
||||
audit.save!
|
||||
end
|
||||
|
||||
send_file(zip.finish,
|
||||
:filename => filename_for_content_disposition(@project.name + "-" + DateTime.now.strftime("%y%m%d%H%M%S") + ".zip"),
|
||||
@ -304,8 +306,8 @@ class DmsfController < ApplicationController
|
||||
|
||||
max_files = 0
|
||||
max_files = Setting.plugin_redmine_dmsf["dmsf_max_file_download"].to_i
|
||||
if max_files > 0 && zip.file_count > max_files
|
||||
raise ZipMaxFilesError, zip.file_count
|
||||
if max_files > 0 && zip.files.length > max_files
|
||||
raise ZipMaxFilesError, zip.files.length
|
||||
end
|
||||
|
||||
zip
|
||||
|
||||
@ -45,7 +45,6 @@ class DmsfFilesController < ApplicationController
|
||||
return
|
||||
end
|
||||
end
|
||||
Rails.logger.info "#{Time.now} from #{request.remote_ip}/#{request.env["HTTP_X_FORWARDED_FOR"]}: #{User.current.login} downloaded #{@project.identifier}://#{@file.dmsf_path_str} revision #{@revision.id}"
|
||||
check_project(@revision.file)
|
||||
send_revision
|
||||
return
|
||||
@ -113,7 +112,7 @@ class DmsfFilesController < ApplicationController
|
||||
@file.reload
|
||||
|
||||
flash[:notice] = (flash[:notice].nil? ? "" : flash[:notice]) + l(:notice_file_revision_created)
|
||||
Rails.logger.info "#{Time.now} from #{request.remote_ip}/#{request.env["HTTP_X_FORWARDED_FOR"]}: #{User.current.login} created new revision of file #{@project.identifier}://#{@file.dmsf_path_str}"
|
||||
log_activity("new revision")
|
||||
begin
|
||||
DmsfMailer.deliver_files_updated(User.current, [@file])
|
||||
rescue ActionView::MissingTemplate => e
|
||||
@ -130,7 +129,7 @@ class DmsfFilesController < ApplicationController
|
||||
if !@file.nil?
|
||||
if @file.delete
|
||||
flash[:notice] = l(:notice_file_deleted)
|
||||
Rails.logger.info "#{Time.now} from #{request.remote_ip}/#{request.env["HTTP_X_FORWARDED_FOR"]}: #{User.current.login} deleted file #{@project.identifier}://#{@file.dmsf_path_str}"
|
||||
log_activity("deleted")
|
||||
DmsfMailer.deliver_files_deleted(User.current, [@file])
|
||||
else
|
||||
flash[:error] = l(:error_file_is_locked)
|
||||
@ -143,7 +142,7 @@ class DmsfFilesController < ApplicationController
|
||||
if !@revision.nil? && !@revision.deleted
|
||||
if @revision.delete
|
||||
flash[:notice] = l(:notice_revision_deleted)
|
||||
Rails.logger.info "#{Time.now} from #{request.remote_ip}/#{request.env["HTTP_X_FORWARDED_FOR"]}: #{User.current.login} deleted revision #{@project.identifier}://#{@revision.file.dmsf_path_str}/#{@revision.id}"
|
||||
log_activity("deleted")
|
||||
else
|
||||
# TODO: check this error handling
|
||||
@revision.errors.each {|e| flash[:error] = e[1]}
|
||||
@ -202,7 +201,15 @@ class DmsfFilesController < ApplicationController
|
||||
|
||||
private
|
||||
|
||||
def log_activity(action)
|
||||
Rails.logger.info "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')} #{User.current.login}@#{request.remote_ip}/#{request.env['HTTP_X_FORWARDED_FOR']}: #{action} dmsf://#{@file.project.identifier}/#{@file.id}/#{@revision.id if @revision}"
|
||||
end
|
||||
|
||||
def send_revision
|
||||
log_activity("downloaded")
|
||||
access = DmsfFileRevisionAccess.new(:user_id => User.current.id, :dmsf_file_revision_id => @revision.id,
|
||||
:action => DmsfFileRevisionAccess::DownloadAction)
|
||||
access.save!
|
||||
send_file(@revision.disk_file,
|
||||
:filename => filename_for_content_disposition(@revision.name),
|
||||
:type => @revision.detect_content_type,
|
||||
|
||||
@ -138,8 +138,7 @@ class DmsfUploadController < ApplicationController
|
||||
end
|
||||
end
|
||||
unless files.empty?
|
||||
Rails.logger.info "#{Time.now} from #{request.remote_ip}/#{request.env["HTTP_X_FORWARDED_FOR"]}: #{User.current.login} uploaded for project #{@project.identifier}:"
|
||||
files.each {|file| Rails.logger.info "\t#{file.dmsf_path_str}:"}
|
||||
files.each {|file| log_activity(file, "uploaded")}
|
||||
begin
|
||||
DmsfMailer.deliver_files_updated(User.current, files)
|
||||
rescue ActionView::MissingTemplate => e
|
||||
@ -155,6 +154,10 @@ class DmsfUploadController < ApplicationController
|
||||
|
||||
private
|
||||
|
||||
def log_activity(file, action)
|
||||
Rails.logger.info "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')} #{User.current.login}@#{request.remote_ip}/#{request.env['HTTP_X_FORWARDED_FOR']}: #{action} dmsf://#{file.project.identifier}/#{file.id}/#{file.last_revision.id}"
|
||||
end
|
||||
|
||||
def find_project
|
||||
@project = Project.find(params[:id])
|
||||
end
|
||||
|
||||
@ -22,12 +22,12 @@ require 'iconv'
|
||||
|
||||
class DmsfZip
|
||||
|
||||
attr_reader :file_count
|
||||
attr_reader :files
|
||||
|
||||
def initialize()
|
||||
@zip = Tempfile.new(["dmsf_zip",".zip"])
|
||||
@zip_file = Zip::ZipOutputStream.new(@zip.path)
|
||||
@file_count = 0
|
||||
@files = []
|
||||
end
|
||||
|
||||
def finish
|
||||
@ -56,7 +56,7 @@ class DmsfZip
|
||||
@zip_file.write(buffer)
|
||||
end
|
||||
end
|
||||
@file_count += 1
|
||||
@files << file
|
||||
end
|
||||
|
||||
def add_folder(folder, root_path = nil)
|
||||
|
||||
@ -74,7 +74,8 @@ class DmsfFileRevision < ActiveRecord::Base
|
||||
if Setting.plugin_redmine_dmsf["dmsf_really_delete_files"]
|
||||
dependent = DmsfFileRevision.find(:all, :conditions =>
|
||||
["disk_filename = :filename", {:filename => self.disk_filename}])
|
||||
File.delete(self.disk_file) if dependent.length <= 1
|
||||
File.delete(self.disk_file) if dependent.length <= 1 && File.exist?(self.disk_file)
|
||||
DmsfFileRevisionAccess.find(:all, :conditions => ["dmsf_file_revision_id = ?", self.id]).each {|a| a.destroy}
|
||||
self.destroy
|
||||
else
|
||||
self.deleted = true
|
||||
|
||||
27
app/models/dmsf_file_revision_access.rb
Normal file
27
app/models/dmsf_file_revision_access.rb
Normal file
@ -0,0 +1,27 @@
|
||||
# Redmine plugin for Document Management System "Features"
|
||||
#
|
||||
# Copyright (C) 2011 Vít Jonáš <vit.jonas@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class DmsfFileRevisionAccess < ActiveRecord::Base
|
||||
unloadable
|
||||
belongs_to :revision, :class_name => "DmsfFileRevision", :foreign_key => "dmsf_file_revision_id"
|
||||
belongs_to :user
|
||||
|
||||
DownloadAction = 0
|
||||
EmailAction = 1
|
||||
|
||||
end
|
||||
@ -19,17 +19,9 @@
|
||||
class DmsfNormalization < ActiveRecord::Migration
|
||||
def self.up
|
||||
rename_column :dmsf_folders, :name, :title
|
||||
|
||||
create_table :dmsf_file_revision_audit do |t|
|
||||
t.references :dmsf_file_revision, :null => false
|
||||
t.integer :action, :default => 0, :null => false # 0 ... download, 1 ... email
|
||||
t.references :user, :null => false
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :dmsf_file_revision_audit
|
||||
rename_column :dmsf_folders, :title, :name
|
||||
end
|
||||
|
||||
|
||||
33
db/migrate/05_dmsf_0_9_0_1.rb
Normal file
33
db/migrate/05_dmsf_0_9_0_1.rb
Normal file
@ -0,0 +1,33 @@
|
||||
# Redmine plugin for Document Management System "Features"
|
||||
#
|
||||
# Copyright (C) 2011 Vít Jonáš <vit.jonas@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class Dmsf0901 < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table :dmsf_file_revision_accesses do |t|
|
||||
t.references :dmsf_file_revision, :null => false
|
||||
t.integer :action, :default => 0, :null => false # 0 ... download, 1 ... email
|
||||
t.references :user, :null => false
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :dmsf_file_revision_accesses
|
||||
end
|
||||
|
||||
end
|
||||
Loading…
x
Reference in New Issue
Block a user