mirror of
https://github.com/AJMicke/KickerELO.git
synced 2026-03-11 13:31:02 +01:00
Refine the sign in solution by Moritz921
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
package org.kickerelo.kickerelo.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
|
||||
import com.vaadin.flow.spring.security.VaadinWebSecurity;
|
||||
|
||||
@Profile("prod")
|
||||
@Configuration
|
||||
class SecurityConfiguration extends VaadinWebSecurity {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
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());
|
||||
}
|
||||
}
|
||||
@@ -12,13 +12,16 @@ import com.vaadin.flow.component.sidenav.SideNav;
|
||||
import com.vaadin.flow.component.sidenav.SideNavItem;
|
||||
import com.vaadin.flow.dom.Style;
|
||||
import com.vaadin.flow.router.Layout;
|
||||
import org.kickerelo.kickerelo.util.AccessControlService;
|
||||
import org.kickerelo.kickerelo.views.*;
|
||||
|
||||
@Layout
|
||||
@JsModule("./prefers-color-scheme.js")
|
||||
public class KickerAppLayout extends AppLayout {
|
||||
AccessControlService accessControlService;
|
||||
|
||||
public KickerAppLayout() {
|
||||
public KickerAppLayout(AccessControlService accessControlService) {
|
||||
this.accessControlService = accessControlService;
|
||||
DrawerToggle drawerToggle = new DrawerToggle();
|
||||
|
||||
H1 title = new H1("Kicker-ELO");
|
||||
@@ -26,6 +29,23 @@ public class KickerAppLayout extends AppLayout {
|
||||
|
||||
addToNavbar(drawerToggle, title);
|
||||
|
||||
// Add login/logout button
|
||||
if (accessControlService.userAllowedForRole("")) {
|
||||
Anchor logoutLink = new Anchor("/logout", "Logout");
|
||||
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()),
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.kickerelo.kickerelo.util;
|
||||
|
||||
public interface AccessControlService {
|
||||
boolean userAllowedForRole(String role);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.kickerelo.kickerelo.util;
|
||||
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Profile("prod")
|
||||
public class AccessControlServiceProdImpl implements AccessControlService {
|
||||
@Override
|
||||
public boolean userAllowedForRole(String role) {
|
||||
// Check if authentication is present
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (auth == null || !(auth.getPrincipal() instanceof OidcUser oidcUser)) return false;
|
||||
|
||||
// Empty String means there just needs to be authentication, not a specific group
|
||||
if (role.isEmpty()) return true;
|
||||
|
||||
// Get the list of groups the user is part of
|
||||
Object groupsObj = oidcUser.getClaims().getOrDefault("groups", List.of());
|
||||
if (!(groupsObj instanceof List<?>)) return false;
|
||||
|
||||
// Keep only Strings in the list
|
||||
List<String> listOfGroups = ((List<?>) groupsObj).stream()
|
||||
.filter(String.class::isInstance)
|
||||
.map(String.class::cast)
|
||||
.toList();
|
||||
|
||||
// Check if the user is part of the required group
|
||||
return listOfGroups.contains(role);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.kickerelo.kickerelo.util;
|
||||
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Profile("test")
|
||||
public class AccessControlServiceTestImpl implements AccessControlService {
|
||||
@Override
|
||||
public boolean userAllowedForRole(String role) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,29 @@
|
||||
package org.kickerelo.kickerelo.views;
|
||||
|
||||
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.kickerelo.kickerelo.util.AccessControlService;
|
||||
|
||||
import com.vaadin.flow.component.button.Button;
|
||||
import com.vaadin.flow.component.html.H2;
|
||||
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.Route;
|
||||
import org.kickerelo.kickerelo.exception.DuplicatePlayerException;
|
||||
import org.kickerelo.kickerelo.exception.InvalidDataException;
|
||||
import org.kickerelo.kickerelo.exception.PlayerNameNotSetException;
|
||||
import org.kickerelo.kickerelo.service.KickerEloService;
|
||||
|
||||
@Route("admin")
|
||||
public class AdminView extends VerticalLayout {
|
||||
public AdminView(KickerEloService service) {
|
||||
H2 subheader = new H2("Verwaltung");
|
||||
|
||||
public AdminView(KickerEloService service, AccessControlService accessControlService) {
|
||||
// Deny access if user isn't part of the Kicker Admin group
|
||||
if (!accessControlService.userAllowedForRole("Kicker Admin")) {
|
||||
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 +49,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();
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
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
|
||||
spring.jpa.show-sql=true
|
||||
|
||||
# == OIDC Configuration ==
|
||||
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
|
||||
|
||||
vaadin.urlMapping=/app/*
|
||||
|
||||
BIN
src/main/resources/static/icon.png
Normal file
BIN
src/main/resources/static/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 205 KiB |
Reference in New Issue
Block a user