Add max upload size to config

This commit is contained in:
Bartek Fabiszewski 2020-06-02 22:25:06 +02:00
parent 6c032ddc5a
commit 62729088c5
20 changed files with 142 additions and 108 deletions

View File

@ -22,5 +22,6 @@
<config name="stroke_opacity" value="d:0;" />
<config name="stroke_weight" value="i:0;" />
<config name="units" value="s:6:&quot;metric&quot;;" />
<config name="upload_maxsize" value="i:0;" />
<ol_layers />
</dataset>

View File

@ -80,7 +80,8 @@ class MigrateTest extends UloggerDatabaseTestCase {
["name" => "stroke_color", "value" => "s:7:\"#abcdef\";"],
["name" => "stroke_opacity", "value" => "i:1;"],
["name" => "stroke_weight", "value" => "i:22;"],
["name" => "units", "value" => "s:8:\"imperial\";"]
["name" => "units", "value" => "s:8:\"imperial\";"],
["name" => "upload_maxsize", "value" => "i:0;"]
]];
$actual = $this->getConnection()->createQueryTable(
"config",

View File

@ -131,8 +131,14 @@ class uConfig {
* @var string Stroke color
*/
public $colorHilite = "#feff6a";
/**
* @var int Maximum size of uploaded files in bytes.
* Will be adjusted to system maximum upload size
*/
public $uploadMaxSize;
public function __construct($useDatabase = true) {
$this->uploadMaxSize = uUtils::getUploadMaxSize();
if ($useDatabase) {
$this->setFromDatabase();
}
@ -215,47 +221,49 @@ class uConfig {
$placeholder = self::db()->lobPlaceholder();
$query = "UPDATE " . self::db()->table('config') . "
SET value = CASE name
WHEN 'map_api' THEN $placeholder
WHEN 'latitude' THEN $placeholder
WHEN 'longitude' THEN $placeholder
WHEN 'google_key' THEN $placeholder
WHEN 'require_auth' THEN $placeholder
WHEN 'public_tracks' THEN $placeholder
WHEN 'pass_lenmin' THEN $placeholder
WHEN 'pass_strength' THEN $placeholder
WHEN 'interval_seconds' THEN $placeholder
WHEN 'lang' THEN $placeholder
WHEN 'units' THEN $placeholder
WHEN 'stroke_weight' THEN $placeholder
WHEN 'stroke_color' THEN $placeholder
WHEN 'stroke_opacity' THEN $placeholder
WHEN 'color_extra' THEN $placeholder
WHEN 'color_hilite' THEN $placeholder
WHEN 'color_normal' THEN $placeholder
WHEN 'color_start' THEN $placeholder
WHEN 'color_stop' THEN $placeholder
WHEN 'color_extra' THEN $placeholder
WHEN 'color_hilite' THEN $placeholder
WHEN 'google_key' THEN $placeholder
WHEN 'interval_seconds' THEN $placeholder
WHEN 'lang' THEN $placeholder
WHEN 'latitude' THEN $placeholder
WHEN 'longitude' THEN $placeholder
WHEN 'map_api' THEN $placeholder
WHEN 'pass_lenmin' THEN $placeholder
WHEN 'pass_strength' THEN $placeholder
WHEN 'public_tracks' THEN $placeholder
WHEN 'require_auth' THEN $placeholder
WHEN 'stroke_color' THEN $placeholder
WHEN 'stroke_opacity' THEN $placeholder
WHEN 'stroke_weight' THEN $placeholder
WHEN 'units' THEN $placeholder
WHEN 'upload_maxsize' THEN $placeholder
END";
$stmt = self::db()->prepare($query);
$params = [
$this->mapApi,
$this->initLatitude,
$this->initLongitude,
$this->googleKey,
$this->requireAuthentication,
$this->publicTracks,
$this->passLenMin,
$this->passStrength,
$this->interval,
$this->lang,
$this->units,
$this->strokeWeight,
$this->strokeColor,
$this->strokeOpacity,
$this->colorExtra,
$this->colorHilite,
$this->colorNormal,
$this->colorStart,
$this->colorStop,
$this->colorExtra,
$this->colorHilite
$this->googleKey,
$this->initLatitude,
$this->initLongitude,
$this->interval,
$this->lang,
$this->mapApi,
$this->passLenMin,
$this->passStrength,
$this->publicTracks,
$this->requireAuthentication,
$this->strokeColor,
$this->strokeOpacity,
$this->strokeWeight,
$this->units,
$this->uploadMaxSize
];
$stmt->execute(array_map('serialize', $params));
@ -419,6 +427,12 @@ class uConfig {
if (isset($arr['color_hilite']) && !empty($arr['color_hilite'])) {
$this->colorHilite = $arr['color_hilite'];
}
if (isset($arr['upload_maxsize']) && is_numeric($arr['upload_maxsize'])) {
$this->uploadMaxSize = (int) $arr['upload_maxsize'];
if ($this->uploadMaxSize === 0 || $this->uploadMaxSize > uUtils::getUploadMaxSize()) {
$this->uploadMaxSize = uUtils::getUploadMaxSize();
}
}
}
}

View File

@ -32,7 +32,7 @@ class uUpload {
const META_ERROR = "error";
const META_SIZE = "size";
public static $uploadDir = ROOT_DIR . "/uploads/";
private static $filePattern = "[a-z0-9_.]{20,}";
private static $filePattern = "/[a-z0-9_.]{20,}/";
private static $mimeMap = [];
/**

View File

@ -125,7 +125,7 @@
<div class="section">
<div id="import" class="menu-title"><?= $lang['import'] ?></div>
<form id="import-form" enctype="multipart/form-data" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="<?= uUtils::getUploadMaxSize() ?>" />
<input type="hidden" name="MAX_FILE_SIZE" value="<?= $config->uploadMaxSize ?>" />
<input type="file" id="input-file" name="gpx" data-bind="inputFile"/>
</form>
<a id="import-gpx" class="menu-link" data-bind="onImportGpx">gpx</a>

View File

@ -42,7 +42,7 @@ export default class uAjax {
/**
* Perform ajax HTTP request
* @param {string} url Request URL
* @param {Object|HTMLFormElement} [data] Optional request parameters: key/value pairs or form element
* @param {Object|HTMLFormElement|FormData} [data] Optional request parameters: key/value pairs or form element
* @param {Object} [options] Optional options
* @param {string} [options.method='GET'] Optional query method, default 'GET'
* @return {Promise<Object, Error>}
@ -81,12 +81,15 @@ export default class uAjax {
reject(new Error(message));
}
};
let body;
if (data instanceof HTMLFormElement) {
data = new FormData(data);
}
let body;
if (data instanceof FormData) {
if (method === 'POST') {
body = new FormData(data);
body = data;
} else {
body = new URLSearchParams(new FormData(data)).toString();
body = new URLSearchParams(data).toString();
}
} else {
for (const key in data) {
@ -108,7 +111,7 @@ export default class uAjax {
body = null;
}
xhr.open(method, url, true);
if (method === 'POST' && !(data instanceof HTMLFormElement)) {
if (method === 'POST' && !(data instanceof FormData)) {
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
}
xhr.send(body);

View File

@ -23,28 +23,29 @@ import uObserve from './observe.js';
/**
* @class uConfig
* @property {number} interval;
* @property {string} units
* @property {string} lang
* @property {string} mapApi
* @property {string} googleKey
* @property {uLayerCollection} olLayers
* @property {number} initLatitude
* @property {number} initLongitude
* @property {number} initLongitude
* @property {boolean} requireAuth
* @property {boolean} publicTracks
* @property {number} passStrength
* @property {number} passLenMin
* @property {number} strokeWeight
* @property {string} strokeColor
* @property {number} strokeOpacity
* @property {boolean} showLatest
* @property {string} colorExtra
* @property {string} colorHilite
* @property {string} colorNormal
* @property {string} colorStart
* @property {string} colorStop
* @property {string} colorExtra
* @property {string} colorHilite
* @property {string} googleKey
* @property {number} initLatitude
* @property {number} initLongitude
* @property {number} initLongitude
* @property {number} interval;
* @property {string} lang
* @property {string} mapApi
* @property {uLayerCollection} olLayers
* @property {number} passLenMin
* @property {number} passStrength
* @property {boolean} publicTracks
* @property {boolean} requireAuth
* @property {boolean} showLatest
* @property {string} strokeColor
* @property {number} strokeOpacity
* @property {number} strokeWeight
* @property {string} units
* @property {number} uploadMaxSize
*/
export default class uConfig {
@ -74,6 +75,7 @@ export default class uConfig {
this.colorStop = '#ff6a00';
this.colorExtra = '#cccccc';
this.colorHilite = '#feff6a';
this.uploadMaxSize = 0;
this.initUnits();
}

View File

@ -32,29 +32,30 @@ export default class ConfigDialogModel extends ViewModel {
constructor() {
super({
interval: config.interval,
units: config.units,
lang: config.lang,
mapApi: config.mapApi,
googleKey: config.googleKey,
layerId: config.olLayers.getPriorityLayer().toString(),
layers: new uLayerCollection(new uLayer(0, 'OpenStreetMap', '', 0), ...config.olLayers),
layerName: null,
layerUrl: null,
initLatitude: config.initLatitude,
initLongitude: config.initLongitude,
requireAuth: config.requireAuth,
publicTracks: config.publicTracks,
passStrength: config.passStrength,
passLenMin: config.passLenMin,
strokeWeight: config.strokeWeight,
strokeColor: config.strokeColor,
strokeOpacity: config.strokeOpacity,
colorExtra: config.colorExtra,
colorHilite: config.colorHilite,
colorNormal: config.colorNormal,
colorStart: config.colorStart,
colorStop: config.colorStop,
colorExtra: config.colorExtra,
colorHilite: config.colorHilite
googleKey: config.googleKey,
initLatitude: config.initLatitude,
initLongitude: config.initLongitude,
interval: config.interval,
lang: config.lang,
layerId: config.olLayers.getPriorityLayer().toString(),
layerName: null,
layers: new uLayerCollection(new uLayer(0, 'OpenStreetMap', '', 0), ...config.olLayers),
layerUrl: null,
mapApi: config.mapApi,
passLenMin: config.passLenMin,
passStrength: config.passStrength,
publicTracks: config.publicTracks,
requireAuth: config.requireAuth,
strokeColor: config.strokeColor,
strokeOpacity: config.strokeOpacity,
strokeWeight: config.strokeWeight,
units: config.units,
uploadMaxSize: config.uploadMaxSize
});
this.model.onCancel = () => this.onCancel();
this.model.onSave = () => this.onSave();
@ -242,6 +243,8 @@ export default class ConfigDialogModel extends ViewModel {
<option value="2"${this.model.passStrength === 2 ? ' selected' : ''}>paSsword1</option>
<option value="3"${this.model.passStrength === 3 ? ' selected' : ''}>paSsword1#</option>
</select></label>
<label><b>${$._('uploadmaxsize')}</b>
<input type="number" data-bind="uploadMaxSize" min="0" value="${this.model.uploadMaxSize}" required></label>
<label><b>${$._('requireauth')}</b>
<input type="checkbox" data-bind="requireAuth"${this.model.requireAuth ? ' checked' : ''}></label>
<label><b>${$._('publictracks')}</b>

View File

@ -52,6 +52,7 @@ describe('Config tests', () => {
expect(config.factorDistanceMajor).toBeDefined();
expect(config.unitDistanceMajor).toBeDefined();
expect(config.unitDay).toBeDefined();
expect(config.uploadMaxSize).toBeDefined();
});
it('should set units to imperial', () => {

View File

@ -52,7 +52,7 @@ describe('ConfigDialogModel tests', () => {
const testElements = [
'interval', 'units', 'lang', 'mapApi', 'googleKey', 'layerName', 'layerId', 'layerUrl', 'initLatitude', 'initLongitude',
'requireAuth', 'publicTracks', 'passStrength', 'passLenMin', 'strokeWeight', 'strokeColor', 'strokeOpacity',
'colorNormal', 'colorStart', 'colorStop', 'colorExtra', 'colorHilite'
'colorNormal', 'colorStart', 'colorStop', 'colorExtra', 'colorHilite', 'uploadMaxSize'
];
testElements.forEach((name) => {
it(`should trigger model property change for ${name}`, (done) => {

View File

@ -145,7 +145,7 @@ $lang["config"] = "Settings";
$lang["editingconfig"] = "Default application settings";
$lang["latitude"] = "Initial latitude";
$lang["longitude"] = "Initial longitude";
$lang["interval"] = "Interval";
$lang["interval"] = "Interval (s)";
$lang["googlekey"] = "Google Maps API key";
$lang["passlength"] = "Minimum password length";
$lang["passstrength"] = "Minimum password strength";
@ -159,6 +159,7 @@ $lang["colorstart"] = "Start marker color";
$lang["colorstop"] = "Stop marker color";
$lang["colorextra"] = "Extra marker color";
$lang["colorhilite"] = "Hilite marker color";
$lang["uploadmaxsize"] = "Maximum upload size (B)";
$lang["ollayers"] = "OpenLayers layer";
$lang["layername"] = "Layer name";
$lang["layerurl"] = "Layer URL";

View File

@ -49,7 +49,8 @@ INSERT INTO `config` (`name`, `value`) VALUES
('stroke_color', 's:7:"#ff0000";'),
('stroke_opacity', 'd:1;'),
('stroke_weight', 'i:2;'),
('units', 's:6:"metric";');
('units', 's:6:"metric";'),
('upload_maxsize', 'i:0;');
--
-- Table structure for table `ol_layers`

View File

@ -222,7 +222,8 @@ function getQueries() {
('stroke_color', 's:7:\"#ff0000\";'),
('stroke_opacity', 'd:1;'),
('stroke_weight', 'i:2;'),
('units', 's:6:\"metric\";')";
('units', 's:6:\"metric\";'),
('upload_maxsize', 'i:0;')";
$queries[] = "CREATE TABLE `$tLayers` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
@ -271,7 +272,8 @@ function getQueries() {
('stroke_color', 's:7:\"#ff0000\";'),
('stroke_opacity', 'd:1;'),
('stroke_weight', 'i:2;'),
('units', 's:6:\"metric\";')";
('units', 's:6:\"metric\";'),
('upload_maxsize', 'i:0;')";
$queries[] = "CREATE TABLE $tLayers (
id serial PRIMARY KEY,
@ -320,7 +322,8 @@ function getQueries() {
('stroke_color', 's:7:\"#ff0000\";'),
('stroke_opacity', 'd:1;'),
('stroke_weight', 'i:2;'),
('units', 's:6:\"metric\";')";
('units', 's:6:\"metric\";'),
('upload_maxsize', 'i:0;')";
$queries[] = "CREATE TABLE `$tLayers` (
`id` integer PRIMARY KEY AUTOINCREMENT,

View File

@ -275,7 +275,8 @@ function getQueries($dbDriver) {
('stroke_color', 's:7:\"#ff0000\";'),
('stroke_opacity', 'd:1;'),
('stroke_weight', 'i:2;'),
('units', 's:6:\"metric\";');";
('units', 's:6:\"metric\";'),
('upload_maxsize', 'i:0;')";
$queries[] = "CREATE TABLE `$tLayers` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
@ -361,7 +362,8 @@ function getQueries($dbDriver) {
('stroke_color', 's:7:\"#ff0000\";'),
('stroke_opacity', 'd:1;'),
('stroke_weight', 'i:2;'),
('units', 's:6:\"metric\";')";
('units', 's:6:\"metric\";'),
('upload_maxsize', 'i:0;')";
$queries[] = "CREATE TABLE $tLayers (
id serial PRIMARY KEY,
@ -446,7 +448,8 @@ function getQueries($dbDriver) {
('stroke_color', 's:7:\"#ff0000\";'),
('stroke_opacity', 'd:1;'),
('stroke_weight', 'i:2;'),
('units', 's:6:\"metric\";');";
('units', 's:6:\"metric\";'),
('upload_maxsize', 'i:0;')";
$queries[] = "CREATE TABLE `$tLayers` (
`id` integer PRIMARY KEY AUTOINCREMENT,

View File

@ -105,7 +105,8 @@ INSERT INTO `config` (`name`, `value`) VALUES
('stroke_color', 's:7:"#ff0000";'),
('stroke_opacity', 'd:1;'),
('stroke_weight', 'i:2;'),
('units', 's:6:"metric";');
('units', 's:6:"metric";'),
('upload_maxsize', 'i:0;');
-- --------------------------------------------------------

View File

@ -107,7 +107,8 @@ INSERT INTO config (name, value) VALUES
('stroke_color', 's:7:"#ff0000";'),
('stroke_opacity', 'd:1;'),
('stroke_weight', 'i:2;'),
('units', 's:6:"metric";');
('units', 's:6:"metric";'),
('upload_maxsize', 'i:0;');
-- --------------------------------------------------------

View File

@ -102,7 +102,8 @@ INSERT INTO `config` (`name`, `value`) VALUES
('stroke_color', 's:7:"#ff0000";'),
('stroke_opacity', 'd:1;'),
('stroke_weight', 'i:2;'),
('units', 's:6:"metric";');
('units', 's:6:"metric";'),
('upload_maxsize', 'i:0;');
-- --------------------------------------------------------

View File

@ -36,20 +36,26 @@ if ($auth->isAuthenticated()) {
}
$resultConfig = [
"interval" => $config->interval,
"units" => $config->units,
"lang" => $config->lang,
"mapApi" => $config->mapApi,
"colorExtra" => $config->colorExtra,
"colorHilite" => $config->colorHilite,
"colorNormal" => $config->colorNormal,
"colorStart" => $config->colorStart,
"colorStop" => $config->colorStop,
"googleKey" => $config->googleKey,
"initLatitude" => $config->initLatitude,
"initLongitude" => $config->initLongitude,
"requireAuth" => $config->requireAuthentication,
"publicTracks" => $config->publicTracks,
"interval" => $config->interval,
"lang" => $config->lang,
"mapApi" => $config->mapApi,
"passLenMin" => $config->passLenMin,
"passStrength" => $config->passStrength,
"strokeWeight" => $config->strokeWeight,
"publicTracks" => $config->publicTracks,
"requireAuth" => $config->requireAuthentication,
"strokeColor" => $config->strokeColor,
"strokeOpacity" => $config->strokeOpacity,
"strokeWeight" => $config->strokeWeight,
"units" => $config->units,
"uploadMaxSize" => $config->uploadMaxSize,
"layers" => []
];
foreach ($config->olLayers as $key => $val) {

View File

@ -29,15 +29,6 @@ $auth = new uAuth();
$config = uConfig::getInstance();
$lang = (new uLang($config))->getStrings();
$uploadErrors = [];
$uploadErrors[UPLOAD_ERR_INI_SIZE] = "The uploaded file exceeds the upload_max_filesize directive in php.ini";
$uploadErrors[UPLOAD_ERR_FORM_SIZE] = "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form";
$uploadErrors[UPLOAD_ERR_PARTIAL] = "The uploaded file was only partially uploaded";
$uploadErrors[UPLOAD_ERR_NO_FILE] = "No file was uploaded";
$uploadErrors[UPLOAD_ERR_NO_TMP_DIR] = "Missing a temporary folder";
$uploadErrors[UPLOAD_ERR_CANT_WRITE] = "Failed to write file to disk";
$uploadErrors[UPLOAD_ERR_EXTENSION] = "A PHP extension stopped the file upload";
if (!$auth->isAuthenticated()) {
uUtils::exitWithError($lang["private"]);
}

View File

@ -47,7 +47,8 @@ $data = [
'color_start' => uUtils::postInt('colorStart'),
'color_stop' => uUtils::postInt('colorStop'),
'color_extra' => uUtils::postInt('colorExtra'),
'color_hilite' => uUtils::postInt('colorHilite')
'color_hilite' => uUtils::postInt('colorHilite'),
'upload_maxsize' => uUtils::postInt('uploadMaxSize')
];
$config = uConfig::getInstance();