Settings and checks for maximum artifact size #2
13 changed files with 69 additions and 12 deletions
|
@ -16,7 +16,6 @@ import net.friedl.fling.model.json.PathSerializer;
|
|||
|
||||
@Configuration
|
||||
public class FlingConfiguration {
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.io.IOException;
|
|||
import java.util.UUID;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.io.InputStreamResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
@ -32,6 +33,8 @@ import net.friedl.fling.service.archive.ArchiveService;
|
|||
@SecurityRequirement(name = "bearer")
|
||||
@Validated
|
||||
public class ArtifactController {
|
||||
@Value("${fling.max-artifact-size:-1}")
|
||||
private Long maxArtifactSize;
|
||||
|
||||
private ArtifactService artifactService;
|
||||
private ArchiveService archiveService;
|
||||
|
@ -58,6 +61,10 @@ public class ArtifactController {
|
|||
@PostMapping(path = "/{id}/data")
|
||||
public void uploadArtifactData(@PathVariable UUID id, HttpServletRequest request)
|
||||
throws IOException {
|
||||
if(maxArtifactSize >= 0 && maxArtifactSize < request.getContentLengthLong()) {
|
||||
throw new IOException("Maximum artifact size exceeded");
|
||||
}
|
||||
|
||||
archiveService.storeArtifact(id, request.getInputStream());
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,12 @@
|
|||
"type": "java.util.Long",
|
||||
"description": "Time until JWT tokens expire",
|
||||
"sourceType": "net.friedl.fling.security.FlingWebSecurityConfiguration"
|
||||
},
|
||||
{
|
||||
"name": "fling.max-artifact-size",
|
||||
"type": "java.util.Long",
|
||||
"description": "Maximum artifact size in bytes. -1 to disable.",
|
||||
"sourceType": "net.friedl.fling.controller.ArtifactController"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -11,7 +11,7 @@ spring:
|
|||
servlet:
|
||||
multipart.max-file-size: -1
|
||||
multipart.max-request-size: -1
|
||||
|
||||
|
||||
logging.level:
|
||||
root: WARN
|
||||
net.friedl: TRACE
|
||||
|
@ -21,6 +21,7 @@ logging.level:
|
|||
# spring.http.log-request-details: true
|
||||
|
||||
fling:
|
||||
max-artifact-size: 209715200 # 200 MB
|
||||
archive.filesystem.archive-path: /home/armin/Desktop/fling
|
||||
security:
|
||||
allowed-origins:
|
||||
|
|
|
@ -16,6 +16,7 @@ logging.level:
|
|||
root: WARN
|
||||
|
||||
fling:
|
||||
max-artifact-size: 209715200 # 200 MB
|
||||
archive.filesystem.archive-path: "/var/fling/files"
|
||||
security:
|
||||
allowed-origins:
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
REACT_APP_API=https://fling.friedl.net
|
||||
REACT_APP_LOGLEVEL=warn
|
||||
REACT_APP_FILESIZE=209715200
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
REACT_APP_API=http://localhost:8080/
|
||||
REACT_APP_LOGLEVEL=trace
|
||||
REACT_APP_FILESIZE=209715200
|
||||
|
||||
|
|
5
web/fling/package-lock.json
generated
5
web/fling/package-lock.json
generated
|
@ -13376,6 +13376,11 @@
|
|||
"resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz",
|
||||
"integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw=="
|
||||
},
|
||||
"vanillatoasts": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/vanillatoasts/-/vanillatoasts-1.4.0.tgz",
|
||||
"integrity": "sha512-DVMPPWVVt/x1B2f4iVpCw3rYDceu1PGRV8ECc3OfUC8By6O14OdXWjKryfaz8UorBuNe8btDIsujp6YP6gDNGA=="
|
||||
},
|
||||
"vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
"react-scripts": "3.4.1",
|
||||
"redux": "^4.0.5",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"spectre.css": "^0.5.8"
|
||||
"spectre.css": "^0.5.8",
|
||||
"vanillatoasts": "^1.4.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
|
|
|
@ -100,7 +100,9 @@ export default function FlingArtifacts() {
|
|||
.then(result => {
|
||||
log.debug(`Got ${result.length} artifacts`);
|
||||
for (let artifact of result) {
|
||||
artifacts.push(<FlingArtifactRow key={artifact.id} artifact={artifact} reloadArtifactsFn={getArtifacts} />);
|
||||
if(artifact.archived) {
|
||||
artifacts.push(<FlingArtifactRow key={artifact.id} artifact={artifact} reloadArtifactsFn={getArtifacts} />);
|
||||
}
|
||||
}
|
||||
|
||||
setArtifacts(artifacts);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import log from 'loglevel';
|
||||
import VanillaToasts from 'vanillatoasts';
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
|
@ -81,9 +82,21 @@ export default function Upload() {
|
|||
stopEvent(ev);
|
||||
ev.persist();
|
||||
|
||||
let evFiles = ev.dataTransfer.files;
|
||||
let maxSize = process.env.REACT_APP_FILESIZE;
|
||||
let evFiles = fileListToArray(ev.dataTransfer.files);
|
||||
|
||||
if (!evFiles) {
|
||||
for (let i = evFiles.length - 1; i >= 0; i--) {
|
||||
if (maxSize && maxSize >= 0 && evFiles[i].size > maxSize) {
|
||||
VanillaToasts.create({
|
||||
title: "Maximum file size exceeded",
|
||||
text: `${evFiles[i].name} exceeds the maximum file size of ${prettifyBytes(maxSize)}`,
|
||||
type: "warning"
|
||||
});
|
||||
evFiles.splice(i, 1);
|
||||
};
|
||||
}
|
||||
|
||||
if (evFiles.lenght === 0) {
|
||||
console.warn("Dropzone triggered without files");
|
||||
return;
|
||||
}
|
||||
|
@ -198,6 +211,7 @@ export default function Upload() {
|
|||
</div>
|
||||
<div className="upload-command-line m-2">
|
||||
<span className="total-upload">Total Size: {totalSize()}</span>
|
||||
<span className="total-upload">{`Max: ${prettifyBytes(process.env.REACT_APP_FILESIZE)}`}</span>
|
||||
<button className="btn btn-primary btn-upload" onClick={handleUpload}>Upload</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import log from 'loglevel';
|
||||
import VanillaToasts from 'vanillatoasts';
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
|
||||
import { Switch, Route, useLocation, Link } from "react-router-dom";
|
||||
|
@ -17,7 +18,10 @@ function Artifacts(props) {
|
|||
|
||||
let flingClient = new FlingClient();
|
||||
flingClient.getArtifacts(props.fling.id)
|
||||
.then(artifacts => setArtifacts(artifacts));
|
||||
.then(artifacts => {
|
||||
artifacts = artifacts.filter(a => a.archived)
|
||||
setArtifacts(artifacts)
|
||||
});
|
||||
}, [props.fling]);
|
||||
|
||||
function renderArtifact(artifact) {
|
||||
|
@ -119,9 +123,21 @@ function Upload(props) {
|
|||
stopEvent(ev);
|
||||
ev.persist();
|
||||
|
||||
let evFiles = ev.dataTransfer.files;
|
||||
let maxSize = process.env.REACT_APP_FILESIZE;
|
||||
let evFiles = fileListToArray(ev.dataTransfer.files);
|
||||
|
||||
if (!evFiles) {
|
||||
for (let i = evFiles.length - 1; i >= 0; i--) {
|
||||
if (maxSize && maxSize >= 0 && evFiles[i].size > maxSize) {
|
||||
VanillaToasts.create({
|
||||
title: "Maximum file size exceeded",
|
||||
text: `${evFiles[i].name} exceeds the maximum file size of ${prettifyBytes(maxSize)}`,
|
||||
type: "warning"
|
||||
});
|
||||
evFiles.splice(i, 1);
|
||||
};
|
||||
}
|
||||
|
||||
if (evFiles.length === 0) {
|
||||
console.warn("Dropzone triggered without files");
|
||||
return;
|
||||
}
|
||||
|
@ -236,6 +252,7 @@ function Upload(props) {
|
|||
</div>
|
||||
<div className="upload-command-line m-2">
|
||||
<span className="total-upload">Total Size: {totalSize()}</span>
|
||||
<span className="total-upload">{`Max: ${prettifyBytes(process.env.REACT_APP_FILESIZE)}`}</span>
|
||||
<button className="btn btn-primary btn-upload" onClick={handleUpload}>Upload</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -303,10 +320,10 @@ export default function FlingUserList(props) {
|
|||
<li className={`tab-item ${location.pathname !== path("upload") ? "active" : ""}`}>
|
||||
<Link to={path("files")}>Files</Link>
|
||||
</li>
|
||||
{ props.fling.allowUpload
|
||||
{props.fling.allowUpload
|
||||
? <li className={`tab-item ${location.pathname === path("upload") ? "active" : ""}`}>
|
||||
<Link to={path("upload")}>Upload</Link>
|
||||
</li>
|
||||
<Link to={path("upload")}>Upload</Link>
|
||||
</li>
|
||||
: <></>
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import { BrowserRouter } from "react-router-dom";
|
|||
|
||||
import App from './App';
|
||||
|
||||
import 'vanillatoasts/vanillatoasts.css';
|
||||
import "./style/fling.scss";
|
||||
|
||||
import * as serviceWorker from './serviceWorker';
|
||||
|
|
Loading…
Reference in a new issue