commit d411f1436f5e4f311e3ad205b2f7d42abff29b00
Author: Vojtěch Danišík <32537562+danisik@users.noreply.github.com>
Date:   Mon May 4 13:17:04 2020 +0200

    re #8014 Login into app + session for user.

diff --git a/src/main/java/vldc/aswi/configuration/AppConfig.java b/src/main/java/vldc/aswi/configuration/AppConfig.java
index 8082dc75..ecef3155 100644
--- a/src/main/java/vldc/aswi/configuration/AppConfig.java
+++ b/src/main/java/vldc/aswi/configuration/AppConfig.java
@@ -6,13 +6,17 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
 import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
+import org.springframework.security.crypto.password.NoOpPasswordEncoder;
 import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.util.matcher.RegexRequestMatcher;
 import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@@ -69,6 +73,7 @@ public class AppConfig extends WebSecurityConfigurerAdapter implements WebMvcCon
         return viewResolver;
     }
 
+
     @Bean
     public PasswordEncoder passwordEncoder() {
     	return new BCryptPasswordEncoder();
@@ -76,7 +81,6 @@ public class AppConfig extends WebSecurityConfigurerAdapter implements WebMvcCon
 
 	@Override
 	protected void configure(HttpSecurity http) throws Exception {
-		/*
 		http
 		.authorizeRequests()
 			.mvcMatchers("/login").permitAll()
@@ -86,14 +90,13 @@ public class AppConfig extends WebSecurityConfigurerAdapter implements WebMvcCon
 		.formLogin()
 			.loginPage("/login")
 			.permitAll()
-			.defaultSuccessUrl("/")
+			.defaultSuccessUrl("/", true)
 			.and()
 		.logout()
 			.logoutRequestMatcher(new RegexRequestMatcher("/logout", "GET"))
 			.invalidateHttpSession(true)
 			.deleteCookies("JSESSIONID")
 			.permitAll();
-		 */
 	}
 
 	@Override
@@ -108,10 +111,9 @@ public class AppConfig extends WebSecurityConfigurerAdapter implements WebMvcCon
 		registry
 		.addResourceHandler("/css/**")
 		.addResourceLocations("/css/");
-
         registry
-                .addResourceHandler("/js/**")
-                .addResourceLocations("/js/");
+		.addResourceHandler("/js/**")
+		.addResourceLocations("/js/");
 		registry
 		.addResourceHandler("/webfonts/**")
 		.addResourceLocations("/webfonts/");
diff --git a/src/main/java/vldc/aswi/dao/UserRepository.java b/src/main/java/vldc/aswi/dao/UserRepository.java
index da5584ee..28b40401 100644
--- a/src/main/java/vldc/aswi/dao/UserRepository.java
+++ b/src/main/java/vldc/aswi/dao/UserRepository.java
@@ -16,4 +16,11 @@ public interface UserRepository extends CrudRepository<User, Long> {
      * @return User if ID is present in database.
      */
     User getById(Long Id);
+
+    /**
+     * Find User by his username.
+     * @param username user's username.
+     * @return User if username is presented in database.
+     */
+    User findByUsername(String username);
 }
diff --git a/src/main/java/vldc/aswi/domain/User.java b/src/main/java/vldc/aswi/domain/User.java
index ffc4900d..178ce41d 100644
--- a/src/main/java/vldc/aswi/domain/User.java
+++ b/src/main/java/vldc/aswi/domain/User.java
@@ -27,7 +27,7 @@ public class User extends EntityParent {
     private String password;
 
     /** Role of user. */
-    @ManyToOne(fetch=FetchType.LAZY)
+    @ManyToOne(fetch=FetchType.EAGER)
     @JoinColumn(name = "role_id")
     private Role role;
 
diff --git a/src/main/java/vldc/aswi/model/login/WebCredentials.java b/src/main/java/vldc/aswi/model/login/WebCredentials.java
new file mode 100644
index 00000000..f31002d6
--- /dev/null
+++ b/src/main/java/vldc/aswi/model/login/WebCredentials.java
@@ -0,0 +1,107 @@
+package vldc.aswi.model.login;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.stream.Collectors;
+
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+/**
+ * Model used in spring security representing user credentials saved in session.
+ */
+public class WebCredentials implements UserDetails {
+
+	private static final long serialVersionUID = 26298569253774237L;
+
+	private final String username;
+	private final String password;
+	private Collection<String> roles;
+
+	/**
+	 * Constructor.
+	 * @param username Username of user.
+	 * @param password Password of user.
+	 */
+	public WebCredentials(String username, String password) {
+		this.username = username;
+		this.password = password;
+		this.roles = new LinkedList<>();
+	}
+
+	/**
+	 * Get authorities for logged User.
+	 * @return List of roles.
+	 */
+	@Override
+	public Collection<? extends GrantedAuthority> getAuthorities() {
+		return this.roles
+		.stream()
+		.map(SimpleGrantedAuthority::new)
+		.collect(Collectors.toList());
+	}
+
+	/**
+	 * Get logged user password.
+	 * @return User password.
+	 */
+	@Override
+	public String getPassword() {
+		return this.password;
+	}
+
+	/**
+	 * Get logged user username.
+	 * @return User username.
+	 */
+	@Override
+	public String getUsername() {
+		return this.username;
+	}
+
+	/**
+	 * Check if account is non expired.
+	 * @return True.
+	 */
+	@Override
+	public boolean isAccountNonExpired() {
+		return true;
+	}
+
+	/**
+	 * Check if account is non locked.
+	 * @return True.
+	 */
+	@Override
+	public boolean isAccountNonLocked() {
+		return true;
+	}
+
+	/**
+	 * Check if Credentials non expired.
+	 * @return True.
+	 */
+	@Override
+	public boolean isCredentialsNonExpired() {
+		return true;
+	}
+
+	/**
+	 * Check if user is enabled.
+	 * @return True.
+	 */
+	@Override
+	public boolean isEnabled() {
+		return true;
+	}
+
+	/**
+	 * Add role for user in webcredentials object.
+	 * @param role new role for user.
+	 */
+	public void addRole(String role) {
+		this.roles.add(role);
+	}
+
+}
diff --git a/src/main/java/vldc/aswi/service/UserManager.java b/src/main/java/vldc/aswi/service/UserManager.java
index 632120de..b4c9aa5c 100644
--- a/src/main/java/vldc/aswi/service/UserManager.java
+++ b/src/main/java/vldc/aswi/service/UserManager.java
@@ -21,5 +21,5 @@ public interface UserManager {
      * @param password - password for user.
      * @return ID of newly created user.
      */
-    Long addUser(String username, String password);
+    Long addUser(String username, String password, Long roleId);
 }
diff --git a/src/main/java/vldc/aswi/service/UserManagerImpl.java b/src/main/java/vldc/aswi/service/UserManagerImpl.java
index b07e6b3f..6ef5d175 100644
--- a/src/main/java/vldc/aswi/service/UserManagerImpl.java
+++ b/src/main/java/vldc/aswi/service/UserManagerImpl.java
@@ -5,10 +5,15 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.event.ContextRefreshedEvent;
 import org.springframework.context.event.EventListener;
 import org.springframework.core.annotation.Order;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
 import vldc.aswi.dao.RoleRepository;
 import vldc.aswi.dao.UserRepository;
 import vldc.aswi.domain.User;
+import vldc.aswi.model.login.WebCredentials;
 
 import javax.transaction.Transactional;
 import java.util.LinkedList;
@@ -19,7 +24,10 @@ import java.util.List;
  */
 @Service
 @Slf4j
-public class UserManagerImpl implements UserManager {
+public class UserManagerImpl implements UserManager, UserDetailsService {
+
+    @Autowired
+    private PasswordEncoder encoder;
 
     /** Autowired user repository. */
     @Autowired
@@ -32,7 +40,6 @@ public class UserManagerImpl implements UserManager {
     /**
      * Initialization setup for user manager. Check if user repository contains records and if not, initialize default values.
      */
-    /*
     @EventListener(classes = {
             ContextRefreshedEvent.class
     })
@@ -40,19 +47,35 @@ public class UserManagerImpl implements UserManager {
     @Transactional
     public void setup() {
         if (this.userRepository.count() == 0) {
-            log.info("No user present, creating 'admin', 'referentka', 'prorektor'.");
-            Long idAdmin = this.addUser("admin", "admin");
-            Long idReferentka = this.addUser("referentka", "referentka");
-            Long idProrektor = this.addUser("prorektor", "prorektor");
-
-            User admin = this.userRepository.getById(idAdmin);
-            User referentka = this.userRepository.getById(idReferentka);
-            User prorektor = this.userRepository.getById(idProrektor);
-
-            //admin.setRole();
+            log.info("No user present");
+            /*
+            this.addUser("administrator", "demo", (long) 1);
+            this.addUser("fakulta", "demo", (long) 2);
+            this.addUser("referentka", "demo", (long) 3);
+            this.addUser("prorektor", "demo", (long) 4);
+             */
         }
     }
+
+    /**
+     * Load user details by his username.
+     * @param username Username of user.
+     * @return UserDetails of user.
+     * @throws UsernameNotFoundException Exception.
      */
+    @Override
+    @Transactional
+    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+        User user = this.userRepository.findByUsername(username);
+        if (user == null) {
+            throw new UsernameNotFoundException("Invalid username!");
+        }
+
+        WebCredentials credentials = new WebCredentials(user.getUsername(), user.getPassword());
+        credentials.addRole(user.getRole().getName());
+
+        return credentials;
+    }
 
     /**
      * Get all users from database.
@@ -72,8 +95,10 @@ public class UserManagerImpl implements UserManager {
      * @return ID of newly created user.
      */
     @Override
-    public Long addUser(String username, String password) {
-        User user = new User(username, password);
+    public Long addUser(String username, String password, Long roleId) {
+        String hashed = this.encoder.encode(password);
+        User user = new User(username, hashed);
+        user.setRole(this.roleRepository.getById(roleId));
         this.userRepository.save(user);
         return user.getId();
     }
diff --git a/src/main/java/vldc/aswi/service/parameter/ParameterManagerImpl.java b/src/main/java/vldc/aswi/service/parameter/ParameterManagerImpl.java
index 0abf32f4..38f33b35 100644
--- a/src/main/java/vldc/aswi/service/parameter/ParameterManagerImpl.java
+++ b/src/main/java/vldc/aswi/service/parameter/ParameterManagerImpl.java
@@ -231,28 +231,30 @@ public class ParameterManagerImpl implements ParameterManager {
      * @param parameterValuesList - List of updated parameters.
      */
     private void updateParameters(List<Parameter> parameterValuesList) {
-        for (Parameter parameterValues : parameterValuesList) {
+        for (Parameter parameterWithValues : parameterValuesList) {
+            List<ParameterValue> values = new ArrayList<>(parameterWithValues.getParameterValues());
+
             // Get current parameter from database.
-            Parameter parameter = this.parameterRepository.getById(parameterValues.getId());
+            Parameter parameter = this.parameterRepository.getById(parameterWithValues.getId());
             // Update current parameter values.
-            parameter.setName(parameterValues.getName());
-            parameter.setParameterOrder(parameterValues.getParameterOrder());
-            parameter.setNameOfSelect(parameterValues.getNameOfSelect());
-            parameter.setAssembly(this.assemblyRepository.getById(parameterValues.getAssembly().getId()));
-            parameter.setParameterType(this.parameterTypeRepository.getById(parameterValues.getParameterType().getId()));
-            parameter.setDefaultValue(parameterValues.getDefaultValue());
+            parameter.setName(parameterWithValues.getName());
+            parameter.setParameterOrder(parameterWithValues.getParameterOrder());
+            parameter.setNameOfSelect(parameterWithValues.getNameOfSelect());
+            parameter.setAssembly(this.assemblyRepository.getById(parameterWithValues.getAssembly().getId()));
+            parameter.setParameterType(this.parameterTypeRepository.getById(parameterWithValues.getParameterType().getId()));
+            parameter.setDefaultValue(parameterWithValues.getDefaultValue());
 
             // Insert changes into database.
             this.parameterRepository.save(parameter);
 
             // Update parameter values, locations, functions and operators.
-            if (parameter.getParameterType().equals("Výčet")) {
-                updateParameterValues(parameterValues.getId(), parameterValues.getParameterValues());
+            if (parameter.getParameterType().getName().equals("Výčet")) {
+                updateParameterValues(parameterWithValues.getId(), values);
             }
 
-            updateParameterLocations(parameterValues.getId(), parameterValues.getLocations());
-            updateParameterFunctions(parameterValues.getId(), parameterValues.getFunctions());
-            updateParameterOperators(parameterValues.getId(), parameterValues.getOperators());
+            updateParameterLocations(parameterWithValues.getId(), parameterWithValues.getLocations());
+            updateParameterFunctions(parameterWithValues.getId(), parameterWithValues.getFunctions());
+            updateParameterOperators(parameterWithValues.getId(), parameterWithValues.getOperators());
         }
     }
 
@@ -377,40 +379,18 @@ public class ParameterManagerImpl implements ParameterManager {
         List<ParameterValue> newParameterValuesDeleted = new LinkedList<>(newParameterValues);
         currentParameterValuesDeleted.removeAll(newParameterValuesDeleted);
 
-        // Get updated parameter values.
-        List<ParameterValue> currentParameterValuesUpdated = new LinkedList<>(currentParameterValues);
-        List<ParameterValue> newParameterValuesUpdated = new LinkedList<>(newParameterValues);
-        newParameterValuesUpdated.retainAll(currentParameterValuesUpdated);
-
         // If there is no changes, do not update.
-        if (newParameterValuesNew.size() == 0 && currentParameterValuesDeleted.size() == 0 && newParameterValuesUpdated.size() == 0) return;
+        if (newParameterValuesNew.size() == 0 && currentParameterValuesDeleted.size() == 0) return;
 
         // Delete removed parameter values.
         for (ParameterValue parameterValue : currentParameterValuesDeleted) {
             this.parameterValueRepository.delete(parameterValue);
         }
 
-        // Update parameter values.
-        updateParameterValueValues(newParameterValuesUpdated);
-
         // Add new parameter values.
         addParameterValueValues(parameterId, newParameterValuesNew);
     }
 
-    /**
-     * Update all updated parameter values.
-     * @param updatedParameterValuesList - List of all updated parameter values.
-     */
-    private void updateParameterValueValues(List<ParameterValue> updatedParameterValuesList) {
-        for (ParameterValue parameterValueValues : updatedParameterValuesList) {
-            ParameterValue parameterValue = this.parameterValueRepository.getById(parameterValueValues.getId());
-            parameterValue.setValue(parameterValueValues.getValue());
-
-            // Insert changes into database.
-            this.parameterValueRepository.save(parameterValue);
-        }
-    }
-
     /**
      * Add new parameter values.
      * @param parameterId - ID of parameter.
diff --git a/src/main/java/vldc/aswi/web/controller/LoginController.java b/src/main/java/vldc/aswi/web/controller/LoginController.java
index 27d2983b..04f14458 100644
--- a/src/main/java/vldc/aswi/web/controller/LoginController.java
+++ b/src/main/java/vldc/aswi/web/controller/LoginController.java
@@ -2,13 +2,20 @@ package vldc.aswi.web.controller;
 
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.servlet.ModelAndView;
 
 @Controller
 public class LoginController extends BasicController {
 
+	/**
+	 * Get mapping method for login page.
+	 * @return Model and view for login page.
+	 */
 	@GetMapping("/login")
-	public String login() {
-		return "login";
+	public ModelAndView login() {
+		ModelAndView modelAndView = new ModelAndView("login");
+
+		return modelAndView;
 	}
 
 }
diff --git a/src/main/webapp/WEB-INF/templates/login.html b/src/main/webapp/WEB-INF/templates/login.html
index b487fd83..cd4ffa83 100644
--- a/src/main/webapp/WEB-INF/templates/login.html
+++ b/src/main/webapp/WEB-INF/templates/login.html
@@ -19,11 +19,11 @@
 				<table>
 					<tr>
 						<td>Přihlašovací jméno:</td>
-						<td><input type="text" class="form-control"/></td>
+						<td><input type="text" name="username" id="username" class="form-control"/></td>
 					</tr>
 					<tr>
 						<td>Heslo:</td>
-						<td><input type="password" class="form-control"/></td>
+						<td><input type="password" name="password" id="password" class="form-control"/></td>
 					</tr>
 					<tr>
 						<td><button class="btn-primary btn" type="submit">Přihlásit</button></td>
