diff --git a/README.md b/README.md
index e6d4183c..bc942283 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,6 @@
# Spring Boot Web Application
-#Part 6
-##Part 5
-This repository has the project files for a tutorial series on Spring Boot available from by website at [Spring Framework Guru](https://springframework.guru)
-##Part 4
-This repository has the project files for a tutorial series on Spring Boot available from by website at [Spring Framework Guru](https://springframework.guru/spring-boot-web-application-part-4-spring-mvc/)
+##Part 6
+This repository has the project files for the post SPRING BOOT WEB APPLICATION, PART 6 – SPRING SECURITY WITH DAO Authentication Provider
+that is part of the tutorial series on Spring Boot available from by website at [Spring Framework Guru](https://springfrspringframework.guru)
-In this part of the tutorial series, I show how to setup a Spring MVC controller to suport CRUD operations, a Spring service facad over a Spring Data JPA repository, and Thymeleaf templates for the web application.
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index a54a7b54..6766bbb8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -47,17 +47,17 @@
+
org.webjars
- bootstrap
- 3.3.4
+ jquery
+ 2.1.4
org.webjars
- jquery
- 2.1.4
+ bootstrap
+ 3.3.4
-
com.h2database
h2
@@ -67,6 +67,20 @@
spring-boot-starter-test
test
+
+
+
+ org.jasypt
+ jasypt
+ 1.9.2
+
+
+
+ org.jasypt
+ jasypt-springsecurity3
+ 1.9.2
+
+
diff --git a/src/main/java/guru/springframework/bootstrap/ProductLoader.java b/src/main/java/guru/springframework/bootstrap/ProductLoader.java
deleted file mode 100644
index 0120eba2..00000000
--- a/src/main/java/guru/springframework/bootstrap/ProductLoader.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package guru.springframework.bootstrap;
-
-import guru.springframework.domain.Product;
-import guru.springframework.repositories.ProductRepository;
-import org.apache.log4j.Logger;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationListener;
-import org.springframework.context.event.ContextRefreshedEvent;
-import org.springframework.stereotype.Component;
-
-import java.math.BigDecimal;
-
-@Component
-public class ProductLoader implements ApplicationListener {
-
- private ProductRepository productRepository;
-
- private Logger log = Logger.getLogger(ProductLoader.class);
-
- @Autowired
- public void setProductRepository(ProductRepository productRepository) {
- this.productRepository = productRepository;
- }
-
- @Override
- public void onApplicationEvent(ContextRefreshedEvent event) {
-
- Product shirt = new Product();
- shirt.setDescription("Spring Framework Guru Shirt");
- shirt.setPrice(new BigDecimal("18.95"));
- shirt.setImageUrl("https://springframework.guru/wp-content/uploads/2015/04/spring_framework_guru_shirt-rf412049699c14ba5b68bb1c09182bfa2_8nax2_512.jpg");
- shirt.setProductId("235268845711068308");
- productRepository.save(shirt);
-
- log.info("Saved Shirt - id: " + shirt.getId());
-
- Product mug = new Product();
- mug.setDescription("Spring Framework Guru Mug");
- mug.setImageUrl("https://springframework.guru/wp-content/uploads/2015/04/spring_framework_guru_coffee_mug-r11e7694903c348e1a667dfd2f1474d95_x7j54_8byvr_512.jpg");
- mug.setProductId("168639393495335947");
- mug.setPrice(new BigDecimal("11.95"));
- productRepository.save(mug);
-
- log.info("Saved Mug - id:" + mug.getId());
- }
-}
diff --git a/src/main/java/guru/springframework/bootstrap/SpringJpaBootstrap.java b/src/main/java/guru/springframework/bootstrap/SpringJpaBootstrap.java
new file mode 100644
index 00000000..9de34368
--- /dev/null
+++ b/src/main/java/guru/springframework/bootstrap/SpringJpaBootstrap.java
@@ -0,0 +1,127 @@
+package guru.springframework.bootstrap;
+
+import guru.springframework.domain.Product;
+import guru.springframework.domain.Role;
+import guru.springframework.domain.User;
+import guru.springframework.repositories.ProductRepository;
+import guru.springframework.services.RoleService;
+import guru.springframework.services.UserService;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Component
+public class SpringJpaBootstrap implements ApplicationListener {
+
+ private ProductRepository productRepository;
+ private UserService userService;
+ private RoleService roleService;
+
+ private Logger log = Logger.getLogger(SpringJpaBootstrap.class);
+
+ @Autowired
+ public void setProductRepository(ProductRepository productRepository) {
+ this.productRepository = productRepository;
+ }
+
+ @Autowired
+ public void setUserService(UserService userService) {
+ this.userService = userService;
+ }
+
+ @Autowired
+ public void setRoleService(RoleService roleService) {
+ this.roleService = roleService;
+ }
+
+
+ @Override
+ public void onApplicationEvent(ContextRefreshedEvent event) {
+ loadProducts();
+ loadUsers();
+ loadRoles();
+ assignUsersToUserRole();
+ assignUsersToAdminRole();
+ }
+
+ private void loadProducts() {
+ Product shirt = new Product();
+ shirt.setDescription("Spring Framework Guru Shirt");
+ shirt.setPrice(new BigDecimal("18.95"));
+ shirt.setImageUrl("https://springframework.guru/wp-content/uploads/2015/04/spring_framework_guru_shirt-rf412049699c14ba5b68bb1c09182bfa2_8nax2_512.jpg");
+ shirt.setProductId("235268845711068308");
+ productRepository.save(shirt);
+
+ log.info("Saved Shirt - id: " + shirt.getId());
+
+ Product mug = new Product();
+ mug.setDescription("Spring Framework Guru Mug");
+ mug.setImageUrl("https://springframework.guru/wp-content/uploads/2015/04/spring_framework_guru_coffee_mug-r11e7694903c348e1a667dfd2f1474d95_x7j54_8byvr_512.jpg");
+ mug.setProductId("168639393495335947");
+ mug.setPrice(new BigDecimal("11.95"));
+ productRepository.save(mug);
+
+ log.info("Saved Mug - id:" + mug.getId());
+ }
+
+ private void loadUsers() {
+ User user1 = new User();
+ user1.setUsername("user");
+ user1.setPassword("user");
+ userService.saveOrUpdate(user1);
+
+ User user2 = new User();
+ user2.setUsername("admin");
+ user2.setPassword("admin");
+ userService.saveOrUpdate(user2);
+
+ }
+
+ private void loadRoles() {
+ Role role = new Role();
+ role.setRole("USER");
+ roleService.saveOrUpdate(role);
+ log.info("Saved role" + role.getRole());
+ Role adminRole = new Role();
+ adminRole.setRole("ADMIN");
+ roleService.saveOrUpdate(adminRole);
+ log.info("Saved role" + adminRole.getRole());
+ }
+ private void assignUsersToUserRole() {
+ List roles = (List) roleService.listAll();
+ List users = (List) userService.listAll();
+
+ roles.forEach(role -> {
+ if (role.getRole().equalsIgnoreCase("USER")) {
+ users.forEach(user -> {
+ if (user.getUsername().equals("user")) {
+ user.addRole(role);
+ userService.saveOrUpdate(user);
+ }
+ });
+ }
+ });
+ }
+ private void assignUsersToAdminRole() {
+ List roles = (List) roleService.listAll();
+ List users = (List) userService.listAll();
+
+ roles.forEach(role -> {
+ if (role.getRole().equalsIgnoreCase("ADMIN")) {
+ users.forEach(user -> {
+ if (user.getUsername().equals("admin")) {
+ user.addRole(role);
+ userService.saveOrUpdate(user);
+ }
+ });
+ }
+ });
+ }
+}
+
+
diff --git a/src/main/java/guru/springframework/config/CommonBeanConfig.java b/src/main/java/guru/springframework/config/CommonBeanConfig.java
new file mode 100644
index 00000000..8ceed08d
--- /dev/null
+++ b/src/main/java/guru/springframework/config/CommonBeanConfig.java
@@ -0,0 +1,15 @@
+package guru.springframework.config;
+
+import org.jasypt.util.password.StrongPasswordEncryptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class CommonBeanConfig {
+
+ @Bean
+ public StrongPasswordEncryptor strongEncryptor(){
+ StrongPasswordEncryptor encryptor = new StrongPasswordEncryptor();
+ return encryptor;
+ }
+}
diff --git a/src/main/java/guru/springframework/config/SpringSecConfig.java b/src/main/java/guru/springframework/config/SpringSecConfig.java
new file mode 100644
index 00000000..8e4b6057
--- /dev/null
+++ b/src/main/java/guru/springframework/config/SpringSecConfig.java
@@ -0,0 +1,67 @@
+package guru.springframework.config;
+
+import org.jasypt.springsecurity3.authentication.encoding.PasswordEncoder;
+import org.jasypt.util.password.StrongPasswordEncryptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
+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;
+
+@Configuration
+public class SpringSecConfig extends WebSecurityConfigurerAdapter {
+
+ private AuthenticationProvider authenticationProvider;
+
+ @Autowired
+ @Qualifier("daoAuthenticationProvider")
+ public void setAuthenticationProvider(AuthenticationProvider authenticationProvider) {
+ this.authenticationProvider = authenticationProvider;
+ }
+
+ @Bean
+ public PasswordEncoder passwordEncoder(StrongPasswordEncryptor passwordEncryptor){
+ PasswordEncoder passwordEncoder = new PasswordEncoder();
+ passwordEncoder.setPasswordEncryptor(passwordEncryptor);
+ return passwordEncoder;
+ }
+
+ @Bean
+ public DaoAuthenticationProvider daoAuthenticationProvider(PasswordEncoder passwordEncoder,
+ UserDetailsService userDetailsService){
+
+ DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
+ daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
+ daoAuthenticationProvider.setUserDetailsService(userDetailsService);
+ return daoAuthenticationProvider;
+ }
+
+ @Autowired
+ public void configureAuthManager(AuthenticationManagerBuilder authenticationManagerBuilder){
+ authenticationManagerBuilder.authenticationProvider(authenticationProvider);
+ }
+ @Override
+ protected void configure(HttpSecurity httpSecurity) throws Exception {
+ httpSecurity
+ .authorizeRequests().antMatchers("/","/products","/product/show/*","/console/**","/h2-console/**").permitAll()
+ .anyRequest().authenticated()
+ .and()
+ .formLogin().loginPage("/login").permitAll()
+ .and()
+ .logout().permitAll();
+
+ httpSecurity.csrf().disable();
+ httpSecurity.headers().frameOptions().disable();
+ // httpSecurity.csrf().disable();
+ // httpSecurity.headers().frameOptions().disable();
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/guru/springframework/configuration/WebConfiguration.java b/src/main/java/guru/springframework/config/WebConfig.java
similarity index 74%
rename from src/main/java/guru/springframework/configuration/WebConfiguration.java
rename to src/main/java/guru/springframework/config/WebConfig.java
index 18723229..4e7a89e3 100644
--- a/src/main/java/guru/springframework/configuration/WebConfiguration.java
+++ b/src/main/java/guru/springframework/config/WebConfig.java
@@ -1,12 +1,11 @@
-package guru.springframework.configuration;
-
+package guru.springframework.config;
import org.h2.server.web.WebServlet;
-import org.springframework.boot.web.servlet.ServletRegistrationBean;
+import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
-public class WebConfiguration {
+public class WebConfig {
@Bean
ServletRegistrationBean h2servletRegistration(){
ServletRegistrationBean registrationBean = new ServletRegistrationBean( new WebServlet());
diff --git a/src/main/java/guru/springframework/configuration/SecurityConfiguration.java b/src/main/java/guru/springframework/configuration/SecurityConfiguration.java
deleted file mode 100644
index 136b8c6f..00000000
--- a/src/main/java/guru/springframework/configuration/SecurityConfiguration.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package guru.springframework.configuration;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Configuration;
-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.WebSecurityConfigurerAdapter;
-
-@Configuration
-public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
-
- @Override
- protected void configure(HttpSecurity httpSecurity) throws Exception {
- httpSecurity
- .authorizeRequests().antMatchers("/","/products","/product/show/*","/console/**").permitAll()
- .anyRequest().authenticated()
- .and()
- .formLogin().loginPage("/login").permitAll()
- .and()
- .logout().permitAll();
-
- httpSecurity.csrf().disable();
- httpSecurity.headers().frameOptions().disable();
- }
- @Autowired
- public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
- auth
- .inMemoryAuthentication()
- .withUser("admin").password("admin").roles("ADMIN")
- .and().withUser("user").password("user").roles("USER");;
- }
-
-}
\ No newline at end of file
diff --git a/src/main/java/guru/springframework/converters/UserToUserDetails.java b/src/main/java/guru/springframework/converters/UserToUserDetails.java
new file mode 100644
index 00000000..2bfa6c90
--- /dev/null
+++ b/src/main/java/guru/springframework/converters/UserToUserDetails.java
@@ -0,0 +1,31 @@
+package guru.springframework.converters;
+
+import guru.springframework.domain.User;
+import guru.springframework.services.security.UserDetailsImpl;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Component;
+import java.util.ArrayList;
+import java.util.Collection;
+
+@Component
+public class UserToUserDetails implements Converter {
+ @Override
+ public UserDetails convert(User user) {
+ UserDetailsImpl userDetails = new UserDetailsImpl();
+
+ if (user != null) {
+ userDetails.setUsername(user.getUsername());
+ userDetails.setPassword(user.getEncryptedPassword());
+ userDetails.setEnabled(user.getEnabled());
+ Collection authorities = new ArrayList<>();
+ user.getRoles().forEach(role -> {
+ authorities.add(new SimpleGrantedAuthority(role.getRole()));
+ });
+ userDetails.setAuthorities(authorities);
+ }
+
+ return userDetails;
+ }
+}
diff --git a/src/main/java/guru/springframework/domain/AbstractDomainClass.java b/src/main/java/guru/springframework/domain/AbstractDomainClass.java
new file mode 100644
index 00000000..2497cb1d
--- /dev/null
+++ b/src/main/java/guru/springframework/domain/AbstractDomainClass.java
@@ -0,0 +1,56 @@
+package guru.springframework.domain;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * Created by jt on 12/16/15.
+ */
+@MappedSuperclass
+public class AbstractDomainClass implements DomainObject {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ Integer id;
+
+ @Version
+ private Integer version;
+
+ private Date dateCreated;
+ private Date lastUpdated;
+
+ @Override
+ public Integer getId() {
+ return this.id;
+ }
+
+ @Override
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public Integer getVersion() {
+ return version;
+ }
+
+ public void setVersion(Integer version) {
+ this.version = version;
+ }
+
+ public Date getDateCreated() {
+ return dateCreated;
+ }
+
+ public Date getLastUpdated() {
+ return lastUpdated;
+ }
+
+ @PreUpdate
+ @PrePersist
+ public void updateTimeStamps() {
+ lastUpdated = new Date();
+ if (dateCreated==null) {
+ dateCreated = new Date();
+ }
+ }
+}
diff --git a/src/main/java/guru/springframework/domain/DomainObject.java b/src/main/java/guru/springframework/domain/DomainObject.java
new file mode 100644
index 00000000..5744c4e7
--- /dev/null
+++ b/src/main/java/guru/springframework/domain/DomainObject.java
@@ -0,0 +1,11 @@
+package guru.springframework.domain;
+
+/**
+ * Created by jt on 11/14/15.
+ */
+public interface DomainObject {
+
+ Integer getId();
+
+ void setId(Integer id);
+}
diff --git a/src/main/java/guru/springframework/domain/Role.java b/src/main/java/guru/springframework/domain/Role.java
new file mode 100644
index 00000000..b3aa107b
--- /dev/null
+++ b/src/main/java/guru/springframework/domain/Role.java
@@ -0,0 +1,57 @@
+package guru.springframework.domain;
+
+import guru.springframework.domain.AbstractDomainClass;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by jt on 12/18/15.
+ */
+@Entity
+public class Role extends AbstractDomainClass {
+
+ private String role;
+
+ @ManyToMany(fetch = FetchType.EAGER)
+ @JoinTable
+ // ~ defaults to @JoinTable(name = "USER_ROLE", joinColumns = @JoinColumn(name = "role_id"),
+ // inverseJoinColumns = @joinColumn(name = "user_id"))
+ private List users = new ArrayList<>();
+
+ public String getRole() {
+ return role;
+ }
+
+ public void setRole(String role) {
+ this.role = role;
+ }
+
+ public List getUsers() {
+ return users;
+ }
+
+ public void setUsers(List users) {
+ this.users = users;
+ }
+
+ public void addUser(User user){
+ if(!this.users.contains(user)){
+ this.users.add(user);
+ }
+
+ if(!user.getRoles().contains(this)){
+ user.getRoles().add(this);
+ }
+ }
+
+ public void removeUser(User user){
+ this.users.remove(user);
+ user.getRoles().remove(this);
+ }
+
+}
diff --git a/src/main/java/guru/springframework/domain/User.java b/src/main/java/guru/springframework/domain/User.java
new file mode 100644
index 00000000..cb32755e
--- /dev/null
+++ b/src/main/java/guru/springframework/domain/User.java
@@ -0,0 +1,91 @@
+package guru.springframework.domain;
+
+import javax.persistence.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by jt on 12/14/15.
+ */
+@Entity
+public class User extends AbstractDomainClass {
+
+ private String username;
+
+ @Transient
+ private String password;
+
+ private String encryptedPassword;
+ private Boolean enabled = true;
+
+ @ManyToMany(fetch = FetchType.EAGER)
+ @JoinTable
+ // ~ defaults to @JoinTable(name = "USER_ROLE", joinColumns = @JoinColumn(name = "user_id"),
+ // inverseJoinColumns = @joinColumn(name = "role_id"))
+ private List roles = new ArrayList<>();
+ private Integer failedLoginAttempts = 0;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getEncryptedPassword() {
+ return encryptedPassword;
+ }
+
+ public void setEncryptedPassword(String encryptedPassword) {
+ this.encryptedPassword = encryptedPassword;
+ }
+
+ public Boolean getEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(Boolean enabled) {
+ this.enabled = enabled;
+ }
+
+
+ public List getRoles() {
+ return roles;
+ }
+
+ public void setRoles(List roles) {
+ this.roles = roles;
+ }
+
+ public void addRole(Role role){
+ if(!this.roles.contains(role)){
+ this.roles.add(role);
+ }
+
+ if(!role.getUsers().contains(this)){
+ role.getUsers().add(this);
+ }
+ }
+
+ public void removeRole(Role role){
+ this.roles.remove(role);
+ role.getUsers().remove(this);
+ }
+
+ public Integer getFailedLoginAttempts() {
+ return failedLoginAttempts;
+ }
+
+ public void setFailedLoginAttempts(Integer failedLoginAttempts) {
+ this.failedLoginAttempts = failedLoginAttempts;
+ }
+}
diff --git a/src/main/java/guru/springframework/repositories/RoleRepository.java b/src/main/java/guru/springframework/repositories/RoleRepository.java
new file mode 100644
index 00000000..771382e5
--- /dev/null
+++ b/src/main/java/guru/springframework/repositories/RoleRepository.java
@@ -0,0 +1,7 @@
+package guru.springframework.repositories;
+
+import guru.springframework.domain.Role;
+import org.springframework.data.repository.CrudRepository;
+
+public interface RoleRepository extends CrudRepository{
+}
diff --git a/src/main/java/guru/springframework/repositories/UserRepository.java b/src/main/java/guru/springframework/repositories/UserRepository.java
new file mode 100644
index 00000000..50cc69df
--- /dev/null
+++ b/src/main/java/guru/springframework/repositories/UserRepository.java
@@ -0,0 +1,8 @@
+package guru.springframework.repositories;
+
+import guru.springframework.domain.User;
+import org.springframework.data.repository.CrudRepository;
+
+public interface UserRepository extends CrudRepository{
+ User findByUsername(String username);
+}
diff --git a/src/main/java/guru/springframework/services/CRUDService.java b/src/main/java/guru/springframework/services/CRUDService.java
new file mode 100644
index 00000000..95ba2cea
--- /dev/null
+++ b/src/main/java/guru/springframework/services/CRUDService.java
@@ -0,0 +1,13 @@
+package guru.springframework.services;
+
+import java.util.List;
+
+public interface CRUDService {
+ List> listAll();
+
+ T getById(Integer id);
+
+ T saveOrUpdate(T domainObject);
+
+ void delete(Integer id);
+}
diff --git a/src/main/java/guru/springframework/services/RoleService.java b/src/main/java/guru/springframework/services/RoleService.java
new file mode 100644
index 00000000..e6e1ecc7
--- /dev/null
+++ b/src/main/java/guru/springframework/services/RoleService.java
@@ -0,0 +1,6 @@
+package guru.springframework.services;
+
+import guru.springframework.domain.Role;
+
+public interface RoleService extends CRUDService {
+}
diff --git a/src/main/java/guru/springframework/services/RoleServiceImpl.java b/src/main/java/guru/springframework/services/RoleServiceImpl.java
new file mode 100644
index 00000000..4e199ba8
--- /dev/null
+++ b/src/main/java/guru/springframework/services/RoleServiceImpl.java
@@ -0,0 +1,45 @@
+package guru.springframework.services;
+
+import guru.springframework.domain.Role;
+import guru.springframework.repositories.RoleRepository;
+import guru.springframework.services.RoleService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+@Profile("springdatajpa")
+public class RoleServiceImpl implements RoleService {
+
+ private RoleRepository roleRepository;
+
+ @Autowired
+ public void setRoleRepository(RoleRepository roleRepository) {
+ this.roleRepository = roleRepository;
+ }
+
+ @Override
+ public List> listAll() {
+ List roles = new ArrayList<>();
+ roleRepository.findAll().forEach(roles::add);
+ return roles;
+ }
+
+ @Override
+ public Role getById(Integer id) {
+ return roleRepository.findOne(id);
+ }
+
+ @Override
+ public Role saveOrUpdate(Role domainObject) {
+ return roleRepository.save(domainObject);
+ }
+
+ @Override
+ public void delete(Integer id) {
+ roleRepository.delete(id);
+ }
+}
diff --git a/src/main/java/guru/springframework/services/UserService.java b/src/main/java/guru/springframework/services/UserService.java
new file mode 100644
index 00000000..f501e923
--- /dev/null
+++ b/src/main/java/guru/springframework/services/UserService.java
@@ -0,0 +1,9 @@
+package guru.springframework.services;
+
+import guru.springframework.domain.User;
+
+public interface UserService extends CRUDService {
+
+ User findByUsername(String username);
+
+}
diff --git a/src/main/java/guru/springframework/services/UserServiceImpl.java b/src/main/java/guru/springframework/services/UserServiceImpl.java
new file mode 100644
index 00000000..14ebc46d
--- /dev/null
+++ b/src/main/java/guru/springframework/services/UserServiceImpl.java
@@ -0,0 +1,64 @@
+package guru.springframework.services;
+
+import guru.springframework.domain.User;
+
+import guru.springframework.repositories.UserRepository;
+import guru.springframework.services.UserService;
+import guru.springframework.services.security.EncryptionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+@Profile("springdatajpa")
+public class UserServiceImpl implements UserService {
+
+ private UserRepository userRepository;
+
+ @Autowired
+ public void setUserRepository(UserRepository userRepository) {
+ this.userRepository = userRepository;
+ }
+
+ private EncryptionService encryptionService;
+
+ @Autowired
+ public void setEncryptionService(EncryptionService encryptionService) {
+ this.encryptionService = encryptionService;
+ }
+
+
+ @Override
+ public List> listAll() {
+ List users = new ArrayList<>();
+ userRepository.findAll().forEach(users::add); //fun with Java 8
+ return users;
+ }
+
+ @Override
+ public User getById(Integer id) {
+ return userRepository.findOne(id);
+ }
+
+ @Override
+ public User saveOrUpdate(User domainObject) {
+ if(domainObject.getPassword() != null){
+ domainObject.setEncryptedPassword(encryptionService.encryptString(domainObject.getPassword()));
+ }
+ return userRepository.save(domainObject);
+ }
+ @Override
+ @Transactional
+ public void delete(Integer id) {
+ userRepository.delete(id);
+ }
+
+ @Override
+ public User findByUsername(String username) {
+ return userRepository.findByUsername(username);
+ }
+}
diff --git a/src/main/java/guru/springframework/services/jpaservices/AbstractJpaDaoService.java b/src/main/java/guru/springframework/services/jpaservices/AbstractJpaDaoService.java
new file mode 100644
index 00000000..e5396554
--- /dev/null
+++ b/src/main/java/guru/springframework/services/jpaservices/AbstractJpaDaoService.java
@@ -0,0 +1,17 @@
+package guru.springframework.services.jpaservices;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceUnit;
+
+/**
+ * Created by jt on 12/14/15.
+ */
+public class AbstractJpaDaoService {
+
+ protected EntityManagerFactory emf;
+
+ @PersistenceUnit
+ public void setEmf(EntityManagerFactory emf) {
+ this.emf = emf;
+ }
+}
diff --git a/src/main/java/guru/springframework/services/jpaservices/RoleServiceJpaImpl.java b/src/main/java/guru/springframework/services/jpaservices/RoleServiceJpaImpl.java
new file mode 100644
index 00000000..1a853bcc
--- /dev/null
+++ b/src/main/java/guru/springframework/services/jpaservices/RoleServiceJpaImpl.java
@@ -0,0 +1,51 @@
+package guru.springframework.services.jpaservices;
+
+import guru.springframework.domain.Role;
+import guru.springframework.services.RoleService;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.EntityManager;
+import java.util.List;
+
+/**
+ * Created by jt on 12/18/15.
+ */
+@Service
+@Profile("jpadao")
+public class RoleServiceJpaImpl extends AbstractJpaDaoService implements RoleService {
+
+ @Override
+ public List> listAll() {
+ EntityManager em = emf.createEntityManager();
+
+ return em.createQuery("from Role", Role.class).getResultList();
+ }
+
+ @Override
+ public Role getById(Integer id) {
+ EntityManager em = emf.createEntityManager();
+ return em.find(Role.class, id);
+ }
+
+ @Override
+ public Role saveOrUpdate(Role domainObject) {
+ EntityManager em = emf.createEntityManager();
+
+ em.getTransaction().begin();
+
+ Role saveRole = em.merge(domainObject);
+ em.getTransaction().commit();
+
+ return saveRole;
+ }
+
+ @Override
+ public void delete(Integer id) {
+ EntityManager em = emf.createEntityManager();
+
+ em.getTransaction().begin();
+ em.remove(em.find(Role.class, id));
+ em.getTransaction().commit();
+ }
+}
diff --git a/src/main/java/guru/springframework/services/jpaservices/UserServiceJpaDaoImpl.java b/src/main/java/guru/springframework/services/jpaservices/UserServiceJpaDaoImpl.java
new file mode 100644
index 00000000..a6d3b761
--- /dev/null
+++ b/src/main/java/guru/springframework/services/jpaservices/UserServiceJpaDaoImpl.java
@@ -0,0 +1,72 @@
+package guru.springframework.services.jpaservices;
+
+import guru.springframework.domain.User;
+import guru.springframework.services.UserService;
+import guru.springframework.services.security.EncryptionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
+
+import javax.persistence.EntityManager;
+import java.util.List;
+
+/**
+ * Created by jt on 12/14/15.
+ */
+@Service
+@Profile("jpadao")
+public class UserServiceJpaDaoImpl extends AbstractJpaDaoService implements UserService {
+
+ private EncryptionService encryptionService;
+
+ @Autowired
+ public void setEncryptionService(EncryptionService encryptionService) {
+ this.encryptionService = encryptionService;
+ }
+
+ @Override
+ public List> listAll() {
+ EntityManager em = emf.createEntityManager();
+
+ return em.createQuery("from User", User.class).getResultList();
+ }
+
+ @Override
+ public User getById(Integer id) {
+ EntityManager em = emf.createEntityManager();
+
+ return em.find(User.class, id);
+ }
+
+ @Override
+ public User saveOrUpdate(User domainObject) {
+ EntityManager em = emf.createEntityManager();
+
+ em.getTransaction().begin();
+
+ if(domainObject.getPassword() != null){
+ domainObject.setEncryptedPassword(encryptionService.encryptString(domainObject.getPassword()));
+ }
+
+ User saveduser = em.merge(domainObject);
+ em.getTransaction().commit();
+
+ return saveduser;
+ }
+
+ @Override
+ public void delete(Integer id) {
+ EntityManager em = emf.createEntityManager();
+
+ em.getTransaction().begin();
+ em.remove(em.find(User.class, id));
+ em.getTransaction().commit();
+ }
+
+ @Override
+ public User findByUsername(String userName) {
+ EntityManager em = emf.createEntityManager();
+
+ return em.createQuery("from User where userName = :userName", User.class).setParameter("userName", userName).getSingleResult();
+ }
+}
diff --git a/src/main/java/guru/springframework/services/mapservices/AbstractMapService.java b/src/main/java/guru/springframework/services/mapservices/AbstractMapService.java
new file mode 100644
index 00000000..5a4832c7
--- /dev/null
+++ b/src/main/java/guru/springframework/services/mapservices/AbstractMapService.java
@@ -0,0 +1,47 @@
+package guru.springframework.services.mapservices;
+
+import guru.springframework.domain.DomainObject;
+
+import java.util.*;
+
+/**
+ * Created by jt on 11/14/15.
+ */
+public abstract class AbstractMapService {
+ protected Map domainMap;
+
+ public AbstractMapService() {
+ domainMap = new HashMap<>();
+ }
+
+ public List listAll() {
+ return new ArrayList<>(domainMap.values());
+ }
+
+ public DomainObject getById(Integer id) {
+ return domainMap.get(id);
+ }
+
+ public DomainObject saveOrUpdate(DomainObject domainObject) {
+ if (domainObject != null){
+
+ if (domainObject.getId() == null){
+ domainObject.setId(getNextKey());
+ }
+ domainMap.put(domainObject.getId(), domainObject);
+
+ return domainObject;
+ } else {
+ throw new RuntimeException("Object Can't be null");
+ }
+ }
+
+ public void delete(Integer id) {
+ domainMap.remove(id);
+ }
+
+ private Integer getNextKey(){
+ return Collections.max(domainMap.keySet()) + 1;
+ }
+
+}
diff --git a/src/main/java/guru/springframework/services/mapservices/RoleServiceMapImpl.java b/src/main/java/guru/springframework/services/mapservices/RoleServiceMapImpl.java
new file mode 100644
index 00000000..2260c649
--- /dev/null
+++ b/src/main/java/guru/springframework/services/mapservices/RoleServiceMapImpl.java
@@ -0,0 +1,12 @@
+package guru.springframework.services.mapservices;
+
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
+
+/**
+ * Created by jt on 12/18/15.
+ */
+@Service
+@Profile("map")
+public class RoleServiceMapImpl extends AbstractMapService {
+}
diff --git a/src/main/java/guru/springframework/services/mapservices/UserServiceMapImpl.java b/src/main/java/guru/springframework/services/mapservices/UserServiceMapImpl.java
new file mode 100644
index 00000000..c78f4a5a
--- /dev/null
+++ b/src/main/java/guru/springframework/services/mapservices/UserServiceMapImpl.java
@@ -0,0 +1,67 @@
+package guru.springframework.services.mapservices;
+
+import guru.springframework.domain.DomainObject;
+import guru.springframework.domain.User;
+import guru.springframework.services.UserService;
+import guru.springframework.services.security.EncryptionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Predicate;
+
+/**
+ * Created by jt on 12/14/15.
+ */
+@Service
+@Profile("map")
+public class UserServiceMapImpl extends AbstractMapService implements UserService {
+
+ private EncryptionService encryptionService;
+
+ @Autowired
+ public void setEncryptionService(EncryptionService encryptionService) {
+ this.encryptionService = encryptionService;
+ }
+
+ @Override
+ public List listAll() {
+ return super.listAll();
+ }
+
+ @Override
+ public User getById(Integer id) {
+ return (User) super.getById(id);
+ }
+
+ @Override
+ public User saveOrUpdate(User domainObject) {
+
+ if(domainObject.getPassword() != null){
+ domainObject.setEncryptedPassword(encryptionService.encryptString(domainObject.getPassword()));
+ }
+
+ return (User) super.saveOrUpdate(domainObject);
+ }
+
+ @Override
+ public void delete(Integer id) {
+ super.delete(id);
+ }
+
+ @Override
+ public User findByUsername(String userName) {
+
+ Optional returnUser = domainMap.values().stream().filter(new Predicate() {
+ @Override
+ public boolean test(DomainObject domainObject) {
+ User user = (User) domainObject;
+ return user.getUsername().equalsIgnoreCase(userName);
+ }
+ }).findFirst();
+
+ return (User) returnUser.get();
+ }
+}
diff --git a/src/main/java/guru/springframework/services/security/EncryptionService.java b/src/main/java/guru/springframework/services/security/EncryptionService.java
new file mode 100644
index 00000000..d24444ad
--- /dev/null
+++ b/src/main/java/guru/springframework/services/security/EncryptionService.java
@@ -0,0 +1,6 @@
+package guru.springframework.services.security;
+
+public interface EncryptionService {
+ String encryptString(String input);
+ boolean checkPassword(String plainPassword, String encryptedPassword);
+}
diff --git a/src/main/java/guru/springframework/services/security/EncryptionServiceImpl.java b/src/main/java/guru/springframework/services/security/EncryptionServiceImpl.java
new file mode 100644
index 00000000..5802596c
--- /dev/null
+++ b/src/main/java/guru/springframework/services/security/EncryptionServiceImpl.java
@@ -0,0 +1,24 @@
+package guru.springframework.services.security;
+
+import org.jasypt.util.password.StrongPasswordEncryptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class EncryptionServiceImpl implements EncryptionService {
+
+ private StrongPasswordEncryptor strongEncryptor;
+
+ @Autowired
+ public void setStrongEncryptor(StrongPasswordEncryptor strongEncryptor) {
+ this.strongEncryptor = strongEncryptor;
+ }
+
+ public String encryptString(String input){
+ return strongEncryptor.encryptPassword(input);
+ }
+
+ public boolean checkPassword(String plainPassword, String encryptedPassword){
+ return strongEncryptor.checkPassword(plainPassword, encryptedPassword);
+ }
+}
diff --git a/src/main/java/guru/springframework/services/security/UserDetailsImpl.java b/src/main/java/guru/springframework/services/security/UserDetailsImpl.java
new file mode 100644
index 00000000..aa54fd3a
--- /dev/null
+++ b/src/main/java/guru/springframework/services/security/UserDetailsImpl.java
@@ -0,0 +1,68 @@
+package guru.springframework.services.security;
+
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import java.util.Collection;
+
+
+public class UserDetailsImpl implements UserDetails {
+
+ private Collection authorities;
+ private String username;
+ private String password;
+ private Boolean enabled = true;
+
+ public void setAuthorities(Collection authorities) {
+ this.authorities = authorities;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public void setEnabled(Boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ @Override
+ public Collection extends GrantedAuthority> getAuthorities() {
+ return authorities;
+ }
+
+ @Override
+ public String getPassword() {
+ return password;
+ }
+
+ @Override
+ public String getUsername() {
+ return username;
+ }
+
+ @Override
+ public boolean isAccountNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isAccountNonLocked() {
+ return true;
+ }
+
+ @Override
+ public boolean isCredentialsNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+
+}
diff --git a/src/main/java/guru/springframework/services/security/UserDetailsServiceImpl.java b/src/main/java/guru/springframework/services/security/UserDetailsServiceImpl.java
new file mode 100644
index 00000000..d178a87b
--- /dev/null
+++ b/src/main/java/guru/springframework/services/security/UserDetailsServiceImpl.java
@@ -0,0 +1,34 @@
+package guru.springframework.services.security;
+
+import guru.springframework.domain.User;
+import guru.springframework.services.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.core.convert.converter.Converter;
+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;
+
+@Service("userDetailsService")
+public class UserDetailsServiceImpl implements UserDetailsService {
+
+ private UserService userService;
+ private Converter userUserDetailsConverter;
+
+ @Autowired
+ public void setUserService(UserService userService) {
+ this.userService = userService;
+ }
+
+ @Autowired
+ @Qualifier(value = "userToUserDetails")
+ public void setUserUserDetailsConverter(Converter userUserDetailsConverter) {
+ this.userUserDetailsConverter = userUserDetailsConverter;
+ }
+
+ @Override
+ public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+ return userUserDetailsConverter.convert(userService.findByUsername(username));
+ }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 8681379f..e367db1f 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1 +1 @@
-#logging.level.org.h2.server: DEBUG
+spring.profiles.active=springdatajpa
diff --git a/src/main/resources/templates/fragments/header.html b/src/main/resources/templates/fragments/header.html
index 859c36f2..77dea2e2 100644
--- a/src/main/resources/templates/fragments/header.html
+++ b/src/main/resources/templates/fragments/header.html
@@ -13,7 +13,7 @@
Home
diff --git a/src/main/resources/templates/fragments/headerinc.html b/src/main/resources/templates/fragments/headerinc.html
index 57b18037..521863d9 100644
--- a/src/main/resources/templates/fragments/headerinc.html
+++ b/src/main/resources/templates/fragments/headerinc.html
@@ -2,13 +2,12 @@
-
-
-
+
+
diff --git a/src/main/resources/templates/products.html b/src/main/resources/templates/products.html
index 0045dfd3..2e20e6b5 100644
--- a/src/main/resources/templates/products.html
+++ b/src/main/resources/templates/products.html
@@ -17,7 +17,9 @@
Product Listing
-
+
+
+
@@ -27,18 +29,18 @@
Product Id |
Description |
Price |
- View |
- Edit |
- Delete |
+ View |
+ Edit |
+ Delete |
Id |
Product Id |
descirption |
price |
- View |
- Edit |
- Delete |
+ View |
+ Edit |
+ Delete |
diff --git a/src/main/resources/templates/productshow.html b/src/main/resources/templates/productshow.html
index 4a3895c1..b6725a93 100644
--- a/src/main/resources/templates/productshow.html
+++ b/src/main/resources/templates/productshow.html
@@ -14,9 +14,10 @@