Commit 9b81d0a20f63e14957761dd584b5dfb9884c8d48
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
Showing
5 changed files
with
179 additions
and
13 deletions
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