Compare commits

..

No commits in common. "751aa257b14332c3715f673e93734ad67201cc3b" and "0c248adff7b985a0c929efdfd63cae7db372a4b0" have entirely different histories.

10 changed files with 7 additions and 203 deletions

View file

@ -62,15 +62,13 @@
<artifactId>line-awesome</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>

View file

@ -1,72 +0,0 @@
package com.application.munera;
import com.application.munera.views.login.LoginView;
import com.vaadin.flow.spring.security.VaadinWebSecurity;
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.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.provisioning.UserDetailsManager;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@EnableWebSecurity
@Configuration
public class SecurityConfiguration
extends VaadinWebSecurity {
@Override
protected void configure(HttpSecurity http) throws Exception {
// Delegating the responsibility of general configurations
// of http security to the super class. It's configuring
// the followings: Vaadin's CSRF protection by ignoring
// framework's internal requests, default request cache,
// ignoring public views annotated with @AnonymousAllowed,
// restricting access to other views/endpoints, and enabling
// NavigationAccessControl authorization.
// You can add any possible extra configurations of your own
// here (the following is just an example):
// http.rememberMe().alwaysRemember(false);
// Configure your static resources with public access before calling
// super.configure(HttpSecurity) as it adds final anyRequest matcher
http.authorizeHttpRequests(auth -> auth.requestMatchers(new AntPathRequestMatcher("/public/**"))
.permitAll());
super.configure(http);
// This is important to register your login view to the
// navigation access control mechanism:
setLoginView(http, LoginView.class);
}
@Override
public void configure(WebSecurity web) throws Exception {
// Customize your WebSecurity configuration.
super.configure(web);
}
/**
* Demo UserDetailsManager which only provides two hardcoded
* in memory users and their roles.
* NOTE: This shouldn't be used in real world applications.
*/
@Bean
public UserDetailsManager userDetailsService() {
UserDetails user =
User.withUsername("user")
.password("{noop}user")
.roles("USER")
.build();
UserDetails admin =
User.withUsername("admin")
.password("{noop}admin")
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
}

View file

@ -1,33 +0,0 @@
package com.application.munera.services;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.server.VaadinServletRequest;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Component;
@Component
public class SecurityService {
private static final String LOGOUT_SUCCESS_URL = "/";
public UserDetails getAuthenticatedUser() {
SecurityContext context = SecurityContextHolder.getContext();
Object principal = context.getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
return (UserDetails) context.getAuthentication().getPrincipal();
}
// Anonymous or no authentication.
return null;
}
public void logout() {
UI.getCurrent().getPage().setLocation(LOGOUT_SUCCESS_URL);
SecurityContextLogoutHandler logoutHandler = new SecurityContextLogoutHandler();
logoutHandler.logout(
VaadinServletRequest.getCurrent().getHttpServletRequest(), null,
null);
}
}

View file

@ -1,24 +1,16 @@
package com.application.munera.views;
import com.application.munera.views.categories.CategoriesView;
import com.application.munera.views.dashboard.DashboardView;
import com.application.munera.views.events.EventsView;
import com.application.munera.views.expenses.*;
import com.application.munera.views.people.PeopleView;
import com.vaadin.flow.component.applayout.AppLayout;
import com.vaadin.flow.component.applayout.DrawerToggle;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.html.Footer;
import com.vaadin.flow.component.html.H1;
import com.vaadin.flow.component.html.Header;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.Scroller;
import com.vaadin.flow.component.sidenav.SideNav;
import com.vaadin.flow.component.sidenav.SideNavItem;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.spring.security.AuthenticationContext;
import com.vaadin.flow.theme.lumo.LumoUtility;
import org.vaadin.lineawesome.LineAwesomeIcon;
@ -28,10 +20,8 @@ import org.vaadin.lineawesome.LineAwesomeIcon;
public class MainLayout extends AppLayout {
private H1 viewTitle;
private final transient AuthenticationContext authContext;
public MainLayout(AuthenticationContext authContext) {
this.authContext = authContext;
public MainLayout() {
setPrimarySection(Section.DRAWER);
addDrawerContent();
addHeaderContent();
@ -44,22 +34,7 @@ public class MainLayout extends AppLayout {
viewTitle = new H1();
viewTitle.addClassNames(LumoUtility.FontSize.LARGE, LumoUtility.Margin.NONE);
// Creating the logout button
Button logout = new Button("Logout", click -> this.authContext.logout());
// Adding some padding to the logout button
logout.getStyle().set("padding", "10px");
// Creating the header and adding the logout button to the far left
HorizontalLayout header = new HorizontalLayout(logout);
header.setWidthFull(); // Make the header take the full width
header.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.CENTER);
header.setJustifyContentMode(FlexComponent.JustifyContentMode.END); // Align items to the start (left)
header.getStyle().set("padding", "0 10px"); // Add padding around the header if needed
addToNavbar(true, toggle, viewTitle);
addToNavbar(header);
}
private void addDrawerContent() {

View file

@ -1,4 +1,4 @@
package com.application.munera.views.categories;
package com.application.munera.views.expenses;
import com.application.munera.data.Category;
import com.application.munera.services.CategoryService;
@ -22,14 +22,12 @@ import com.vaadin.flow.data.binder.BeanValidationBinder;
import com.vaadin.flow.data.binder.ValidationException;
import com.vaadin.flow.router.*;
import com.vaadin.flow.spring.data.VaadinSpringDataHelpers;
import jakarta.annotation.security.PermitAll;
import org.springframework.data.domain.PageRequest;
import org.springframework.orm.ObjectOptimisticLockingFailureException;
import java.util.Optional;
@PageTitle("Categories")
@PermitAll
@Route(value = "categories/:categoryID?/:action?(edit)", layout = MainLayout.class)
@Uses(Icon.class)
public class CategoriesView extends Div implements BeforeEnterObserver {

View file

@ -1,4 +1,4 @@
package com.application.munera.views.dashboard;
package com.application.munera.views.expenses;
import com.application.munera.data.Expense;
import com.application.munera.data.Person;
@ -11,7 +11,6 @@ import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import jakarta.annotation.security.PermitAll;
import java.math.BigDecimal;
import java.time.Year;
@ -21,7 +20,6 @@ import java.util.*;
import java.util.stream.Collectors;
//@HtmlImport("frontend://styles/shared-styles.html") // If you have custom styles
@PermitAll
@PageTitle("Dashboard")
@Route(value = "dashboard", layout = MainLayout.class)
public class DashboardView extends Div {

View file

@ -1,4 +1,4 @@
package com.application.munera.views.events;
package com.application.munera.views.expenses;
import com.application.munera.data.Event;
import com.application.munera.data.Person;
@ -28,14 +28,12 @@ import com.vaadin.flow.router.BeforeEnterObserver;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.spring.data.VaadinSpringDataHelpers;
import jakarta.annotation.security.PermitAll;
import org.springframework.data.domain.PageRequest;
import org.springframework.orm.ObjectOptimisticLockingFailureException;
import java.util.Optional;
@PageTitle("Events")
@PermitAll
@Route(value = "events/:eventID?/:action?(edit)", layout = MainLayout.class)
@Uses(Icon.class)
public class EventsView extends Div implements BeforeEnterObserver {

View file

@ -30,7 +30,6 @@ import com.vaadin.flow.data.binder.BeanValidationBinder;
import com.vaadin.flow.data.binder.ValidationException;
import com.vaadin.flow.data.renderer.ComponentRenderer;
import com.vaadin.flow.router.*;
import jakarta.annotation.security.PermitAll;
import org.springframework.orm.ObjectOptimisticLockingFailureException;
import org.vaadin.klaudeta.PaginatedGrid;
@ -39,7 +38,6 @@ import java.util.Objects;
import java.util.Optional;
import java.util.Set;
@PermitAll
@PageTitle("Expenses")
@Route(value = "/:expenseID?/:action?(edit)", layout = MainLayout.class)
@RouteAlias(value = "", layout = MainLayout.class)

View file

@ -1,4 +1,4 @@
package com.application.munera.views.people;
package com.application.munera.views.expenses;
import com.application.munera.data.Person;
import com.application.munera.services.PersonService;
@ -28,7 +28,6 @@ import com.vaadin.flow.router.BeforeEnterObserver;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.spring.data.VaadinSpringDataHelpers;
import jakarta.annotation.security.PermitAll;
import org.springframework.data.domain.PageRequest;
import org.springframework.orm.ObjectOptimisticLockingFailureException;
@ -36,7 +35,6 @@ import java.math.BigDecimal;
import java.util.Optional;
@PageTitle("People")
@PermitAll
@Route(value = "people/:personID?/:action?(edit)", layout = MainLayout.class)
@Uses(Icon.class)
public class PeopleView extends Div implements BeforeEnterObserver {

View file

@ -1,54 +0,0 @@
package com.application.munera.views.login;
import com.vaadin.flow.component.html.H1;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.login.LoginForm;
import com.vaadin.flow.component.login.LoginI18n;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.BeforeEnterEvent;
import com.vaadin.flow.router.BeforeEnterObserver;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.server.auth.AnonymousAllowed;
@Route("login")
@PageTitle("Login")
@AnonymousAllowed
public class LoginView extends VerticalLayout implements BeforeEnterObserver {
private final LoginForm login = new LoginForm();
public LoginView() {
addClassName("login-view");
setSizeFull();
setJustifyContentMode(JustifyContentMode.CENTER);
setAlignItems(Alignment.CENTER);
login.setAction("login");
// Customize the LoginForm
LoginI18n i18n = LoginI18n.createDefault();
i18n.getForm().setForgotPassword("Forgot password?");
login.setI18n(i18n);
// Add a listener for the Forgot password button
login.addForgotPasswordListener(event -> {
Notification.show("Tough shit, feature aint ready yet!", 3000, Notification.Position.BOTTOM_CENTER);
});
add(new H1("Munera"), new H2("An expense tracking application"), login);
}
@Override
public void beforeEnter(BeforeEnterEvent beforeEnterEvent) {
if(beforeEnterEvent.getLocation()
.getQueryParameters()
.getParameters()
.containsKey("error")) {
login.setError(true);
}
}
}