Redmine uses SHA256 instead of MD5 for file digests #783
This commit is contained in:
parent
ed43639ec0
commit
edc17a32f0
@ -20,7 +20,7 @@
|
|||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
require 'tmpdir'
|
require 'tmpdir'
|
||||||
require 'digest/md5'
|
require 'digest'
|
||||||
require 'csv'
|
require 'csv'
|
||||||
|
|
||||||
module DmsfHelper
|
module DmsfHelper
|
||||||
@ -42,16 +42,13 @@ module DmsfHelper
|
|||||||
def self.sanitize_filename(filename)
|
def self.sanitize_filename(filename)
|
||||||
# get only the filename, not the whole path
|
# get only the filename, not the whole path
|
||||||
just_filename = File.basename(filename.gsub('\\\\', '/'))
|
just_filename = File.basename(filename.gsub('\\\\', '/'))
|
||||||
|
|
||||||
# replace all non alphanumeric, hyphens or periods with underscore
|
# replace all non alphanumeric, hyphens or periods with underscore
|
||||||
just_filename = just_filename.gsub(/[^\w\.\-]/,'_')
|
just_filename = just_filename.gsub(/[^\w\.\-]/,'_')
|
||||||
|
|
||||||
unless just_filename =~ %r{^[a-zA-Z0-9_\.\-]*$}
|
unless just_filename =~ %r{^[a-zA-Z0-9_\.\-]*$}
|
||||||
# keep the extension if any
|
# keep the extension if any
|
||||||
extension = $1 if just_filename =~ %r{(\.[a-zA-Z0-9]+)$}
|
extension = $1 if just_filename =~ %r{(\.[a-zA-Z0-9]+)$}
|
||||||
just_filename = Digest::MD5.hexdigest(just_filename) << extension
|
just_filename = Digest::SHA256.hexdigest(just_filename) << extension
|
||||||
end
|
end
|
||||||
|
|
||||||
just_filename
|
just_filename
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
require 'digest/md5'
|
require 'digest'
|
||||||
|
|
||||||
class DmsfFileRevision < ActiveRecord::Base
|
class DmsfFileRevision < ActiveRecord::Base
|
||||||
|
|
||||||
@ -290,7 +290,7 @@ class DmsfFileRevision < ActiveRecord::Base
|
|||||||
|
|
||||||
def self.create_digest(path)
|
def self.create_digest(path)
|
||||||
begin
|
begin
|
||||||
Digest::MD5.file(path).hexdigest
|
Digest::SHA256.file(path).hexdigest
|
||||||
rescue Exception => e
|
rescue Exception => e
|
||||||
Rails.logger.error e.message
|
Rails.logger.error e.message
|
||||||
0
|
0
|
||||||
@ -301,9 +301,17 @@ class DmsfFileRevision < ActiveRecord::Base
|
|||||||
self.digest = DmsfFileRevision.create_digest(self.disk_file)
|
self.digest = DmsfFileRevision.create_digest(self.disk_file)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns either MD5 or SHA256 depending on the way self.digest was computed
|
||||||
|
def digest_type
|
||||||
|
self.digest.size < 64 ? 'MD5' : 'SHA256' if digest.present?
|
||||||
|
end
|
||||||
|
|
||||||
def tooltip
|
def tooltip
|
||||||
text = ''
|
if self.description.present?
|
||||||
text = self.description if self.description.present?
|
text = self.description
|
||||||
|
else
|
||||||
|
text = ''
|
||||||
|
end
|
||||||
if self.comment.present?
|
if self.comment.present?
|
||||||
text += ' / ' if text.present?
|
text += ' / ' if text.present?
|
||||||
text += self.comment
|
text += self.comment
|
||||||
|
|||||||
@ -162,8 +162,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<% if revision.digest.present? %>
|
<% if revision.digest.present? %>
|
||||||
<div class="status attribute">
|
<div class="status attribute">
|
||||||
<%= content_tag :div, 'MD5', :class => 'label' %>
|
<%= content_tag :div, l(:field_digest), :class => 'label' %>
|
||||||
<%= content_tag :div, revision.digest, :class => 'value wiki' %>
|
<%= content_tag :div, "#{revision.digest_type}: #{revision.digest}", :class => 'value wiki' %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<%= render 'dmsf/custom_fields', :object => revision %>
|
<%= render 'dmsf/custom_fields', :object => revision %>
|
||||||
|
|||||||
@ -0,0 +1,28 @@
|
|||||||
|
# encoding: utf-8
|
||||||
|
#
|
||||||
|
# Redmine plugin for Document Management System "Features"
|
||||||
|
#
|
||||||
|
# Copyright (C) 2011-17 Karel Pičman <karel.picman@kontron.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 ChangeRevisionDigestLimitTo64 < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
change_column :dmsf_file_revisions, :digest, :string, limit: 64
|
||||||
|
end
|
||||||
|
def down
|
||||||
|
change_column :dmsf_file_revisions, :digest, :string, limit: 40
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
desc <<-END_DESC
|
desc <<-END_DESC
|
||||||
DMSF maintenance task
|
DMSF maintenance task
|
||||||
* Create missing MD5 digest for all file revisions
|
* Create missing checksum for all file revisions
|
||||||
|
|
||||||
Available options:
|
Available options:
|
||||||
*dry_run - test, no changes to the database
|
*dry_run - test, no changes to the database
|
||||||
|
|||||||
@ -29,13 +29,16 @@ class DmsfFileRevisionTest < RedmineDmsf::Test::UnitTest
|
|||||||
@revision1 = DmsfFileRevision.find_by_id 1
|
@revision1 = DmsfFileRevision.find_by_id 1
|
||||||
@revision2 = DmsfFileRevision.find_by_id 2
|
@revision2 = DmsfFileRevision.find_by_id 2
|
||||||
@revision5 = DmsfFileRevision.find_by_id 5
|
@revision5 = DmsfFileRevision.find_by_id 5
|
||||||
|
@revision8 = DmsfFileRevision.find_by_id 8
|
||||||
@wf1 = DmsfWorkflow.find_by_id 1
|
@wf1 = DmsfWorkflow.find_by_id 1
|
||||||
|
Setting.plugin_redmine_dmsf['dmsf_storage_directory'] = File.expand_path '../../fixtures/files', __FILE__
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_truth
|
def test_truth
|
||||||
assert_kind_of DmsfFileRevision, @revision1
|
assert_kind_of DmsfFileRevision, @revision1
|
||||||
assert_kind_of DmsfFileRevision, @revision2
|
assert_kind_of DmsfFileRevision, @revision2
|
||||||
assert_kind_of DmsfFileRevision, @revision5
|
assert_kind_of DmsfFileRevision, @revision5
|
||||||
|
assert_kind_of DmsfFileRevision, @revision8
|
||||||
assert_kind_of DmsfWorkflow, @wf1
|
assert_kind_of DmsfWorkflow, @wf1
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -54,7 +57,16 @@ class DmsfFileRevisionTest < RedmineDmsf::Test::UnitTest
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_create_digest
|
def test_create_digest
|
||||||
assert_equal @revision5.create_digest, 0, "MD5 should be 0, if the file is missing"
|
assert @revision1.create_digest.length > 40
|
||||||
|
assert_equal @revision8.create_digest, 0, 'Digest should be 0, if the file is missing'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_digest_type
|
||||||
|
# Old type MD5
|
||||||
|
assert_equal 'MD5', @revision1.digest_type
|
||||||
|
# New type SHA256
|
||||||
|
@revision1.create_digest
|
||||||
|
assert_equal 'SHA256', @revision1.digest_type
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_new_storage_filename
|
def test_new_storage_filename
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user