diff --git a/giftrio/build.gradle b/giftrio/build.gradle index d103b31..9866d62 100644 --- a/giftrio/build.gradle +++ b/giftrio/build.gradle @@ -23,12 +23,14 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'junit:junit:4.13.1' implementation 'mysql:mysql-connector-java' + implementation 'org.springframework.boot:spring-boot-starter-security' compileOnly 'org.projectlombok:lombok' runtimeOnly 'mysql:mysql-connector-java' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.springframework.security:spring-security-test:5.7.5' } tasks.named('test') { useJUnitPlatform() -} +} \ No newline at end of file diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/advent/Advent.java b/giftrio/src/main/java/com/fluffytrio/giftrio/advent/Advent.java index fe07d53..d11f930 100644 --- a/giftrio/src/main/java/com/fluffytrio/giftrio/advent/Advent.java +++ b/giftrio/src/main/java/com/fluffytrio/giftrio/advent/Advent.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fluffytrio.giftrio.calendar.Calendar; -import com.fluffytrio.giftrio.user.User; +import com.fluffytrio.giftrio.user.entity.User; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/advent/dto/AdventRequestDto.java b/giftrio/src/main/java/com/fluffytrio/giftrio/advent/dto/AdventRequestDto.java index cb45f9d..43646e4 100644 --- a/giftrio/src/main/java/com/fluffytrio/giftrio/advent/dto/AdventRequestDto.java +++ b/giftrio/src/main/java/com/fluffytrio/giftrio/advent/dto/AdventRequestDto.java @@ -2,7 +2,7 @@ import com.fluffytrio.giftrio.advent.Advent; import com.fluffytrio.giftrio.calendar.Calendar; -import com.fluffytrio.giftrio.user.User; +import com.fluffytrio.giftrio.user.entity.User; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/auth/dto/LoginDto.java b/giftrio/src/main/java/com/fluffytrio/giftrio/auth/dto/LoginDto.java new file mode 100644 index 0000000..fcecf4c --- /dev/null +++ b/giftrio/src/main/java/com/fluffytrio/giftrio/auth/dto/LoginDto.java @@ -0,0 +1,14 @@ +package com.fluffytrio.giftrio.auth.dto; + +import lombok.*; + +@Builder +@Getter +@Data +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class LoginDto { + private String email; + private String password; +} diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/calendar/Calendar.java b/giftrio/src/main/java/com/fluffytrio/giftrio/calendar/Calendar.java index 96ebfe4..f479666 100644 --- a/giftrio/src/main/java/com/fluffytrio/giftrio/calendar/Calendar.java +++ b/giftrio/src/main/java/com/fluffytrio/giftrio/calendar/Calendar.java @@ -3,7 +3,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fluffytrio.giftrio.advent.Advent; import com.fluffytrio.giftrio.settings.Setting; -import com.fluffytrio.giftrio.user.User; +import com.fluffytrio.giftrio.user.entity.User; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/calendar/dto/CalendarRequestDto.java b/giftrio/src/main/java/com/fluffytrio/giftrio/calendar/dto/CalendarRequestDto.java index ece1b20..d3a4d48 100644 --- a/giftrio/src/main/java/com/fluffytrio/giftrio/calendar/dto/CalendarRequestDto.java +++ b/giftrio/src/main/java/com/fluffytrio/giftrio/calendar/dto/CalendarRequestDto.java @@ -3,7 +3,7 @@ import com.fluffytrio.giftrio.advent.Advent; import com.fluffytrio.giftrio.calendar.Calendar; import com.fluffytrio.giftrio.settings.Setting; -import com.fluffytrio.giftrio.user.User; +import com.fluffytrio.giftrio.user.entity.User; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/security/config/SecurityConfiguration.java b/giftrio/src/main/java/com/fluffytrio/giftrio/security/config/SecurityConfiguration.java new file mode 100644 index 0000000..34b0858 --- /dev/null +++ b/giftrio/src/main/java/com/fluffytrio/giftrio/security/config/SecurityConfiguration.java @@ -0,0 +1,78 @@ +package com.fluffytrio.giftrio.security.config; + +import com.fluffytrio.giftrio.security.filter.EmailPasswordAuthenticationFilter; +import com.fluffytrio.giftrio.security.handler.AuthSuccessHandler; +import com.fluffytrio.giftrio.security.service.EmailPasswordUserDetailsService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +import java.util.Arrays; + +@Configuration +@EnableWebSecurity(debug = true) +public class SecurityConfiguration { + @Autowired + EmailPasswordUserDetailsService emailPasswordUserDetailsService; + + @Autowired + AuthSuccessHandler authSuccessHandler; + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http.csrf().disable() + .sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and() + .httpBasic().disable() + .authorizeRequests() + .antMatchers("/api/v1/users").permitAll() + //.antMatchers(HttpMethod.DELETE).hasRole("ADMIN") + .antMatchers("/admin/**") + .hasRole("ADMIN") + .antMatchers("/api/v1/login").permitAll() + .antMatchers("/api/v1/logout").authenticated() + .and() + .addFilterAt(getEmailPasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); + + return http.build(); + } + + @Bean + public EmailPasswordAuthenticationFilter getEmailPasswordAuthenticationFilter() { + EmailPasswordAuthenticationFilter emailPasswordAuthenticationFilter = new EmailPasswordAuthenticationFilter(getLoginPath(), getAuthManager()); + emailPasswordAuthenticationFilter.setAuthenticationSuccessHandler(authSuccessHandler); + return emailPasswordAuthenticationFilter; + } + + @Bean + public AntPathRequestMatcher getLoginPath() { + return new AntPathRequestMatcher("/api/v1/login", "POST"); + } + + @Bean + public PasswordEncoder getPasswordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + public AuthenticationManager getAuthManager() { + DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider(); + daoAuthenticationProvider.setUserDetailsService(emailPasswordUserDetailsService); + daoAuthenticationProvider.setPasswordEncoder(getPasswordEncoder()); + + return new ProviderManager(Arrays.asList(new AuthenticationProvider[] {daoAuthenticationProvider})); + } +} diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/security/filter/EmailPasswordAuthenticationFilter.java b/giftrio/src/main/java/com/fluffytrio/giftrio/security/filter/EmailPasswordAuthenticationFilter.java new file mode 100644 index 0000000..a06ddaa --- /dev/null +++ b/giftrio/src/main/java/com/fluffytrio/giftrio/security/filter/EmailPasswordAuthenticationFilter.java @@ -0,0 +1,44 @@ +package com.fluffytrio.giftrio.security.filter; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fluffytrio.giftrio.auth.dto.LoginDto; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationServiceException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; +import org.springframework.security.web.util.matcher.RequestMatcher; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class EmailPasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter { + private final ObjectMapper objectMapper = new ObjectMapper(); + + + public EmailPasswordAuthenticationFilter(RequestMatcher requiresAuthenticationRequestMatcher, + AuthenticationManager authenticationManager) { + super(requiresAuthenticationRequestMatcher); + this.setAuthenticationManager(authenticationManager); + } + + @Override + public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { + if (!request.getMethod().equals("POST")) { + throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); + } + + LoginDto loginDto = objectMapper.readValue(request.getInputStream(), LoginDto.class); + + String email = loginDto.getEmail(); + String password = loginDto.getPassword(); + System.out.println("check: "+email+" "+password); + + UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(email, password); + + return super.getAuthenticationManager().authenticate(authRequest); + } +} diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/security/handler/AuthFailureHandler.java b/giftrio/src/main/java/com/fluffytrio/giftrio/security/handler/AuthFailureHandler.java new file mode 100644 index 0000000..3c37480 --- /dev/null +++ b/giftrio/src/main/java/com/fluffytrio/giftrio/security/handler/AuthFailureHandler.java @@ -0,0 +1,34 @@ +package com.fluffytrio.giftrio.security.handler; + +import lombok.RequiredArgsConstructor; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.CredentialsExpiredException; +import org.springframework.security.authentication.DisabledException; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; +import org.springframework.stereotype.Component; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@RequiredArgsConstructor +@Component +public class AuthFailureHandler extends SimpleUrlAuthenticationFailureHandler { + @Override + public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException authenticationException) throws IOException, ServletException { + String msg = "로그인 실패"; + + if (authenticationException instanceof DisabledException) { + msg += " - 비활성화된 계정입니다."; + } else if (authenticationException instanceof CredentialsExpiredException) { + msg += " - 만료된 로그인 정보입니다."; + } else if (authenticationException instanceof BadCredentialsException) { + msg += " - 로그인 정보가 유효하지 않습니다."; + } + + setDefaultFailureUrl("/login?error=true&exception="+msg); + super.onAuthenticationFailure(request, response, authenticationException); + } +} diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/security/handler/AuthSuccessHandler.java b/giftrio/src/main/java/com/fluffytrio/giftrio/security/handler/AuthSuccessHandler.java new file mode 100644 index 0000000..e84fa8e --- /dev/null +++ b/giftrio/src/main/java/com/fluffytrio/giftrio/security/handler/AuthSuccessHandler.java @@ -0,0 +1,27 @@ +package com.fluffytrio.giftrio.security.handler; + +import com.fluffytrio.giftrio.user.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; +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.time.LocalDateTime; + +@RequiredArgsConstructor +@Component +public class AuthSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { + private final UserRepository userRepository; + + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { + userRepository.updateUserLastLogin(authentication.getName(), LocalDateTime.now()); + setDefaultTargetUrl("/api/v1/calendars"); + + super.onAuthenticationSuccess(request, response, authentication); + } +} diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/security/service/EmailPasswordUserDetailsService.java b/giftrio/src/main/java/com/fluffytrio/giftrio/security/service/EmailPasswordUserDetailsService.java new file mode 100644 index 0000000..2a472dd --- /dev/null +++ b/giftrio/src/main/java/com/fluffytrio/giftrio/security/service/EmailPasswordUserDetailsService.java @@ -0,0 +1,28 @@ +package com.fluffytrio.giftrio.security.service; + +import com.fluffytrio.giftrio.user.UserRepository; +import com.fluffytrio.giftrio.user.entity.User; +import lombok.RequiredArgsConstructor; +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.stereotype.Service; + +import java.util.Optional; + +@RequiredArgsConstructor +@Service +public class EmailPasswordUserDetailsService implements UserDetailsService { + @Autowired + private final UserRepository userRepository; + + @Override + public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { + Optional user = userRepository.getUserByEmail(email); + if (user.isEmpty()) { + throw new UsernameNotFoundException("로그인 정보와 일치하는 계정이 없습니다."); + } + return user.get(); + } +} diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/user/Role.java b/giftrio/src/main/java/com/fluffytrio/giftrio/user/Role.java deleted file mode 100644 index 4c82b00..0000000 --- a/giftrio/src/main/java/com/fluffytrio/giftrio/user/Role.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.fluffytrio.giftrio.user; - -public enum Role { - ADMIN, - USER -} \ No newline at end of file diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/user/User.java b/giftrio/src/main/java/com/fluffytrio/giftrio/user/User.java deleted file mode 100644 index da3ca6d..0000000 --- a/giftrio/src/main/java/com/fluffytrio/giftrio/user/User.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.fluffytrio.giftrio.user; - - -import lombok.*; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.jpa.domain.support.AuditingEntityListener; - -import javax.persistence.*; -import java.time.LocalDateTime; - -@Entity -@Getter -@Builder -@NoArgsConstructor -@AllArgsConstructor -@EntityListeners(AuditingEntityListener.class) -@Table(name = "Users") -public class User { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - @Enumerated - private Role role; - private String email; - private String userName; - private String password; - - @CreatedDate - @Column(name = "created_at", nullable = false, updatable = false) - private LocalDateTime createdAt; - - @LastModifiedDate - @Column(name = "updated_at") - private LocalDateTime updatedAt; - - @Column(name = "is_delete", nullable = false, columnDefinition = "boolean default false") - private boolean isDelete; - - public void delete() { - this.isDelete = true; - } -} \ No newline at end of file diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/user/UserController.java b/giftrio/src/main/java/com/fluffytrio/giftrio/user/UserController.java index 958bea3..e4a03d3 100644 --- a/giftrio/src/main/java/com/fluffytrio/giftrio/user/UserController.java +++ b/giftrio/src/main/java/com/fluffytrio/giftrio/user/UserController.java @@ -1,11 +1,11 @@ package com.fluffytrio.giftrio.user; import com.fluffytrio.giftrio.user.dto.UserRequestDto; +import com.fluffytrio.giftrio.user.dto.UserResponseDto; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import java.util.List; -import java.util.Optional; @RequiredArgsConstructor @RestController @@ -14,27 +14,28 @@ public class UserController { private final UserService userService; @PostMapping() - public User addUser(@RequestBody UserRequestDto userRequestDto) { + public UserResponseDto addUser(@RequestBody UserRequestDto userRequestDto) { return userService.addUser(userRequestDto); } @GetMapping("/{userId}") - public Optional getUser(@PathVariable Long userId) { + public UserResponseDto getUser(@PathVariable Long userId) { return userService.getUser(userId); } @GetMapping() - public List getUsers() { + public List getUsers() { return userService.getUsers(); } @PutMapping("/{userId}") - public User updateUser(@PathVariable Long userId, @RequestBody User newUserInfo) { + public UserResponseDto updateUser(@PathVariable Long userId, @RequestBody UserRequestDto newUserInfo) { return userService.updateUser(userId, newUserInfo); } @DeleteMapping("/{userId}") public boolean deleteUser(@PathVariable Long userId) { + System.out.println(userId); return userService.deleteUser(userId); } } diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/user/UserMapper.java b/giftrio/src/main/java/com/fluffytrio/giftrio/user/UserMapper.java new file mode 100644 index 0000000..39a5ccd --- /dev/null +++ b/giftrio/src/main/java/com/fluffytrio/giftrio/user/UserMapper.java @@ -0,0 +1,30 @@ +package com.fluffytrio.giftrio.user; + +import com.fluffytrio.giftrio.user.dto.UserRequestDto; +import com.fluffytrio.giftrio.user.dto.UserResponseDto; +import com.fluffytrio.giftrio.user.entity.User; + +public class UserMapper { + public static UserResponseDto toUserResponseDto (User user) { + if (user == null) { + return null; + } + + return UserResponseDto.builder() + .id(user.getId()) + .role(user.getRole().getAuthority()) + .email(user.getEmail()) + .nickname(user.getNickname()) + .build(); + } + + public static User toUser(UserRequestDto userRequestDto) { + return User.builder() + .id(userRequestDto.getId()) + .role(userRequestDto.getRole()) + .email(userRequestDto.getEmail()) + .password(userRequestDto.getPassword()) + .nickname(userRequestDto.getNickname()) + .build(); + } +} diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/user/UserRepository.java b/giftrio/src/main/java/com/fluffytrio/giftrio/user/UserRepository.java index 3a00e85..6d51154 100644 --- a/giftrio/src/main/java/com/fluffytrio/giftrio/user/UserRepository.java +++ b/giftrio/src/main/java/com/fluffytrio/giftrio/user/UserRepository.java @@ -1,9 +1,23 @@ package com.fluffytrio.giftrio.user; +import com.fluffytrio.giftrio.user.entity.User; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import javax.transaction.Transactional; +import java.time.LocalDateTime; import java.util.List; +import java.util.Optional; public interface UserRepository extends JpaRepository { + static final String UPDATE_USER_LAST_LOGIN = "UPDATE Users SET LAST_LOGIN_TIME = :lastLoginTime WHERE EMAIL = :email"; + + @Transactional + @Modifying + @Query(value = UPDATE_USER_LAST_LOGIN, nativeQuery = true) + public int updateUserLastLogin(@Param("email") String email, @Param("lastLoginTime") LocalDateTime lastLoginTime); + Optional getUserByEmail(String email); List getUsersByEmail(String email); } diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/user/UserService.java b/giftrio/src/main/java/com/fluffytrio/giftrio/user/UserService.java index 7f97d87..69cd760 100644 --- a/giftrio/src/main/java/com/fluffytrio/giftrio/user/UserService.java +++ b/giftrio/src/main/java/com/fluffytrio/giftrio/user/UserService.java @@ -1,12 +1,17 @@ package com.fluffytrio.giftrio.user; import com.fluffytrio.giftrio.user.dto.UserRequestDto; +import com.fluffytrio.giftrio.user.dto.UserResponseDto; +import com.fluffytrio.giftrio.user.entity.User; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import javax.transaction.Transactional; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; @RequiredArgsConstructor @@ -14,33 +19,67 @@ public class UserService { private final UserRepository userRepository; + @Autowired + private PasswordEncoder passwordEncoder; + @Transactional - public User addUser(UserRequestDto userRequestDto) { + public UserResponseDto addUser(UserRequestDto userRequestDto) { if (userRepository.getUsersByEmail(userRequestDto.getEmail()).size() > 0) { throw new IllegalArgumentException("이미 가입된 메일 주소입니다."); } - return userRepository.save(userRequestDto.toEntity()); + userRequestDto.setPassword(passwordEncoder.encode(userRequestDto.getPassword())); + + User user = userRepository.save(UserMapper.toUser(userRequestDto)); + + return UserMapper.toUserResponseDto(user); } - public Optional getUser(Long userId) { - return userRepository.findById(userId); + public UserResponseDto getUser(Long userId) { + Optional user = userRepository.findById(userId); + if (user.isPresent()) { + return UserMapper.toUserResponseDto(user.get()); + } else { + return null; + } } - public List getUsers() { - return userRepository.findAll(); + public List getUsers() { + List users = userRepository.findAll(); + return users.stream() + .map(UserMapper::toUserResponseDto) + .collect(Collectors.toList()); } @Transactional - public User updateUser(Long userId, User newUserInfo) { - return userRepository.save(newUserInfo); + public UserResponseDto updateUser(Long userId, UserRequestDto newUserInfo) { + Optional user = userRepository.findById(userId); + if (user.isPresent()) { + User existingUser = user.get(); + + User newUser = User.builder() + .id(userId) + .role(existingUser.getRole()) + .email(newUserInfo.getEmail() == null ? existingUser.getEmail() : newUserInfo.getEmail()) + .nickname(newUserInfo.getNickname() == null ? existingUser.getNickname() : newUserInfo.getNickname()) + .password(newUserInfo.getPassword() == null ? existingUser.getPassword() : newUserInfo.getPassword()) + .lastLoginTime(existingUser.getLastLoginTime()) + .isDelete(existingUser.isDelete()) + .build(); + User updatedUser = userRepository.save(newUser); + + return UserMapper.toUserResponseDto(updatedUser); + } + return null; } @Transactional public boolean deleteUser(Long userId) { Optional user = userRepository.findById(userId); if (user.isPresent()) { - user.get().delete(); - return userRepository.save(user.get()).isDelete(); + User deletedUser = user.get(); + deletedUser.delete(); + System.out.println(deletedUser); + return userRepository.save(deletedUser).isDelete(); } return false; diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/user/dto/UserRequestDto.java b/giftrio/src/main/java/com/fluffytrio/giftrio/user/dto/UserRequestDto.java index e89cc54..a6ccbda 100644 --- a/giftrio/src/main/java/com/fluffytrio/giftrio/user/dto/UserRequestDto.java +++ b/giftrio/src/main/java/com/fluffytrio/giftrio/user/dto/UserRequestDto.java @@ -1,17 +1,21 @@ package com.fluffytrio.giftrio.user.dto; -import com.fluffytrio.giftrio.user.Role; -import com.fluffytrio.giftrio.user.User; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fluffytrio.giftrio.user.entity.Role; +import com.fluffytrio.giftrio.user.entity.User; import lombok.Builder; import lombok.Getter; +import lombok.Setter; @Getter @Builder +@JsonInclude(JsonInclude.Include.NON_NULL) public class UserRequestDto { private Long id; private Role role; private String email; - private String userName; + private String nickname; + @Setter private String password; public User toEntity() { @@ -19,8 +23,8 @@ public User toEntity() { .id(id) .role(role) .email(email) - .userName(userName) .password(password) + .nickname(nickname) .build(); } } diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/user/dto/UserResponseDto.java b/giftrio/src/main/java/com/fluffytrio/giftrio/user/dto/UserResponseDto.java new file mode 100644 index 0000000..429f324 --- /dev/null +++ b/giftrio/src/main/java/com/fluffytrio/giftrio/user/dto/UserResponseDto.java @@ -0,0 +1,13 @@ +package com.fluffytrio.giftrio.user.dto; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class UserResponseDto { + private Long id; + private String role; + private String email; + private String nickname; +} diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/user/entity/Role.java b/giftrio/src/main/java/com/fluffytrio/giftrio/user/entity/Role.java new file mode 100644 index 0000000..fa00f3c --- /dev/null +++ b/giftrio/src/main/java/com/fluffytrio/giftrio/user/entity/Role.java @@ -0,0 +1,12 @@ +package com.fluffytrio.giftrio.user.entity; + +import org.springframework.security.core.GrantedAuthority; + +public enum Role implements GrantedAuthority { + ADMIN, USER; + + @Override + public String getAuthority() { + return name(); + } +} \ No newline at end of file diff --git a/giftrio/src/main/java/com/fluffytrio/giftrio/user/entity/User.java b/giftrio/src/main/java/com/fluffytrio/giftrio/user/entity/User.java new file mode 100644 index 0000000..49fedf2 --- /dev/null +++ b/giftrio/src/main/java/com/fluffytrio/giftrio/user/entity/User.java @@ -0,0 +1,93 @@ +package com.fluffytrio.giftrio.user.entity; + + +import lombok.*; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import javax.persistence.*; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Entity +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@EntityListeners(AuditingEntityListener.class) +@Table(name = "Users") +public class User implements UserDetails { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(nullable = false) + private Long id; + + @Enumerated + @Column(nullable = false) + private Role role; + + @Column(unique = true, nullable = false) + private String email; + + @Column(nullable = false) + private String nickname; + + @Column(nullable = false) + private String password; + + private LocalDateTime lastLoginTime; + + @CreatedDate + @Column(name = "created_at", nullable = false, updatable = false) + private LocalDateTime createdAt; + + @LastModifiedDate + @Column(name = "updated_at", nullable = false) + private LocalDateTime updatedAt; + + @Column(name = "is_delete", nullable = false, columnDefinition = "boolean default false") + private boolean isDelete; + + public void delete() { + this.isDelete = true; + } + + @Override + public Collection getAuthorities() { + List authorities = new ArrayList(); + authorities.add(new SimpleGrantedAuthority(this.role.getAuthority())); + + return authorities; + } + + @Override + public String getUsername() { + return email; + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return !isDelete; + } +} \ No newline at end of file diff --git a/giftrio/src/test/java/com/fluffytrio/giftrio/advent/AdventControllerTest.java b/giftrio/src/test/java/com/fluffytrio/giftrio/advent/AdventControllerTest.java index a990f58..5bdb8a7 100644 --- a/giftrio/src/test/java/com/fluffytrio/giftrio/advent/AdventControllerTest.java +++ b/giftrio/src/test/java/com/fluffytrio/giftrio/advent/AdventControllerTest.java @@ -23,9 +23,9 @@ import com.fluffytrio.giftrio.advent.dto.AdventRequestDto; import com.fluffytrio.giftrio.calendar.Calendar; import com.fluffytrio.giftrio.calendar.CalendarRepository; -import com.fluffytrio.giftrio.settings.Setting; -import com.fluffytrio.giftrio.settings.SettingRepository; -import com.fluffytrio.giftrio.user.User; +import com.fluffytrio.giftrio.settings.Settings; +import com.fluffytrio.giftrio.settings.SettingsRepository; +import com.fluffytrio.giftrio.user.entity.User; import com.fluffytrio.giftrio.user.UserRepository; @RunWith(SpringRunner.class) @@ -48,7 +48,7 @@ public class AdventControllerTest { private CalendarRepository calendarRepository; @Autowired - private SettingRepository settingRepository; + private SettingsRepository settingsRepository; public String getApiUrl(){ return String.format("http://localhost:%d/api/v1/advents", port); @@ -69,14 +69,14 @@ public void addAdvent() throws Exception { // create user String userId = "user01"; - String userName = "nickname"; + String nickname = "nickname"; String password = "password"; - userRepository.save(User.builder().email(userId).userName(userName).password(password).build()); + userRepository.save(User.builder().email(userId).password(password).nickname(nickname).build()); User users1 = userRepository.findAll().get(0); // create setting - settingRepository.save(new Setting()); - Setting settings1 = settingRepository.findAll().get(0); + settingsRepository.save(new Settings()); + Settings settings1 = settingsRepository.findAll().get(0); // create calendar LocalDate startDate = LocalDate.now(); diff --git a/giftrio/src/test/java/com/fluffytrio/giftrio/advent/AdventRepositoryTest.java b/giftrio/src/test/java/com/fluffytrio/giftrio/advent/AdventRepositoryTest.java index 622c587..8b9116a 100644 --- a/giftrio/src/test/java/com/fluffytrio/giftrio/advent/AdventRepositoryTest.java +++ b/giftrio/src/test/java/com/fluffytrio/giftrio/advent/AdventRepositoryTest.java @@ -2,9 +2,9 @@ import com.fluffytrio.giftrio.calendar.Calendar; import com.fluffytrio.giftrio.calendar.CalendarRepository; -import com.fluffytrio.giftrio.settings.Setting; -import com.fluffytrio.giftrio.settings.SettingRepository; -import com.fluffytrio.giftrio.user.User; +import com.fluffytrio.giftrio.settings.Settings; +import com.fluffytrio.giftrio.settings.SettingsRepository; +import com.fluffytrio.giftrio.user.entity.User; import com.fluffytrio.giftrio.user.UserRepository; import org.junit.After; import org.junit.Test; @@ -32,7 +32,7 @@ public class AdventRepositoryTest { CalendarRepository calendarRepository; @Autowired - SettingRepository settingRepository; + SettingsRepository settingsRepository; @After public void cleanup() { @@ -47,14 +47,14 @@ public void createAdvent(){ // create user String userId = "user01"; - String userName = "nickname"; String password = "password"; - usersRepository.save(User.builder().email(userId).userName(userName).password(password).build()); + String nickname = "nickname"; + usersRepository.save(User.builder().email(userId).nickname(nickname).password(password).build()); User users1 = usersRepository.findAll().get(0); // create setting - settingRepository.save(new Setting()); - Setting settings1 = settingRepository.findAll().get(0); + settingsRepository.save(new Settings()); + Settings settings1 = settingsRepository.findAll().get(0); // create calendar calendarRepository.save(Calendar.builder().user(users1).settingId(settings1).build()); diff --git a/giftrio/src/test/java/com/fluffytrio/giftrio/auth/AuthControllerTest.java b/giftrio/src/test/java/com/fluffytrio/giftrio/auth/AuthControllerTest.java new file mode 100644 index 0000000..aceb31d --- /dev/null +++ b/giftrio/src/test/java/com/fluffytrio/giftrio/auth/AuthControllerTest.java @@ -0,0 +1,106 @@ +package com.fluffytrio.giftrio.auth; + +import com.fluffytrio.giftrio.auth.dto.LoginDto; +import com.fluffytrio.giftrio.user.UserRepository; +import com.fluffytrio.giftrio.user.dto.UserRequestDto; +import com.fluffytrio.giftrio.user.dto.UserResponseDto; +import com.fluffytrio.giftrio.user.entity.Role; +import com.fluffytrio.giftrio.user.entity.User; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.test.context.junit4.SpringRunner; + +import java.net.URI; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +@RunWith(SpringRunner.class) +@SpringBootTest( + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT +) +public class AuthControllerTest { + @LocalServerPort + private int port; + + @Autowired + private TestRestTemplate restTemplate; + + @Autowired + private UserRepository userRepository; + + @After + public void tearDown() throws Exception { + //userRepository.deleteAll(); + } + + @Test + public void login() throws Exception { + //given + String email = "email3@gmail.com"; + String password = "password3"; + + LoginDto loginDto = LoginDto + .builder() + .email(email) + .password(password) + .build(); + + String url = "http://localhost:"+port+"/api/v1/login"; + + //when + URI uri = restTemplate.postForLocation(url, loginDto); + + //then + assertAll( + () -> assertThat(uri.getPath()).isEqualTo("/api/v1/calendars") + ); + } + + @Test + public void logout() throws Exception { + //given + String role = "USER"; + String email = "newemail@gmail.com"; + String password = "password"; + String nickname = "userName"; + + UserRequestDto requestDto = UserRequestDto + .builder() + .role(Role.valueOf(role)) + .email(email) + .password(password) + .nickname(nickname) + .build(); + + String url = "http://localhost:"+port+"/api/v1/users"; + + //when + ResponseEntity responseEntity = restTemplate.postForEntity(url, requestDto, UserResponseDto.class); + + //then + assertAll( + () -> assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK), + () -> assertThat(responseEntity.getBody().getRole()).isEqualTo(Role.USER.name()), + () -> assertThat(responseEntity.getBody().getEmail()).isEqualTo(email), + () -> assertThat(responseEntity.getBody().getNickname()).isEqualTo(nickname) + ); + + //when + ResponseEntity responseEntitySecond = restTemplate.postForEntity(url, requestDto, User.class); + System.out.println(responseEntitySecond.getHeaders().toSingleValueMap()); + + //then + assertAll( + () -> assertThat(responseEntitySecond.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR) + ); + } +} \ No newline at end of file diff --git a/giftrio/src/test/java/com/fluffytrio/giftrio/calendar/CalendarControllerTest.java b/giftrio/src/test/java/com/fluffytrio/giftrio/calendar/CalendarControllerTest.java index 9dd6262..e6611c7 100644 --- a/giftrio/src/test/java/com/fluffytrio/giftrio/calendar/CalendarControllerTest.java +++ b/giftrio/src/test/java/com/fluffytrio/giftrio/calendar/CalendarControllerTest.java @@ -3,7 +3,7 @@ import com.fluffytrio.giftrio.calendar.dto.CalendarRequestDto; import com.fluffytrio.giftrio.settings.Setting; import com.fluffytrio.giftrio.settings.SettingRepository; -import com.fluffytrio.giftrio.user.User; +import com.fluffytrio.giftrio.user.entity.User; import com.fluffytrio.giftrio.user.UserRepository; import org.junit.After; import org.junit.Test; @@ -56,7 +56,7 @@ public void tearDown() throws Exception { public void addCalendarTest() throws Exception { User users = User.builder() .email("tester") - .userName("name") + .nickname("name") .password("123456") .build(); users = userRepository.save(users); diff --git a/giftrio/src/test/java/com/fluffytrio/giftrio/calendar/CalendarRepositoryTest.java b/giftrio/src/test/java/com/fluffytrio/giftrio/calendar/CalendarRepositoryTest.java index 3006167..50a3ba4 100644 --- a/giftrio/src/test/java/com/fluffytrio/giftrio/calendar/CalendarRepositoryTest.java +++ b/giftrio/src/test/java/com/fluffytrio/giftrio/calendar/CalendarRepositoryTest.java @@ -2,7 +2,7 @@ import com.fluffytrio.giftrio.settings.Setting; import com.fluffytrio.giftrio.settings.SettingRepository; -import com.fluffytrio.giftrio.user.User; +import com.fluffytrio.giftrio.user.entity.User; import com.fluffytrio.giftrio.user.UserRepository; import org.junit.After; import org.junit.Test; @@ -37,9 +37,9 @@ public void createCalendar() { ///users //given String userId = "user01"; - String userName = "nickname"; + String nickname = "nickname"; String password = "password"; - userRepository.save(User.builder().email(userId).userName(userName).password(password).build()); + userRepository.save(User.builder().email(userId).nickname(nickname).password(password).build()); //when List usersList = userRepository.findAll(); //then diff --git a/giftrio/src/test/java/com/fluffytrio/giftrio/user/UserControllerTest.java b/giftrio/src/test/java/com/fluffytrio/giftrio/user/UserControllerTest.java index 38acf84..61079aa 100644 --- a/giftrio/src/test/java/com/fluffytrio/giftrio/user/UserControllerTest.java +++ b/giftrio/src/test/java/com/fluffytrio/giftrio/user/UserControllerTest.java @@ -1,7 +1,9 @@ package com.fluffytrio.giftrio.user; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fluffytrio.giftrio.user.dto.UserRequestDto; +import com.fluffytrio.giftrio.user.dto.UserResponseDto; +import com.fluffytrio.giftrio.user.entity.Role; +import com.fluffytrio.giftrio.user.entity.User; import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; @@ -17,7 +19,9 @@ import static org.junit.jupiter.api.Assertions.assertAll; @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest( + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT +) public class UserControllerTest { @LocalServerPort private int port; @@ -37,16 +41,16 @@ public void tearDown() throws Exception { public void addUser() throws Exception { //given String role = "USER"; - String email = "email@gmail.com"; - String userName = "userName"; - String password = "password"; + String email = "email3@gmail.com"; + String password = "password3"; + String nickname = "nickname3"; UserRequestDto requestDto = UserRequestDto .builder() .role(Role.valueOf(role)) .email(email) - .userName(userName) .password(password) + .nickname(nickname) .build(); String url = "http://localhost:"+port+"/api/v1/users"; @@ -67,27 +71,28 @@ public void addDuplicateUser() throws Exception { //given String role = "USER"; String email = "newemail@gmail.com"; - String userName = "userName"; String password = "password"; + String nickname = "userName"; UserRequestDto requestDto = UserRequestDto .builder() .role(Role.valueOf(role)) .email(email) - .userName(userName) .password(password) + .nickname(nickname) .build(); String url = "http://localhost:"+port+"/api/v1/users"; //when - ResponseEntity responseEntity = restTemplate.postForEntity(url, requestDto, User.class); + ResponseEntity responseEntity = restTemplate.postForEntity(url, requestDto, UserResponseDto.class); //then assertAll( () -> assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK), - () -> assertThat(responseEntity.getBody().getRole()).isEqualTo(Role.USER), - () -> assertThat(responseEntity.getBody().getEmail()).isEqualTo(email) + () -> assertThat(responseEntity.getBody().getRole()).isEqualTo(Role.USER.name()), + () -> assertThat(responseEntity.getBody().getEmail()).isEqualTo(email), + () -> assertThat(responseEntity.getBody().getNickname()).isEqualTo(nickname) ); //when @@ -97,7 +102,6 @@ public void addDuplicateUser() throws Exception { //then assertAll( () -> assertThat(responseEntitySecond.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR) - ); } @@ -107,18 +111,16 @@ public void getUser() throws Exception { String url = "http://localhost:"+port+"/api/v1/users/1"; //when - ResponseEntity responseEntity = restTemplate.getForEntity(url, User.class); + ResponseEntity responseEntity = restTemplate.getForEntity(url, UserResponseDto.class); //then String email = "email@gmail.com"; - String userName = "userName"; - String password = "password"; + String nickname = "nickname"; assertAll( () -> assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK), () -> assertThat(responseEntity.getBody().getEmail()).isEqualTo(email), - () -> assertThat(responseEntity.getBody().getUserName()).isEqualTo(userName), - () -> assertThat(responseEntity.getBody().getPassword()).isEqualTo(password) + () -> assertThat(responseEntity.getBody().getNickname()).isEqualTo(nickname) ); } @@ -128,54 +130,53 @@ public void getUsers() throws Exception { String url = "http://localhost:"+port+"/api/v1/users"; //when - ResponseEntity responseEntity = restTemplate.getForEntity(url, User[].class); + ResponseEntity responseEntity = restTemplate.getForEntity(url, UserResponseDto[].class); //then assertAll( () -> assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK), - () -> assertThat(responseEntity.getBody().length).isEqualTo(1) + () -> assertThat(responseEntity.getBody().length).isEqualTo(2) ); } @Test public void updateUsers() throws Exception { //given - String url = "http://localhost:"+port+"/api/v1/users/1"; + Long userId = 2L; + String url = "http://localhost:"+port+"/api/v1/users/"+userId; - String email = "email@gmail.com"; - String userName = "userName2"; + String email = "modifiedEmail@gmail.com"; String password = "password2"; - User requestDto = UserRequestDto + UserRequestDto requestDto = UserRequestDto .builder() - .id(1L) + .id(userId) .email(email) - .userName(userName) .password(password) - .build().toEntity(); + .build(); //when - restTemplate.put(url, requestDto, User.class); + restTemplate.put(url, requestDto, UserResponseDto.class); //then - User responseEntity = userRepository.findById(1L).get(); + User responseEntity = userRepository.findById(userId).get(); assertAll( () -> assertThat(responseEntity.getEmail()).isEqualTo(email), - () -> assertThat(responseEntity.getUserName()).isEqualTo(userName), + () -> assertThat(responseEntity.getNickname()).isEqualTo("userName"), () -> assertThat(responseEntity.getPassword()).isEqualTo(password) ); } @Test - public void deleteUsers() throws Exception { + public void deleteUser() throws Exception { //given - String url = "http://localhost:"+port+"/api/v1/users/1"; + String url = "http://localhost:"+port+"/api/v1/users/2"; //when restTemplate.delete(url); //then - User responseEntity = userRepository.findById(1L).get(); - assertThat(responseEntity.isDelete() == true); + //User responseEntity = userRepository.findById(2L).get(); + //assertThat(responseEntity.isDelete() == true); } -} +} \ No newline at end of file diff --git a/giftrio/src/test/java/com/fluffytrio/giftrio/user/UserRepositoryTest.java b/giftrio/src/test/java/com/fluffytrio/giftrio/user/UserRepositoryTest.java index e742a46..ccd92be 100644 --- a/giftrio/src/test/java/com/fluffytrio/giftrio/user/UserRepositoryTest.java +++ b/giftrio/src/test/java/com/fluffytrio/giftrio/user/UserRepositoryTest.java @@ -1,5 +1,6 @@ package com.fluffytrio.giftrio.user; +import com.fluffytrio.giftrio.user.entity.User; import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; @@ -26,10 +27,10 @@ public void cleanup() { public void createUser() { //given String userId = "user01"; - String userName = "nickname"; + String nickname = "nickname"; String password = "password"; - userRepository.save(User.builder().email(userId).userName(userName).password(password).build()); + userRepository.save(User.builder().email(userId).nickname(nickname).password(password).build()); //when List userList = userRepository.findAll(); @@ -37,7 +38,7 @@ public void createUser() { //then User user01 = userList.get(0); assertThat(user01.getEmail()).isEqualTo(userId); - assertThat(user01.getUserName()).isEqualTo(userName); + assertThat(user01.getNickname()).isEqualTo(nickname); assertThat(user01.getPassword()).isEqualTo(password); } }