diff --git a/pom.xml b/pom.xml
index 462d94c..93ab052 100644
--- a/pom.xml
+++ b/pom.xml
@@ -116,7 +116,6 @@
javax.servlet
javax.servlet-api
-
provided
@@ -163,6 +162,11 @@
spring-boot-starter-test
test
+
+ org.springframework.security
+ spring-security-test
+ test
+
com.vaadin
vaadin-testbench
diff --git a/src/main/java/de/kreth/invoice/config/KeycloakConfigResolverLocal.java b/src/main/java/de/kreth/invoice/config/KeycloakConfigResolverLocal.java
index 9c980d7..2b87d11 100644
--- a/src/main/java/de/kreth/invoice/config/KeycloakConfigResolverLocal.java
+++ b/src/main/java/de/kreth/invoice/config/KeycloakConfigResolverLocal.java
@@ -8,9 +8,9 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public class KeycloakConfigResolverLocal {
- @Bean
- public KeycloakConfigResolver keyCloakConfigResolver() {
- return new KeycloakSpringBootConfigResolver();
- }
+ @Bean
+ public KeycloakConfigResolver keyCloakConfigResolver() {
+ return new KeycloakSpringBootConfigResolver();
+ }
}
diff --git a/src/main/java/de/kreth/invoice/config/SecurityUtils.java b/src/main/java/de/kreth/invoice/config/SecurityUtils.java
index 2d0b94d..a3183ce 100644
--- a/src/main/java/de/kreth/invoice/config/SecurityUtils.java
+++ b/src/main/java/de/kreth/invoice/config/SecurityUtils.java
@@ -11,6 +11,10 @@ import org.springframework.security.core.context.SecurityContextHolder;
import com.vaadin.flow.shared.ApplicationConstants;
public class SecurityUtils {
+
+ private SecurityUtils() {
+ }
+
/**
* Tests if the request is an internal framework request. The test consists of
* checking if the request parameter is present and if its value is consistent
diff --git a/src/main/java/de/kreth/invoice/config/UiSecurityConfig.java b/src/main/java/de/kreth/invoice/config/UiSecurityConfig.java
index 08e8805..e9280e8 100644
--- a/src/main/java/de/kreth/invoice/config/UiSecurityConfig.java
+++ b/src/main/java/de/kreth/invoice/config/UiSecurityConfig.java
@@ -22,60 +22,58 @@ import org.springframework.security.web.authentication.session.SessionAuthentica
@KeycloakConfiguration
public class UiSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
- @Autowired
- private KeycloakClientRequestFactory factory;
+ @Autowired
+ private KeycloakClientRequestFactory factory;
- @Autowired
- public void configureGlobal(AuthenticationManagerBuilder auth) {
- KeycloakAuthenticationProvider keyCloakAuthProvider = keycloakAuthenticationProvider();
- keyCloakAuthProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
- auth.authenticationProvider(keyCloakAuthProvider);
- }
+ @Autowired
+ public void configureGlobal(AuthenticationManagerBuilder auth) {
+ KeycloakAuthenticationProvider keyCloakAuthProvider = keycloakAuthenticationProvider();
+ keyCloakAuthProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
+ auth.authenticationProvider(keyCloakAuthProvider);
+ }
- @Bean
- @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
- public KeycloakRestTemplate restTemplate() {
- return new KeycloakRestTemplate(factory);
- }
+ @Bean
+ @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+ public KeycloakRestTemplate restTemplate() {
+ return new KeycloakRestTemplate(factory);
+ }
- @Bean
- @Override
- protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
- return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
- }
+ @Bean
+ @Override
+ protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
+ return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
+ }
- @Override
- public void configure(HttpSecurity http) throws Exception {
- super.configure(http);
- http.cors().disable()
- .csrf().disable()
- .anonymous().disable()
- .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED).and()
- .authorizeRequests().requestMatchers(SecurityUtils::isFrameworkInternalRequest).permitAll()
- .anyRequest().hasAnyRole("ROLE_trainer", "ROLE_admin");
- }
+ @Override
+ public void configure(HttpSecurity http) throws Exception {
+ super.configure(http);
+ http.cors().disable().csrf().disable().anonymous().disable().sessionManagement()
+ .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED).and().authorizeRequests()
+ .requestMatchers(SecurityUtils::isFrameworkInternalRequest).permitAll().anyRequest()
+ .hasAnyRole("admin", "INVOICE_USER");
+ }
- @Override
- public void configure(WebSecurity web) throws Exception {
- web.ignoring().antMatchers(
- // Vaadin Flow static resources //
- "/VAADIN/**",
- // the standard favicon URI
- "/favicon.ico",
- // the robots exclusion standard
- "/robots.txt",
- // web application manifest //
- "/manifest.webmanifest", "/sw.js", "/offline-page.html",
- // (development mode) static resources //
- "/frontend/**",
- // (development mode) webjars //
- "/webjars/**",
- // (production mode) static resources //
- "/frontend-es5/**", "/frontend-es6/**");
- }
+ @Override
+ public void configure(WebSecurity web) throws Exception {
+ web.ignoring().antMatchers(
+ // Vaadin Flow static resources //
+ "/VAADIN/**",
+ // the standard favicon URI
+ "/favicon.ico",
+ // the robots exclusion standard
+ "/robots.txt",
+ // web application manifest //
+ "/manifest.webmanifest", "/sw.js", "/offline-page.html",
+ // (development mode) static resources //
+ "/frontend/**",
+ // (development mode) webjars //
+ "/webjars/**",
+ // (production mode) static resources //
+ "/frontend-es5/**", "/frontend-es6/**");
+ }
- @Bean
- public static KeycloakConfigResolver keycloakConfigResolver() {
- return new KeycloakSpringBootConfigResolver();
- }
+ @Bean
+ public static KeycloakConfigResolver keycloakConfigResolver() {
+ return new KeycloakSpringBootConfigResolver();
+ }
}
diff --git a/src/main/java/de/kreth/invoice/views/View.java b/src/main/java/de/kreth/invoice/views/View.java
index 9b3890e..8c0441e 100644
--- a/src/main/java/de/kreth/invoice/views/View.java
+++ b/src/main/java/de/kreth/invoice/views/View.java
@@ -5,7 +5,6 @@ import java.util.Iterator;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.access.prepost.PreAuthorize;
import com.vaadin.flow.component.ClickEvent;
import com.vaadin.flow.component.Text;
@@ -42,7 +41,6 @@ import de.kreth.invoice.views.user.UserDetailsDialog;
@PageTitle("")
@Route(value = "")
-@PreAuthorize("hasRole('INVOICE_USER')")
public class View extends VerticalLayout implements BeforeEnterObserver {
private static final long serialVersionUID = 1L;
diff --git a/src/main/java/de/kreth/invoice/views/user/UserDetailsDialog.java b/src/main/java/de/kreth/invoice/views/user/UserDetailsDialog.java
index 8eff28a..d9d50ab 100644
--- a/src/main/java/de/kreth/invoice/views/user/UserDetailsDialog.java
+++ b/src/main/java/de/kreth/invoice/views/user/UserDetailsDialog.java
@@ -33,44 +33,44 @@ import de.kreth.invoice.report.Signature;
public class UserDetailsDialog extends Dialog {
- private static final long serialVersionUID = -6255487997073609068L;
+ private static final long serialVersionUID = -6255487997073609068L;
- private Logger logger = LoggerFactory.getLogger(getClass());
+ private Logger logger = LoggerFactory.getLogger(getClass());
- private final Binder bankBinder = new Binder<>();
- private final Binder adressBinder = new Binder<>();
+ private final Binder bankBinder = new Binder<>();
+ private final Binder adressBinder = new Binder<>();
// private final TextField loginName;
- private final TextField prename;
+ private final TextField prename;
- private final TextField surname;
+ private final TextField surname;
- private final TextField bankName;
+ private final TextField bankName;
- private final TextField iban;
+ private final TextField iban;
- private final TextField bic;
+ private final TextField bic;
- private final TextField adress1;
+ private final TextField adress1;
- private final TextField adress2;
+ private final TextField adress2;
- private final TextField zipCode;
+ private final TextField zipCode;
- private final TextField city;
+ private final TextField city;
- private final Button okButton;
+ private final Button okButton;
- private final Image signatureImage;
- private final Upload upload;
+ private final Image signatureImage;
+ private final Upload upload;
- private User user;
+ private User user;
- private boolean isValidAndClosedWithOk = false;
+ private boolean isValidAndClosedWithOk = false;
- public UserDetailsDialog(// UserBankRepository bankRepository, UserAdressRepository adressRepository
- ) {
+ public UserDetailsDialog(// UserBankRepository bankRepository, UserAdressRepository adressRepository
+ ) {
// this.bankRepository = bankRepository;
// this.adressRepository = adressRepository;
@@ -78,151 +78,145 @@ public class UserDetailsDialog extends Dialog {
// loginName.setLabel("Login Name");
// loginName.setEnabled(false);
- prename = new TextField();
- prename.setLabel("Vorname");
- prename.setEnabled(false);
-
- surname = new TextField();
- surname.setLabel("Nachname");
- surname.setEnabled(false);
-
- bankName = new TextField();
- bankName.setLabel("Name der Bank");
- bankBinder.forField(bankName)
- .asRequired("Der BankName darf nicht leer sein.")
- .bind(UserBank::getBankName, UserBank::setBankName);
-
- iban = new TextField();
- iban.setLabel("IBAN");
- bankBinder.forField(iban)
- .asRequired("Die IBAN darf nicht leer sein.")
- .bind(UserBank::getIban, UserBank::setIban);
-
- bic = new TextField();
- bic.setLabel("BIC");
- bankBinder.forField(bic).bind(UserBank::getBic, UserBank::setBic);
-
- adress1 = new TextField();
- adress1.setLabel("Straße");
- adressBinder.forField(adress1)
- .asRequired("Die Straße muss angegeben sein.")
- .bind(UserAdress::getAdress1, UserAdress::setAdress1);
-
- adress2 = new TextField();
- adress2.setLabel("Adresszusatz");
- adressBinder.forField(adress2)
- .bind(UserAdress::getAdress2, UserAdress::setAdress2);
-
- zipCode = new TextField();
- zipCode.setLabel("Postleitzahl");
- adressBinder.forField(zipCode)
- .asRequired("Die Postleitzahl muss angegeben sein.")
- .bind(UserAdress::getZip, UserAdress::setZip);
-
- city = new TextField();
- city.setLabel("Ort");
- adressBinder.forField(city)
- .asRequired("Der Ort muss angegeben sein.")
- .bind(UserAdress::getCity, UserAdress::setCity);
-
- signatureImage = new Image();
- signatureImage.setAlt("Keine Unterschrift konfiguriert");
-
- upload = new Upload(this::receiveUpload);
- upload.addFinishedListener(ev -> updateSignatureImage());
-
- VerticalLayout layout = new VerticalLayout();
- layout.add(prename, surname);
- layout.add(new Hr());
- layout.add(bankName, iban, bic);
- layout.add(new Hr());
- HorizontalLayout cityLayout = new HorizontalLayout();
- cityLayout.add(zipCode, city);
-
- layout.add(adress1, adress2, cityLayout, new FormLayout(signatureImage, upload));
-
- okButton = new Button("OK", ev -> {
- BinderValidationStatus bankValidation = bankBinder.validate();
- BinderValidationStatus adressValidation = adressBinder.validate();
-
- if (bankValidation.isOk() && adressValidation.isOk()) {
- user.setBank(bankBinder.getBean());
- user.setAdress(adressBinder.getBean());
- isValidAndClosedWithOk = true;
- close();
- }
- });
-
- Button cancel = new Button("Abbrechen", ev -> close());
-
- HorizontalLayout buttons = new HorizontalLayout();
- buttons.add(okButton, cancel);
- layout.add(buttons);
-
- add(layout);
- }
-
- private OutputStream receiveUpload(String filename, String mimeType) {
-
- Signature signature = new Signature(user);
- try {
- return signature.createOutputStream(filename);
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
- }
+ prename = new TextField();
+ prename.setLabel("Vorname");
+ prename.setEnabled(false);
+
+ surname = new TextField();
+ surname.setLabel("Nachname");
+ surname.setEnabled(false);
+
+ bankName = new TextField();
+ bankName.setLabel("Name der Bank");
+ bankBinder.forField(bankName).asRequired("Der BankName darf nicht leer sein.").bind(UserBank::getBankName,
+ UserBank::setBankName);
+
+ iban = new TextField();
+ iban.setLabel("IBAN");
+ bankBinder.forField(iban).asRequired("Die IBAN darf nicht leer sein.").bind(UserBank::getIban,
+ UserBank::setIban);
+
+ bic = new TextField();
+ bic.setLabel("BIC");
+ bankBinder.forField(bic).bind(UserBank::getBic, UserBank::setBic);
+
+ adress1 = new TextField();
+ adress1.setLabel("Straße");
+ adressBinder.forField(adress1).asRequired("Die Straße muss angegeben sein.").bind(UserAdress::getAdress1,
+ UserAdress::setAdress1);
+
+ adress2 = new TextField();
+ adress2.setLabel("Adresszusatz");
+ adressBinder.forField(adress2).bind(UserAdress::getAdress2, UserAdress::setAdress2);
+
+ zipCode = new TextField();
+ zipCode.setLabel("Postleitzahl");
+ adressBinder.forField(zipCode).asRequired("Die Postleitzahl muss angegeben sein.").bind(UserAdress::getZip,
+ UserAdress::setZip);
+
+ city = new TextField();
+ city.setLabel("Ort");
+ adressBinder.forField(city).asRequired("Der Ort muss angegeben sein.").bind(UserAdress::getCity,
+ UserAdress::setCity);
+
+ signatureImage = new Image();
+ signatureImage.setAlt("Keine Unterschrift konfiguriert");
+
+ upload = new Upload(this::receiveUpload);
+ upload.addFinishedListener(ev -> updateSignatureImage());
+
+ VerticalLayout layout = new VerticalLayout();
+ layout.add(prename, surname);
+ layout.add(new Hr());
+ layout.add(bankName, iban, bic);
+ layout.add(new Hr());
+ HorizontalLayout cityLayout = new HorizontalLayout();
+ cityLayout.add(zipCode, city);
+
+ layout.add(adress1, adress2, cityLayout, new FormLayout(signatureImage, upload));
+
+ okButton = new Button("OK", ev -> {
+ BinderValidationStatus bankValidation = bankBinder.validate();
+ BinderValidationStatus adressValidation = adressBinder.validate();
+
+ if (bankValidation.isOk() && adressValidation.isOk()) {
+ user.setBank(bankBinder.getBean());
+ user.setAdress(adressBinder.getBean());
+ isValidAndClosedWithOk = true;
+ close();
+ }
+ });
- public void setUser(User user) {
+ Button cancel = new Button("Abbrechen", ev -> close());
- this.user = Objects.requireNonNull(user);
+ HorizontalLayout buttons = new HorizontalLayout();
+ buttons.add(okButton, cancel);
+ layout.add(buttons);
- this.prename.setValue(user.getGivenName());
- this.surname.setValue(user.getFamilyName());
- bankBinder.setBean(user.getBank().clone());
- adressBinder.setBean(user.getAdress().clone());
- updateSignatureImage();
- }
+ add(layout);
+ }
- public boolean isValidAndClosedWithOk() {
- return isValidAndClosedWithOk;
- }
+ private OutputStream receiveUpload(String filename, String mimeType) {
- private void updateSignatureImage() {
- if (user != null && user.getId() != null) {
- upload.setUploadButton(null);
- Signature signature = new Signature(user);
- if (signature.isSignatureImageExists()) {
- File signatureUrl = signature.getSignatureUrl();
- logger.info("Showing signature: {}", signatureUrl);
+ Signature signature = new Signature(user);
+ try {
+ return signature.createOutputStream(filename);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
- StreamResource resource = new StreamResource("Unterschrift", new InputStreamFactory() {
+ public void setUser(User user) {
- private static final long serialVersionUID = 1L;
+ this.user = Objects.requireNonNull(user);
- @Override
- public InputStream createInputStream() {
- try {
- return new FileInputStream(signatureUrl);
- } catch (FileNotFoundException e) {
- throw new UncheckedIOException(e);
+ this.prename.setValue(user.getGivenName());
+ this.surname.setValue(user.getFamilyName());
+ bankBinder.setBean(user.getBank().clone());
+ adressBinder.setBean(user.getAdress().clone());
+ updateSignatureImage();
+ }
+
+ public boolean isValidAndClosedWithOk() {
+ return isValidAndClosedWithOk;
+ }
+
+ private void updateSignatureImage() {
+ if (user != null && user.getId() != null) {
+ upload.setUploadButton(null);
+ Signature signature = new Signature(user);
+ if (signature.isSignatureImageExists()) {
+ File signatureUrl = signature.getSignatureUrl();
+ logger.info("Showing signature: {}", signatureUrl);
+
+ StreamResource resource = new StreamResource("Unterschrift", new InputStreamFactory() {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public InputStream createInputStream() {
+ try {
+ return new FileInputStream(signatureUrl);
+ } catch (FileNotFoundException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+ });
+ signatureImage.setWidth("192px");
+ signatureImage.setHeight("62px");
+ signatureImage.setSrc(resource);
}
- }
- });
- signatureImage.setWidth("192px");
- signatureImage.setHeight("62px");
- signatureImage.setSrc(resource);
- }
- } else {
- signatureImage.setWidth(null);
- signatureImage.setHeight(null);
- upload.setVisible(false);
- signatureImage.setAlt(
- "Eine Unterschrift kann konfiguriert werden, nachdem die Benutzerdaten gespeichert wurden.");
+ } else {
+ signatureImage.setWidth(null);
+ signatureImage.setHeight(null);
+ upload.setVisible(false);
+ signatureImage.setAlt(
+ "Eine Unterschrift kann konfiguriert werden, nachdem die Benutzerdaten gespeichert wurden.");
+ }
}
- }
- public User getUser() {
- return user;
- }
+ public User getUser() {
+ return user;
+ }
}