From 244f6cbf9590c081c2e10a5d93d9b942ec751c0a Mon Sep 17 00:00:00 2001
From: Moritz <34131471+Moritz921@users.noreply.github.com>
Date: Thu, 12 Jun 2025 21:24:16 +0200
Subject: [PATCH] Add OIDC support (#39)
* Update readme
* First try in oidc implementation
* Add secrets
* Add connection to fs auth provider, redirect not tested
* Working prototype
This commit implements the oidc compatibility with the caveat of having
every subsite under the app path. For that, there is also a redirection
handler to redirect the home page to the app home page.
* Small cleanup
* Fix access even when logged in
* Update application-prod.properties
* Ignore login when in test env
* Fix reviews
---
.gitignore | 7 ++
README.md | 2 +-
pom.xml | 8 ++
.../kickerelo/KickerEloApplication.java | 8 +-
.../kickerelo/config/SecurityConfig.java | 25 ++++++
.../kickerelo/layout/KickerAppLayout.java | 25 ++++++
.../kickerelo/util/RedirectController.java | 12 +++
.../kickerelo/kickerelo/views/AdminView.java | 83 +++++++++++++++++--
.../kickerelo/views/Enter1vs1View.java | 15 ++--
.../kickerelo/views/Enter2vs2View.java | 15 ++--
.../kickerelo/views/Graph1vs1View.java | 6 +-
.../kickerelo/views/Graph2vs2View.java | 6 +-
.../kickerelo/views/History1vs1View.java | 9 +-
.../kickerelo/views/History2vs2View.java | 9 +-
.../kickerelo/views/PlayerListView.java | 11 +--
.../kickerelo/views/Stat2vs2View.java | 11 +--
.../resources/application-prod.properties | 12 ++-
.../resources/application-test.properties | 13 ++-
18 files changed, 223 insertions(+), 54 deletions(-)
create mode 100644 src/main/java/org/kickerelo/kickerelo/config/SecurityConfig.java
create mode 100644 src/main/java/org/kickerelo/kickerelo/util/RedirectController.java
diff --git a/.gitignore b/.gitignore
index fac9f1f..6ed06f0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,13 @@ target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
+data.mv.db
+src/main/bundles
+node_modules
+
+# for secrets
+.env
+.vscode
### IntelliJ IDEA ###
.idea/modules.xml
diff --git a/README.md b/README.md
index ab7c5bf..2cb3d0e 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# KickerELO
KickerELO is a web application for displaying Elo ratings for foosball (table soccer) games.
-It uses **Spring Boot** for the backend, **Vaadin** for the frontend, and **MariaDB** as the database.
+It uses **Spring Boot** for the backend, **Vaadin** for the frontend, and **MariaDB** as the database. It is compatible with any OpenID Connect (OIDC) provider.
## Requirements
diff --git a/pom.xml b/pom.xml
index 1908030..71577cd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,6 +38,10 @@
org.springframework.boot
spring-boot-starter-data-jpa
+
+ org.springframework.boot
+ spring-boot-starter-web
+
com.vaadin
vaadin-spring-boot-starter
@@ -63,6 +67,10 @@
spring-boot-starter-test
test
+
+ org.springframework.boot
+ spring-boot-starter-oauth2-client
+
diff --git a/src/main/java/org/kickerelo/kickerelo/KickerEloApplication.java b/src/main/java/org/kickerelo/kickerelo/KickerEloApplication.java
index 0252816..d9ce578 100644
--- a/src/main/java/org/kickerelo/kickerelo/KickerEloApplication.java
+++ b/src/main/java/org/kickerelo/kickerelo/KickerEloApplication.java
@@ -1,13 +1,14 @@
package org.kickerelo.kickerelo;
-import com.vaadin.flow.component.page.AppShellConfigurator;
-import com.vaadin.flow.server.PWA;
-import com.vaadin.flow.theme.Theme;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import com.vaadin.flow.component.page.AppShellConfigurator;
+import com.vaadin.flow.server.PWA;
+import com.vaadin.flow.theme.Theme;
+
@SpringBootApplication
@EntityScan(basePackages = "org.kickerelo.kickerelo.data")
@@ -19,5 +20,4 @@ public class KickerEloApplication implements AppShellConfigurator {
public static void main(String[] args) {
SpringApplication.run(KickerEloApplication.class, args);
}
-
}
diff --git a/src/main/java/org/kickerelo/kickerelo/config/SecurityConfig.java b/src/main/java/org/kickerelo/kickerelo/config/SecurityConfig.java
new file mode 100644
index 0000000..2cca3ce
--- /dev/null
+++ b/src/main/java/org/kickerelo/kickerelo/config/SecurityConfig.java
@@ -0,0 +1,25 @@
+package org.kickerelo.kickerelo.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+
+import com.vaadin.flow.spring.security.VaadinWebSecurity;
+
+@Configuration
+class SecurityConfiguration extends VaadinWebSecurity {
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+
+ // super.configure(http);
+
+ http
+ .authorizeHttpRequests(auth -> auth
+ .requestMatchers("/app/admin/**", "/app/admin", "/app/app/admin/**", "/app/app/admin").hasAuthority("Kicker Admin")
+ .anyRequest().permitAll()
+ )
+ .oauth2Login(org.springframework.security.config.Customizer.withDefaults())
+ .logout(logout -> logout.logoutSuccessUrl("/"))
+ .csrf(csrf -> csrf.disable());
+ }
+}
diff --git a/src/main/java/org/kickerelo/kickerelo/layout/KickerAppLayout.java b/src/main/java/org/kickerelo/kickerelo/layout/KickerAppLayout.java
index ef3ff53..1d3d2c1 100644
--- a/src/main/java/org/kickerelo/kickerelo/layout/KickerAppLayout.java
+++ b/src/main/java/org/kickerelo/kickerelo/layout/KickerAppLayout.java
@@ -14,6 +14,11 @@ import com.vaadin.flow.dom.Style;
import com.vaadin.flow.router.Layout;
import org.kickerelo.kickerelo.views.*;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+
+
@Layout
@JsModule("./prefers-color-scheme.js")
public class KickerAppLayout extends AppLayout {
@@ -26,6 +31,26 @@ public class KickerAppLayout extends AppLayout {
addToNavbar(drawerToggle, title);
+ // Add login/logout button
+ Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+ boolean isAuthenticated = auth != null && auth.isAuthenticated() && !(auth instanceof AnonymousAuthenticationToken);
+
+ if (isAuthenticated && auth != null && auth.getPrincipal() instanceof org.springframework.security.oauth2.core.oidc.user.OidcUser oidcUser) {
+ Anchor logoutLink = new Anchor("/logout", "Logout (" + oidcUser.getPreferredUsername() + ")");
+ logoutLink.getElement().getStyle()
+ .set("margin-left", "auto")
+ .set("margin-right", "10px")
+ .set("align-self", "center");
+ addToNavbar(logoutLink);
+ } else {
+ Anchor loginLink = new Anchor("/oauth2/authorization/oidc", "Login");
+ loginLink.getElement().getStyle()
+ .set("margin-left", "auto")
+ .set("margin-right", "10px")
+ .set("align-self", "center");
+ addToNavbar(loginLink);
+ }
+
SideNav general = new SideNav("Allgemein");
general.setCollapsible(true);
general.addItem(new SideNavItem("Spielerliste", PlayerListView.class, VaadinIcon.GROUP.create()),
diff --git a/src/main/java/org/kickerelo/kickerelo/util/RedirectController.java b/src/main/java/org/kickerelo/kickerelo/util/RedirectController.java
new file mode 100644
index 0000000..25b54b1
--- /dev/null
+++ b/src/main/java/org/kickerelo/kickerelo/util/RedirectController.java
@@ -0,0 +1,12 @@
+package org.kickerelo.kickerelo.util;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+
+@Controller
+public class RedirectController {
+ @GetMapping("/")
+ public String redirectToApp() {
+ return "redirect:/app";
+ }
+}
diff --git a/src/main/java/org/kickerelo/kickerelo/views/AdminView.java b/src/main/java/org/kickerelo/kickerelo/views/AdminView.java
index 5098cbb..f000dc7 100644
--- a/src/main/java/org/kickerelo/kickerelo/views/AdminView.java
+++ b/src/main/java/org/kickerelo/kickerelo/views/AdminView.java
@@ -1,21 +1,85 @@
package org.kickerelo.kickerelo.views;
-import com.vaadin.flow.component.button.Button;
-import com.vaadin.flow.component.html.H2;
-import com.vaadin.flow.component.notification.Notification;
-import com.vaadin.flow.component.notification.NotificationVariant;
-import com.vaadin.flow.component.orderedlayout.VerticalLayout;
-import com.vaadin.flow.component.textfield.TextField;
-import com.vaadin.flow.router.Route;
+import java.util.List;
+
import org.kickerelo.kickerelo.exception.DuplicatePlayerException;
import org.kickerelo.kickerelo.exception.InvalidDataException;
import org.kickerelo.kickerelo.exception.PlayerNameNotSetException;
import org.kickerelo.kickerelo.service.KickerEloService;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.oauth2.core.oidc.user.OidcUser;
+
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.html.Paragraph;
+import com.vaadin.flow.component.notification.Notification;
+import com.vaadin.flow.component.notification.NotificationVariant;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.component.textfield.TextField;
+import com.vaadin.flow.router.BeforeEnterEvent;
+import com.vaadin.flow.router.Route;
@Route("admin")
public class AdminView extends VerticalLayout {
- public AdminView(KickerEloService service) {
- H2 subheader = new H2("Verwaltung");
+
+ private final org.springframework.core.env.Environment environment;
+
+ // Methode zum Prüfen, ob das "test"-Profil aktiv ist
+ private boolean isTestProfileActive() {
+ for (String profile : environment.getActiveProfiles()) {
+ if ("test".equals(profile)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isAuthentikated() {
+ Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+ if (auth != null && auth.getPrincipal() instanceof OidcUser oidcUser) {
+ Object groupsObj = oidcUser.getClaims().getOrDefault("groups", List.of());
+ List listOfGroups;
+ if (groupsObj instanceof List> groupsList) {
+ listOfGroups = groupsList.stream()
+ .filter(String.class::isInstance)
+ .map(String.class::cast)
+ .toList();
+ } else {
+ listOfGroups = List.of();
+ }
+
+ return listOfGroups.contains("Kicker Admin");
+ } else {
+ return false;
+ }
+ }
+
+ public void beforeEnter(BeforeEnterEvent event) {
+ if (isTestProfileActive()) {
+ return; // Skip authentication check in test profile
+ }
+ Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+ if (auth == null || !(auth.getPrincipal() instanceof OidcUser oidcUser)) {
+ event.rerouteTo("");
+ return;
+ }
+
+ var groups = oidcUser.getClaimAsStringList("groups");
+ if (groups == null || !groups.contains("Kicker Admin")) {
+ event.rerouteTo("");
+ }
+ }
+
+ public AdminView(KickerEloService service, org.springframework.core.env.Environment environment) {
+ this.environment = environment;
+
+ if (!isTestProfileActive()) {
+ if (!isAuthentikated()) {
+ add(new Paragraph("Du bist nicht berechtigt, diese Seite zu sehen."));
+ getUI().ifPresent(ui -> ui.navigate(""));
+ return;
+ }
+ }
TextField spielername = new TextField("Spielername");
spielername.addClassName("bordered");
@@ -41,6 +105,7 @@ public class AdminView extends VerticalLayout {
service.recalculateAll1vs1();
Notification.show("Recalculating finished").addThemeVariants(NotificationVariant.LUMO_SUCCESS);
});
+
Button recalc2vs2Button = new Button("2 vs 2 Elo neu berechnen", e -> {
Notification.show("Recalculating Elo").addThemeVariants(NotificationVariant.LUMO_WARNING);
service.recalculateAll2vs2();
diff --git a/src/main/java/org/kickerelo/kickerelo/views/Enter1vs1View.java b/src/main/java/org/kickerelo/kickerelo/views/Enter1vs1View.java
index e4ceb54..3123aac 100644
--- a/src/main/java/org/kickerelo/kickerelo/views/Enter1vs1View.java
+++ b/src/main/java/org/kickerelo/kickerelo/views/Enter1vs1View.java
@@ -1,5 +1,12 @@
package org.kickerelo.kickerelo.views;
+import org.kickerelo.kickerelo.data.Spieler;
+import org.kickerelo.kickerelo.exception.DuplicatePlayerException;
+import org.kickerelo.kickerelo.exception.InvalidDataException;
+import org.kickerelo.kickerelo.exception.NoSuchPlayerException;
+import org.kickerelo.kickerelo.exception.PlayerNameNotSetException;
+import org.kickerelo.kickerelo.service.KickerEloService;
+
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.html.H2;
@@ -8,14 +15,8 @@ import com.vaadin.flow.component.notification.NotificationVariant;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.IntegerField;
import com.vaadin.flow.router.Route;
-import org.kickerelo.kickerelo.data.Spieler;
-import org.kickerelo.kickerelo.exception.DuplicatePlayerException;
-import org.kickerelo.kickerelo.exception.InvalidDataException;
-import org.kickerelo.kickerelo.exception.NoSuchPlayerException;
-import org.kickerelo.kickerelo.exception.PlayerNameNotSetException;
-import org.kickerelo.kickerelo.service.KickerEloService;
-@Route(value = "enter1vs1")
+@Route("enter1vs1")
public class Enter1vs1View extends VerticalLayout {
public Enter1vs1View(KickerEloService eloService) {
diff --git a/src/main/java/org/kickerelo/kickerelo/views/Enter2vs2View.java b/src/main/java/org/kickerelo/kickerelo/views/Enter2vs2View.java
index e354255..3bba582 100644
--- a/src/main/java/org/kickerelo/kickerelo/views/Enter2vs2View.java
+++ b/src/main/java/org/kickerelo/kickerelo/views/Enter2vs2View.java
@@ -1,5 +1,12 @@
package org.kickerelo.kickerelo.views;
+import org.kickerelo.kickerelo.data.Spieler;
+import org.kickerelo.kickerelo.exception.DuplicatePlayerException;
+import org.kickerelo.kickerelo.exception.InvalidDataException;
+import org.kickerelo.kickerelo.exception.NoSuchPlayerException;
+import org.kickerelo.kickerelo.exception.PlayerNameNotSetException;
+import org.kickerelo.kickerelo.service.KickerEloService;
+
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.html.H2;
@@ -8,14 +15,8 @@ import com.vaadin.flow.component.notification.NotificationVariant;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.IntegerField;
import com.vaadin.flow.router.Route;
-import org.kickerelo.kickerelo.data.Spieler;
-import org.kickerelo.kickerelo.exception.DuplicatePlayerException;
-import org.kickerelo.kickerelo.exception.InvalidDataException;
-import org.kickerelo.kickerelo.exception.NoSuchPlayerException;
-import org.kickerelo.kickerelo.exception.PlayerNameNotSetException;
-import org.kickerelo.kickerelo.service.KickerEloService;
-@Route(value = "enter2vs2")
+@Route("enter2vs2")
public class Enter2vs2View extends VerticalLayout {
public Enter2vs2View(KickerEloService eloService) {
H2 subheading = new H2("2 vs 2 Ergebnis");
diff --git a/src/main/java/org/kickerelo/kickerelo/views/Graph1vs1View.java b/src/main/java/org/kickerelo/kickerelo/views/Graph1vs1View.java
index 9b7928c..63e94cc 100644
--- a/src/main/java/org/kickerelo/kickerelo/views/Graph1vs1View.java
+++ b/src/main/java/org/kickerelo/kickerelo/views/Graph1vs1View.java
@@ -3,13 +3,13 @@ package org.kickerelo.kickerelo.views;
import java.util.ArrayList;
import java.util.List;
+import org.kickerelo.kickerelo.repository.SpielerRepository;
+import org.kickerelo.kickerelo.util.comparator.Spieler1vs1EloComparator;
+
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;
-import org.kickerelo.kickerelo.repository.SpielerRepository;
-import org.kickerelo.kickerelo.util.comparator.Spieler1vs1EloComparator;
-
@Route("graph1vs1")
public class Graph1vs1View extends VerticalLayout {
diff --git a/src/main/java/org/kickerelo/kickerelo/views/Graph2vs2View.java b/src/main/java/org/kickerelo/kickerelo/views/Graph2vs2View.java
index c0de179..068ca9f 100644
--- a/src/main/java/org/kickerelo/kickerelo/views/Graph2vs2View.java
+++ b/src/main/java/org/kickerelo/kickerelo/views/Graph2vs2View.java
@@ -3,13 +3,13 @@ package org.kickerelo.kickerelo.views;
import java.util.ArrayList;
import java.util.List;
+import org.kickerelo.kickerelo.repository.SpielerRepository;
+import org.kickerelo.kickerelo.util.comparator.Spieler2vs2EloComparator;
+
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;
-import org.kickerelo.kickerelo.repository.SpielerRepository;
-import org.kickerelo.kickerelo.util.comparator.Spieler2vs2EloComparator;
-
@Route("graph2vs2")
public class Graph2vs2View extends VerticalLayout {
diff --git a/src/main/java/org/kickerelo/kickerelo/views/History1vs1View.java b/src/main/java/org/kickerelo/kickerelo/views/History1vs1View.java
index b11607d..5680b1f 100644
--- a/src/main/java/org/kickerelo/kickerelo/views/History1vs1View.java
+++ b/src/main/java/org/kickerelo/kickerelo/views/History1vs1View.java
@@ -1,5 +1,10 @@
package org.kickerelo.kickerelo.views;
+import java.util.List;
+
+import org.kickerelo.kickerelo.data.Ergebnis1vs1;
+import org.kickerelo.kickerelo.repository.Ergebnis1vs1Repository;
+
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.GridSortOrder;
import com.vaadin.flow.component.grid.dataview.GridListDataView;
@@ -13,10 +18,6 @@ import com.vaadin.flow.data.renderer.ComponentRenderer;
import com.vaadin.flow.data.renderer.LocalDateTimeRenderer;
import com.vaadin.flow.data.value.ValueChangeMode;
import com.vaadin.flow.router.Route;
-import org.kickerelo.kickerelo.data.Ergebnis1vs1;
-import org.kickerelo.kickerelo.repository.Ergebnis1vs1Repository;
-
-import java.util.List;
@Route("history1vs1")
public class History1vs1View extends HistoryView {
diff --git a/src/main/java/org/kickerelo/kickerelo/views/History2vs2View.java b/src/main/java/org/kickerelo/kickerelo/views/History2vs2View.java
index 1dd9eb3..bf0f2b3 100644
--- a/src/main/java/org/kickerelo/kickerelo/views/History2vs2View.java
+++ b/src/main/java/org/kickerelo/kickerelo/views/History2vs2View.java
@@ -1,5 +1,10 @@
package org.kickerelo.kickerelo.views;
+import java.util.List;
+
+import org.kickerelo.kickerelo.data.Ergebnis2vs2;
+import org.kickerelo.kickerelo.repository.Ergebnis2vs2Repository;
+
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.GridSortOrder;
import com.vaadin.flow.component.grid.dataview.GridListDataView;
@@ -14,10 +19,6 @@ import com.vaadin.flow.data.renderer.ComponentRenderer;
import com.vaadin.flow.data.renderer.LocalDateTimeRenderer;
import com.vaadin.flow.data.value.ValueChangeMode;
import com.vaadin.flow.router.Route;
-import org.kickerelo.kickerelo.data.Ergebnis2vs2;
-import org.kickerelo.kickerelo.repository.Ergebnis2vs2Repository;
-
-import java.util.List;
@Route("history2vs2")
diff --git a/src/main/java/org/kickerelo/kickerelo/views/PlayerListView.java b/src/main/java/org/kickerelo/kickerelo/views/PlayerListView.java
index 205dbae..7f61a0f 100644
--- a/src/main/java/org/kickerelo/kickerelo/views/PlayerListView.java
+++ b/src/main/java/org/kickerelo/kickerelo/views/PlayerListView.java
@@ -1,17 +1,18 @@
package org.kickerelo.kickerelo.views;
+import java.util.List;
+
+import org.kickerelo.kickerelo.data.Spieler;
+import org.kickerelo.kickerelo.service.KickerEloService;
+
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.GridSortOrder;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.data.provider.SortDirection;
import com.vaadin.flow.router.Route;
-import org.kickerelo.kickerelo.data.Spieler;
-import org.kickerelo.kickerelo.service.KickerEloService;
-import java.util.List;
-
-@Route("")
+@Route("/")
public class PlayerListView extends VerticalLayout {
public PlayerListView(KickerEloService eloService) {
setSizeFull();
diff --git a/src/main/java/org/kickerelo/kickerelo/views/Stat2vs2View.java b/src/main/java/org/kickerelo/kickerelo/views/Stat2vs2View.java
index 9ca71c2..d30d4c3 100644
--- a/src/main/java/org/kickerelo/kickerelo/views/Stat2vs2View.java
+++ b/src/main/java/org/kickerelo/kickerelo/views/Stat2vs2View.java
@@ -1,5 +1,11 @@
package org.kickerelo.kickerelo.views;
+import org.kickerelo.kickerelo.data.Spieler;
+import org.kickerelo.kickerelo.repository.Ergebnis2vs2Repository;
+import org.kickerelo.kickerelo.service.KickerEloService;
+import org.kickerelo.kickerelo.service.Stat2vs2Service;
+import org.kickerelo.kickerelo.util.Position;
+
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.NativeLabel;
@@ -8,11 +14,6 @@ import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.progressbar.ProgressBar;
import com.vaadin.flow.component.progressbar.ProgressBarVariant;
import com.vaadin.flow.router.Route;
-import org.kickerelo.kickerelo.data.Spieler;
-import org.kickerelo.kickerelo.repository.Ergebnis2vs2Repository;
-import org.kickerelo.kickerelo.service.KickerEloService;
-import org.kickerelo.kickerelo.service.Stat2vs2Service;
-import org.kickerelo.kickerelo.util.Position;
@Route("stat2vs2")
public class Stat2vs2View extends VerticalLayout {
diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties
index bf204a5..ca0774f 100644
--- a/src/main/resources/application-prod.properties
+++ b/src/main/resources/application-prod.properties
@@ -10,5 +10,15 @@ spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=false
spring.jpa.open-in-view=false
+# == OIDC Configuration ==
+spring.security.oauth2.client.registration.oidc.client-id=${OIDC_CLIENT_ID}
+spring.security.oauth2.client.registration.oidc.client-secret=${OIDC_CLIENT_SECRET}
+spring.security.oauth2.client.registration.oidc.scope=openid,email,profile
+spring.security.oauth2.client.registration.oidc.redirect-uri=${OIDC_REDIRECT_URI}
+spring.security.oauth2.client.provider.oidc.jwk-set-uri=${OIDC_JWK_SET_URI}
+spring.security.oauth2.client.provider.oidc.issuer-uri=${OIDC_ISSUER_URI}
+
+vaadin.urlMapping=/app/*
+
# In prod mode, never add the test data to the database
-spring.sql.init.mode=never
\ No newline at end of file
+spring.sql.init.mode=never
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index 535b5ba..40805fd 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -1,9 +1,20 @@
server.port=${PORT:8080}
logging.level.org.atmosphere = warn
+logging.level.org.springframework.security=DEBUG
spring.mustache.check-template-location = false
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=update
-spring.jpa.show-sql=true
\ No newline at end of file
+spring.jpa.show-sql=true
+
+# == OIDC Configuration ==
+spring.security.oauth2.client.registration.oidc.client-id=${OIDC_CLIENT_ID}
+spring.security.oauth2.client.registration.oidc.client-secret=${OIDC_CLIENT_SECRET}
+spring.security.oauth2.client.registration.oidc.scope=openid,email,profile
+spring.security.oauth2.client.registration.oidc.redirect-uri=${OIDC_REDIRECT_URI}
+spring.security.oauth2.client.provider.oidc.jwk-set-uri=${OIDC_JWK_SET_URI}
+spring.security.oauth2.client.provider.oidc.issuer-uri=${OIDC_ISSUER_URI}
+
+vaadin.urlMapping=/app/*