Erweiterungen
This commit is contained in:
9
.claude/settings.local.json
Normal file
9
.claude/settings.local.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(mvn compile:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
}
|
||||
}
|
||||
2
pom.xml
2
pom.xml
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>de.assecutor.emulatorstation</groupId>
|
||||
<artifactId>emulatorstation</artifactId>
|
||||
<version>0.9.6</version>
|
||||
<version>0.9.7</version>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
|
||||
Binary file not shown.
@@ -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<String, UserInfo> 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<String, NiederlassungInfo> 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<String, String> activeNiederlassungen = new ConcurrentHashMap<>();
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
@@ -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<String> 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);
|
||||
|
||||
@@ -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");
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package de.assecutor.emulatorstation.pojo;
|
||||
|
||||
public record NiederlassungInfo(String name, String ip, String port, String urlExtension) {
|
||||
}
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user