Commit 9b81d0a20f63e14957761dd584b5dfb9884c8d48

Authored by Conrad Vermeulen
1 parent d2db6f87

KTS-3240

"Add MD5 hash to assist with validation of repository storage"
Fixed.

Committed By: Conrad Vermeulen
Reviewed By: Megan Watson

git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/trunk@8366 c91229c3-7414-0410-bfa2-8a42b809f60b
bin/md5_validation.php 0 → 100644
  1 +<?php
  2 +/**
  3 + * $Id: $
  4 + *
  5 + * Base class for database-backed objects
  6 + *
  7 + * KnowledgeTree Open Source Edition
  8 + * Document Management Made Simple
  9 + * Copyright (C) 2004 - 2008 The Jam Warehouse Software (Pty) Limited
  10 + *
  11 + * This program is free software; you can redistribute it and/or modify it under
  12 + * the terms of the GNU General Public License version 3 as published by the
  13 + * Free Software Foundation.
  14 + *
  15 + * This program is distributed in the hope that it will be useful, but WITHOUT
  16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  18 + * details.
  19 + *
  20 + * You should have received a copy of the GNU General Public License
  21 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  22 + *
  23 + * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place,
  24 + * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com.
  25 + *
  26 + * The interactive user interfaces in modified source and object code versions
  27 + * of this program must display Appropriate Legal Notices, as required under
  28 + * Section 5 of the GNU General Public License version 3.
  29 + *
  30 + * In accordance with Section 7(b) of the GNU General Public License version 3,
  31 + * these Appropriate Legal Notices must retain the display of the "Powered by
  32 + * KnowledgeTree" logo and retain the original copyright notice. If the display of the
  33 + * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
  34 + * must display the words "Powered by KnowledgeTree" and retain the original
  35 + * copyright notice.
  36 + * Contributor( s): ______________________________________
  37 + */
  38 +
  39 +require_once('../config/dmsDefaults.php');
  40 +
  41 +print "KnowledgeTree MD5 Validation Tool\n";
  42 +print "=================================\n\n";
  43 +print "NOTE: This utility make take some time to run to completion!\n\n";
  44 +
  45 +$sql = "SELECT
  46 + dcv.id, dmv.document_id, MAX(dmv.id) AS metadata_version_id, MAX(dmv.metadata_version) AS metadata_version
  47 + FROM
  48 + document_content_version AS dcv
  49 + INNER JOIN document_metadata_version AS dmv ON dcv.id = dmv.content_version_id
  50 + GROUP BY
  51 + dcv.id
  52 + ORDER BY dcv.document_id";
  53 +
  54 +$rows = DBUtil::getResultArray(array($sql));
  55 +
  56 +$total = count($rows);
  57 +$problem = 0;
  58 +$ok = 0;
  59 +$no_hash = 0;
  60 +$current = 0;
  61 +$dots = 0;
  62 +
  63 +foreach($rows as $row)
  64 +{
  65 + if (++$current % 100 == 0)
  66 + {
  67 + print '.';
  68 + if ($dots++ % 60 == 0)
  69 + {
  70 + print "\n";
  71 + }
  72 + }
  73 + $content_id = $row['id'];
  74 + $document_id = $row['document_id'];
  75 + $metadata_version = $row['metadata_version'];
  76 + $metadata_version_id = $row['metadata_version_id'];
  77 +
  78 + $document = Document::get($document_id, $metadata_version_id);
  79 + $core = &$document->_oDocumentContentVersion;
  80 +
  81 + $filename = $document->getFileName();
  82 + $md5 = $core->getStorageHash();
  83 +
  84 + if (empty($md5))
  85 + {
  86 + if ($dots > 0) print "\n";
  87 + print("Document Id: $document_id - Content Id: $content_id - No MD5 hash available.\n");
  88 +
  89 + $no_hash++;
  90 + $current = 0; $dots = 0;
  91 + // don't exit here, we do so later
  92 + }
  93 +
  94 + $storage = KTStorageManagerUtil::getSingleton();
  95 + $storage_path = $storage->temporaryFile($document);
  96 + if (PEAR::isError($storage_path))
  97 + {
  98 + if ($dots > 0) print "\n";
  99 + print("Document Id: $document_id - Content Id: $content_id - Storage engine reported an error: " . $storage_path->getMessage() . "\n");
  100 +
  101 + $no_hash++;
  102 + $current = 0; $dots = 0;
  103 + continue;
  104 + }
  105 + if (!file_exists($storage_path))
  106 + {
  107 + if ($dots > 0) print "\n";
  108 + print("Document Id: $document_id - Content Id: $content_id - File '$storage_path' cannot be found!\n");
  109 +
  110 + $no_hash++;
  111 + $current = 0; $dots = 0;
  112 + continue;
  113 + }
  114 +
  115 + $actual_md5 = md5_file($storage_path);
  116 +
  117 + $storage->freeTemporaryFile($storage_path);
  118 +
  119 + if (empty($md5))
  120 + {
  121 + $core->setStorageHash($actual_md5);
  122 + $core->update();
  123 + print("\tHash set to: $actual_md5\n");
  124 + continue;
  125 + }
  126 +
  127 +
  128 + if ($md5 != $actual_md5)
  129 + {
  130 + if ($dots > 0) print "\n";
  131 + print("Document Id: $document_id - Content ID: $content_id - MD5 difference\n");
  132 + print("\tStored MD5: $md5\n");
  133 + print("\tCurrent MD5: $actual_md5\n");
  134 + $problem++;
  135 + $current = 0; $dots = 0;
  136 + continue;
  137 + }
  138 + $ok++;
  139 +}
  140 +
  141 +print("\nStatistics:\n");
  142 +print("\tNo Problem:\t$ok\n");
  143 +print("\tProblem:\t$problem\n");
  144 +print("\tNo Hash:\t$no_hash\n");
  145 +print("\tTotal:\t\t$total\n");
  146 +
  147 +
  148 +?>
0 \ No newline at end of file 149 \ No newline at end of file
lib/documentmanagement/documentcontentversion.inc.php
@@ -5,32 +5,32 @@ @@ -5,32 +5,32 @@
5 * KnowledgeTree Open Source Edition 5 * KnowledgeTree Open Source Edition
6 * Document Management Made Simple 6 * Document Management Made Simple
7 * Copyright (C) 2004 - 2008 The Jam Warehouse Software (Pty) Limited 7 * Copyright (C) 2004 - 2008 The Jam Warehouse Software (Pty) Limited
8 - * 8 + *
9 * This program is free software; you can redistribute it and/or modify it under 9 * This program is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU General Public License version 3 as published by the 10 * the terms of the GNU General Public License version 3 as published by the
11 * Free Software Foundation. 11 * Free Software Foundation.
12 - * 12 + *
13 * This program is distributed in the hope that it will be useful, but WITHOUT 13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 15 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * details. 16 * details.
17 - * 17 + *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 - * 20 + *
21 * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place, 21 * You can contact The Jam Warehouse Software (Pty) Limited, Unit 1, Tramber Place,
22 * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com. 22 * Blake Street, Observatory, 7925 South Africa. or email info@knowledgetree.com.
23 - * 23 + *
24 * The interactive user interfaces in modified source and object code versions 24 * The interactive user interfaces in modified source and object code versions
25 * of this program must display Appropriate Legal Notices, as required under 25 * of this program must display Appropriate Legal Notices, as required under
26 * Section 5 of the GNU General Public License version 3. 26 * Section 5 of the GNU General Public License version 3.
27 - * 27 + *
28 * In accordance with Section 7(b) of the GNU General Public License version 3, 28 * In accordance with Section 7(b) of the GNU General Public License version 3,
29 * these Appropriate Legal Notices must retain the display of the "Powered by 29 * these Appropriate Legal Notices must retain the display of the "Powered by
30 - * KnowledgeTree" logo and retain the original copyright notice. If the display of the 30 + * KnowledgeTree" logo and retain the original copyright notice. If the display of the
31 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices 31 * logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
32 - * must display the words "Powered by KnowledgeTree" and retain the original  
33 - * copyright notice. 32 + * must display the words "Powered by KnowledgeTree" and retain the original
  33 + * copyright notice.
34 * Contributor( s): ______________________________________ 34 * Contributor( s): ______________________________________
35 * 35 *
36 */ 36 */
@@ -61,6 +61,8 @@ class KTDocumentContentVersion extends KTEntity { @@ -61,6 +61,8 @@ class KTDocumentContentVersion extends KTEntity {
61 /** Where in the storage this file can be found */ 61 /** Where in the storage this file can be found */
62 var $sStoragePath; 62 var $sStoragePath;
63 63
  64 + var $md5hash;
  65 +
64 var $_aFieldToSelect = array( 66 var $_aFieldToSelect = array(
65 "iId" => "id", 67 "iId" => "id",
66 68
@@ -72,13 +74,14 @@ class KTDocumentContentVersion extends KTEntity { @@ -72,13 +74,14 @@ class KTDocumentContentVersion extends KTEntity {
72 "iMajorVersion" => 'major_version', 74 "iMajorVersion" => 'major_version',
73 "iMinorVersion" => 'minor_version', 75 "iMinorVersion" => 'minor_version',
74 "sStoragePath" => 'storage_path', 76 "sStoragePath" => 'storage_path',
  77 + 'md5hash' => 'md5hash'
75 ); 78 );
76 -  
77 function KTDocumentContentVersion() { 79 function KTDocumentContentVersion() {
78 } 80 }
79 81
80 function getFileName() { return $this->sFileName; } 82 function getFileName() { return $this->sFileName; }
81 function setFileName($sNewValue) { $this->sFileName = $sNewValue; } 83 function setFileName($sNewValue) { $this->sFileName = $sNewValue; }
  84 + function getDocumentId() { return $this->iDocumentId; }
82 function getFileSize() { return $this->iSize; } 85 function getFileSize() { return $this->iSize; }
83 function setFileSize($iNewValue) { $this->iSize = $iNewValue; } 86 function setFileSize($iNewValue) { $this->iSize = $iNewValue; }
84 function getSize() { return $this->iSize; } 87 function getSize() { return $this->iSize; }
@@ -91,6 +94,8 @@ class KTDocumentContentVersion extends KTEntity { @@ -91,6 +94,8 @@ class KTDocumentContentVersion extends KTEntity {
91 function setMinorVersionNumber($iNewValue) { $this->iMinorVersion = $iNewValue; } 94 function setMinorVersionNumber($iNewValue) { $this->iMinorVersion = $iNewValue; }
92 function getStoragePath() { return $this->sStoragePath; } 95 function getStoragePath() { return $this->sStoragePath; }
93 function setStoragePath($sNewValue) { $this->sStoragePath = $sNewValue; } 96 function setStoragePath($sNewValue) { $this->sStoragePath = $sNewValue; }
  97 + function getStorageHash() { return $this->md5hash; }
  98 + function setStorageHash($sNewValue) { $this->md5hash = $sNewValue; }
94 99
95 function getVersion() { 100 function getVersion() {
96 return sprintf("%s.%s", $this->getMajorVersionNumber(), $this->getMinorVersionNumber()); 101 return sprintf("%s.%s", $this->getMajorVersionNumber(), $this->getMinorVersionNumber());
@@ -101,9 +106,12 @@ class KTDocumentContentVersion extends KTEntity { @@ -101,9 +106,12 @@ class KTDocumentContentVersion extends KTEntity {
101 } 106 }
102 107
103 function &createFromArray($aOptions) { 108 function &createFromArray($aOptions) {
104 - return KTEntityUtil::createFromArray('KTDocumentContentVersion', $aOptions); 109 + return KTEntityUtil::createFromArray('KTDocumentContentVersion', $aOptions);
105 } 110 }
106 111
  112 +
  113 +
  114 +
107 function create() { 115 function create() {
108 if (empty($this->iSize)) { 116 if (empty($this->iSize)) {
109 $this->iSize = 0; 117 $this->iSize = 0;
lib/documentmanagement/documentutil.inc.php
@@ -727,6 +727,14 @@ class KTDocumentUtil { @@ -727,6 +727,14 @@ class KTDocumentUtil {
727 return PEAR::raiseError(sprintf(_kt("Couldn't store contents: %s"), _kt('The uploaded file does not exist.'))); 727 return PEAR::raiseError(sprintf(_kt("Couldn't store contents: %s"), _kt('The uploaded file does not exist.')));
728 } 728 }
729 729
  730 + $md5hash = md5_file($sFilename);
  731 + $content = $oDocument->_oDocumentContentVersion;
  732 + $content->setStorageHash($md5hash);
  733 + $content->update();
  734 +
  735 + if (empty($aOptions)) $aOptions = array();
  736 + $aOptions['md5hash'] = $md5hash;
  737 +
730 $sType = KTMime::getMimeTypeFromFile($sFilename); 738 $sType = KTMime::getMimeTypeFromFile($sFilename);
731 $iMimeTypeId = KTMime::getMimeTypeID($sType, $oDocument->getFileName()); 739 $iMimeTypeId = KTMime::getMimeTypeID($sType, $oDocument->getFileName());
732 $oDocument->setMimeTypeId($iMimeTypeId); 740 $oDocument->setMimeTypeId($iMimeTypeId);
@@ -1121,11 +1129,11 @@ class KTDocumentUtil { @@ -1121,11 +1129,11 @@ class KTDocumentUtil {
1121 $oDocument->setModifiedUserId($oUser->getId()); 1129 $oDocument->setModifiedUserId($oUser->getId());
1122 $oDocument->setMinorVersionNumber($oDocument->getMinorVersionNumber()+1); 1130 $oDocument->setMinorVersionNumber($oDocument->getMinorVersionNumber()+1);
1123 $oDocument->_oDocumentContentVersion->setFilename($sNewFilename); 1131 $oDocument->_oDocumentContentVersion->setFilename($sNewFilename);
1124 - 1132 +
1125 $sType = KTMime::getMimeTypeFromFile($sNewFilename); 1133 $sType = KTMime::getMimeTypeFromFile($sNewFilename);
1126 $iMimeTypeId = KTMime::getMimeTypeID($sType, $sNewFilename); 1134 $iMimeTypeId = KTMime::getMimeTypeID($sType, $sNewFilename);
1127 $oDocument->setMimeTypeId($iMimeTypeId); 1135 $oDocument->setMimeTypeId($iMimeTypeId);
1128 - 1136 +
1129 $bSuccess = $oDocument->update(); 1137 $bSuccess = $oDocument->update();
1130 if ($bSuccess !== true) { 1138 if ($bSuccess !== true) {
1131 if (PEAR::isError($bSuccess)) { 1139 if (PEAR::isError($bSuccess)) {
sql/mysql/install/structure.sql
@@ -253,6 +253,7 @@ CREATE TABLE `document_content_version` ( @@ -253,6 +253,7 @@ CREATE TABLE `document_content_version` (
253 `major_version` int(11) NOT NULL default '0', 253 `major_version` int(11) NOT NULL default '0',
254 `minor_version` int(11) NOT NULL default '0', 254 `minor_version` int(11) NOT NULL default '0',
255 `storage_path` varchar(250) default NULL, 255 `storage_path` varchar(250) default NULL,
  256 + `md5hash` char(32) default NULL,
256 PRIMARY KEY (`id`), 257 PRIMARY KEY (`id`),
257 KEY `document_id` (`document_id`), 258 KEY `document_id` (`document_id`),
258 KEY `mime_id` (`mime_id`), 259 KEY `mime_id` (`mime_id`),
sql/mysql/upgrade/3.5.3/content_md5hash.sql 0 → 100644
  1 +ALTER TABLE document_content_version ADD md5hash char(32);
0 \ No newline at end of file 2 \ No newline at end of file