working on file deletion
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -4,11 +4,13 @@ package de.srsoftware.umbrella.files;
|
||||
import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
|
||||
import static de.srsoftware.umbrella.core.Constants.*;
|
||||
import static de.srsoftware.umbrella.core.ModuleRegistry.*;
|
||||
import static de.srsoftware.umbrella.core.ResponseCode.HTTP_SERVER_ERROR;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
|
||||
import static de.srsoftware.umbrella.files.Constants.CONFIG_DATABASE;
|
||||
import static de.srsoftware.umbrella.files.Constants.CONFIG_FILESTORE;
|
||||
import static java.net.HttpURLConnection.HTTP_OK;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.text.MessageFormat.format;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import de.srsoftware.configuration.Configuration;
|
||||
@@ -51,6 +53,110 @@ public class FileModule extends BaseHandler implements FileService {
|
||||
ModuleRegistry.add(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDelete(Path path, HttpExchange ex) throws IOException {
|
||||
addCors(ex);
|
||||
try {
|
||||
Optional<Token> token = SessionToken.from(ex).map(Token::of);
|
||||
var user = userService().loadUser(token);
|
||||
if (user.isEmpty()) return unauthorized(ex);
|
||||
var head = path.pop();
|
||||
return switch (head){
|
||||
case COMPANY -> deleteCompanyFile(path, ex, user.get());
|
||||
case PROJECT -> deleteProjectFile(path, ex, user.get());
|
||||
case USER -> deleteUserFile(path, ex, user.get());
|
||||
case null, default -> throw UmbrellaException.notFound("invalid location: {0}", head);
|
||||
};
|
||||
} catch (UmbrellaException e) {
|
||||
return send(ex,e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean deleteCompanyFile(Path path, HttpExchange ex, UmbrellaUser user) throws IOException {
|
||||
var cpId = path.pop();
|
||||
var companies = companyService();
|
||||
Map<Long, Company> companyList;
|
||||
if (cpId == null){
|
||||
companyList = companies.listCompaniesOf(user);
|
||||
var map = companyList.values().stream().collect(Collectors.toMap(company -> "/company/"+company.id(), Company::name));
|
||||
return sendContent(ex,Map.of("dirs",map));
|
||||
}
|
||||
|
||||
long cid;
|
||||
try {
|
||||
cid = Long.parseLong(cpId);
|
||||
} catch (NumberFormatException e) {
|
||||
throw invalidFieldException(COMPANY_ID,"Long");
|
||||
}
|
||||
|
||||
var company = companies.get(cid);
|
||||
var filename = "/company/"+cid;
|
||||
if (!path.empty()) filename += "/"+URLDecoder.decode(path.toString(),UTF_8);
|
||||
if (!companies.membership(cid,user.id()) && !fileDb.isPermitted(user,filename)) throw forbidden("You are not allowed to access {0}",filename);
|
||||
var file = new File(baseDir+filename);
|
||||
if (!file.exists()) throw unprocessable("{0} does not exist!",filename);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean deleteProjectFile(Path path, HttpExchange ex, UmbrellaUser user) throws IOException {
|
||||
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);
|
||||
return deleteFile(ex, new File(baseDir+filename));
|
||||
}
|
||||
|
||||
private static boolean dropDir(File dir) {
|
||||
File[] nested = dir.listFiles();
|
||||
if (nested != null) {
|
||||
for (File file : nested) {
|
||||
if (!dropDir(file)) return false;
|
||||
}
|
||||
}
|
||||
return dir.delete();
|
||||
}
|
||||
|
||||
private boolean deleteFile(HttpExchange ex, File file) throws IOException {
|
||||
if (!file.exists()) throw unprocessable("{0} does not exist!",file.getName());
|
||||
if (!dropDir(file)) return sendContent(ex,HTTP_SERVER_ERROR,format("Failed to delete {0}",file.getName()));
|
||||
Map<String,Object> map = getDirectory(file.getParentFile());
|
||||
map.put("title",file.getName());
|
||||
return sendContent(ex,map);
|
||||
|
||||
}
|
||||
|
||||
private boolean deleteUserFile(Path path, HttpExchange ex, UmbrellaUser user) {
|
||||
var userId = path.pop();
|
||||
if (userId == null) throw missingFieldException(USER_ID);
|
||||
long uid;
|
||||
try {
|
||||
uid = Long.parseLong(userId);
|
||||
} catch (NumberFormatException e) {
|
||||
throw invalidFieldException(PROJECT_ID,"Long");
|
||||
}
|
||||
var filename = "/user/"+uid;
|
||||
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);
|
||||
var file = new File(baseDir+filename);
|
||||
if (!file.exists()) throw unprocessable("{0} does not exist!",filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doGet(Path path, HttpExchange ex) throws IOException {
|
||||
addCors(ex);
|
||||
|
||||
Reference in New Issue
Block a user