Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
6a6b96b
Refactored Modules
Schlaumeier5 Mar 29, 2026
8d5d015
Now using new config format in frontend
Schlaumeier5 Mar 29, 2026
90ca8aa
New AccessManager approach: using WebPath registry for access managing
Schlaumeier5 Mar 30, 2026
681e32c
Added ModuleRequestHandler
Schlaumeier5 Mar 30, 2026
32d3040
Fixed a few bugs
Schlaumeier5 Mar 30, 2026
fe8c056
Added some functionality to modules page
Schlaumeier5 Mar 30, 2026
2368a71
New module loading system
Schlaumeier5 Mar 30, 2026
a3dab83
Now publishing to maven so that plugins can import
Schlaumeier5 Mar 30, 2026
72df300
Added Dependency, better Module loading system
Schlaumeier5 Mar 30, 2026
7a7109e
Safer yaml handling
Schlaumeier5 Mar 30, 2026
c7a9776
Fixed a few more loading bugs
Schlaumeier5 Mar 30, 2026
d430dd7
New ResourceManager approach
Schlaumeier5 Mar 30, 2026
deb3ad0
Renamed Modules to Plugins for the concept to match the label better
Schlaumeier5 Mar 30, 2026
77d4e6a
Set version to 1.0.2
Schlaumeier5 Mar 30, 2026
e83b6da
Plugins are now enabled on start
Schlaumeier5 Mar 30, 2026
d24a979
Adding config persistence
Schlaumeier5 Mar 30, 2026
eaf6c47
Added BoolSettings to module config page
Schlaumeier5 Mar 30, 2026
f1a8dbe
Now merged resources from different ResourceProviders are possible
Schlaumeier5 Mar 30, 2026
e182a4c
Fixed a little bug with MergeHelper
Schlaumeier5 Mar 30, 2026
69176f2
New templating system
Schlaumeier5 Mar 30, 2026
06c0f3a
Admin dashboard navigation is now extendable by plugins pretty easily
Schlaumeier5 Mar 30, 2026
781d22c
Added student dashboard nav
Schlaumeier5 Mar 30, 2026
b755c0e
Added STUDENT_OTHER navigation type
Schlaumeier5 Mar 30, 2026
bcc7123
Bumped version to v1.1.0-SNAPSHOT-0
Schlaumeier5 Mar 30, 2026
3b4eb58
Added new navigation type: admin student view
Schlaumeier5 Mar 30, 2026
af77b4d
New Navigation type: admin student other nav
Schlaumeier5 Mar 30, 2026
12fca75
Added new navigation type for other admin pages
Schlaumeier5 Mar 31, 2026
b3ea707
Added teacher student nav
Schlaumeier5 Mar 31, 2026
24df220
Added teacher_student_other_nav
Schlaumeier5 Mar 31, 2026
c2cc11c
Added other teacher navigation types that are not currently used but …
Schlaumeier5 Mar 31, 2026
1ff29c4
Introduced RegistryEnums
Schlaumeier5 Mar 31, 2026
c049f53
Added remaining teacher navigation types
Schlaumeier5 Mar 31, 2026
06604a5
Added nav to editor
Schlaumeier5 Mar 31, 2026
f1d6a2e
Potential fix for code scanning alert no. 13: Incomplete string escap…
Schlaumeier5 Mar 31, 2026
1adc605
Potential fix for code scanning alert no. 14: Arbitrary file access d…
Schlaumeier5 Mar 31, 2026
768f680
Potential fix for security alert #14
Schlaumeier5 Mar 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ target
.idea
bin
.gradle
build
build
/modules
/plugins
28 changes: 27 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ plugins {
java
application
id("com.github.johnrengelman.shadow") version "8.1.1"
id("maven-publish")
}

group = "igs-landstuhl"

version = "v1.0.1-PATCH-2"
version = "v1.1.0-SNAPSHOT-0"

application {
mainClass.set("de.igslandstuhl.database.Application")
Expand All @@ -22,6 +23,7 @@ dependencies {
implementation("commons-codec:commons-codec:1.19.0")
implementation("com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20260101.1")
implementation("org.jline:jline:3.30.6") // for better console input handling
implementation("org.yaml:snakeyaml:2.2") // plugin imports

testImplementation("org.junit.jupiter:junit-jupiter:5.13.4") // using JUnit 5 (latest)
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
Expand Down Expand Up @@ -50,3 +52,27 @@ java {
languageVersion.set(JavaLanguageVersion.of(17)) // or another version you prefer
}
}

publishing {
publications {
create<MavenPublication>("mavenJava") {
from(components["java"])

groupId = "igs-landstuhl"
artifactId = "student-database"
version = project.version.toString()
}
}

repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/Learn-Monitor/student-database/")

credentials {
username = System.getenv("GITHUB_ACTOR")
password = System.getenv("GITHUB_TOKEN")
}
}
}
}
24 changes: 18 additions & 6 deletions src/main/java/de/igslandstuhl/database/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
import java.util.ArrayList;
import java.util.List;

import org.jline.reader.UserInterruptException;

import de.igslandstuhl.database.api.SerializationException;
import de.igslandstuhl.database.api.Subject;
import de.igslandstuhl.database.api.Topic;
import de.igslandstuhl.database.api.modules.WebModule;
import de.igslandstuhl.database.client.HTMLTemplate;
import de.igslandstuhl.database.holidays.Holiday;
import de.igslandstuhl.database.plugins.PluginLoader;
import de.igslandstuhl.database.server.Server;
import de.igslandstuhl.database.server.commands.Command;
import de.igslandstuhl.database.server.webserver.WebPath;
Expand Down Expand Up @@ -105,19 +108,28 @@ public static void main(String[] args) throws Exception {

Holiday.setupCurrentSchoolYear();
PostRequestHandler.registerHandlers();
WebModule.registerModules();
PluginLoader.getInstance().registerPlugins();

WebPath.registerPaths();
HTMLTemplate.registerAll();
GetRequestHandler.getInstance().registerHandlers();

if (getInstance().runsWebServer()) {
Server.getInstance().getWebServer().start();
}

while (true) {
if (!getInstance().suppressCmd()) {
CommandLineUtils.waitForCommandAndExec();
PluginLoader.getInstance().enablePlugins();

Runtime.getRuntime().addShutdownHook(new Thread(() -> PluginLoader.getInstance().unloadPlugins(),"Plugin cleanup thread"));

try {
while (true) {
if (!getInstance().suppressCmd()) {
CommandLineUtils.waitForCommandAndExec();
}
}
}
} catch (UserInterruptException e) {
System.exit(0);
} // Program exit using Ctrl+C
}
}
60 changes: 56 additions & 4 deletions src/main/java/de/igslandstuhl/database/Registry.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,34 @@

import java.io.Closeable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;

import de.igslandstuhl.database.api.modules.WebModule;
import de.igslandstuhl.database.client.HTMLTemplate;
import de.igslandstuhl.database.client.navigation.NavigationElement;
import de.igslandstuhl.database.client.navigation.NavigationType;
import de.igslandstuhl.database.plugins.Plugin;
import de.igslandstuhl.database.server.commands.Command;
import de.igslandstuhl.database.server.commands.CommandDescription;
import de.igslandstuhl.database.server.webserver.WebPath;
import de.igslandstuhl.database.server.webserver.handlers.HttpHandler;
import de.igslandstuhl.database.server.webserver.requests.APIPostRequest;
import de.igslandstuhl.database.server.webserver.requests.GetRequest;
import de.igslandstuhl.database.utils.RegistryEnum;

public class Registry<K, V> implements Closeable {
private static final Registry<String,Command> COMMAND_REGISTRY = new Registry<>();
private static final Registry<String,CommandDescription> COMMAND_DESCRIPTION_REGISTRY = new Registry<>();
private static final Registry<String,HttpHandler<APIPostRequest>> POST_HANDLER_REGISTRY = new Registry<>();
private static final Registry<String,HttpHandler<GetRequest>> GET_HANDLER_REGISTRY = new Registry<>();
private static final Registry<String,WebModule> MODULE_REGISTRY = new Registry<>();
private static final Registry<String,Plugin> PLUGIN_REGISTRY = new Registry<>();
private static final Registry<String,WebPath> WEB_PATH_REGISTRY = new Registry<>();

private static final EnumRegistry<NavigationType,NavigationElement> NAVIGATION_REGISTRY = new EnumRegistry<>(NavigationType.class);
private static final Registry<String,HTMLTemplate> TEMPLATE_REGISTRY = new Registry<>();

public static Registry<String,Command> commandRegistry() {
return COMMAND_REGISTRY;
}
Expand All @@ -29,19 +39,30 @@ public static Registry<String, HttpHandler<APIPostRequest>> postRequestHandlerRe
public static Registry<String, HttpHandler<GetRequest>> getRequestHandlerRegistry() {
return GET_HANDLER_REGISTRY;
}
public static Registry<String, WebModule> moduleRegistry() {
return MODULE_REGISTRY;
public static Registry<String, Plugin> pluginRegistry() {
return PLUGIN_REGISTRY;
}
public static Registry<String, CommandDescription> commandDescriptionRegistry() {
return COMMAND_DESCRIPTION_REGISTRY;
}
public static Registry<String, WebPath> webPathRegistry() {
return WEB_PATH_REGISTRY;
}
public static EnumRegistry<NavigationType, NavigationElement> navigationRegistry() {
return NAVIGATION_REGISTRY;
}
public static Registry<String, HTMLTemplate> templateRegistry() {
return TEMPLATE_REGISTRY;
}

private final Map<K,V> objects = new HashMap<>();
private boolean locked = false;

private void checkLocked() {
if (locked) throw new RegistryLockedException();
}
public synchronized void register(K key, V value) {
checkLocked();
objects.put(key, value);
}
public synchronized Stream<V> stream() {
Expand All @@ -53,6 +74,37 @@ public synchronized Stream<K> keyStream() {
public synchronized V get(K key) {
return objects.get(key);
}
public synchronized void unregister(K key) {
objects.remove(key);
}
public synchronized void lock() {
locked = true;
}

public static class EnumRegistry<K extends RegistryEnum<K>, V> {
private final Map<K,Set<V>> objects = new HashMap<>();

private EnumRegistry(Class<K> clazz) {
try {
Registry<String,K> enumRegistry = RegistryEnum.init(clazz);
enumRegistry.stream().forEach((k) -> objects.put(k, new HashSet<>()));
} catch (Exception e) {
throw new RuntimeException("Could not initialize registry enum " + clazz.getName(), e);
}
}
public synchronized void register(K key, V value) {
objects.get(key).add(value);
}
public synchronized Stream<V> stream(K key) {
return objects.get(key).stream();
}
public synchronized Stream<K> keyStream() {
return objects.keySet().stream();
}
public synchronized void unregister(K key) {
objects.get(key).clear();
}
}

@Override
public void close() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package de.igslandstuhl.database;

public class RegistryLockedException extends RuntimeException {
public RegistryLockedException() {
super("Registry already locked");
}
public RegistryLockedException(String message) {
super(message);
}
public RegistryLockedException(Throwable cause) {
super(cause);
}
public RegistryLockedException(String message, Throwable cause) {
super(message, cause);
}
public RegistryLockedException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
137 changes: 0 additions & 137 deletions src/main/java/de/igslandstuhl/database/api/modules/WebModule.java

This file was deleted.

Loading
Loading