Browse Source

implemented user file upload and project file upload

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
module/files
Stephan Richter 1 month ago
parent
commit
2b4f73349d
  1. 69
      files/src/main/java/de/srsoftware/umbrella/files/FileModule.java
  2. 33
      frontend/src/routes/files/Index.svelte

69
files/src/main/java/de/srsoftware/umbrella/files/FileModule.java

@ -13,6 +13,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.configuration.Configuration; import de.srsoftware.configuration.Configuration;
import de.srsoftware.tools.MimeType;
import de.srsoftware.tools.Path; import de.srsoftware.tools.Path;
import de.srsoftware.tools.SessionToken; import de.srsoftware.tools.SessionToken;
import de.srsoftware.umbrella.core.BaseHandler; import de.srsoftware.umbrella.core.BaseHandler;
@ -23,9 +24,8 @@ import de.srsoftware.umbrella.core.model.Company;
import de.srsoftware.umbrella.core.model.Project; import de.srsoftware.umbrella.core.model.Project;
import de.srsoftware.umbrella.core.model.Token; import de.srsoftware.umbrella.core.model.Token;
import de.srsoftware.umbrella.core.model.UmbrellaUser; import de.srsoftware.umbrella.core.model.UmbrellaUser;
import java.io.File;
import java.io.FileInputStream; import java.io.*;
import java.io.IOException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.HashMap; import java.util.HashMap;
@ -205,7 +205,43 @@ public class FileModule extends BaseHandler implements FileService {
} }
private boolean postProjectDirectory(Path path, HttpExchange ex, UmbrellaUser user) throws IOException { private boolean postProjectDirectory(Path path, HttpExchange ex, UmbrellaUser user) throws IOException {
return false; var prjId = path.pop();
var projects = projectService();
if (prjId == null){
var projectList = projects.listUserProjects(user.id(),true);
var map = projectList.values().stream().collect(Collectors.toMap(prj -> "/project/"+prj.id(),Project::name));
return sendContent(ex,Map.of("dirs",map));
}
long pid;
try {
pid = Long.parseLong(prjId);
} catch (NumberFormatException e) {
throw invalidFieldException(PROJECT_ID,"Long");
}
var project = projects.loadMembers(projects.load(pid));
var filename = "/project/"+pid;
if (!path.empty()) filename += "/"+URLDecoder.decode(path.toString(),UTF_8);
if (!project.hasMember(user) && !fileDb.isPermitted(user,filename)) throw forbidden("You are not allowed to access {0}",filename);
var file = new File(baseDir+filename);
if (contentType(ex).isPresent()) { // file upload
var out = new FileOutputStream(file);
var body = ex.getRequestBody();
body.transferTo(out);
body.close();
out.close();
} else {
if (file.exists()) throw unprocessable("{0} already exists!", filename);
try {
file.mkdirs();
} catch (Exception e) {
throw unprocessable("Failed to create {0}", filename);
}
}
Map<String,Object> map = getDirectory(file.getParentFile());
map.put("title",filename);
return sendContent(ex,map);
} }
private boolean postUserDirectory(Path path, HttpExchange ex, UmbrellaUser user) throws IOException { private boolean postUserDirectory(Path path, HttpExchange ex, UmbrellaUser user) throws IOException {
@ -221,18 +257,19 @@ public class FileModule extends BaseHandler implements FileService {
if (!path.empty()) filename += "/"+URLDecoder.decode(path.toString(),UTF_8); if (!path.empty()) filename += "/"+URLDecoder.decode(path.toString(),UTF_8);
if (uid != user.id() && !fileDb.isPermitted(user,filename)) throw forbidden("You are not allowed to access {0}",filename); if (uid != user.id() && !fileDb.isPermitted(user,filename)) throw forbidden("You are not allowed to access {0}",filename);
var file = new File(baseDir+filename); var file = new File(baseDir+filename);
var contentType = contentType(ex).orElse(null); if (contentType(ex).isPresent()) { // file upload
if (MIME_FORM_DATA.equals(contentType)) { // file upload var out = new FileOutputStream(file);
// TODO: create parent directory if it does not exist var body = ex.getRequestBody();
// TODO: create file and write content body.transferTo(out);
return false; body.close();
} out.close();
} else {
if (file.exists()) throw unprocessable("{0} already exists!",filename); if (file.exists()) throw unprocessable("{0} already exists!", filename);
try { try {
file.mkdirs(); file.mkdirs();
} catch (Exception e) { } catch (Exception e) {
throw unprocessable("Failed to create {0}",filename); throw unprocessable("Failed to create {0}", filename);
}
} }
Map<String,Object> map = getDirectory(file.getParentFile()); Map<String,Object> map = getDirectory(file.getParentFile());
map.put("title",filename); map.put("title",filename);

33
frontend/src/routes/files/Index.svelte

@ -42,8 +42,7 @@
method: 'POST' method: 'POST'
}); });
if (res.ok) { if (res.ok) {
yikes(); handleDirectory(res);
loadChildren(window.location.pathname);
new_dir = null; new_dir = null;
} else { } else {
error(res); error(res);
@ -51,6 +50,14 @@
return false; return false;
} }
async function handleDirectory(res){
let json = await res.json();
if (json.dirs) children.dirs = json.dirs;
if (json.files) children.files = json.files;
if (json.title) children.title = json.title;
yikes();
}
async function loadChildren(p){ async function loadChildren(p){
p = p.substring(6); p = p.substring(6);
if (p == '') p = '/'; if (p == '') p = '/';
@ -67,14 +74,10 @@
const url = api(`files${p}`); const url = api(`files${p}`);
const res = await fetch(url,{credentials:'include'}); const res = await fetch(url,{credentials:'include'});
if (res.ok){ if (res.ok){
let json = await res.json();
if (json.dirs) children.dirs = json.dirs;
if (json.files) children.files = json.files;
if (json.title) children.title = json.title;
parent = p.substring(0, p.lastIndexOf("/")); parent = p.substring(0, p.lastIndexOf("/"));
if (parent == '/user'||p=='/project'||p=='/company') parent = '/'; if (parent == '/user'||p=='/project'||p=='/company') parent = '/';
form = !(p=='/company'||p=='/project'||p=='/user'); form = !(p=='/company'||p=='/project'||p=='/user');
yikes(); handleDirectory(res);
} else { } else {
error(res); error(res);
} }
@ -98,18 +101,18 @@
async function upload_file(ev){ async function upload_file(ev){
ev.preventDefault(); ev.preventDefault();
console.log(files); const url = api('files'+path+'/'+files[0].name);
const dataArray = new FormData(); const resp = await fetch(url, {
dataArray.append("uploadFile", files);
const url = api('files'+path);
const resp = fetch(url, {
credentials: 'include', credentials: 'include',
method: 'POST', method: 'POST',
headers: [["Content-Type", "multipart/form-data"]], headers: {
body: dataArray "Content-Type": "application/unknown",
},
body: files[0]
}); });
if (resp.ok){ if (resp.ok){
yikes(); handleDirectory(resp);
files = null;
} else { } else {
error(resp); error(resp);
} }

Loading…
Cancel
Save