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.
|
||||
|
||||
require 'tmpdir'
|
||||
require 'digest/md5'
|
||||
require 'digest'
|
||||
require 'csv'
|
||||
|
||||
module DmsfHelper
|
||||
@ -42,16 +42,13 @@ module DmsfHelper
|
||||
def self.sanitize_filename(filename)
|
||||
# get only the filename, not the whole path
|
||||
just_filename = File.basename(filename.gsub('\\\\', '/'))
|
||||
|
||||
# replace all non alphanumeric, hyphens or periods with underscore
|
||||
just_filename = just_filename.gsub(/[^\w\.\-]/,'_')
|
||||
|
||||
unless just_filename =~ %r{^[a-zA-Z0-9_\.\-]*$}
|
||||
# keep the extension if any
|
||||
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
|
||||
|
||||
just_filename
|
||||
end
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
require 'digest/md5'
|
||||
require 'digest'
|
||||
|
||||
class DmsfFileRevision < ActiveRecord::Base
|
||||
|
||||
@ -290,7 +290,7 @@ class DmsfFileRevision < ActiveRecord::Base
|
||||
|
||||
def self.create_digest(path)
|
||||
begin
|
||||
Digest::MD5.file(path).hexdigest
|
||||
Digest::SHA256.file(path).hexdigest
|
||||
rescue Exception => e
|
||||
Rails.logger.error e.message
|
||||
0
|
||||
@ -301,9 +301,17 @@ class DmsfFileRevision < ActiveRecord::Base
|
||||
self.digest = DmsfFileRevision.create_digest(self.disk_file)
|
||||
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
|
||||
text = ''
|
||||
text = self.description if self.description.present?
|
||||
if self.description.present?
|
||||
text = self.description
|
||||
else
|
||||
text = ''
|
||||
end
|
||||
if self.comment.present?
|
||||
text += ' / ' if text.present?
|
||||
text += self.comment
|
||||
|
||||
@ -162,8 +162,8 @@
|
||||
</div>
|
||||
<% if revision.digest.present? %>
|
||||
<div class="status attribute">
|
||||
<%= content_tag :div, 'MD5', :class => 'label' %>
|
||||
<%= content_tag :div, revision.digest, :class => 'value wiki' %>
|
||||
<%= content_tag :div, l(:field_digest), :class => 'label' %>
|
||||
<%= content_tag :div, "#{revision.digest_type}: #{revision.digest}", :class => 'value wiki' %>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= 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
|
||||
DMSF maintenance task
|
||||
* Create missing MD5 digest for all file revisions
|
||||
* Create missing checksum for all file revisions
|
||||
|
||||
Available options:
|
||||
*dry_run - test, no changes to the database
|
||||
|
||||
@ -29,13 +29,16 @@ class DmsfFileRevisionTest < RedmineDmsf::Test::UnitTest
|
||||
@revision1 = DmsfFileRevision.find_by_id 1
|
||||
@revision2 = DmsfFileRevision.find_by_id 2
|
||||
@revision5 = DmsfFileRevision.find_by_id 5
|
||||
@revision8 = DmsfFileRevision.find_by_id 8
|
||||
@wf1 = DmsfWorkflow.find_by_id 1
|
||||
Setting.plugin_redmine_dmsf['dmsf_storage_directory'] = File.expand_path '../../fixtures/files', __FILE__
|
||||
end
|
||||
|
||||
def test_truth
|
||||
assert_kind_of DmsfFileRevision, @revision1
|
||||
assert_kind_of DmsfFileRevision, @revision2
|
||||
assert_kind_of DmsfFileRevision, @revision5
|
||||
assert_kind_of DmsfFileRevision, @revision8
|
||||
assert_kind_of DmsfWorkflow, @wf1
|
||||
end
|
||||
|
||||
@ -54,7 +57,16 @@ class DmsfFileRevisionTest < RedmineDmsf::Test::UnitTest
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
def test_new_storage_filename
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user