From 74600740eb8ed04a23cc5ffdd8e586d1c3e3fd43 Mon Sep 17 00:00:00 2001 From: L_DelOff <51275636+LDelOff@users.noreply.github.com> Date: Wed, 1 Mar 2023 23:45:18 +0300 Subject: [PATCH 1/9] =?UTF-8?q?=D0=98=D0=BD=D0=B8=D1=82=20=D1=81=D0=BA?= =?UTF-8?q?=D1=80=D0=B8=D0=BF=D1=82=D1=8B=20=D0=B4=D0=BB=D1=8F=20mysql?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/db/scripts/changelog-master.xml | 9 +++++++++ .../db/scripts/release_0_0_1/changelog.xml | 10 ++++++++++ .../release_0_0_1/scripts/01_create_table_users.sql | 13 +++++++++++++ .../release_0_0_1/scripts/02_create_table_roles.sql | 13 +++++++++++++ 4 files changed, 45 insertions(+) create mode 100644 src/main/resources/db/scripts/changelog-master.xml create mode 100644 src/main/resources/db/scripts/release_0_0_1/changelog.xml create mode 100644 src/main/resources/db/scripts/release_0_0_1/scripts/01_create_table_users.sql create mode 100644 src/main/resources/db/scripts/release_0_0_1/scripts/02_create_table_roles.sql diff --git a/src/main/resources/db/scripts/changelog-master.xml b/src/main/resources/db/scripts/changelog-master.xml new file mode 100644 index 0000000..1614c28 --- /dev/null +++ b/src/main/resources/db/scripts/changelog-master.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/src/main/resources/db/scripts/release_0_0_1/changelog.xml b/src/main/resources/db/scripts/release_0_0_1/changelog.xml new file mode 100644 index 0000000..a86ce26 --- /dev/null +++ b/src/main/resources/db/scripts/release_0_0_1/changelog.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/src/main/resources/db/scripts/release_0_0_1/scripts/01_create_table_users.sql b/src/main/resources/db/scripts/release_0_0_1/scripts/01_create_table_users.sql new file mode 100644 index 0000000..c1b9e5a --- /dev/null +++ b/src/main/resources/db/scripts/release_0_0_1/scripts/01_create_table_users.sql @@ -0,0 +1,13 @@ +-- liquibase formatted sql + +-- changeset L_DelOff:create_table_users rollbackSplitStatements:true +-- comment: Создание таблицы с пользователями + +CREATE TABLE USERS +( + ID VARCHAR(36) PRIMARY KEY COMMENT 'Идентификатор', + USERNAME VARCHAR(64) UNIQUE COMMENT 'Имя пользователя', + PASSWORD VARCHAR(36) COMMENT 'Пароль' +); + +-- rollback DROP TABLE USERS; \ No newline at end of file diff --git a/src/main/resources/db/scripts/release_0_0_1/scripts/02_create_table_roles.sql b/src/main/resources/db/scripts/release_0_0_1/scripts/02_create_table_roles.sql new file mode 100644 index 0000000..0bee998 --- /dev/null +++ b/src/main/resources/db/scripts/release_0_0_1/scripts/02_create_table_roles.sql @@ -0,0 +1,13 @@ +-- liquibase formatted sql + +-- changeset L_DelOff:create_table_roles rollbackSplitStatements:true +-- comment: Создание таблицы с ролями + +CREATE TABLE ROLES +( + ID VARCHAR(36) PRIMARY KEY COMMENT 'Идентификатор роли', + NAME VARCHAR(64) UNIQUE COMMENT 'Имя роли' +); + + +-- rollback DROP TABLE ROLES; \ No newline at end of file From 9eebb2bfff2655e4cf3857ef67b2977cd61cbd8e Mon Sep 17 00:00:00 2001 From: L_DelOff <51275636+LDelOff@users.noreply.github.com> Date: Wed, 1 Mar 2023 23:46:16 +0300 Subject: [PATCH 2/9] =?UTF-8?q?Security=20=D1=88=D0=B0=D0=B1=D0=BB=D0=BE?= =?UTF-8?q?=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 64 +++++++++++++++++++ src/main/java/ru/ldeloff/Main.java | 7 -- .../java/ru/ldeloff/hedgehogcloud/Main.java | 11 ++++ .../AuthenticationSuccessUserHandler.java | 25 ++++++++ .../hedgehogcloud/config/MvcConfig.java | 13 ++++ .../config/WebSecurityConfig.java | 61 ++++++++++++++++++ .../controller/LoginController.java | 13 ++++ .../hedgehogcloud/entity/RoleEntity.java | 31 +++++++++ .../hedgehogcloud/entity/UserEntity.java | 63 ++++++++++++++++++ .../repository/RoleRepository.java | 7 ++ .../repository/UserRepository.java | 8 +++ .../hedgehogcloud/service/UserService.java | 38 +++++++++++ src/main/resources/application.yml | 14 ++++ src/main/resources/templates/login.html | 26 ++++++++ 14 files changed, 374 insertions(+), 7 deletions(-) delete mode 100644 src/main/java/ru/ldeloff/Main.java create mode 100644 src/main/java/ru/ldeloff/hedgehogcloud/Main.java create mode 100644 src/main/java/ru/ldeloff/hedgehogcloud/config/AuthenticationSuccessUserHandler.java create mode 100644 src/main/java/ru/ldeloff/hedgehogcloud/config/MvcConfig.java create mode 100644 src/main/java/ru/ldeloff/hedgehogcloud/config/WebSecurityConfig.java create mode 100644 src/main/java/ru/ldeloff/hedgehogcloud/controller/LoginController.java create mode 100644 src/main/java/ru/ldeloff/hedgehogcloud/entity/RoleEntity.java create mode 100644 src/main/java/ru/ldeloff/hedgehogcloud/entity/UserEntity.java create mode 100644 src/main/java/ru/ldeloff/hedgehogcloud/repository/RoleRepository.java create mode 100644 src/main/java/ru/ldeloff/hedgehogcloud/repository/UserRepository.java create mode 100644 src/main/java/ru/ldeloff/hedgehogcloud/service/UserService.java create mode 100644 src/main/resources/application.yml create mode 100644 src/main/resources/templates/login.html diff --git a/pom.xml b/pom.xml index 7a4a000..4c7f6ec 100644 --- a/pom.xml +++ b/pom.xml @@ -8,9 +8,73 @@ HedgeHogCloud 1.0-SNAPSHOT + + org.springframework.boot + spring-boot-starter-parent + 2.6.2 + + 17 17 + 17 + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security + spring-security-test + test + + + mysql + mysql-connector-java + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.projectlombok + lombok + 1.18.26 + provided + + + + org.liquibase + liquibase-core + 4.19.0 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${project.parent.version} + + + + \ No newline at end of file diff --git a/src/main/java/ru/ldeloff/Main.java b/src/main/java/ru/ldeloff/Main.java deleted file mode 100644 index 7620479..0000000 --- a/src/main/java/ru/ldeloff/Main.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.ldeloff; - -public class Main { - public static void main(String[] args) { - System.out.println("Hello world!"); - } -} \ No newline at end of file diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/Main.java b/src/main/java/ru/ldeloff/hedgehogcloud/Main.java new file mode 100644 index 0000000..682f8e1 --- /dev/null +++ b/src/main/java/ru/ldeloff/hedgehogcloud/Main.java @@ -0,0 +1,11 @@ +package ru.ldeloff.hedgehogcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Main { + public static void main(String[] args) { + SpringApplication.run(Main.class,args); + } +} \ No newline at end of file diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/config/AuthenticationSuccessUserHandler.java b/src/main/java/ru/ldeloff/hedgehogcloud/config/AuthenticationSuccessUserHandler.java new file mode 100644 index 0000000..74e28cd --- /dev/null +++ b/src/main/java/ru/ldeloff/hedgehogcloud/config/AuthenticationSuccessUserHandler.java @@ -0,0 +1,25 @@ +package ru.ldeloff.hedgehogcloud.config; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.springframework.stereotype.Component; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Set; + +@Component +public class AuthenticationSuccessUserHandler implements AuthenticationSuccessHandler { + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { + Set roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities()); + if (roles.contains("ROLE_ADMIN")) { + response.sendRedirect("/admin"); + } else { + response.sendRedirect("/user"); + } + } +} diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/config/MvcConfig.java b/src/main/java/ru/ldeloff/hedgehogcloud/config/MvcConfig.java new file mode 100644 index 0000000..8160a3c --- /dev/null +++ b/src/main/java/ru/ldeloff/hedgehogcloud/config/MvcConfig.java @@ -0,0 +1,13 @@ +package ru.ldeloff.hedgehogcloud.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class MvcConfig implements WebMvcConfigurer { + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/login").setViewName("login"); + } +} diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/config/WebSecurityConfig.java b/src/main/java/ru/ldeloff/hedgehogcloud/config/WebSecurityConfig.java new file mode 100644 index 0000000..fbfe448 --- /dev/null +++ b/src/main/java/ru/ldeloff/hedgehogcloud/config/WebSecurityConfig.java @@ -0,0 +1,61 @@ +package ru.ldeloff.hedgehogcloud.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +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.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.NoOpPasswordEncoder; +import ru.ldeloff.hedgehogcloud.service.UserService; + + +@Configuration +@EnableWebSecurity +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + UserService userService; + AuthenticationSuccessUserHandler authenticationSuccessUserHandler; + + public WebSecurityConfig(UserService userService, AuthenticationSuccessUserHandler authenticationSuccessUserHandler) { + this.userService = userService; + this.authenticationSuccessUserHandler = authenticationSuccessUserHandler; + } + + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.formLogin() + // указываем страницу с формой логина + .loginPage("/login") + //указываем логику обработки при логине + .successHandler(authenticationSuccessUserHandler) + // указываем action с формы логина + .loginProcessingUrl("/login") + // указываем параметры логина и пароля с формы логина + .usernameParameter("j_username") + .passwordParameter("j_password") + // даем доступ к форме логина всем + .permitAll(); + http + // делаем страницу регистрации недоступной для авторизированных пользователей + .authorizeRequests() + //страницы аутентификации доступна всем + .antMatchers("/login").anonymous() + .antMatchers("/").authenticated() + // защищенные URL + .antMatchers("/admin/**").access("hasAnyRole('ROLE_ADMIN')") + .antMatchers("/user").permitAll() + .and().formLogin(); + } + + @Autowired + protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(userService).passwordEncoder(NoOpPasswordEncoder.getInstance()); + } +} diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/controller/LoginController.java b/src/main/java/ru/ldeloff/hedgehogcloud/controller/LoginController.java new file mode 100644 index 0000000..ba5629c --- /dev/null +++ b/src/main/java/ru/ldeloff/hedgehogcloud/controller/LoginController.java @@ -0,0 +1,13 @@ +package ru.ldeloff.hedgehogcloud.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class LoginController { + + @GetMapping(value = "/login") + public String loginPage() { + return "login"; + } +} diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/entity/RoleEntity.java b/src/main/java/ru/ldeloff/hedgehogcloud/entity/RoleEntity.java new file mode 100644 index 0000000..da5eb44 --- /dev/null +++ b/src/main/java/ru/ldeloff/hedgehogcloud/entity/RoleEntity.java @@ -0,0 +1,31 @@ +package ru.ldeloff.hedgehogcloud.entity; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Transient; +import java.util.Set; + +@NoArgsConstructor +@Getter +@Setter +@Entity +@Table(name = "roles") +public class RoleEntity implements GrantedAuthority { + @Id + private String id; + private String name; + @Transient + private Set users; + + @Override + public String getAuthority() { + return getName(); + } +} diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/entity/UserEntity.java b/src/main/java/ru/ldeloff/hedgehogcloud/entity/UserEntity.java new file mode 100644 index 0000000..94a8749 --- /dev/null +++ b/src/main/java/ru/ldeloff/hedgehogcloud/entity/UserEntity.java @@ -0,0 +1,63 @@ +package ru.ldeloff.hedgehogcloud.entity; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import javax.persistence.*; +import java.util.Collection; +import java.util.Set; + +@NoArgsConstructor +@Getter +@Setter +@Entity +@Table(name = "users") +public class UserEntity implements UserDetails { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private String id; + private String username; + private String password; + + @ManyToMany(fetch = FetchType.EAGER) + private Set roles; + + @Override + public Collection getAuthorities() { + return null; + } + + @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 true; + } +} diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/repository/RoleRepository.java b/src/main/java/ru/ldeloff/hedgehogcloud/repository/RoleRepository.java new file mode 100644 index 0000000..75a517f --- /dev/null +++ b/src/main/java/ru/ldeloff/hedgehogcloud/repository/RoleRepository.java @@ -0,0 +1,7 @@ +package ru.ldeloff.hedgehogcloud.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import ru.ldeloff.hedgehogcloud.entity.RoleEntity; + +public interface RoleRepository extends JpaRepository { +} diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/repository/UserRepository.java b/src/main/java/ru/ldeloff/hedgehogcloud/repository/UserRepository.java new file mode 100644 index 0000000..4603bcf --- /dev/null +++ b/src/main/java/ru/ldeloff/hedgehogcloud/repository/UserRepository.java @@ -0,0 +1,8 @@ +package ru.ldeloff.hedgehogcloud.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import ru.ldeloff.hedgehogcloud.entity.UserEntity; + +public interface UserRepository extends JpaRepository { + UserEntity findByUsername(String username); +} diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/service/UserService.java b/src/main/java/ru/ldeloff/hedgehogcloud/service/UserService.java new file mode 100644 index 0000000..17654ec --- /dev/null +++ b/src/main/java/ru/ldeloff/hedgehogcloud/service/UserService.java @@ -0,0 +1,38 @@ +package ru.ldeloff.hedgehogcloud.service; + +import org.springframework.beans.factory.annotation.Autowired; +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.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Service; +import ru.ldeloff.hedgehogcloud.entity.UserEntity; +import ru.ldeloff.hedgehogcloud.repository.RoleRepository; +import ru.ldeloff.hedgehogcloud.repository.UserRepository; + +import javax.persistence.Entity; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + + +@Service +public class UserService implements UserDetailsService { + UserRepository userRepository; + RoleRepository roleRepository; + + @Autowired + public UserService(UserRepository userRepository, + RoleRepository roleRepository) { + this.userRepository = userRepository; + this.roleRepository = roleRepository; + } + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + UserEntity user = userRepository.findByUsername(username); + if (user == null) { + throw new UsernameNotFoundException("User not found"); + } + return user; + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..c2e5d26 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,14 @@ +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/hedgehogcloud?verifyServerCertificate=false&useSSL=false&requireSSL=false&useLegacyDatetimeCode=false&&serverTimezone=UTC&allowPublicKeyRetrieval=true + username: root + password: 123 + liquibase: + enabled: true + change-log: classpath:db/scripts/changelog-master.xml + url: jdbc:mysql://localhost:3306/hedgehogcloud?verifyServerCertificate=false&useSSL=false&requireSSL=false&useLegacyDatetimeCode=false&&serverTimezone=UTC&allowPublicKeyRetrieval=true + user: root + password: 123 + liquibase-schema: "liquibase" + default-schema: "hedgehogcloud" diff --git a/src/main/resources/templates/login.html b/src/main/resources/templates/login.html new file mode 100644 index 0000000..a69d21c --- /dev/null +++ b/src/main/resources/templates/login.html @@ -0,0 +1,26 @@ + + + + + + Login Page + + + +
+
+
+
+
+

Please sign in

+ + + +
+
+
+
+
+ + + \ No newline at end of file From cd695b9cb49c41a4d054f6aa1536dc4561df9ed4 Mon Sep 17 00:00:00 2001 From: L_DelOff <51275636+LDelOff@users.noreply.github.com> Date: Sat, 4 Mar 2023 21:46:38 +0300 Subject: [PATCH 3/9] =?UTF-8?q?=D0=B5=D0=BD=D1=82=D0=B8=D1=82=D0=B8=20?= =?UTF-8?q?=D0=BD=D0=B0=D1=81=D0=BB=D0=B5=D0=B4=D1=83=D1=8E=D1=82=D1=81?= =?UTF-8?q?=D1=8F=20=D0=BE=D1=82=20=D1=81=D1=83=D0=BF=D0=B5=D1=80=D0=BA?= =?UTF-8?q?=D0=BB=D0=B0=D1=81=D1=81=D0=B0.=20=D0=98=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D0=BB=20=D1=81=D0=B2=D1=8F=D0=B7=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hedgehogcloud/entity/BaseEntity.java | 33 +++++++++++++++++++ .../hedgehogcloud/entity/RoleEntity.java | 13 ++++---- .../hedgehogcloud/entity/UserEntity.java | 18 +++++----- .../db/scripts/release_0_0_1/changelog.xml | 1 + .../scripts/03_create_table_users_roles.sql | 19 +++++++++++ 5 files changed, 68 insertions(+), 16 deletions(-) create mode 100644 src/main/java/ru/ldeloff/hedgehogcloud/entity/BaseEntity.java create mode 100644 src/main/resources/db/scripts/release_0_0_1/scripts/03_create_table_users_roles.sql diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/entity/BaseEntity.java b/src/main/java/ru/ldeloff/hedgehogcloud/entity/BaseEntity.java new file mode 100644 index 0000000..fb79963 --- /dev/null +++ b/src/main/java/ru/ldeloff/hedgehogcloud/entity/BaseEntity.java @@ -0,0 +1,33 @@ +package ru.ldeloff.hedgehogcloud.entity; + +import com.sun.istack.NotNull; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.domain.Persistable; + +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; +import javax.persistence.Transient; +import java.util.UUID; + +@NoArgsConstructor +@Setter +@MappedSuperclass +@EqualsAndHashCode +public class BaseEntity implements Persistable { + @Id + protected String id = UUID.randomUUID().toString(); + @Transient + private Boolean justCreated = false; + + @Override + public String getId() { + return null; + } + + @Override + public boolean isNew() { + return justCreated; + } +} diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/entity/RoleEntity.java b/src/main/java/ru/ldeloff/hedgehogcloud/entity/RoleEntity.java index da5eb44..59598f5 100644 --- a/src/main/java/ru/ldeloff/hedgehogcloud/entity/RoleEntity.java +++ b/src/main/java/ru/ldeloff/hedgehogcloud/entity/RoleEntity.java @@ -6,10 +6,7 @@ import lombok.Setter; import org.springframework.security.core.GrantedAuthority; import org.springframework.transaction.annotation.Transactional; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.persistence.Transient; +import javax.persistence.*; import java.util.Set; @NoArgsConstructor @@ -17,13 +14,15 @@ import java.util.Set; @Setter @Entity @Table(name = "roles") -public class RoleEntity implements GrantedAuthority { - @Id - private String id; +public class RoleEntity extends BaseEntity implements GrantedAuthority { private String name; @Transient + @ManyToMany private Set users; + public String getName() { + return name; + } @Override public String getAuthority() { return getName(); diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/entity/UserEntity.java b/src/main/java/ru/ldeloff/hedgehogcloud/entity/UserEntity.java index 94a8749..7faa23d 100644 --- a/src/main/java/ru/ldeloff/hedgehogcloud/entity/UserEntity.java +++ b/src/main/java/ru/ldeloff/hedgehogcloud/entity/UserEntity.java @@ -1,14 +1,12 @@ package ru.ldeloff.hedgehogcloud.entity; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; +import lombok.*; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import javax.persistence.*; import java.util.Collection; +import java.util.HashSet; import java.util.Set; @NoArgsConstructor @@ -16,15 +14,17 @@ import java.util.Set; @Setter @Entity @Table(name = "users") -public class UserEntity implements UserDetails { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private String id; +public class UserEntity extends BaseEntity implements UserDetails { private String username; private String password; @ManyToMany(fetch = FetchType.EAGER) - private Set roles; + @JoinTable( + name = "users_roles", + joinColumns = { @JoinColumn(name = "user_id") }, + inverseJoinColumns = { @JoinColumn(name = "role_id") } + ) + private Set roles = new HashSet<>(); @Override public Collection getAuthorities() { diff --git a/src/main/resources/db/scripts/release_0_0_1/changelog.xml b/src/main/resources/db/scripts/release_0_0_1/changelog.xml index a86ce26..4ce4477 100644 --- a/src/main/resources/db/scripts/release_0_0_1/changelog.xml +++ b/src/main/resources/db/scripts/release_0_0_1/changelog.xml @@ -6,5 +6,6 @@ + \ No newline at end of file diff --git a/src/main/resources/db/scripts/release_0_0_1/scripts/03_create_table_users_roles.sql b/src/main/resources/db/scripts/release_0_0_1/scripts/03_create_table_users_roles.sql new file mode 100644 index 0000000..0e6a177 --- /dev/null +++ b/src/main/resources/db/scripts/release_0_0_1/scripts/03_create_table_users_roles.sql @@ -0,0 +1,19 @@ +-- liquibase formatted sql + +-- changeset L_DelOff:create_table_users_roles rollbackSplitStatements:true +-- comment: Создание сопоставляющей таблицы пользователь - роли + +CREATE TABLE users_roles +( + `user_id` VARCHAR(36) NOT NULL, + `role_id` VARCHAR(36) NOT NULL, + PRIMARY KEY (`user_id`,`role_id`), + KEY `role_id` (`role_id`), + CONSTRAINT `users_roles_ibfk_1` + FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), + CONSTRAINT `users_roles_ibfk_2` + FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) +); + + +-- rollback DROP TABLE users_roles; \ No newline at end of file From d2257d43230994b333d79fb1bf3f658401b5ab82 Mon Sep 17 00:00:00 2001 From: L_DelOff <51275636+LDelOff@users.noreply.github.com> Date: Sat, 4 Mar 2023 21:47:11 +0300 Subject: [PATCH 4/9] =?UTF-8?q?=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D1=8B=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20?= =?UTF-8?q?=D1=81=20=D1=80=D0=BE=D0=BB=D1=8F=D0=BC=D0=B8=20=D0=B2=20=D0=B1?= =?UTF-8?q?=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/RoleRepository.java | 3 ++ .../hedgehogcloud/service/RoleService.java | 8 +++++ .../service/RoleServiceImpl.java | 31 +++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 src/main/java/ru/ldeloff/hedgehogcloud/service/RoleService.java create mode 100644 src/main/java/ru/ldeloff/hedgehogcloud/service/RoleServiceImpl.java diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/repository/RoleRepository.java b/src/main/java/ru/ldeloff/hedgehogcloud/repository/RoleRepository.java index 75a517f..60d5e7a 100644 --- a/src/main/java/ru/ldeloff/hedgehogcloud/repository/RoleRepository.java +++ b/src/main/java/ru/ldeloff/hedgehogcloud/repository/RoleRepository.java @@ -1,7 +1,10 @@ package ru.ldeloff.hedgehogcloud.repository; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; import ru.ldeloff.hedgehogcloud.entity.RoleEntity; +@Repository public interface RoleRepository extends JpaRepository { + RoleEntity findByName(String name); } diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/service/RoleService.java b/src/main/java/ru/ldeloff/hedgehogcloud/service/RoleService.java new file mode 100644 index 0000000..8efb05c --- /dev/null +++ b/src/main/java/ru/ldeloff/hedgehogcloud/service/RoleService.java @@ -0,0 +1,8 @@ +package ru.ldeloff.hedgehogcloud.service; + +import ru.ldeloff.hedgehogcloud.entity.RoleEntity; + +public interface RoleService { + void saveRole(RoleEntity roleEntity); + RoleEntity getByName(String name); +} diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/service/RoleServiceImpl.java b/src/main/java/ru/ldeloff/hedgehogcloud/service/RoleServiceImpl.java new file mode 100644 index 0000000..5e08e12 --- /dev/null +++ b/src/main/java/ru/ldeloff/hedgehogcloud/service/RoleServiceImpl.java @@ -0,0 +1,31 @@ +package ru.ldeloff.hedgehogcloud.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; +import ru.ldeloff.hedgehogcloud.entity.RoleEntity; +import ru.ldeloff.hedgehogcloud.entity.UserEntity; +import ru.ldeloff.hedgehogcloud.repository.RoleRepository; + +@Service +public class RoleServiceImpl implements RoleService { + RoleRepository roleRepository; + + public RoleServiceImpl(RoleRepository roleRepository) { + this.roleRepository = roleRepository; + } + + + public void saveRole(RoleEntity role) { + RoleEntity roleTemp = getByName(role.getName()); + if (roleTemp == null) { + roleRepository.save(role); + } + } + + @Override + public RoleEntity getByName(String name) { + return roleRepository.findByName(name); + } + +} From 8cb50f6762d01cacfd4bdfcf2572074cee88cf7a Mon Sep 17 00:00:00 2001 From: L_DelOff <51275636+LDelOff@users.noreply.github.com> Date: Sat, 4 Mar 2023 21:47:36 +0300 Subject: [PATCH 5/9] =?UTF-8?q?=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D1=8B=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20?= =?UTF-8?q?=D1=81=20=D1=8E=D0=B7=D0=B5=D1=80=D0=B0=D0=BC=D0=B8=20=D0=B2=20?= =?UTF-8?q?=D0=B1=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/UserRepository.java | 3 ++ .../hedgehogcloud/service/UserService.java | 35 ++------------ .../service/UserServiceImpl.java | 46 +++++++++++++++++++ 3 files changed, 53 insertions(+), 31 deletions(-) create mode 100644 src/main/java/ru/ldeloff/hedgehogcloud/service/UserServiceImpl.java diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/repository/UserRepository.java b/src/main/java/ru/ldeloff/hedgehogcloud/repository/UserRepository.java index 4603bcf..9aedbf1 100644 --- a/src/main/java/ru/ldeloff/hedgehogcloud/repository/UserRepository.java +++ b/src/main/java/ru/ldeloff/hedgehogcloud/repository/UserRepository.java @@ -1,8 +1,11 @@ package ru.ldeloff.hedgehogcloud.repository; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; import ru.ldeloff.hedgehogcloud.entity.UserEntity; +@Repository public interface UserRepository extends JpaRepository { UserEntity findByUsername(String username); + } diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/service/UserService.java b/src/main/java/ru/ldeloff/hedgehogcloud/service/UserService.java index 17654ec..1fb3c71 100644 --- a/src/main/java/ru/ldeloff/hedgehogcloud/service/UserService.java +++ b/src/main/java/ru/ldeloff/hedgehogcloud/service/UserService.java @@ -1,38 +1,11 @@ package ru.ldeloff.hedgehogcloud.service; -import org.springframework.beans.factory.annotation.Autowired; 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.bcrypt.BCryptPasswordEncoder; -import org.springframework.stereotype.Service; import ru.ldeloff.hedgehogcloud.entity.UserEntity; -import ru.ldeloff.hedgehogcloud.repository.RoleRepository; -import ru.ldeloff.hedgehogcloud.repository.UserRepository; -import javax.persistence.Entity; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; - - -@Service -public class UserService implements UserDetailsService { - UserRepository userRepository; - RoleRepository roleRepository; - - @Autowired - public UserService(UserRepository userRepository, - RoleRepository roleRepository) { - this.userRepository = userRepository; - this.roleRepository = roleRepository; - } - - @Override - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - UserEntity user = userRepository.findByUsername(username); - if (user == null) { - throw new UsernameNotFoundException("User not found"); - } - return user; - } +public interface UserService extends UserDetailsService { + UserDetails loadUserByUsername(String username); + void saveUser(UserEntity user); + UserEntity getByUserName(String name); // TODO попробовать userdetails юзать } diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/service/UserServiceImpl.java b/src/main/java/ru/ldeloff/hedgehogcloud/service/UserServiceImpl.java new file mode 100644 index 0000000..9da1c73 --- /dev/null +++ b/src/main/java/ru/ldeloff/hedgehogcloud/service/UserServiceImpl.java @@ -0,0 +1,46 @@ +package ru.ldeloff.hedgehogcloud.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; +import ru.ldeloff.hedgehogcloud.entity.UserEntity; +import ru.ldeloff.hedgehogcloud.repository.RoleRepository; +import ru.ldeloff.hedgehogcloud.repository.UserRepository; + +@Service +public class UserServiceImpl implements UserService { + UserRepository userRepository; + RoleRepository roleRepository; + + @Autowired + public UserServiceImpl(UserRepository userRepository, + RoleRepository roleRepository) { + this.userRepository = userRepository; + this.roleRepository = roleRepository; + } + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + UserEntity user = userRepository.findByUsername(username); + if (user == null) { + throw new UsernameNotFoundException("User not found"); + } + return user; + } + + @Override + public void saveUser(UserEntity user) { + UserEntity userTemp = getByUserName(user.getUsername()); + if (userTemp == null) { + userRepository.save(user); + } + } + + @Override + public UserEntity getByUserName(String name) { + return userRepository.findByUsername(name); + } + + +} From b21d3a6a5b97eef87a2e645d0cd1b22c9f4ae757 Mon Sep 17 00:00:00 2001 From: L_DelOff <51275636+LDelOff@users.noreply.github.com> Date: Sat, 4 Mar 2023 21:48:07 +0300 Subject: [PATCH 6/9] =?UTF-8?q?=D0=B4=D0=B5=D1=84=D0=BE=D0=BB=D1=82=D0=BD?= =?UTF-8?q?=D0=B0=D1=8F=20=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=B8=D1=86=D0=B0?= =?UTF-8?q?=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ldeloff/hedgehogcloud/config/WebSecurityConfig.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/config/WebSecurityConfig.java b/src/main/java/ru/ldeloff/hedgehogcloud/config/WebSecurityConfig.java index fbfe448..83fa1b4 100644 --- a/src/main/java/ru/ldeloff/hedgehogcloud/config/WebSecurityConfig.java +++ b/src/main/java/ru/ldeloff/hedgehogcloud/config/WebSecurityConfig.java @@ -9,16 +9,16 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.NoOpPasswordEncoder; -import ru.ldeloff.hedgehogcloud.service.UserService; +import ru.ldeloff.hedgehogcloud.service.UserServiceImpl; @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { - UserService userService; + UserServiceImpl userService; AuthenticationSuccessUserHandler authenticationSuccessUserHandler; - public WebSecurityConfig(UserService userService, AuthenticationSuccessUserHandler authenticationSuccessUserHandler) { + public WebSecurityConfig(UserServiceImpl userService, AuthenticationSuccessUserHandler authenticationSuccessUserHandler) { this.userService = userService; this.authenticationSuccessUserHandler = authenticationSuccessUserHandler; } @@ -32,7 +32,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { protected void configure(HttpSecurity http) throws Exception { http.formLogin() // указываем страницу с формой логина - .loginPage("/login") + //.loginPage("/login") //указываем логику обработки при логине .successHandler(authenticationSuccessUserHandler) // указываем action с формы логина From 7bb16ec60db80deb832b66bb6ef070bb9c64c647 Mon Sep 17 00:00:00 2001 From: L_DelOff <51275636+LDelOff@users.noreply.github.com> Date: Sat, 4 Mar 2023 21:49:17 +0300 Subject: [PATCH 7/9] =?UTF-8?q?=D0=B0=D0=B2=D1=82=D0=BE=D0=B7=D0=B0=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B1=D0=B0=D0=B7?= =?UTF-8?q?=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/initclass/InitDB.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/main/java/ru/ldeloff/hedgehogcloud/config/initclass/InitDB.java diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/config/initclass/InitDB.java b/src/main/java/ru/ldeloff/hedgehogcloud/config/initclass/InitDB.java new file mode 100644 index 0000000..1b82f77 --- /dev/null +++ b/src/main/java/ru/ldeloff/hedgehogcloud/config/initclass/InitDB.java @@ -0,0 +1,39 @@ +package ru.ldeloff.hedgehogcloud.config.initclass; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import ru.ldeloff.hedgehogcloud.entity.RoleEntity; +import ru.ldeloff.hedgehogcloud.entity.UserEntity; +import ru.ldeloff.hedgehogcloud.service.RoleService; +import ru.ldeloff.hedgehogcloud.service.UserService; + +import java.util.HashSet; +import java.util.List; + +@Component +public class InitDB implements ApplicationRunner { + UserService userService; + RoleService roleService; + + public InitDB(UserService userService, RoleService roleService) { + this.userService = userService; + this.roleService = roleService; + } + + @Override + @Transactional + public void run(ApplicationArguments args) throws Exception { + RoleEntity role = new RoleEntity(); + role.setName("ROLE_ADMIN"); + roleService.saveRole(role); + + UserEntity user = new UserEntity(); + user.setUsername("admin"); + user.setPassword("123"); + user.setRoles(new HashSet<>(List.of(roleService.getByName(role.getName())))); + userService.saveUser(user); + } +} From 00eaf8816df4e91c272572bf5e96952123f62080 Mon Sep 17 00:00:00 2001 From: L_DelOff <51275636+LDelOff@users.noreply.github.com> Date: Sun, 12 Mar 2023 16:49:05 +0300 Subject: [PATCH 8/9] =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=20=D1=81=20=D0=BE=D0=B1=D1=8B?= =?UTF-8?q?=D1=87=D0=BD=D0=BE=D0=B9=20=D1=80=D0=BE=D0=BB=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ldeloff/hedgehogcloud/config/initclass/InitDB.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/config/initclass/InitDB.java b/src/main/java/ru/ldeloff/hedgehogcloud/config/initclass/InitDB.java index 1b82f77..f1e6df2 100644 --- a/src/main/java/ru/ldeloff/hedgehogcloud/config/initclass/InitDB.java +++ b/src/main/java/ru/ldeloff/hedgehogcloud/config/initclass/InitDB.java @@ -30,10 +30,20 @@ public class InitDB implements ApplicationRunner { role.setName("ROLE_ADMIN"); roleService.saveRole(role); + RoleEntity role2 = new RoleEntity(); + role2.setName("ROLE_USER"); + roleService.saveRole(role2); + UserEntity user = new UserEntity(); user.setUsername("admin"); user.setPassword("123"); user.setRoles(new HashSet<>(List.of(roleService.getByName(role.getName())))); userService.saveUser(user); + + UserEntity user2 = new UserEntity(); + user2.setUsername("user"); + user2.setPassword("123"); + user2.setRoles(new HashSet<>(List.of(roleService.getByName(role2.getName())))); + userService.saveUser(user2); } } From 6b842573f4dbd01d9ec24594506c2eedb08a4d09 Mon Sep 17 00:00:00 2001 From: L_DelOff <51275636+LDelOff@users.noreply.github.com> Date: Sun, 12 Mar 2023 16:50:11 +0300 Subject: [PATCH 9/9] =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B8=D0=B7=D0=B2=D0=BB=D0=B5=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D1=80=D0=B0=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ru/ldeloff/hedgehogcloud/entity/UserEntity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ru/ldeloff/hedgehogcloud/entity/UserEntity.java b/src/main/java/ru/ldeloff/hedgehogcloud/entity/UserEntity.java index 7faa23d..469491f 100644 --- a/src/main/java/ru/ldeloff/hedgehogcloud/entity/UserEntity.java +++ b/src/main/java/ru/ldeloff/hedgehogcloud/entity/UserEntity.java @@ -28,7 +28,7 @@ public class UserEntity extends BaseEntity implements UserDetails { @Override public Collection getAuthorities() { - return null; + return getRoles(); } @Override