+--------------------------------------------------------------------+
| CiviCRM version 5 |
+--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2018 |
+ | Copyright CiviCRM LLC (c) 2004-2019 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
/**
*
* @package CRM
- * @copyright CiviCRM LLC (c) 2004-2018
+ * @copyright CiviCRM LLC (c) 2004-2019
* $Id$
*
*/
static $_signableFields = array('entityTable', 'entityID', 'fileID');
+ /**
+ * Takes an associative array and creates a File object.
+ *
+ * @param array $params
+ * (reference ) an assoc array of name/value pairs.
+ *
+ * @return CRM_Core_BAO_File
+ */
+ public static function create($params) {
+ $fileDAO = new CRM_Core_DAO_File();
+
+ $op = empty($params['id']) ? 'create' : 'edit';
+
+ CRM_Utils_Hook::pre($op, 'File', CRM_Utils_Array::value('id', $params), $params);
+
+ $fileDAO->copyValues($params);
+
+ if (empty($params['id']) && empty($params['created_id'])) {
+ $fileDAO->created_id = CRM_Core_Session::getLoggedInContactID();
+ }
+
+ $fileDAO->save();
+
+ CRM_Utils_Hook::post($op, 'File', $fileDAO->id, $fileDAO);
+
+ return $fileDAO;
+ }
+
/**
* @param int $fileID
* @param int $entityID
- * @param null $entityTable
*
* @return array
*/
- public static function path($fileID, $entityID, $entityTable = NULL) {
+ public static function path($fileID, $entityID) {
$entityFileDAO = new CRM_Core_DAO_EntityFile();
- if ($entityTable) {
- $entityFileDAO->entity_table = $entityTable;
- }
$entityFileDAO->entity_id = $entityID;
$entityFileDAO->file_id = $fileID;
$dao = CRM_Core_DAO::executeQuery($sql, $params);
$results = array();
while ($dao->fetch()) {
+ $fileHash = self::generateFileHash($dao->entity_id, $dao->cfID);
$result['fileID'] = $dao->cfID;
$result['entityID'] = $dao->cefID;
$result['mime_type'] = $dao->mime_type;
$result['description'] = $dao->description;
$result['cleanName'] = CRM_Utils_File::cleanFileName($dao->uri);
$result['fullPath'] = $config->customFileUploadDir . DIRECTORY_SEPARATOR . $dao->uri;
- $result['url'] = CRM_Utils_System::url('civicrm/file', "reset=1&id={$dao->cfID}&eid={$dao->entity_id}");
+ $result['url'] = CRM_Utils_System::url('civicrm/file', "reset=1&id={$dao->cfID}&eid={$dao->entity_id}&fcs={$fileHash}");
$result['href'] = "<a href=\"{$result['url']}\">{$result['cleanName']}</a>";
$result['tag'] = CRM_Core_BAO_EntityTag::getTag($dao->cfID, 'civicrm_file');
$result['icon'] = CRM_Utils_File::getIconFromMimeType($dao->mime_type);
return NULL;
}
+ /**
+ * Generates a MD5 Hash to be appended to file URLS to be checked when trying to download the file.
+ * @param int $eid entity id the file is attached to
+ * @param int $fid file ID
+ * @return string
+ */
+ public static function generateFileHash($eid = NULL, $fid = NULL, $genTs = NULL, $life = NULL) {
+ // Use multiple (but stable) inputs for hash information.
+ $siteKey = defined('CIVICRM_SITE_KEY') ? CIVICRM_SITE_KEY : 'NO_SITE_KEY';
+
+ if (!$genTs) {
+ $genTs = time();
+ }
+ if (!$life) {
+ $life = 24 * 2;
+ }
+ // Trim 8 chars off the string, make it slightly easier to find
+ // but reveals less information from the hash.
+ $cs = hash_hmac('sha256', "{$fid}_{$life}", $siteKey);
+ 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;
+ }
+
}