php upload restrictions
This commit is contained in:
parent
89badafbb1
commit
c847650b1f
@ -150,6 +150,32 @@ namespace Api {
|
|||||||
->where(new CondNull("valid_until"), new Compare("valid_until", $sql->now(), ">="));
|
->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);
|
$this->result["files"] = $this->createFileList($res);
|
||||||
if ($row["token_type"] === "upload") {
|
if ($row["token_type"] === "upload") {
|
||||||
|
$maxFiles = ($row["maxFiles"] ?? 0);
|
||||||
|
$maxSize = ($row["maxSize"] ?? 0);
|
||||||
|
|
||||||
$this->result["restrictions"] = array(
|
$this->result["restrictions"] = array(
|
||||||
"maxFiles" => $row["maxFiles"] ?? 0,
|
"maxFiles" => ($maxFiles <= 0 ? $this->getMaxFiles() : min($this->getMaxFiles(), $maxFiles)),
|
||||||
"maxSize" => $row["maxSize"] ?? 0,
|
"maxSize" => ($maxSize <= 0 ? $this->getMaxFileSizePHP() : min($this->getMaxFileSizePHP(), $maxSize)),
|
||||||
"extensions" => $row["extensions"] ?? "",
|
"extensions" => $row["extensions"] ?? "",
|
||||||
"parentId" => $row["parentId"] ?? 0
|
"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 {
|
class RevokeToken extends FileAPI {
|
||||||
public function __construct(User $user, bool $externalCall = false) {
|
public function __construct(User $user, bool $externalCall = false) {
|
||||||
parent::__construct($user, $externalCall, array(
|
parent::__construct($user, $externalCall, array(
|
||||||
|
6
fileControlPanel/.idea/misc.xml
Normal file
6
fileControlPanel/.idea/misc.xml
Normal 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;
|
padding: 0;
|
||||||
border: none;
|
border: none;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-control-buttons {
|
.file-control-buttons {
|
||||||
@ -61,7 +62,3 @@
|
|||||||
.file-table td:nth-child(n+3), .file-table th:nth-child(n+3) {
|
.file-table td:nth-child(n+3), .file-table th:nth-child(n+3) {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-table tr, .file-table td {
|
|
||||||
height: 40px;
|
|
||||||
}
|
|
@ -57,7 +57,7 @@ export function FileBrowser(props) {
|
|||||||
</svg>;
|
</svg>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createFileIcon(mimeType, size=2) {
|
function createFileIcon(mimeType, size="2x") {
|
||||||
let icon = "";
|
let icon = "";
|
||||||
if (mimeType !== null) {
|
if (mimeType !== null) {
|
||||||
mimeType = mimeType.toLowerCase().trim();
|
mimeType = mimeType.toLowerCase().trim();
|
||||||
@ -92,7 +92,7 @@ export function FileBrowser(props) {
|
|||||||
icon = "file" + (icon ? ("-" + icon) : icon);
|
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) {
|
function formatSize(size) {
|
||||||
@ -134,9 +134,37 @@ export function FileBrowser(props) {
|
|||||||
return ids;
|
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) {
|
function createFileList(elements, indentation=0) {
|
||||||
let rows = [];
|
let rows = [];
|
||||||
let i = 0;
|
let i = 0;
|
||||||
|
|
||||||
|
const scale = 0.45;
|
||||||
|
const iconSize = "lg";
|
||||||
|
|
||||||
const values = Object.values(elements);
|
const values = Object.values(elements);
|
||||||
for (const fileElement of values) {
|
for (const fileElement of values) {
|
||||||
let name = fileElement.name;
|
let name = fileElement.name;
|
||||||
@ -148,13 +176,13 @@ export function FileBrowser(props) {
|
|||||||
let svg = [];
|
let svg = [];
|
||||||
if (indentation > 0) {
|
if (indentation > 0) {
|
||||||
for (let i = 0; i < indentation - 1; i++) {
|
for (let i = 0; i < indentation - 1; i++) {
|
||||||
svg.push(svgLeft(0.75));
|
svg.push(svgLeft(scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i === values.length - 1) {
|
if (i === values.length - 1) {
|
||||||
svg.push(svgEnd(0.75));
|
svg.push(svgEnd(scale));
|
||||||
} else {
|
} 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"}>
|
<tr key={"file-" + uid} data-id={uid} className={"file-row"}>
|
||||||
<td>
|
<td>
|
||||||
{ svg }
|
{ svg }
|
||||||
{ createFileIcon(mimeType) }
|
{ createFileIcon(mimeType, iconSize) }
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{fileElement.isDirectory ? name :
|
{fileElement.isDirectory ? name :
|
||||||
<a href={"/api/file/download?id=" + uid + token} download={true}>{name}</a>
|
<a href={"/api/file/download?id=" + uid + token} download={true}>{name}</a>
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td>{type}</td>
|
<td>{getTypeName(type)}</td>
|
||||||
<td>{size}</td>
|
<td>{size}</td>
|
||||||
<td>
|
<td>
|
||||||
<input type={"checkbox"} checked={!!fileElement.selected}
|
<input type={"checkbox"} checked={!!fileElement.selected}
|
||||||
@ -215,7 +243,7 @@ export function FileBrowser(props) {
|
|||||||
const file = filesToUpload[i];
|
const file = filesToUpload[i];
|
||||||
uploadedFiles.push(
|
uploadedFiles.push(
|
||||||
<span className={"uploaded-file"} key={i}>
|
<span className={"uploaded-file"} key={i}>
|
||||||
{ createFileIcon(file.type, 3) }
|
{ createFileIcon(file.type, "3x") }
|
||||||
<span>{file.name}</span>
|
<span>{file.name}</span>
|
||||||
<Icon icon={"times"} onClick={(e) => onRemoveUploadedFile(e, i)}/>
|
<Icon icon={"times"} onClick={(e) => onRemoveUploadedFile(e, i)}/>
|
||||||
</span>
|
</span>
|
||||||
|
2
js/files.min.js
vendored
2
js/files.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user