From 76edc327d4f5d1be70a6cc26ec04d0b52b6cf4c8 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Tue, 12 Feb 2019 15:50:40 -0800 Subject: [PATCH] generateFileHash() and validateFileHash() should be colocated The two functions (`generateFileHash()` and `validateFileHash()`) are tightly-coupled. Most changes to one would require a matching change in the other. So they should be parallel. It'd be OK to say "the hash formula is a general utility for any party using file APIs" (so put `generateFileHash()` and `validateFileHash()` in `CRM_Core_BAO_File`). It'd be OK to say "the hash formula is specific to the end-point/page which serves files" (so put `generateFileHash()` and `validateFileHash()` in `CRM_Core_Page_File`). The former feels a bit more accurate, so I pushed it toward that. --- CRM/Core/BAO/File.php | 24 +++++++++++++++++++++++ CRM/Core/Page/File.php | 26 +------------------------ tests/phpunit/api/v3/AttachmentTest.php | 2 +- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/CRM/Core/BAO/File.php b/CRM/Core/BAO/File.php index a1aba72106..4468dd8c0f 100644 --- a/CRM/Core/BAO/File.php +++ b/CRM/Core/BAO/File.php @@ -789,4 +789,28 @@ AND CEF.entity_id = %2"; return "{$cs}_{$genTs}_{$life}"; } + /** + * Validate a file Hash + * @param string $hash + * @param int $eid Entity Id the file is attached to + * @param int $fid File Id + * @return bool + */ + public static function validateFileHash($hash, $eid, $fid) { + $input = CRM_Utils_System::explode('_', $hash, 3); + $inputTs = CRM_Utils_Array::value(1, $input); + $inputLF = CRM_Utils_Array::value(2, $input); + $testHash = CRM_Core_BAO_File::generateFileHash($eid, $fid, $inputTs, $inputLF); + if (hash_equals($testHash, $hash)) { + $now = time(); + if ($inputTs + ($inputLF * 60 * 60) >= $now) { + return TRUE; + } + else { + return FALSE; + } + } + return FALSE; + } + } diff --git a/CRM/Core/Page/File.php b/CRM/Core/Page/File.php index 3f0e894193..dec65cc44c 100644 --- a/CRM/Core/Page/File.php +++ b/CRM/Core/Page/File.php @@ -46,7 +46,7 @@ class CRM_Core_Page_File extends CRM_Core_Page { $fid = CRM_Utils_Request::retrieve('fid', 'Positive', $this, FALSE); $id = CRM_Utils_Request::retrieve('id', 'Positive', $this, TRUE); $hash = CRM_Utils_Request::retrieve('fcs', 'Alphanumeric', $this); - if (!self::validateFileHash($hash, $eid, $fid)) { + if (!CRM_Core_BAO_File::validateFileHash($hash, $eid, $fid)) { CRM_Core_Error::statusBounce('URL for file is not valid'); } @@ -84,28 +84,4 @@ class CRM_Core_Page_File extends CRM_Core_Page { } } - /** - * Validate a file Hash - * @param string $hash - * @param int $eid Entity Id the file is attached to - * @param int $fid File Id - * @return bool - */ - public static function validateFileHash($hash, $eid, $fid) { - $input = CRM_Utils_System::explode('_', $hash, 3); - $inputTs = CRM_Utils_Array::value(1, $input); - $inputLF = CRM_Utils_Array::value(2, $input); - $testHash = CRM_Core_BAO_File::generateFileHash($eid, $fid, $inputTs, $inputLF); - if (hash_equals($testHash, $hash)) { - $now = time(); - if ($inputTs + ($inputLF * 60 * 60) >= $now) { - return TRUE; - } - else { - return FALSE; - } - } - return FALSE; - } - } diff --git a/tests/phpunit/api/v3/AttachmentTest.php b/tests/phpunit/api/v3/AttachmentTest.php index b02abf868e..f2721ec852 100644 --- a/tests/phpunit/api/v3/AttachmentTest.php +++ b/tests/phpunit/api/v3/AttachmentTest.php @@ -510,7 +510,7 @@ class api_v3_AttachmentTest extends CiviUnitTestCase { $queryResult = []; $parsedURl = parse_url($result['url']); $parsedQuery = parse_str($parsedURl['query'], $queryResult); - $this->assertTrue(CRM_Core_Page_File::validateFileHash($queryResult['fcs'], $queryResult['eid'], $queryResult['id'])); + $this->assertTrue(CRM_Core_BAO_File::validateFileHash($queryResult['fcs'], $queryResult['eid'], $queryResult['id'])); } sort($actualNames); -- 2.25.1