signup with session
This commit is contained in:
@@ -22,9 +22,12 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
||||
|
||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||
implementation 'org.springframework.session:spring-session-data-redis'
|
||||
implementation 'org.springframework.session:spring-session-core'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
|
||||
|
||||
runtimeOnly 'com.h2database:h2'
|
||||
|
||||
compileOnly 'org.projectlombok:lombok'
|
||||
|
||||
@@ -2,10 +2,13 @@ package com.example.oneul.DTO;
|
||||
|
||||
import com.example.oneul.model.UserEntity;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class LoginDTO {
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
|
||||
public LoginDTO(String username, String password){
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
|
||||
39
src/main/java/com/example/oneul/DTO/SignUpDTO.java
Normal file
39
src/main/java/com/example/oneul/DTO/SignUpDTO.java
Normal file
@@ -0,0 +1,39 @@
|
||||
package com.example.oneul.DTO;
|
||||
|
||||
import com.example.oneul.model.UserEntity;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class SignUpDTO {
|
||||
private String username;
|
||||
private String password1;
|
||||
private String password2;
|
||||
|
||||
public void setUsername(String username ){
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public void setPassword1(String password1){
|
||||
this.password1 = password1;
|
||||
}
|
||||
|
||||
public void setPassword2(String password2){
|
||||
this.password2 = password2;
|
||||
}
|
||||
|
||||
public SignUpDTO() {}
|
||||
|
||||
public SignUpDTO(String username, String password1, String password2){
|
||||
this.username = username;
|
||||
this.password1 = password1;
|
||||
this.password2 = password2;
|
||||
}
|
||||
|
||||
public UserEntity toEntity(){
|
||||
return UserEntity.builder()
|
||||
.username(this.username)
|
||||
.password(this.password1)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,14 @@ package com.example.oneul;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
|
||||
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
|
||||
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableJpaAuditing
|
||||
@EnableRedisHttpSession
|
||||
public class OneulApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(OneulApplication.class, args);
|
||||
}
|
||||
|
||||
37
src/main/java/com/example/oneul/config/RedisConfig.java
Normal file
37
src/main/java/com/example/oneul/config/RedisConfig.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package com.example.oneul.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
@Configuration
|
||||
public class RedisConfig {
|
||||
@Value("${spring.redis.host}")
|
||||
private String hostName;
|
||||
@Value("${spring.redis.port}")
|
||||
private int port;
|
||||
|
||||
@Bean
|
||||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory){
|
||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
||||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
|
||||
redisTemplate.setConnectionFactory(connectionFactory);
|
||||
return redisTemplate;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RedisConnectionFactory redisConnectionFactory() {
|
||||
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
|
||||
redisStandaloneConfiguration.setHostName(hostName);
|
||||
redisStandaloneConfiguration.setPort(port);
|
||||
LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisStandaloneConfiguration);
|
||||
return lettuceConnectionFactory;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.example.oneul.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
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.PasswordEncoder;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
@Bean
|
||||
public PasswordEncoder getPasswordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity httpSecurity) throws Exception {
|
||||
httpSecurity.cors().disable()
|
||||
.csrf().disable()
|
||||
.formLogin().disable()
|
||||
.headers().frameOptions().disable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.example.oneul.controller;
|
||||
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import com.example.oneul.DTO.SignUpDTO;
|
||||
import com.example.oneul.model.UserEntity;
|
||||
import com.example.oneul.service.command.UserCommandService;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
|
||||
@RestController
|
||||
@RequestMapping(value = "/user")
|
||||
public class UserController {
|
||||
private final UserCommandService userCommandService;
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(UserController.class);
|
||||
|
||||
public UserController(UserCommandService userCommandService){
|
||||
this.userCommandService = userCommandService;
|
||||
}
|
||||
|
||||
@RequestMapping(value="/", method=RequestMethod.POST)
|
||||
public UserEntity signUp(@RequestBody SignUpDTO signUpDTO, HttpSession httpSession) {
|
||||
UserEntity user = userCommandService.signUp(signUpDTO.toEntity(), httpSession);
|
||||
return user;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,23 @@
|
||||
package com.example.oneul.model;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityListeners;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
|
||||
@Entity
|
||||
@EntityListeners(AuditingEntityListener.class)
|
||||
public class Post {
|
||||
@Id @GeneratedValue
|
||||
private Long id;
|
||||
@@ -66,6 +70,23 @@ public class Post {
|
||||
this.writer = writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object){
|
||||
if(this == object) {
|
||||
return true;
|
||||
}
|
||||
if(object == null || getClass() != object.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Post that = (Post) object;
|
||||
return this.id == that.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "Post["
|
||||
|
||||
@@ -1,19 +1,24 @@
|
||||
package com.example.oneul.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.EntityListeners;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
|
||||
@Entity
|
||||
public class UserEntity {
|
||||
@EntityListeners(AuditingEntityListener.class)
|
||||
public class UserEntity implements Serializable {
|
||||
@Id @GeneratedValue
|
||||
private Long id;
|
||||
@Column(nullable = false, unique = true)
|
||||
@@ -71,6 +76,23 @@ public class UserEntity {
|
||||
this.createdAt = user.getCreatedAt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object){
|
||||
if(this == object) {
|
||||
return true;
|
||||
}
|
||||
if(object == null || getClass() != object.getClass()) {
|
||||
return false;
|
||||
}
|
||||
UserEntity that = (UserEntity) object;
|
||||
return this.id == that.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "userEntity["
|
||||
|
||||
@@ -4,9 +4,11 @@ import java.util.Optional;
|
||||
|
||||
import com.example.oneul.model.UserEntity;
|
||||
|
||||
import org.springframework.data.redis.core.RedisHash;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@RedisHash
|
||||
@Repository
|
||||
public interface UserCommandRepository extends CrudRepository<UserEntity, Long> {
|
||||
Optional<UserEntity> findByUsername(String username);
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package com.example.oneul.service.command;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import com.example.oneul.model.UserEntity;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public interface UserCommandService {
|
||||
UserEntity signUp(UserEntity userEntity);
|
||||
UserEntity signUp(UserEntity userEntity, HttpSession httpSession);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.example.oneul.service.command;
|
||||
|
||||
import com.example.oneul.exception.UserAlreadyExistException;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import com.example.oneul.model.UserEntity;
|
||||
import com.example.oneul.repository.UserCommandRepository;
|
||||
|
||||
@@ -25,15 +26,15 @@ public class UserCommandServiceImpl implements UserCommandService {
|
||||
|
||||
@Override
|
||||
@Transactional(isolation = Isolation.SERIALIZABLE)
|
||||
public UserEntity signUp(UserEntity userEntity){
|
||||
userCommandRepository.findByUsername(userEntity.getUsername()).ifPresent(user -> {
|
||||
log.debug(user.getUsername() + " is present");
|
||||
throw new UserAlreadyExistException(userEntity.getUsername() + " is already exist.");
|
||||
});
|
||||
public UserEntity signUp(UserEntity userEntity, HttpSession httpSession){
|
||||
// ANCHOR: 이게 맞나..?
|
||||
userEntity.setPassword(passwordEncoder.encode(userEntity.getPassword()));
|
||||
UserEntity user = new UserEntity(userEntity);
|
||||
return userCommandRepository.save(user);
|
||||
UserEntity user = userCommandRepository.save(new UserEntity(userEntity));
|
||||
|
||||
httpSession.setAttribute("user",user);
|
||||
log.info("session id: " + httpSession.getId());
|
||||
log.info("session value: " + httpSession.getAttribute("user"));
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,14 @@ spring:
|
||||
url: jdbc:h2:tcp://localhost/~/test
|
||||
driver-class-name: org.h2.Driver
|
||||
username: "sa"
|
||||
redis:
|
||||
host: 127.0.0.1
|
||||
port: 6379
|
||||
|
||||
server:
|
||||
servlet:
|
||||
session:
|
||||
timeout: 60
|
||||
|
||||
logging:
|
||||
level:
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.example.oneul.controller;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.example.oneul.service.command.UserCommandService;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.ResultActions;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.filter.CharacterEncodingFilter;
|
||||
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
public class UserControllerTest {
|
||||
private MockMvc mvc;
|
||||
@Autowired
|
||||
private UserCommandService userCommandService;
|
||||
private MockHttpSession httpSession = new MockHttpSession();
|
||||
|
||||
@BeforeEach
|
||||
public void setUp(){
|
||||
mvc = MockMvcBuilders.standaloneSetup(new UserController(userCommandService))
|
||||
.addFilters(new CharacterEncodingFilter("UTF-8", true))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("signUp test")
|
||||
public void signUpTest() throws Exception {
|
||||
Map<String, Object> requestBody = new HashMap<>();
|
||||
requestBody.put("username", "zzzinho");
|
||||
requestBody.put("password1", "password");
|
||||
requestBody.put("password2", "password");
|
||||
|
||||
String json = new ObjectMapper().registerModule(new JavaTimeModule()).writeValueAsString(requestBody);
|
||||
|
||||
final ResultActions actions = mvc.perform(
|
||||
post("/user/")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.session(httpSession)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.characterEncoding("UTF-8")
|
||||
.content(json)
|
||||
);
|
||||
|
||||
actions.andExpectAll(status().isOk());
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.example.oneul.service;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import com.example.oneul.DTO.LoginDTO;
|
||||
import com.example.oneul.model.UserEntity;
|
||||
import com.example.oneul.service.command.UserCommandService;
|
||||
@@ -9,18 +11,24 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
@Transactional
|
||||
@SpringBootTest
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class UserCommandServiceTest {
|
||||
@Autowired
|
||||
private UserCommandService userCommandService;
|
||||
|
||||
@Autowired
|
||||
private PasswordEncoder passwordEncoder;
|
||||
protected MockHttpSession httpSession;
|
||||
|
||||
@Test
|
||||
public void signUpTest(){
|
||||
httpSession = new MockHttpSession();
|
||||
LoginDTO loginDTO = new LoginDTO("zzzinho", "password");
|
||||
UserEntity user = userCommandService.signUp(loginDTO.toEntity());
|
||||
UserEntity user = userCommandService.signUp(loginDTO.toEntity(), httpSession);
|
||||
assertEquals(loginDTO.getUsername(), user.getUsername());
|
||||
assertEquals(true, passwordEncoder.matches(loginDTO.getPassword(), user.getPassword()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user