根据内容:https://www.ossez.com/t/spring-lombok/14129 修改实体类死循环问题
This commit is contained in:
parent
ea675b8482
commit
efbefa7902
16
pom.xml
16
pom.xml
|
@ -71,17 +71,31 @@
|
|||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- TEST -->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!--/ TEST -->
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -8,7 +8,7 @@ import java.util.stream.Collectors;
|
|||
import javax.validation.Valid;
|
||||
|
||||
import com.ossez.spring.security.models.ERole;
|
||||
import com.ossez.spring.security.models.entity.Role;
|
||||
import com.ossez.spring.security.models.entity.PersonRole;
|
||||
import com.ossez.spring.security.payload.request.LoginRequest;
|
||||
import com.ossez.spring.security.payload.request.SignupRequest;
|
||||
import com.ossez.spring.security.payload.response.JwtResponse;
|
||||
|
@ -36,26 +36,26 @@ import com.ossez.spring.security.repository.UserRepository;
|
|||
@RestController
|
||||
@RequestMapping("/custom")
|
||||
public class AuthController {
|
||||
@Autowired
|
||||
AuthenticationManager authenticationManager;
|
||||
private final AuthenticationManager authenticationManager;
|
||||
private final UserRepository userRepository;
|
||||
private final RoleRepository roleRepository;
|
||||
private final PasswordEncoder encoder;
|
||||
private final JwtUtils jwtUtils;
|
||||
|
||||
@Autowired
|
||||
UserRepository userRepository;
|
||||
|
||||
@Autowired
|
||||
RoleRepository roleRepository;
|
||||
|
||||
@Autowired
|
||||
PasswordEncoder encoder;
|
||||
|
||||
@Autowired
|
||||
JwtUtils jwtUtils;
|
||||
public AuthController(AuthenticationManager authenticationManager, UserRepository userRepository, RoleRepository roleRepository, PasswordEncoder encoder, JwtUtils jwtUtils) {
|
||||
this.authenticationManager = authenticationManager;
|
||||
this.userRepository = userRepository;
|
||||
this.roleRepository = roleRepository;
|
||||
this.encoder = encoder;
|
||||
this.jwtUtils = jwtUtils;
|
||||
}
|
||||
|
||||
@PostMapping("/signin")
|
||||
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
|
||||
|
||||
Authentication authentication = authenticationManager.authenticate(
|
||||
new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
|
||||
new UsernamePasswordAuthenticationToken(loginRequest.getUserName(), loginRequest.getUserPassword()));
|
||||
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
String jwt = jwtUtils.generateJwtToken(authentication);
|
||||
|
@ -74,13 +74,13 @@ public class AuthController {
|
|||
|
||||
@PostMapping("/register")
|
||||
public ResponseEntity<?> registerUser(@Valid @RequestBody SignupRequest signUpRequest) {
|
||||
if (userRepository.existsByUsername(signUpRequest.getUsername())) {
|
||||
if (userRepository.existsByUserName(signUpRequest.getUsername())) {
|
||||
return ResponseEntity
|
||||
.badRequest()
|
||||
.body(new MessageResponse("Error: Username is already taken!"));
|
||||
}
|
||||
|
||||
if (userRepository.existsByEmail(signUpRequest.getEmail())) {
|
||||
if (userRepository.existsByUserEmail(signUpRequest.getEmail())) {
|
||||
return ResponseEntity
|
||||
.badRequest()
|
||||
.body(new MessageResponse("Error: Email is already in use!"));
|
||||
|
@ -94,36 +94,36 @@ public class AuthController {
|
|||
|
||||
|
||||
Set<String> strRoles = signUpRequest.getRole();
|
||||
Set<Role> roles = new HashSet<>();
|
||||
Set<PersonRole> roles = new HashSet<>();
|
||||
|
||||
if (strRoles == null) {
|
||||
Role userRole = roleRepository.findByName(ERole.ROLE_USER)
|
||||
PersonRole userRole = roleRepository.findByPersonRoleKey(ERole.ROLE_USER)
|
||||
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
|
||||
roles.add(userRole);
|
||||
} else {
|
||||
strRoles.forEach(role -> {
|
||||
switch (role) {
|
||||
case "admin":
|
||||
Role adminRole = roleRepository.findByName(ERole.ROLE_ADMIN)
|
||||
PersonRole adminRole = roleRepository.findByPersonRoleKey(ERole.ROLE_ADMIN)
|
||||
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
|
||||
roles.add(adminRole);
|
||||
|
||||
break;
|
||||
case "mod":
|
||||
Role modRole = roleRepository.findByName(ERole.ROLE_MODERATOR)
|
||||
PersonRole modRole = roleRepository.findByPersonRoleKey(ERole.ROLE_MODERATOR)
|
||||
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
|
||||
roles.add(modRole);
|
||||
|
||||
break;
|
||||
default:
|
||||
Role userRole = roleRepository.findByName(ERole.ROLE_USER)
|
||||
PersonRole userRole = roleRepository.findByPersonRoleKey(ERole.ROLE_USER)
|
||||
.orElseThrow(() -> new RuntimeException("Error: Role is not found."));
|
||||
roles.add(userRole);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
person.setRoles(roles);
|
||||
// person.setRoles(roles);
|
||||
userRepository.save(person);
|
||||
|
||||
return ResponseEntity.ok(new MessageResponse("User registered successfully!"));
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package com.ossez.spring.security.models.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.*;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
import javax.persistence.*;
|
||||
import javax.validation.constraints.Email;
|
||||
|
@ -12,17 +13,16 @@ import java.util.Set;
|
|||
|
||||
/**
|
||||
* Person Entity
|
||||
*
|
||||
* @author YuCheng Hu
|
||||
*/
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Data()
|
||||
@Accessors(chain = true)
|
||||
@Table(name = "Person", uniqueConstraints = {@UniqueConstraint(columnNames = "user_name"), @UniqueConstraint(columnNames = "user_email")})
|
||||
public class Person {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
//@Table(name = "person", uniqueConstraints = {@UniqueConstraint(columnNames = "user_name"), @UniqueConstraint(columnNames = "user_email")})
|
||||
public class Person extends AbstractPersistable<Long> {
|
||||
|
||||
@NotBlank
|
||||
@Size(max = 20)
|
||||
|
@ -33,11 +33,11 @@ public class Person {
|
|||
private String userPassword;
|
||||
|
||||
@NotBlank
|
||||
@Size(max = 50)
|
||||
@Email
|
||||
private String userEmail;
|
||||
|
||||
@ManyToMany(fetch = FetchType.LAZY)
|
||||
@JoinTable(name = "user_roles", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
|
||||
private Set<Role> roles = new HashSet<>();
|
||||
//// @ManyToMany(fetch = FetchType.LAZY)
|
||||
//// @JoinTable(name = "person_role", joinColumns = @JoinColumn(name = "id"))
|
||||
@OneToMany(mappedBy = "person", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
||||
private Set<PersonRole> personRoles;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package com.ossez.spring.security.models.entity;
|
||||
|
||||
import com.ossez.spring.security.models.ERole;
|
||||
import lombok.Data;
|
||||
import org.springframework.data.jpa.domain.AbstractPersistable;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
public class PersonRole extends AbstractPersistable<Long> {
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY, optional = false)
|
||||
@JoinColumn(name = "person_id", nullable = false)
|
||||
private Person person;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(length = 20)
|
||||
private ERole personRoleKey;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package com.ossez.spring.security.models.entity;
|
||||
|
||||
import com.ossez.spring.security.models.ERole;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "roles")
|
||||
@Data
|
||||
public class Role {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Integer id;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(length = 20)
|
||||
private ERole name;
|
||||
}
|
|
@ -1,27 +1,19 @@
|
|||
package com.ossez.spring.security.payload.request;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* Login Request Obj
|
||||
*
|
||||
* @author YuCheng Hu
|
||||
*/
|
||||
@Data
|
||||
public class LoginRequest {
|
||||
@NotBlank
|
||||
private String username;
|
||||
private String userName;
|
||||
|
||||
@NotBlank
|
||||
private String password;
|
||||
|
||||
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;
|
||||
}
|
||||
private String userPassword;
|
||||
}
|
||||
|
|
|
@ -3,11 +3,11 @@ package com.ossez.spring.security.repository;
|
|||
import java.util.Optional;
|
||||
|
||||
import com.ossez.spring.security.models.ERole;
|
||||
import com.ossez.spring.security.models.entity.Role;
|
||||
import com.ossez.spring.security.models.entity.PersonRole;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface RoleRepository extends JpaRepository<Role, Long> {
|
||||
Optional<Role> findByName(ERole name);
|
||||
public interface RoleRepository extends JpaRepository<PersonRole, Long> {
|
||||
Optional<PersonRole> findByPersonRoleKey(ERole name);
|
||||
}
|
||||
|
|
|
@ -3,15 +3,16 @@ package com.ossez.spring.security.repository;
|
|||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.ossez.spring.security.models.entity.Person;
|
||||
|
||||
@Repository
|
||||
public interface UserRepository extends JpaRepository<Person, Long> {
|
||||
Optional<Person> findByUsername(String username);
|
||||
public interface UserRepository extends CrudRepository<Person, Long> {
|
||||
Optional<Person> findByUserName(String userName);
|
||||
|
||||
Boolean existsByUsername(String username);
|
||||
Boolean existsByUserName(String userName);
|
||||
|
||||
Boolean existsByEmail(String email);
|
||||
Boolean existsByUserEmail(String userEmail);
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ public class WebSecurityConfig { // extends WebSecurityConfigurerAdapter {
|
|||
http.cors().and().csrf().disable()
|
||||
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
|
||||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
|
||||
.authorizeRequests().antMatchers("/h2-console/**").permitAll()
|
||||
.authorizeRequests().antMatchers("/custom/**").permitAll()
|
||||
.antMatchers("/api/test/**").permitAll()
|
||||
.anyRequest().authenticated();
|
||||
|
||||
|
|
|
@ -36,16 +36,18 @@ public class UserDetailsImpl implements UserDetails {
|
|||
}
|
||||
|
||||
public static UserDetailsImpl build(Person user) {
|
||||
List<GrantedAuthority> authorities = user.getRoles().stream()
|
||||
.map(role -> new SimpleGrantedAuthority(role.getName().name()))
|
||||
.collect(Collectors.toList());
|
||||
// List<GrantedAuthority> authorities = user.getPersonRoles().stream()
|
||||
// .map(role -> new SimpleGrantedAuthority(role.toString()))
|
||||
// .collect(Collectors.toList());
|
||||
//
|
||||
// return new UserDetailsImpl(
|
||||
// user.getId(),
|
||||
// user.getUserName(),
|
||||
// user.getUserEmail(),
|
||||
// user.getUserPassword(),
|
||||
// authorities);
|
||||
|
||||
return new UserDetailsImpl(
|
||||
user.getId(),
|
||||
user.getUserName(),
|
||||
user.getUserEmail(),
|
||||
user.getUserPassword(),
|
||||
authorities);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,14 +12,17 @@ import com.ossez.spring.security.repository.UserRepository;
|
|||
|
||||
@Service
|
||||
public class UserDetailsServiceImpl implements UserDetailsService {
|
||||
final UserRepository userRepository;
|
||||
|
||||
@Autowired
|
||||
UserRepository userRepository;
|
||||
public UserDetailsServiceImpl(UserRepository userRepository) {
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
Person user = userRepository.findByUsername(username)
|
||||
.orElseThrow(() -> new UsernameNotFoundException("User Not Found with username: " + username));
|
||||
Person user = userRepository.findByUserName(username).orElseThrow(() -> new UsernameNotFoundException("User Not Found with username: " + username));
|
||||
|
||||
return UserDetailsImpl.build(user);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package com.ossez.spring.security;
|
||||
|
||||
import com.ossez.spring.security.models.entity.Person;
|
||||
import com.ossez.spring.security.repository.UserRepository;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.annotation.Commit;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author YuCheng Hu
|
||||
*/
|
||||
@Transactional
|
||||
@DataJpaTest
|
||||
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@Slf4j
|
||||
public class PersonTest {
|
||||
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
|
||||
@Test
|
||||
@Commit
|
||||
void testQueryPerson() {
|
||||
|
||||
Person person = userRepository.findByUserName("huyuchengus").stream().findFirst().orElse(null);
|
||||
|
||||
log.debug("Get Person Email - [{}]", person.getUserEmail());
|
||||
log.debug("ROLEs - [{}]", person.getPersonRoles().size());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<configuration debug="true">
|
||||
<timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>
|
||||
<appender name="STDOUT"
|
||||
class="ch.qos.logback.core.ConsoleAppender">
|
||||
<!-- encoders are assigned by default the type
|
||||
ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||
<Pattern>
|
||||
%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
|
||||
</Pattern>
|
||||
</layout>
|
||||
</appender>
|
||||
<!-- FILE-DEBUG -->
|
||||
<appender name="FILE-DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<prudent>true</prudent>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- daily rollover -->
|
||||
<fileNamePattern>${user.home}/logs/usreio/%d{yyyy-MM-dd}/usreio-debug.log</fileNamePattern>
|
||||
<!-- keep 30 days' worth of history capped at 3GB total size -->
|
||||
<maxHistory>30</maxHistory>
|
||||
<totalSizeCap>3GB</totalSizeCap>
|
||||
</rollingPolicy>
|
||||
<append>true</append>
|
||||
<immediateFlush>true</immediateFlush>
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
<!-- FILE-ERROR -->
|
||||
<appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<prudent>true</prudent>
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>ERROR</level>
|
||||
</filter>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- daily rollover -->
|
||||
<fileNamePattern>${user.home}/logs/usreio/%d{yyyy-MM-dd}/usreio-error.log</fileNamePattern>
|
||||
<!-- keep 30 days' worth of history capped at 3GB total size -->
|
||||
<maxHistory>30</maxHistory>
|
||||
<totalSizeCap>3GB</totalSizeCap>
|
||||
</rollingPolicy>
|
||||
<append>true</append>
|
||||
<immediateFlush>true</immediateFlush>
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
<!-- LOGGER -->
|
||||
<logger name="com.ossez" level="DEBUG"/>
|
||||
<logger name="org.apache" level="INFO"/>
|
||||
<logger name="org.hibernate" level="INFO"/>
|
||||
<logger name="org.springframework" level="INFO"/>
|
||||
<!-- ROOT AND APPENDER -->
|
||||
<root level="debug">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
<appender-ref ref="FILE-DEBUG"/>
|
||||
<appender-ref ref="FILE-ERROR"/>
|
||||
</root>
|
||||
</configuration>
|
Loading…
Reference in New Issue