Commit f6a7616a authored by Carsten  Rose's avatar Carsten Rose
Browse files

Fixes #7293: Implement new logging for file upload.

Logger.php: remove UserAgent - that one is logged in FormSubmitLog Table. Add 'cookie' to filter individual actions.
parent ad263dcd
Pipeline #1080 passed with stage
in 1 minute and 40 seconds
......@@ -1222,6 +1222,7 @@ const UPLOAD_MODE_DELETEOLD = 'deleteOld';
const UPLOAD_MODE_DELETEOLD_NEW = 'deleteOld+new';
const UPLOAD_DEFAULT_MAX_SIZE = '10M';
const UPLOAD_DEFAULT_MIME_TYPE = 'application/pdf';
const UPLOAD_LOG_PREFIX = 'Upload';
const MIME_TYPE_SPLIT_CAPABLE = 'application/pdf';
......
......@@ -30,6 +30,8 @@ class File {
*/
private $session = null;
private $qfqLogFilename = '';
/**
* @param bool|false $phpUnit
* @throws CodeException
......@@ -40,6 +42,7 @@ class File {
$this->session = Session::getInstance($phpUnit);
$this->store = Store::getInstance('', $phpUnit);
$this->qfqLogFilename = $this->store->getVar(SYSTEM_QFQ_LOG, STORE_SYSTEM);
$this->uploadErrMsg = [
UPLOAD_ERR_INI_SIZE => "The uploaded file exceeds the upload_max_filesize directive in php.ini",
......@@ -61,16 +64,17 @@ class File {
$sipUpload = $this->store->getVar(SIP_SIP, STORE_SIP);
if ($sipUpload === false) {
// Throws an exception if content is too big - if content is bigger than 'post_max_size', the POST is lost together with the PHP Upload error message.
$this->checkMaxFileSize($_SERVER['CONTENT_LENGTH']);
if(empty($_FILES)){
if (empty($_FILES)) {
throw new UserFormException('Missing $_FILES[] - the whole request seems broken', ERROR_UPLOAD_FILES_BROKEN);
}
throw new UserFormException('SIP invalid: ' . $sipUpload, ERROR_SIP_INVALID);
}
// Throws an exception if content is too big - if content is bigger than 'post_max_size', the POST is lost together with the PHP Upload error message.
$size = isset($_SERVER['CONTENT_LENGTH']) ? $_SERVER['CONTENT_LENGTH'] : 0;
$this->checkMaxFileSize($size);
$statusUpload = $this->store->getVar($sipUpload, STORE_EXTRA, SANITIZE_ALLOW_ALL);
if ($statusUpload === false) {
$statusUpload = array();
......@@ -99,15 +103,11 @@ class File {
*/
private function checkMaxFileSize($size) {
$maxFileSize = $this->store->getVar(FE_FILE_MAX_FILE_SIZE, STORE_SIP);
$msg = 'File too big.';
if($maxFileSize!==false){
$msg .= ' Max allowed size: ' . $maxFileSize;
}
// Checked and set during form build.
$maxFileSize = $this->store->getVar(FE_FILE_MAX_FILE_SIZE, STORE_SIP . STORE_ZERO);
if ($maxFileSize===false || $size >= $maxFileSize) {
throw new UserFormException($msg, ERROR_UPLOAD_TOO_BIG);
if ($size >= $maxFileSize) {
throw new UserFormException('File too big. Max allowed size: ' . $maxFileSize, ERROR_UPLOAD_TOO_BIG);
}
}
......@@ -119,7 +119,10 @@ class File {
* @throws UserFormException
*/
private function doUpload($sipUpload, array $statusUpload) {
// New upload
$newArr = reset($_FILES);
// Merge new upload date to existing status information
$statusUpload = array_merge($statusUpload, $newArr);
if ($statusUpload[FILES_ERROR] !== UPLOAD_ERR_OK) {
......@@ -128,6 +131,8 @@ class File {
ERROR_UPLOAD);
}
Logger::logMessageWithPrefix(UPLOAD_LOG_PREFIX . ': File under ' . $statusUpload['tmp_name'], $this->qfqLogFilename);
$this->checkMaxFileSize($statusUpload['size']);
$accept = $this->store->getVar(FE_FILE_MIME_TYPE_ACCEPT, STORE_SIP);
......@@ -137,7 +142,14 @@ class File {
// rename uploaded file: ?.cached
$filenameCached = Support::extendFilename($statusUpload[FILES_TMP_NAME], UPLOAD_CACHED);
move_uploaded_file($newArr[FILES_TMP_NAME], $filenameCached);
error_clear_last();
if (!move_uploaded_file($newArr[FILES_TMP_NAME], $filenameCached)) {
$msg = error_get_last();
throw new UserFormException(
json_encode([ERROR_MESSAGE_TO_USER => 'Upload: Error', ERROR_MESSAGE_SUPPORT => $msg]),
ERROR_UPLOAD_FILE_TYPE);
}
$this->store->setVar($sipUpload, $statusUpload, STORE_EXTRA);
}
......@@ -155,7 +167,7 @@ class File {
if (isset($statusUpload[FILES_TMP_NAME]) && $statusUpload[FILES_TMP_NAME] != '') {
$file = Support::extendFilename($statusUpload[FILES_TMP_NAME], UPLOAD_CACHED);
if (file_exists($file)) {
HelperFile::unlink($file);
HelperFile::unlink($file, $this->qfqLogFilename);
}
$statusUpload[FILES_TMP_NAME] = '';
}
......
......@@ -38,6 +38,8 @@ class Save {
private $evaluate = null;
private $qfqLogFilename = '';
/**
* @param array $formSpec
* @param array $feSpecAction
......@@ -56,6 +58,9 @@ class Save {
$this->store = Store::getInstance();
$this->db = new Database($formSpec[F_DB_INDEX]);
$this->evaluate = new Evaluate($this->store, $this->db);
$this->qfqLogFilename = $this->store->getVar(SYSTEM_QFQ_LOG, STORE_SYSTEM);
}
/**
......@@ -589,7 +594,7 @@ class Save {
$oldFile = $arr[EXISTING_PATH_FILE_NAME];
if (file_exists($oldFile)) {
//TODO: it might be possible to delete a file, which is referenced by another record - a check would be nice.
HelperFile::unlink($oldFile);
HelperFile::unlink($oldFile, $this->qfqLogFilename);
}
$flagDelete = ($oldFile != '');
}
......@@ -601,9 +606,15 @@ class Save {
$modeUpload = $flagDelete ? UPLOAD_MODE_DELETEOLD : UPLOAD_MODE_UNCHANGED;
}
Logger::logMessageWithPrefix(UPLOAD_LOG_PREFIX . ': modeUpload= ' . $modeUpload, $this->qfqLogFilename);
// skip uploading the file, if this is an import without a specified file destination
if (!isset($formElement[FE_IMPORT_TO_TABLE]) || isset($formElement[FE_FILE_DESTINATION])) {
$pathFileName = $this->copyUploadFile($formElement, $statusUpload);
$msg = UPLOAD_LOG_PREFIX . ': ';
$msg .= ($pathFileName == '') ? 'Remove old upload / no new upload' : 'File "' . $statusUpload[FILES_TMP_NAME] . '" >> "' . $pathFileName . '"';
Logger::logMessageWithPrefix($msg, $this->qfqLogFilename);
}
HelperFile::chdir($cwd);
......@@ -624,7 +635,9 @@ class Save {
* @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
*/
private function doImport($formElement, $fileName) {
Support::setIfNotSet($formElement, FE_IMPORT_TYPE, FE_IMPORT_TYPE_AUTO);
switch ($formElement[FE_IMPORT_TYPE]) {
case FE_IMPORT_TYPE_AUTO:
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($fileName);
......
......@@ -149,7 +149,7 @@ class HelperFile {
public static function pathInfo($pathFileName) {
$vars = array();
$pathParts = path($pathFileName);
$pathParts = pathinfo($pathFileName);
$vars[VAR_FILENAME] = $pathFileName;
if (isset($pathParts['basename'])) {
......@@ -273,14 +273,19 @@ class HelperFile {
/**
* PHP System function: unlink() with QFQ exception
*
* @param $newSrc
* @param $filename
* @param string $logFilename
* @return string
* @throws UserFormException
*/
public static function unlink($newSrc) {
public static function unlink($filename, $logFilename = '') {
if ($logFilename != '') {
Logger::logMessageWithPrefix("Unlink: $filename", $logFilename);
}
if (false === unlink($newSrc)) {
$msg = self::errorGetLastAsString() . " - unlink($newSrc)";
if (false === unlink($filename)) {
$msg = self::errorGetLastAsString() . " - unlink($filename)";
throw new UserFormException(json_encode([ERROR_MESSAGE_TO_USER => 'unlink failed', ERROR_MESSAGE_SUPPORT => $msg]), ERROR_IO_UNLINK);
}
......
......@@ -61,6 +61,16 @@ class Logger {
fclose($handle);
}
/**
* @param $msg
* @param $filename
* @param string $mode
* @throws UserFormException
*/
public static function logMessageWithPrefix($msg, $filename, $mode = FILE_MODE_APPEND) {
self::logMessage(self::linePre() . $msg, $filename, $mode);
}
/**
* In case $filename is not absolute and if we're in the API directory: Check if we're in api - update relative filename
*
......@@ -82,9 +92,15 @@ class Logger {
* @return string
*/
public static function linePre() {
$str = '=== [' . date('Y-m-d H:i:s');
$cookie = isset($_COOKIE[SESSION_NAME]) ? $_COOKIE[SESSION_NAME] : '<no session cookie>';
$str = '[' . date('Y-m-d H:i:s');
$str .= ' / ' . htmlentities(empty($_SERVER['REMOTE_ADDR']) ? '<no ip>' : $_SERVER['REMOTE_ADDR']);
$str .= ' / ' . htmlentities(empty($_SERVER['HTTP_USER_AGENT']) ? '<no user agent>' : $_SERVER['HTTP_USER_AGENT']);
// $str .= ' / ' . htmlentities(empty($_SERVER['HTTP_USER_AGENT']) ? '<no user agent>' : $_SERVER['HTTP_USER_AGENT']);
$str .= ' / ' . htmlentities($cookie);
$str .= '] ';
return $str;
......
......@@ -1187,6 +1187,8 @@ class Support {
}
/**
* Append $extend to $filename
*
* @param string $filename
* @param string $extend
*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment