Implemeting spring security auth
This commit is contained in:
parent
344477881f
commit
0afb90c068
@ -5,11 +5,11 @@ import com.vaadin.flow.spring.security.VaadinWebSecurity;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.ldap.LdapBindAuthenticationManagerFactory;
|
||||
import org.springframework.security.ldap.DefaultSpringSecurityContextSource;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
|
||||
@EnableWebSecurity
|
||||
@ -25,13 +25,18 @@ public class SecurityConfig extends VaadinWebSecurity {
|
||||
setLoginView(http, LoginView.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManager() {
|
||||
DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource("ldap://ldap.primefactorsolutions.com:389/dc=primefactorsolutions,dc=com");
|
||||
contextSource.setCacheEnvironmentProperties(false);
|
||||
LdapBindAuthenticationManagerFactory factory = new LdapBindAuthenticationManagerFactory(contextSource);
|
||||
factory.setUserDnPatterns("uid={0},ou=users");
|
||||
|
||||
return factory.createAuthenticationManager();
|
||||
@Bean
|
||||
public BCryptPasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DaoAuthenticationProvider authenticationProvider(final UserDetailsService userDetailsService) {
|
||||
final DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
|
||||
authProvider.setUserDetailsService(userDetailsService);
|
||||
authProvider.setPasswordEncoder(passwordEncoder());
|
||||
|
||||
return authProvider;
|
||||
}
|
||||
}
|
||||
|
@ -6,4 +6,5 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface UserRepository extends JpaRepository<User, UUID> {
|
||||
User getByEmail(String email);
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
package com.primefactorsolutions.invoices.model;
|
||||
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
|
||||
public enum Permission implements GrantedAuthority {
|
||||
INVALIDATE_INVOICE,
|
||||
EDIT_COMPANY;
|
||||
|
||||
@Override
|
||||
public String getAuthority() {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,6 +1,24 @@
|
||||
package com.primefactorsolutions.invoices.model;
|
||||
|
||||
public enum Role {
|
||||
ADMIN,
|
||||
REGULAR
|
||||
import lombok.Getter;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
public enum Role implements GrantedAuthority {
|
||||
ADMIN(List.of(Permission.EDIT_COMPANY, Permission.INVALIDATE_INVOICE)),
|
||||
REGULAR(List.of());
|
||||
|
||||
private final List<Permission> permissions;
|
||||
|
||||
Role(final List<Permission> permissions) {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthority() {
|
||||
return this.name();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,25 +1,33 @@
|
||||
package com.primefactorsolutions.invoices.model;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import io.hypersistence.utils.hibernate.type.json.JsonType;
|
||||
import jakarta.persistence.*;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.hibernate.annotations.Type;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Entity
|
||||
@Table(name = "user_")
|
||||
@Data
|
||||
public class User extends AbstractEntity {
|
||||
public class User extends AbstractEntity implements UserDetails {
|
||||
@NotBlank
|
||||
private String email;
|
||||
@NotBlank
|
||||
private String fullName;
|
||||
|
||||
private Role role;
|
||||
@Type(JsonType.class)
|
||||
@Column(columnDefinition = "json")
|
||||
private List<Role> roles;
|
||||
|
||||
private String password;
|
||||
|
||||
@NotNull
|
||||
private Status status;
|
||||
@ -28,4 +36,34 @@ public class User extends AbstractEntity {
|
||||
@JoinColumn(name = "company_id")
|
||||
@NotNull
|
||||
private Company company;
|
||||
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return this.roles.stream().flatMap(r -> r.getPermissions().stream()).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return this.email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return this.status != Status.DISABLED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return this.status != Status.DISABLED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return this.status == Status.ACTIVE;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,55 @@
|
||||
package com.primefactorsolutions.invoices.services;
|
||||
|
||||
import com.vaadin.flow.component.button.Button;
|
||||
import com.vaadin.flow.component.button.ButtonVariant;
|
||||
import com.vaadin.flow.i18n.I18NProvider;
|
||||
import lombok.Data;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@Service
|
||||
@Data
|
||||
public class ComponentBuilder {
|
||||
private final I18NProvider i18NProvider;
|
||||
|
||||
public ButtonBuilder button(String text) {
|
||||
return ButtonBuilder.builder().i18NProvider(i18NProvider).text(text);
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class ButtonBuilder {
|
||||
private String text;
|
||||
private I18NProvider i18NProvider;
|
||||
private ButtonVariant buttonVariant;
|
||||
|
||||
public static ButtonBuilder builder() {
|
||||
return new ButtonBuilder();
|
||||
}
|
||||
|
||||
public Button build() {
|
||||
final Button button = new Button(i18NProvider.getTranslation(text, Locale.of("es")));
|
||||
|
||||
if (buttonVariant != null) {
|
||||
button.addThemeVariants(buttonVariant);
|
||||
}
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
public ButtonBuilder primary() {
|
||||
this.setButtonVariant(ButtonVariant.LUMO_PRIMARY);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ButtonBuilder i18NProvider(I18NProvider i18NProvider) {
|
||||
this.setI18NProvider(i18NProvider);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ButtonBuilder text(String text) {
|
||||
this.setText(text);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
@ -5,6 +5,9 @@ import com.primefactorsolutions.invoices.model.Role;
|
||||
import com.primefactorsolutions.invoices.model.Status;
|
||||
import com.primefactorsolutions.invoices.model.User;
|
||||
import lombok.Data;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
@ -12,7 +15,7 @@ import java.util.UUID;
|
||||
|
||||
@Service
|
||||
@Data
|
||||
public class UserService {
|
||||
public class UserService implements UserDetailsService {
|
||||
private final UserRepository userRepository;
|
||||
private final CompanyService companyService;
|
||||
|
||||
@ -28,10 +31,15 @@ public class UserService {
|
||||
if (updatedUser.getId() == null) {
|
||||
var company = companyService.getCompany();
|
||||
updatedUser.setCompany(company);
|
||||
updatedUser.setRole(Role.REGULAR);
|
||||
updatedUser.setRoles(List.of(Role.REGULAR));
|
||||
updatedUser.setStatus(Status.ACTIVE);
|
||||
}
|
||||
|
||||
userRepository.save(updatedUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
return userRepository.getByEmail(username);
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,9 @@ package com.primefactorsolutions.invoices.views;
|
||||
|
||||
import com.primefactorsolutions.invoices.model.Client;
|
||||
import com.primefactorsolutions.invoices.services.ClientService;
|
||||
import com.primefactorsolutions.invoices.services.ComponentBuilder;
|
||||
import com.primefactorsolutions.invoices.views.component.Breadcrumbs;
|
||||
import com.primefactorsolutions.invoices.views.component.GenericForm;
|
||||
import com.vaadin.flow.component.button.Button;
|
||||
import com.vaadin.flow.component.button.ButtonVariant;
|
||||
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||
import com.vaadin.flow.i18n.I18NProvider;
|
||||
@ -20,7 +19,6 @@ import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.primefactorsolutions.invoices.utils.UiUtils.goTo;
|
||||
@ -34,26 +32,26 @@ public class ClientEditView extends VerticalLayout implements HasUrlParameter<St
|
||||
|
||||
ClientService clientService;
|
||||
I18NProvider i18NProvider;
|
||||
|
||||
ComponentBuilder componentBuilder;
|
||||
GenericForm<Client> clientGenericForm;
|
||||
|
||||
public ClientEditView(ClientService clientService, I18NProvider i18NProvider) {
|
||||
public ClientEditView(ClientService clientService, I18NProvider i18NProvider, ComponentBuilder componentBuilder) {
|
||||
this.clientService = clientService;
|
||||
this.i18NProvider = i18NProvider;
|
||||
this.componentBuilder = componentBuilder;
|
||||
|
||||
var client = new Client();
|
||||
|
||||
this.clientGenericForm = new GenericForm<>(Client.class);
|
||||
this.clientGenericForm.setBean(client);
|
||||
|
||||
String text = this.i18NProvider.getTranslation("action.save", Locale.of("es"));
|
||||
var saveButton = new Button(text);
|
||||
saveButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||
var saveButton = this.componentBuilder.button("action.save").primary().build();
|
||||
saveButton.addClickListener(c -> {
|
||||
var updatedClient = clientGenericForm.getBean();
|
||||
clientService.saveOrUpdateClient(updatedClient);
|
||||
goTo(this, "clients");
|
||||
});
|
||||
var cancelButton = new Button("Cancel");
|
||||
var cancelButton = this.componentBuilder.button("action.cancel").build();
|
||||
cancelButton.addClickListener(c -> goTo(this, "clients"));
|
||||
|
||||
var breadcrumbs = new Breadcrumbs(List.of(Pair.of("Clientes", "clients"), Pair.of("Editar", null)));
|
||||
|
@ -18,6 +18,7 @@ import jakarta.annotation.security.PermitAll;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.vaadin.firitin.components.button.VButton;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@ -34,7 +35,6 @@ public class ProductEditView extends VerticalLayout implements HasUrlParameter<S
|
||||
|
||||
ProductService productService;
|
||||
I18NProvider i18NProvider;
|
||||
|
||||
GenericForm<Product> productGenericForm;
|
||||
|
||||
public ProductEditView(ProductService productService, I18NProvider i18NProvider) {
|
||||
@ -54,9 +54,7 @@ public class ProductEditView extends VerticalLayout implements HasUrlParameter<S
|
||||
goTo(this, "products");
|
||||
});
|
||||
var cancelButton = new Button("Cancel");
|
||||
cancelButton.addClickListener(c -> {
|
||||
goTo(this, "products");
|
||||
});
|
||||
cancelButton.addClickListener(c -> goTo(this, "products"));
|
||||
|
||||
var breadcrumbs = new Breadcrumbs(List.of(Pair.of("Products", "products"), Pair.of("Editar", null)));
|
||||
var buttonLayout = new HorizontalLayout(saveButton, cancelButton);
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.primefactorsolutions.invoices.views;
|
||||
package com.primefactorsolutions.invoices.views.invoices;
|
||||
|
||||
import com.primefactorsolutions.invoices.beans.CabeceraDTO;
|
||||
import com.primefactorsolutions.invoices.beans.ClientDTO;
|
||||
@ -10,6 +10,7 @@ import com.primefactorsolutions.invoices.model.mappers.DetalleMapper;
|
||||
import com.primefactorsolutions.invoices.services.ClientService;
|
||||
import com.primefactorsolutions.invoices.services.CompanyService;
|
||||
import com.primefactorsolutions.invoices.services.InvoiceService;
|
||||
import com.primefactorsolutions.invoices.views.MainLayout;
|
||||
import com.primefactorsolutions.invoices.views.component.invoice.*;
|
||||
import com.primefactorsolutions.invoices.xsd.FacturaComputarizadaComercialExportacionServicio;
|
||||
import com.vaadin.flow.component.*;
|
@ -14,5 +14,8 @@ INSERT INTO "PRODUCT" (ID, VERSION, COMPANY_ID, STATUS, codigo_Producto_Sin, cod
|
||||
precio_Unitario) VALUES ('dcecb825-7bc6-402d-850a-9d4a08fe6663', 1, '108ace19-6d78-4a70-a01f-30b9e3f6b2b8', 1, 1,
|
||||
'PROD001', 'Test product', 1, 1);
|
||||
|
||||
INSERT INTO "USER_" (ID, VERSION, COMPANY_ID, EMAIL, FULL_NAME, ROLE, STATUS) VALUES ('b9f1bbe0-4542-48d3-b88e-452f2891cb68',
|
||||
1, '108ace19-6d78-4a70-a01f-30b9e3f6b2b8', 'alex@test.com', 'alex prudencio', 1, 1);
|
||||
INSERT INTO "USER_" (ID, VERSION, COMPANY_ID, EMAIL, FULL_NAME, ROLES, PASSWORD, STATUS) VALUES ('b9f1bbe0-4542-48d3-b88e-452f2891cb68',
|
||||
1, '108ace19-6d78-4a70-a01f-30b9e3f6b2b8', 'admin@test.com', 'admin test', '[0]' FORMAT JSON, '$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW', 0);
|
||||
|
||||
INSERT INTO "USER_" (ID, VERSION, COMPANY_ID, EMAIL, FULL_NAME, ROLES, PASSWORD, STATUS) VALUES ('547274a6-bb73-462d-85ab-b529fde798fb',
|
||||
1, '108ace19-6d78-4a70-a01f-30b9e3f6b2b8', 'user@test.com', 'user test', '[1]' FORMAT JSON, '$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW', 0);
|
@ -1 +1,2 @@
|
||||
action.save=Save
|
||||
action.cancel=Cancel
|
@ -1 +1,2 @@
|
||||
action.save=Guardar
|
||||
action.cancel=Cancelar
|
@ -1,12 +1,7 @@
|
||||
package com.primefactorsolutions.invoices.views.list;
|
||||
|
||||
import com.primefactorsolutions.invoices.views.FacturaComputarizadaComercialExportacionesServicioEditView;
|
||||
import com.vaadin.flow.component.Component;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class InvoiceFormTest {
|
||||
@Test
|
||||
public void formShownWhenContactSelected() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user