diff --git a/.claude/settings.local.json b/.claude/settings.local.json
new file mode 100644
index 0000000..fec1c41
--- /dev/null
+++ b/.claude/settings.local.json
@@ -0,0 +1,9 @@
+{
+ "permissions": {
+ "allow": [
+ "Bash(mvn compile:*)"
+ ],
+ "deny": [],
+ "ask": []
+ }
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 9da44e6..c79e1c7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
de.assecutor.emulatorstation
emulatorstation
- 0.9.6
+ 0.9.7
jar
diff --git a/src/main/bundles/prod.bundle b/src/main/bundles/prod.bundle
index 1771856..d54a10f 100644
Binary files a/src/main/bundles/prod.bundle and b/src/main/bundles/prod.bundle differ
diff --git a/src/main/java/de/assecutor/emulatorstation/Application.java b/src/main/java/de/assecutor/emulatorstation/Application.java
index 5cd39ef..3ad6318 100644
--- a/src/main/java/de/assecutor/emulatorstation/Application.java
+++ b/src/main/java/de/assecutor/emulatorstation/Application.java
@@ -6,26 +6,38 @@ import com.vaadin.flow.theme.Theme;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import de.assecutor.emulatorstation.pojo.UserInfo;
+import de.assecutor.emulatorstation.pojo.NiederlassungInfo;
@SpringBootApplication
@Push
@Theme("default")
public class Application implements AppShellConfigurator {
public static final Map users = Map.ofEntries(
- Map. entry("admin", new UserInfo("ZY6X9X93Co8m", null, null, null)),
- Map.entry("GFL", new UserInfo("GFL123", "172.18.0.112", "6092", "/gfl")),
- Map.entry("Berlin", new UserInfo("Berlin123", "172.18.0.103", "6083", "/berlin")),
- Map.entry("Bremen", new UserInfo("Bremen123", "172.18.0.101", "6081", "/bremen")),
- Map.entry("Hamburg", new UserInfo("Hamburg123", "172.18.0.102", "6082", "/hamburg")),
- Map.entry("Essen", new UserInfo("Essen123", "172.18.0.107", "6087", "/essen")),
- Map.entry("Leipzig", new UserInfo("Leipzig123", "172.18.0.108", "6088", "/leipzig")),
- Map.entry("Dresden", new UserInfo("Dresden123", "172.18.0.106", "6086", "/dresden")),
- Map.entry("Hannover", new UserInfo("Hannover123", "172.18.0.104", "6084", "")),
- Map.entry("Stuttgart", new UserInfo("Stuttgart123", "172.18.0.111", "6091", "/stuttgart")),
- Map.entry("FrankfurtAmMain", new UserInfo("FrankfurtAmMain123", "172.18.0.105", "6085", "/frankfurt"))
+ Map.entry("user1", new UserInfo("pass1")),
+ Map.entry("user2", new UserInfo("pass2")),
+ Map.entry("user3", new UserInfo("pass3")),
+ Map.entry("user4", new UserInfo("pass4")),
+ Map.entry("user5", new UserInfo("pass5"))
);
+ public static final Map niederlassungen = Map.ofEntries(
+ Map.entry("Berlin", new NiederlassungInfo("Berlin", "172.18.0.103", "6083", "/berlin")),
+ Map.entry("Bremen", new NiederlassungInfo("Bremen", "172.18.0.101", "6081", "/bremen")),
+ Map.entry("Hamburg", new NiederlassungInfo("Hamburg", "172.18.0.102", "6082", "/hamburg")),
+ Map.entry("Essen", new NiederlassungInfo("Essen", "172.18.0.107", "6087", "/essen")),
+ Map.entry("Leipzig", new NiederlassungInfo("Leipzig", "172.18.0.108", "6088", "/leipzig")),
+ Map.entry("Dresden", new NiederlassungInfo("Dresden", "172.18.0.106", "6086", "/dresden")),
+ Map.entry("Hannover", new NiederlassungInfo("Hannover", "172.18.0.104", "6084", "/hannover")),
+ Map.entry("Stuttgart", new NiederlassungInfo("Stuttgart", "172.18.0.111", "6091", "/stuttgart")),
+ Map.entry("Frankfurt am Main", new NiederlassungInfo("Frankfurt am Main", "172.18.0.105", "6085", "/frankfurt")),
+ Map.entry("Geschäftführung", new NiederlassungInfo("Geschäftführung", "172.18.0.112", "6092", "/gfl")),
+ Map.entry("Admin", new NiederlassungInfo("Admin", "172.18.0.110", "6090", "/admin"))
+ );
+
+ public static final Map activeNiederlassungen = new ConcurrentHashMap<>();
+
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
diff --git a/src/main/java/de/assecutor/emulatorstation/base/ui/view/LoginView.java b/src/main/java/de/assecutor/emulatorstation/base/ui/view/LoginView.java
index aebe489..f39c48f 100644
--- a/src/main/java/de/assecutor/emulatorstation/base/ui/view/LoginView.java
+++ b/src/main/java/de/assecutor/emulatorstation/base/ui/view/LoginView.java
@@ -3,8 +3,18 @@ package de.assecutor.emulatorstation.base.ui.view;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.login.LoginForm;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.component.select.Select;
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.textfield.TextField;
+import com.vaadin.flow.component.textfield.PasswordField;
+import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.server.auth.AnonymousAllowed;
+import de.assecutor.emulatorstation.Application;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import java.util.List;
@Route("login")
@AnonymousAllowed
@@ -16,11 +26,56 @@ public class LoginView extends VerticalLayout {
Span title = new Span("Anmelden");
title.getStyle().set("font-size", "24px").set("font-weight", "bold");
- LoginForm loginForm = new LoginForm();
- loginForm.setAction("login");
- loginForm.setForgotPasswordButtonVisible(false);
+ TextField usernameField = new TextField("Benutzername");
+ PasswordField passwordField = new PasswordField("Passwort");
- add(title, loginForm);
+ Select niederlassungSelect = new Select<>();
+ niederlassungSelect.setLabel("Niederlassung");
+ niederlassungSelect.setItems(Application.niederlassungen.keySet().stream().sorted().toList());
+ niederlassungSelect.setPlaceholder("Wählen Sie eine Niederlassung");
+
+ Button loginButton = new Button("Anmelden", event -> {
+ String username = usernameField.getValue();
+ String password = passwordField.getValue();
+ String niederlassung = niederlassungSelect.getValue();
+
+ if (username.isEmpty() || password.isEmpty() || niederlassung == null) {
+ Notification.show("Bitte alle Felder ausfüllen", 3000, Notification.Position.MIDDLE);
+ return;
+ }
+
+ if (!Application.users.containsKey(username) ||
+ !Application.users.get(username).password().equals(password)) {
+ Notification.show("Ungültige Anmeldedaten", 3000, Notification.Position.MIDDLE);
+ return;
+ }
+
+ if (Application.activeNiederlassungen.containsKey(niederlassung)) {
+ Notification.show("Niederlassung ist bereits von einem anderen Benutzer belegt", 3000, Notification.Position.MIDDLE);
+ return;
+ }
+
+ Application.activeNiederlassungen.put(niederlassung, username);
+
+ // Spring Security Authentifizierung setzen
+ var authorities = List.of(new SimpleGrantedAuthority("ROLE_USER"));
+ var authentication = new UsernamePasswordAuthenticationToken(username, password, authorities);
+ SecurityContextHolder.getContext().setAuthentication(authentication);
+
+ getUI().ifPresent(ui -> {
+ ui.getSession().setAttribute("user", username);
+ ui.getSession().setAttribute("username", username);
+ ui.getSession().setAttribute("niederlassung", niederlassung);
+
+ System.out.println("Login erfolgreich - Session-Daten gesetzt:");
+ System.out.println("Username: " + username);
+ System.out.println("Niederlassung: " + niederlassung);
+
+ ui.navigate("main");
+ });
+ });
+
+ add(title, usernameField, passwordField, niederlassungSelect, loginButton);
if (MainLayout.instance != null) {
MainLayout.instance.setDrawerOpened(false);
diff --git a/src/main/java/de/assecutor/emulatorstation/base/ui/view/MainView.java b/src/main/java/de/assecutor/emulatorstation/base/ui/view/MainView.java
index f03a187..4c9ead1 100644
--- a/src/main/java/de/assecutor/emulatorstation/base/ui/view/MainView.java
+++ b/src/main/java/de/assecutor/emulatorstation/base/ui/view/MainView.java
@@ -4,8 +4,12 @@ import com.vaadin.flow.component.ClientCallable;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.dialog.Dialog;
+import com.vaadin.flow.component.html.Div;
+import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.IFrame;
import com.vaadin.flow.component.html.Paragraph;
+import com.vaadin.flow.component.icon.Icon;
+import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.BeforeEnterEvent;
@@ -16,11 +20,11 @@ import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.html.Main;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.server.auth.AnonymousAllowed;
-import com.vaadin.flow.theme.lumo.LumoUtility;
import de.assecutor.emulatorstation.pojo.ExecResponse;
import de.assecutor.emulatorstation.Application;
import jakarta.annotation.security.PermitAll;
-import util.Util;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.net.URI;
import java.net.http.HttpClient;
@@ -34,25 +38,46 @@ import java.util.concurrent.Executors;
@AnonymousAllowed
public final class MainView extends Main implements BeforeEnterObserver
{
- private final String username;
- private final String server;
+ private static final Logger logger = LoggerFactory.getLogger(MainView.class);
+ private String username;
+ private String niederlassung;
+ private String server;
- private final IFrame webView;
+ private final IFrame webView = new IFrame();
+ private final Div emulatorContainer = new Div();
+ private final Div welcomeMessage = new Div();
private final ExecutorService executor = Executors.newSingleThreadExecutor();
MainView() {
- try {
- } catch (Exception ex) {
- showWaitDialog("Fehler!\n" + ex.toString());
- }
+ setSizeFull();
+ getStyle()
+ .set("display", "flex")
+ .set("flex-direction", "column")
+ .set("align-items", "center")
+ .set("justify-content", "center")
+ .set("padding", "5%")
+ .set("box-sizing", "border-box")
+ .set("overflow", "hidden");
- var currentSession = VaadinService.getCurrentRequest().getWrappedSession();
- username = Util.getSessionAttributeWithDefault(currentSession, "username", null);
- server = Util.getSessionAttributeWithDefault(currentSession, "server", "172.16.0.158");
+ var contentContainer = new Div();
+ contentContainer.getStyle()
+ .set("width", "95%")
+ .set("height", "95%")
+ .set("display", "flex")
+ .set("flex-direction", "column")
+ .set("box-sizing", "border-box");
- addClassName(LumoUtility.Padding.MEDIUM);
+ setupInactivityTimer();
+ setupWelcomeMessage(contentContainer);
+ setupEmulatorContainer(contentContainer);
+ setupButtonLayout(contentContainer);
+ add(contentContainer);
+ addAttachListener(event -> loadSessionData());
+ }
+
+ private void setupInactivityTimer() {
String jsCode = """
var inactivityTime = function () {
var time;
@@ -63,41 +88,106 @@ public final class MainView extends Main implements BeforeEnterObserver
document.onscroll = resetTimer;
function logout() {
- $0.$server.logout(); // Server-Logout via RPC
+ $0.$server.logout();
}
function resetTimer() {
clearTimeout(time);
- time = setTimeout(logout, 5 * 60 * 1000); // 5 Minute Inaktivität
+ time = setTimeout(logout, 4 * 60 * 60 * 1000);
}
};
inactivityTime();
""";
UI.getCurrent().getPage().executeJs(jsCode, this);
+ }
- var horizontalLayout = new HorizontalLayout();
- add(horizontalLayout);
+ private void setupWelcomeMessage(Div container) {
+ welcomeMessage.addClassName("welcome-panel");
+ welcomeMessage.getStyle()
+ .set("display", "flex")
+ .set("flex-direction", "column")
+ .set("align-items", "center")
+ .set("justify-content", "center")
+ .set("flex-grow", "1")
+ .set("background-color", "#f8f9fa")
+ .set("border", "2px dashed #dee2e6")
+ .set("border-radius", "8px")
+ .set("color", "#6c757d");
- Button startBtn = new Button("Start", event -> startup());
+ Icon icon = new Icon(VaadinIcon.DESKTOP);
+ icon.setSize("48px");
+ icon.getStyle().set("margin-bottom", "12px");
+
+ H2 title = new H2("Willkommen bei der Emulator Station");
+ title.getStyle().set("margin", "0 0 6px 0").set("color", "#495057").set("font-size", "1.5rem");
+
+ Paragraph description = new Paragraph("Klicken Sie auf 'Start', um Ihren Android Emulator zu starten.");
+ description.getStyle().set("margin", "0").set("text-align", "center").set("font-size", "0.9rem");
+
+ welcomeMessage.add(icon, title, description);
+ container.add(welcomeMessage);
+ }
+
+ private void setupButtonLayout(Div container) {
+ var buttonLayout = new HorizontalLayout();
+ buttonLayout.setJustifyContentMode(HorizontalLayout.JustifyContentMode.CENTER);
+ buttonLayout.getStyle()
+ .set("margin", "0")
+ .set("padding", "8px 0")
+ .set("flex-shrink", "0");
+
+ Button startBtn = new Button("Emulator starten", new Icon(VaadinIcon.PLAY), event -> startup());
startBtn.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
- horizontalLayout.add(startBtn);
- Button logoutBtn = new Button("Logout", event -> logout());
- logoutBtn.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
- horizontalLayout.add(logoutBtn);
+ Button logoutBtn = new Button("Abmelden", new Icon(VaadinIcon.SIGN_OUT), event -> logout());
+ logoutBtn.addThemeVariants(ButtonVariant.LUMO_CONTRAST);
- webView = new IFrame();
- webView.setSizeFull(); // IFrame auf volle Größe setzen
- webView.getElement().setAttribute("frameborder", "0"); // Optional: Rahmen entfernen
+ buttonLayout.add(startBtn, logoutBtn);
+ container.add(buttonLayout);
+ }
- // Layout konfigurieren
- setSizeFull(); // Vertikales Layout auf volle Größe setzen
- add(webView);
+ private void setupEmulatorContainer(Div container) {
+ emulatorContainer.getStyle()
+ .set("border", "2px solid #e9ecef")
+ .set("border-radius", "8px")
+ .set("background-color", "#ffffff")
+ .set("box-shadow", "0 2px 4px rgba(0,0,0,0.1)")
+ .set("overflow", "hidden")
+ .set("display", "none")
+ .set("flex-grow", "1");
- addAttachListener(event -> {
- event.getUI();
- });
+ webView.setSizeFull();
+ webView.getElement().setAttribute("frameborder", "0");
+
+ emulatorContainer.add(webView);
+ container.add(emulatorContainer);
+ }
+
+ private void loadSessionData() {
+ var currentUI = getUI();
+ if (currentUI.isPresent()) {
+ var vaadinSession = currentUI.get().getSession();
+ username = (String) vaadinSession.getAttribute("username");
+ niederlassung = (String) vaadinSession.getAttribute("niederlassung");
+ server = (String) vaadinSession.getAttribute("server");
+ } else {
+ System.err.println("UI nicht verfügbar - kann Session-Daten nicht laden");
+ }
+
+ if (server == null) {
+ server = "172.16.0.158";
+ }
+
+ System.out.println("MainView Session-Daten geladen:");
+ System.out.println("Username: " + username);
+ System.out.println("Niederlassung: " + niederlassung);
+ System.out.println("Server: " + server);
+
+ if (niederlassung == null) {
+ System.err.println("FEHLER: Niederlassung ist null! Benutzer muss sich neu anmelden.");
+ getUI().ifPresent(ui -> ui.navigate("login"));
+ }
}
@Override
@@ -131,6 +221,10 @@ public final class MainView extends Main implements BeforeEnterObserver
ui.access(() -> {
dialog.close();
+ // Willkommensnachricht ausblenden und Emulator anzeigen
+ welcomeMessage.getStyle().set("display", "none");
+ emulatorContainer.getStyle().set("display", "block");
+
refreshWebView();
});
}
@@ -144,7 +238,18 @@ public final class MainView extends Main implements BeforeEnterObserver
}
private void refreshWebView() {
- var url = "https://sb-app.emu.assecutor.org" + Application.users.get(username).urlExtension() + "?autoconnect=true";
+ if (niederlassung == null) {
+ System.err.println("Niederlassung ist null - kann WebView nicht aktualisieren");
+ return;
+ }
+
+ var niederlassungInfo = Application.niederlassungen.get(niederlassung);
+ if (niederlassungInfo == null) {
+ System.err.println("Niederlassungsinfo für '" + niederlassung + "' nicht gefunden");
+ return;
+ }
+
+ var url = "https://sb-app.emu.assecutor.org" + niederlassungInfo.urlExtension() + "?autoconnect=true";
System.out.println("URL: " + url);
@@ -181,10 +286,10 @@ public final class MainView extends Main implements BeforeEnterObserver
exec(execId);
} catch (Exception e) {
- e.printStackTrace();
+ logger.error("Fehler beim Senden der HTTP-Anfrage für App-Download", e);
}
} catch (Exception e) {
- e.printStackTrace();
+ logger.error("Fehler beim Download der App", e);
}
}
@@ -213,7 +318,7 @@ public final class MainView extends Main implements BeforeEnterObserver
exec(execId);
} catch (Exception e) {
- e.printStackTrace();
+ logger.error("Fehler bei der App-Installation", e);
}
}
@@ -233,7 +338,7 @@ public final class MainView extends Main implements BeforeEnterObserver
return response.body();
} catch (Exception e) {
- e.printStackTrace(); // Fehler behandeln
+ logger.error("Fehler beim Ausführen des Befehls mit execId: {}", execId, e);
}
return null;
@@ -252,7 +357,7 @@ public final class MainView extends Main implements BeforeEnterObserver
System.out.println("HTTP-Response-Code: " + response.statusCode()); // Statuscode ausgeben
System.out.println("Response-Body: " + response.body()); // Antwort-Body ausgeben
} catch (Exception e) {
- e.printStackTrace(); // Fehler behandeln
+ logger.error("Fehler beim HTTP-Request", e);
}
}
@@ -294,7 +399,7 @@ public final class MainView extends Main implements BeforeEnterObserver
}
} catch (Exception e) {
- e.printStackTrace();
+ logger.error("Fehler beim Warten auf Container-Start", e);
}
} while (!endLoop);
}
@@ -312,6 +417,8 @@ public final class MainView extends Main implements BeforeEnterObserver
],
"HostConfig": {
"NetworkMode": "votianBridge",
+ "Memory": 10737418240,
+ "CpuCount": 4,
"Dns": [
"172.18.0.15"
],
@@ -343,7 +450,20 @@ public final class MainView extends Main implements BeforeEnterObserver
}
}
}
- """.formatted(Application.users.get(username).port(), Application.users.get(username).ip());
+ """;
+
+ if (niederlassung == null) {
+ System.err.println("Niederlassung ist null - kann Container nicht erstellen");
+ return;
+ }
+
+ var niederlassungInfo = Application.niederlassungen.get(niederlassung);
+ if (niederlassungInfo == null) {
+ System.err.println("Niederlassungsinfo für '" + niederlassung + "' nicht gefunden");
+ return;
+ }
+
+ jsonPayload = jsonPayload.formatted(niederlassungInfo.port(), niederlassungInfo.ip());
System.out.println(jsonPayload);
@@ -360,7 +480,7 @@ public final class MainView extends Main implements BeforeEnterObserver
System.out.println("HTTP-Response-Code: " + response.statusCode());
System.out.println("Response-Body: " + response.body());
} catch (Exception e) {
- e.printStackTrace();
+ logger.error("Fehler beim Erstellen des Containers", e);
}
}
@@ -377,7 +497,7 @@ public final class MainView extends Main implements BeforeEnterObserver
System.out.println("HTTP-Response-Code: " + response.statusCode()); // Statuscode ausgeben
System.out.println("Response-Body: " + response.body()); // Antwort-Body ausgeben
} catch (Exception e) {
- e.printStackTrace(); // Fehler behandeln
+ logger.error("Fehler beim HTTP-Request", e);
}
}
@@ -394,7 +514,7 @@ public final class MainView extends Main implements BeforeEnterObserver
System.out.println("HTTP-Response-Code: " + response.statusCode()); // Statuscode ausgeben
System.out.println("Response-Body: " + response.body()); // Antwort-Body ausgeben
} catch (Exception e) {
- e.printStackTrace(); // Fehler behandeln
+ logger.error("Fehler beim HTTP-Request", e);
}
}
@@ -432,10 +552,15 @@ public final class MainView extends Main implements BeforeEnterObserver
ui.access(() -> {
dialog.close();
+ // Session cleanup vor Navigation
+ if (niederlassung != null) {
+ Application.activeNiederlassungen.remove(niederlassung);
+ }
+
vaadinSession.invalidate();
- // Navigiere den Benutzer zur Main-Seite
- ui.navigate("main");
+ // Navigiere direkt zur Login-Seite
+ ui.navigate("login");
});
}
});
diff --git a/src/main/java/de/assecutor/emulatorstation/base/ui/view/security/SecurityConfig.java b/src/main/java/de/assecutor/emulatorstation/base/ui/view/security/SecurityConfig.java
index 79866a1..161a956 100644
--- a/src/main/java/de/assecutor/emulatorstation/base/ui/view/security/SecurityConfig.java
+++ b/src/main/java/de/assecutor/emulatorstation/base/ui/view/security/SecurityConfig.java
@@ -2,15 +2,8 @@ package de.assecutor.emulatorstation.base.ui.view.security;
import com.vaadin.flow.spring.security.VaadinWebSecurity;
import de.assecutor.emulatorstation.base.ui.view.LoginView;
-import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.core.userdetails.User;
-import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.crypto.password.NoOpPasswordEncoder;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.security.provisioning.InMemoryUserDetailsManager;
-import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import de.assecutor.emulatorstation.Application;
@@ -21,50 +14,21 @@ public class SecurityConfig extends VaadinWebSecurity {
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
- // FormLogin verwenden; Vaadin-LoginView
setLoginView(http, LoginView.class);
http
- .formLogin(form -> form
- .loginPage("/login")
- .successHandler(authenticationSuccessHandler())
- .permitAll()
- )
.logout(logout -> logout
- .logoutSuccessUrl("/main")
+ .logoutSuccessUrl("/login")
+ .addLogoutHandler((request, response, authentication) -> {
+ if (authentication != null) {
+ String username = authentication.getName();
+ Application.activeNiederlassungen.entrySet().removeIf(entry ->
+ entry.getValue().equals(username));
+ }
+ })
);
}
- @Bean
- public UserDetailsService userDetailsService() {
- InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
- Application.users.forEach((username, info) ->
- manager.createUser(User.withUsername(username)
- .password(info.password())
- .roles("USER")
- .build())
- );
- return manager;
- }
-
- @Bean
- @SuppressWarnings("deprecation")
- public PasswordEncoder passwordEncoder() {
- // Für Demo-Zwecke: Passwörter sind im Klartext hinterlegt
- return NoOpPasswordEncoder.getInstance();
- }
-
- @Bean
- public AuthenticationSuccessHandler authenticationSuccessHandler() {
- return (request, response, authentication) -> {
- var session = request.getSession(true);
- String username = authentication.getName();
- session.setAttribute("user", username);
- session.setAttribute("username", username);
- String target = "admin".equalsIgnoreCase(username) ? "/admin" : "/main";
- response.sendRedirect(target);
- };
- }
}
diff --git a/src/main/java/de/assecutor/emulatorstation/base/ui/view/security/SessionListener.java b/src/main/java/de/assecutor/emulatorstation/base/ui/view/security/SessionListener.java
new file mode 100644
index 0000000..c6f7b8f
--- /dev/null
+++ b/src/main/java/de/assecutor/emulatorstation/base/ui/view/security/SessionListener.java
@@ -0,0 +1,20 @@
+package de.assecutor.emulatorstation.base.ui.view.security;
+
+import com.vaadin.flow.server.SessionDestroyEvent;
+import com.vaadin.flow.server.SessionDestroyListener;
+import com.vaadin.flow.spring.annotation.SpringComponent;
+import de.assecutor.emulatorstation.Application;
+
+@SpringComponent
+public class SessionListener implements SessionDestroyListener {
+
+ @Override
+ public void sessionDestroy(SessionDestroyEvent event) {
+ String username = (String) event.getSession().getAttribute("user");
+ String niederlassung = (String) event.getSession().getAttribute("niederlassung");
+
+ if (username != null && niederlassung != null) {
+ Application.activeNiederlassungen.remove(niederlassung);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/de/assecutor/emulatorstation/pojo/NiederlassungInfo.java b/src/main/java/de/assecutor/emulatorstation/pojo/NiederlassungInfo.java
new file mode 100644
index 0000000..4a7856e
--- /dev/null
+++ b/src/main/java/de/assecutor/emulatorstation/pojo/NiederlassungInfo.java
@@ -0,0 +1,4 @@
+package de.assecutor.emulatorstation.pojo;
+
+public record NiederlassungInfo(String name, String ip, String port, String urlExtension) {
+}
\ No newline at end of file
diff --git a/src/main/java/de/assecutor/emulatorstation/pojo/UserInfo.java b/src/main/java/de/assecutor/emulatorstation/pojo/UserInfo.java
index 1019f47..cf3a04b 100644
--- a/src/main/java/de/assecutor/emulatorstation/pojo/UserInfo.java
+++ b/src/main/java/de/assecutor/emulatorstation/pojo/UserInfo.java
@@ -1,6 +1,6 @@
package de.assecutor.emulatorstation.pojo;
-public record UserInfo(String password, String ip, String port, String urlExtension) {
+public record UserInfo(String password) {
}