php upload restrictions

This commit is contained in:
Roman committed 2021-03-30 23:00:34 +02:00
1 parent 89badafbb1
commit c847650b1f
5 files changed
+96 -15

No files matched your search

+52 -2
View File
@@ -150,6 +150,32 @@ namespace Api {
->where(new CondNull("valid_until"), new Compare("valid_until", $sql->now(), ">="));
}
}
private static function unitToBytes($var) : int {
if (is_int($var) || is_numeric($var)) {
return intval($var);
} else {
preg_match("/(\\d+)([KMG])/", $var, $re);
if ($re) {
$units = ["K","M","G"];
$value = intval($re[1]);
$unitIndex = array_search($re[2], $units);
return $value * pow(1024, $unitIndex + 1);
} else {
return -1; // some weird error here
}
}
}
protected function getMaxFileSizePHP() : int {
$uploadMaxFilesize = $this->unitToBytes(ini_get("upload_max_filesize"));
$postMaxSize = $this->unitToBytes(ini_get("post_max_size"));
return min($uploadMaxFilesize, $postMaxSize);
}
protected function getMaxFiles() : int {
return intval(ini_get("max_file_uploads"));
}
}
}
@@ -204,9 +230,12 @@ namespace Api\File {
$this->result["files"] = $this->createFileList($res);
if ($row["token_type"] === "upload") {
$maxFiles = ($row["maxFiles"] ?? 0);
$maxSize = ($row["maxSize"] ?? 0);
$this->result["restrictions"] = array(
"maxFiles" => $row["maxFiles"] ?? 0,
"maxSize" => $row["maxSize"] ?? 0,
"maxFiles" => ($maxFiles <= 0 ? $this->getMaxFiles() : min($this->getMaxFiles(), $maxFiles)),
"maxSize" => ($maxSize <= 0 ? $this->getMaxFileSizePHP() : min($this->getMaxFileSizePHP(), $maxSize)),
"extensions" => $row["extensions"] ?? "",
"parentId" => $row["parentId"] ?? 0
);
@@ -218,6 +247,27 @@ namespace Api\File {
}
}
class GetRestrictions extends FileAPI {
public function __construct(User $user, bool $externalCall = false) {
parent::__construct($user, $externalCall, array());
$this->csrfTokenRequired = false;
$this->loginRequired = true;
}
public function execute($values = array()) {
if (!parent::execute($values)) {
return false;
}
$this->result["restrictions"] = array(
"maxFiles" => $this->getMaxFiles(),
"maxSize" => $this->getMaxFileSizePHP()
);
return true;
}
}
class RevokeToken extends FileAPI {
public function __construct(User $user, bool $externalCall = false) {
parent::__construct($user, $externalCall, array(
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WebPackConfiguration">
<option name="mode" value="DISABLED" />
</component>
</project>
@@ -2,6 +2,7 @@
padding: 0;
border: none;
vertical-align: middle;
font-size: 0.9em;
}
.file-control-buttons {
@@ -60,8 +61,4 @@
.file-table td:nth-child(n+3), .file-table th:nth-child(n+3) {
text-align: center;
}
.file-table tr, .file-table td {
height: 40px;
}
+36 -8
View File
@@ -57,7 +57,7 @@ export function FileBrowser(props) {
</svg>;
}
function createFileIcon(mimeType, size=2) {
function createFileIcon(mimeType, size="2x") {
let icon = "";
if (mimeType !== null) {
mimeType = mimeType.toLowerCase().trim();
@@ -92,7 +92,7 @@ export function FileBrowser(props) {
icon = "file" + (icon ? ("-" + icon) : icon);
}
return <Icon icon={icon} type={"far"} className={"p-1 align-middle fa-" + size + "x"} />
return <Icon icon={icon} type={"far"} className={"p-1 align-middle fa-" + size} />
}
function formatSize(size) {
@@ -134,9 +134,37 @@ export function FileBrowser(props) {
return ids;
}
// TODO: add more mime type names or use an directory here?
function getTypeName(type) {
if (type.toLowerCase() === "directory") {
return "Directory";
}
switch (type.toLowerCase()) {
case "image/jpeg":
return "JPEG-Image";
case "image/png":
return "PNG-Image";
case "application/pdf":
return "PDF-Document";
case "text/plain":
return "Text-Document"
case "application/x-dosexec":
return "Windows Executable";
case "application/vnd.oasis.opendocument.text":
return "OpenOffice-Document";
default:
return type;
}
}
function createFileList(elements, indentation=0) {
let rows = [];
let i = 0;
const scale = 0.45;
const iconSize = "lg";
const values = Object.values(elements);
for (const fileElement of values) {
let name = fileElement.name;
@@ -148,13 +176,13 @@ export function FileBrowser(props) {
let svg = [];
if (indentation > 0) {
for (let i = 0; i < indentation - 1; i++) {
svg.push(svgLeft(0.75));
svg.push(svgLeft(scale));
}
if (i === values.length - 1) {
svg.push(svgEnd(0.75));
svg.push(svgEnd(scale));
} else {
svg.push(svgMiddle(0.75));
svg.push(svgMiddle(scale));
}
}
@@ -162,14 +190,14 @@ export function FileBrowser(props) {
<tr key={"file-" + uid} data-id={uid} className={"file-row"}>
<td>
{ svg }
{ createFileIcon(mimeType) }
{ createFileIcon(mimeType, iconSize) }
</td>
<td>
{fileElement.isDirectory ? name :
<a href={"/api/file/download?id=" + uid + token} download={true}>{name}</a>
}
</td>
<td>{type}</td>
<td>{getTypeName(type)}</td>
<td>{size}</td>
<td>
<input type={"checkbox"} checked={!!fileElement.selected}
@@ -215,7 +243,7 @@ export function FileBrowser(props) {
const file = filesToUpload[i];
uploadedFiles.push(
<span className={"uploaded-file"} key={i}>
{ createFileIcon(file.type, 3) }
{ createFileIcon(file.type, "3x") }
<span>{file.name}</span>
<Icon icon={"times"} onClick={(e) => onRemoveUploadedFile(e, i)}/>
</span>
+1 -1
View File
@@ -299,4 +299,4 @@ e.defineLocale("zh-tw",{months:"一月_二月_三月_四月_五月_六月_七月
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/var r,a,i,o,s;if("undefined"==typeof window||"function"!=typeof MessageChannel){var u=null,l=null,d=function(){if(null!==u)try{var e=t.unstable_now();u(!0,e),u=null}catch(e){throw setTimeout(d,0),e}},c=Date.now();t.unstable_now=function(){return Date.now()-c},r=function(e){null!==u?setTimeout(r,0,e):(u=e,setTimeout(d,0))},a=function(e,t){l=setTimeout(e,t)},i=function(){clearTimeout(l)},o=function(){return!1},s=t.unstable_forceFrameRate=function(){}}else{var f=window.performance,m=window.Date,_=window.setTimeout,h=window.clearTimeout;if("undefined"!=typeof console){var p=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof p&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if("object"==typeof f&&"function"==typeof f.now)t.unstable_now=function(){return f.now()};else{var y=m.now();t.unstable_now=function(){return m.now()-y}}var v=!1,g=null,M=-1,L=5,b=0;o=function(){return t.unstable_now()>=b},s=function(){},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing framerates higher than 125 fps is not unsupported"):L=0<e?Math.floor(1e3/e):5};var k=new MessageChannel,Y=k.port2;k.port1.onmessage=function(){if(null!==g){var e=t.unstable_now();b=e+L;try{g(!0,e)?Y.postMessage(null):(v=!1,g=null)}catch(e){throw Y.postMessage(null),e}}else v=!1},r=function(e){g=e,v||(v=!0,Y.postMessage(null))},a=function(e,n){M=_((function(){e(t.unstable_now())}),n)},i=function(){h(M),M=-1}}function w(e,t){var n=e.length;e.push(t);e:for(;;){var r=n-1>>>1,a=e[r];if(!(void 0!==a&&0<S(a,t)))break e;e[r]=t,e[n]=a,n=r}}function T(e){return void 0===(e=e[0])?null:e}function D(e){var t=e[0];if(void 0!==t){var n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,a=e.length;r<a;){var i=2*(r+1)-1,o=e[i],s=i+1,u=e[s];if(void 0!==o&&0>S(o,n))void 0!==u&&0>S(u,o)?(e[r]=u,e[s]=n,r=s):(e[r]=o,e[i]=n,r=i);else{if(!(void 0!==u&&0>S(u,n)))break e;e[r]=u,e[s]=n,r=s}}}return t}return null}function S(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var x=[],E=[],j=1,H=null,O=3,P=!1,A=!1,F=!1;function C(e){for(var t=T(E);null!==t;){if(null===t.callback)D(E);else{if(!(t.startTime<=e))break;D(E),t.sortIndex=t.expirationTime,w(x,t)}t=T(E)}}function N(e){if(F=!1,C(e),!A)if(null!==T(x))A=!0,r(W);else{var t=T(E);null!==t&&a(N,t.startTime-e)}}function W(e,n){A=!1,F&&(F=!1,i()),P=!0;var r=O;try{for(C(n),H=T(x);null!==H&&(!(H.expirationTime>n)||e&&!o());){var s=H.callback;if(null!==s){H.callback=null,O=H.priorityLevel;var u=s(H.expirationTime<=n);n=t.unstable_now(),"function"==typeof u?H.callback=u:H===T(x)&&D(x),C(n)}else D(x);H=T(x)}if(null!==H)var l=!0;else{var d=T(E);null!==d&&a(N,d.startTime-n),l=!1}return l}finally{H=null,O=r,P=!1}}function R(e){switch(e){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var z=s;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){A||P||(A=!0,r(W))},t.unstable_getCurrentPriorityLevel=function(){return O},t.unstable_getFirstCallbackNode=function(){return T(x)},t.unstable_next=function(e){switch(O){case 1:case 2:case 3:var t=3;break;default:t=O}var n=O;O=t;try{return e()}finally{O=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=z,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=O;O=e;try{return t()}finally{O=n}},t.unstable_scheduleCallback=function(e,n,o){var s=t.unstable_now();if("object"==typeof o&&null!==o){var u=o.delay;u="number"==typeof u&&0<u?s+u:s,o="number"==typeof o.timeout?o.timeout:R(e)}else o=R(e),u=s;return e={id:j++,callback:n,priorityLevel:e,startTime:u,expirationTime:o=u+o,sortIndex:-1},u>s?(e.sortIndex=u,w(E,e),null===T(x)&&e===T(E)&&(F?i():F=!0,a(N,u-s))):(e.sortIndex=o,w(x,e),A||P||(A=!0,r(W))),e},t.unstable_shouldYield=function(){var e=t.unstable_now();C(e);var n=T(x);return n!==H&&null!==H&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime<H.expirationTime||o()},t.unstable_wrapCallback=function(e){var t=O;return function(){var n=O;O=t;try{return e.apply(this,arguments)}finally{O=n}}}},function(e,t,n){"use strict";(function(e){if(n(276),n(473),n(474),e._babelPolyfill)throw new Error("only one instance of babel-polyfill is allowed");e._babelPolyfill=!0;function t(e,t,n){e[t]||Object.defineProperty(e,t,{writable:!0,configurable:!0,value:n})}t(String.prototype,"padLeft","".padStart),t(String.prototype,"padRight","".padEnd),"pop,reverse,shift,keys,values,entries,indexOf,every,some,forEach,map,filter, Line truncated
*/var r,a,i,o,s;if("undefined"==typeof window||"function"!=typeof MessageChannel){var u=null,l=null,d=function(){if(null!==u)try{var e=t.unstable_now();u(!0,e),u=null}catch(e){throw setTimeout(d,0),e}},c=Date.now();t.unstable_now=function(){return Date.now()-c},r=function(e){null!==u?setTimeout(r,0,e):(u=e,setTimeout(d,0))},a=function(e,t){l=setTimeout(e,t)},i=function(){clearTimeout(l)},o=function(){return!1},s=t.unstable_forceFrameRate=function(){}}else{var f=window.performance,m=window.Date,_=window.setTimeout,h=window.clearTimeout;if("undefined"!=typeof console){var p=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!=typeof p&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills")}if("object"==typeof f&&"function"==typeof f.now)t.unstable_now=function(){return f.now()};else{var y=m.now();t.unstable_now=function(){return m.now()-y}}var v=!1,g=null,M=-1,L=5,b=0;o=function(){return t.unstable_now()>=b},s=function(){},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing framerates higher than 125 fps is not unsupported"):L=0<e?Math.floor(1e3/e):5};var k=new MessageChannel,Y=k.port2;k.port1.onmessage=function(){if(null!==g){var e=t.unstable_now();b=e+L;try{g(!0,e)?Y.postMessage(null):(v=!1,g=null)}catch(e){throw Y.postMessage(null),e}}else v=!1},r=function(e){g=e,v||(v=!0,Y.postMessage(null))},a=function(e,n){M=_((function(){e(t.unstable_now())}),n)},i=function(){h(M),M=-1}}function w(e,t){var n=e.length;e.push(t);e:for(;;){var r=n-1>>>1,a=e[r];if(!(void 0!==a&&0<S(a,t)))break e;e[r]=t,e[n]=a,n=r}}function T(e){return void 0===(e=e[0])?null:e}function D(e){var t=e[0];if(void 0!==t){var n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,a=e.length;r<a;){var i=2*(r+1)-1,o=e[i],s=i+1,u=e[s];if(void 0!==o&&0>S(o,n))void 0!==u&&0>S(u,o)?(e[r]=u,e[s]=n,r=s):(e[r]=o,e[i]=n,r=i);else{if(!(void 0!==u&&0>S(u,n)))break e;e[r]=u,e[s]=n,r=s}}}return t}return null}function S(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var x=[],E=[],j=1,H=null,O=3,P=!1,A=!1,F=!1;function C(e){for(var t=T(E);null!==t;){if(null===t.callback)D(E);else{if(!(t.startTime<=e))break;D(E),t.sortIndex=t.expirationTime,w(x,t)}t=T(E)}}function N(e){if(F=!1,C(e),!A)if(null!==T(x))A=!0,r(W);else{var t=T(E);null!==t&&a(N,t.startTime-e)}}function W(e,n){A=!1,F&&(F=!1,i()),P=!0;var r=O;try{for(C(n),H=T(x);null!==H&&(!(H.expirationTime>n)||e&&!o());){var s=H.callback;if(null!==s){H.callback=null,O=H.priorityLevel;var u=s(H.expirationTime<=n);n=t.unstable_now(),"function"==typeof u?H.callback=u:H===T(x)&&D(x),C(n)}else D(x);H=T(x)}if(null!==H)var l=!0;else{var d=T(E);null!==d&&a(N,d.startTime-n),l=!1}return l}finally{H=null,O=r,P=!1}}function R(e){switch(e){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var z=s;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){A||P||(A=!0,r(W))},t.unstable_getCurrentPriorityLevel=function(){return O},t.unstable_getFirstCallbackNode=function(){return T(x)},t.unstable_next=function(e){switch(O){case 1:case 2:case 3:var t=3;break;default:t=O}var n=O;O=t;try{return e()}finally{O=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=z,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=O;O=e;try{return t()}finally{O=n}},t.unstable_scheduleCallback=function(e,n,o){var s=t.unstable_now();if("object"==typeof o&&null!==o){var u=o.delay;u="number"==typeof u&&0<u?s+u:s,o="number"==typeof o.timeout?o.timeout:R(e)}else o=R(e),u=s;return e={id:j++,callback:n,priorityLevel:e,startTime:u,expirationTime:o=u+o,sortIndex:-1},u>s?(e.sortIndex=u,w(E,e),null===T(x)&&e===T(E)&&(F?i():F=!0,a(N,u-s))):(e.sortIndex=o,w(x,e),A||P||(A=!0,r(W))),e},t.unstable_shouldYield=function(){var e=t.unstable_now();C(e);var n=T(x);return n!==H&&null!==H&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime<H.expirationTime||o()},t.unstable_wrapCallback=function(e){var t=O;return function(){var n=O;O=t;try{return e.apply(this,arguments)}finally{O=n}}}},function(e,t,n){"use strict";(function(e){if(n(276),n(473),n(474),e._babelPolyfill)throw new Error("only one instance of babel-polyfill is allowed");e._babelPolyfill=!0;function t(e,t,n){e[t]||Object.defineProperty(e,t,{writable:!0,configurable:!0,value:n})}t(String.prototype,"padLeft","".padStart),t(String.prototype,"padRight","".padEnd),"pop,reverse,shift,keys,values,entries,indexOf,every,some,forEach,map,filter, Line truncated