Browse Source

working on file module

module/files
Stephan Richter 1 month ago
parent
commit
a812fc674b
  1. 3
      files/src/main/java/de/srsoftware/umbrella/files/FileDb.java
  2. 57
      files/src/main/java/de/srsoftware/umbrella/files/FileModule.java
  3. 18
      files/src/main/java/de/srsoftware/umbrella/files/SqliteDb.java
  4. 47
      frontend/src/routes/files/Index.svelte

3
files/src/main/java/de/srsoftware/umbrella/files/FileDb.java

@ -1,4 +1,7 @@
package de.srsoftware.umbrella.files; package de.srsoftware.umbrella.files;
import de.srsoftware.umbrella.core.model.UmbrellaUser;
public interface FileDb { public interface FileDb {
public boolean isPermitted(UmbrellaUser user, String fileName);
} }

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

@ -8,20 +8,25 @@ import de.srsoftware.umbrella.core.BaseHandler;
import de.srsoftware.umbrella.core.ModuleRegistry; import de.srsoftware.umbrella.core.ModuleRegistry;
import de.srsoftware.umbrella.core.api.FileService; import de.srsoftware.umbrella.core.api.FileService;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException; import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
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.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors;
import static de.srsoftware.umbrella.core.ConnectionProvider.connect; import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.ModuleRegistry.projectService;
import static de.srsoftware.umbrella.core.ModuleRegistry.userService; import static de.srsoftware.umbrella.core.ModuleRegistry.userService;
import static de.srsoftware.umbrella.core.Paths.LIST; import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingFieldException;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.unprocessable;
import static de.srsoftware.umbrella.files.Constants.CONFIG_DATABASE; import static de.srsoftware.umbrella.files.Constants.CONFIG_DATABASE;
import static de.srsoftware.umbrella.files.Constants.CONFIG_FILESTORE; import static de.srsoftware.umbrella.files.Constants.CONFIG_FILESTORE;
@ -68,8 +73,50 @@ public class FileModule extends BaseHandler implements FileService {
return false; return false;
} }
private boolean getProjectFiles(Path path, HttpExchange ex, UmbrellaUser user) { private boolean getProjectFiles(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 += "/"+path;
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 (!file.exists()) throw unprocessable("{0} does not exist!",filename);
if (file.isDirectory()){
Map<String,Object> map = getDirectory(file);
map.put("title",filename.replace("/project/"+prjId,project.name()));
return sendContent(ex,map);
}
return getFile(ex, file);
}
private boolean getFile(HttpExchange ex, File file) throws IOException {
return sendContent(ex,new FileInputStream(file));
}
private Map<String,Object> getDirectory(File file) throws IOException {
var children = file.listFiles();
var map = new HashMap<String, Object>();
if (children == null) return map;
var prefixLen = baseDir.toString().length();
for (var child : children){
var o = map.computeIfAbsent(child.isDirectory() ? "dirs" : "files", k -> new HashMap<String, String>());
//noinspection unchecked
((Map<String,String>) o).put(child.toString().substring(prefixLen),child.getName());
}
return map;
} }
private boolean getUserFiles(Path path, HttpExchange ex, UmbrellaUser user) { private boolean getUserFiles(Path path, HttpExchange ex, UmbrellaUser user) {

18
files/src/main/java/de/srsoftware/umbrella/files/SqliteDb.java

@ -1,10 +1,16 @@
package de.srsoftware.umbrella.files; package de.srsoftware.umbrella.files;
import de.srsoftware.tools.jdbc.Condition;
import de.srsoftware.tools.jdbc.Query;
import de.srsoftware.umbrella.core.BaseDb; import de.srsoftware.umbrella.core.BaseDb;
import de.srsoftware.umbrella.core.model.UmbrellaUser;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import static de.srsoftware.tools.jdbc.Condition.equal;
import static de.srsoftware.tools.jdbc.Query.SelectQuery.ALL;
import static de.srsoftware.tools.jdbc.Query.select;
import static de.srsoftware.umbrella.core.Constants.USER_ID; import static de.srsoftware.umbrella.core.Constants.USER_ID;
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.databaseException; import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.databaseException;
import static de.srsoftware.umbrella.files.Constants.FILE; import static de.srsoftware.umbrella.files.Constants.FILE;
@ -36,4 +42,16 @@ public class SqliteDb extends BaseDb implements FileDb {
throw databaseException(e.getMessage()).causedBy(e); throw databaseException(e.getMessage()).causedBy(e);
} }
} }
@Override
public boolean isPermitted(UmbrellaUser user, String fileName) {
try {
var rs = select(ALL).from(TABLE_FILE_SHARES).where(USER_ID, equal(user.id())).where(FILE, equal(fileName)).exec(db);
var result = rs.next();
rs.close();
return result;
} catch (SQLException e) {
throw databaseException("Failed to check file permissions");
}
}
} }

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

@ -2,25 +2,32 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { useTinyRouter } from 'svelte-tiny-router'; import { useTinyRouter } from 'svelte-tiny-router';
import { api } from '../../urls.svelte'; import { api } from '../../urls.svelte';
import { error } from '../../warn.svelte'; import { error, yikes } from '../../warn.svelte';
import { t } from '../../translations.svelte'; import { t } from '../../translations.svelte';
import { user } from '../../user.svelte'; import { user } from '../../user.svelte';
const router = useTinyRouter(); const router = useTinyRouter();
let children = $state({}); let children = $state({});
let path = $state(router.path)
async function loadChildren(path){ async function loadChildren(p){
path = path.substring(6); p = p.substring(6);
if (path == '') path = '/'; if (p == '') p = '/';
children = { dirs : {}}; children = { dirs : {}, files : {}, title : p};
if (path == '/'){ console.log(p);
children.dirs[t('my_files')] = `user/${user.id}`; if (p == '/'){
children.dirs[t('projects')] = `projects`; children.dirs[`/user/${user.id}`] = t('my_files');
children.dirs[t('companies')] = `company`; children.dirs['/project'] = t('projects')
children.dirs['/company'] = t('companies');
} else { } else {
const url = api(`files${path}`); 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;
yikes();
} else { } else {
error(res); error(res);
} }
@ -45,14 +52,24 @@
onMount(() => loadChildren(window.location.pathname)); onMount(() => loadChildren(window.location.pathname));
</script> </script>
<h1>{t('files')}{router.path}</h1> <h1>{t('files')}{children?.title}</h1>
{#if children?.dirs}
<ul> <ul>
{#if children?.dirs}
{#each Object.entries(children.dirs) as [k,v]} {#each Object.entries(children.dirs) as [k,v]}
<li> <li class="dir">
<a href={router.fullPath+'/'+v} {onclick}>{k}</a> <span class="symbol"></span>
<a href={'/files'+k} {onclick}>{v}</a>
</li>
{/each}
{/if}
{#if children.files}
{#each Object.entries(children.files) as [k,v]}
<li class="file">
<span class="symbol"></span>
<a href={'/files'+k} {onclick}>{v}</a>
</li> </li>
{/each} {/each}
</ul>
{/if} {/if}
</ul>

Loading…
Cancel
Save