From 76654bca0206d0d11ce101372186422c0fc2d3a6 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Sat, 17 Aug 2019 12:34:44 +0900 Subject: [PATCH] refactoring --- pom.xml | 33 ++-- .../java/com/totopia/server/Application.java | 15 -- .../ApplicationGsonExclusionStrategy.java | 30 ---- .../com/totopia/server/ServerApplication.java | 15 ++ .../auth/controller/AuthController.java | 98 +++++++++++ .../auth/payload/JwtSigninResponse.java | 13 ++ .../server/auth/payload/SigninRequest.java | 21 +++ .../server/auth/payload/SignupRequest.java | 28 ++++ .../exception/ResourceNotFoundException.java | 22 --- .../commons/base/gson/annotation/Exclude.java | 11 -- .../server/commons/base/model/Base.java | 28 ---- .../commons/data/entity/DateAuditEntity.java | 40 +++++ .../data/entity/UserDateAuditEntity.java | 36 ++++ .../commons/data/payload/ApiResponse.java | 15 ++ .../exception/ResourceNotFoundException.java | 33 ++++ .../totopia/server/config/AuditingConfig.java | 40 +++++ .../totopia/server/config/WebMvcConfig.java | 16 ++ .../server/config/WebSecurityConfig.java | 66 ++++++++ .../jwt/JwtAuthenticationEntryPoint.java | 25 +++ .../config/jwt/JwtAuthenticationFilter.java | 66 ++++++++ .../server/config/jwt/JwtTokenProvider.java | 73 +++++++++ .../config/security/SecurityUserDetails.java | 99 +++++++++++ .../security/SecurityUserDetailsService.java | 36 ++++ .../totopia/server/init/DbInitializer.java | 58 +++++++ .../controller/DashboardController.java | 111 +++++++++++++ .../dashboard/entity/DashboardEntity.java | 54 ++++++ .../repository/DashboardRepository.java | 24 +++ .../user/controller/UserController.java | 125 +++++++------- .../user/entity/BankAccountEntity.java | 49 ++++++ .../modules/user/entity/RoleEntity.java | 37 +++++ .../modules/user/entity/UserEntity.java | 131 +++++++++++++++ .../repository/BankAccountRepository.java | 9 + .../user/repository/RoleRepository.java | 12 ++ .../user/repository/UserRepository.java | 54 ++++++ .../server/modules/user/type/RoleName.java | 5 + .../server/user/model/BankAccount.java | 39 ----- .../com/totopia/server/user/model/Role.java | 44 ----- .../com/totopia/server/user/model/User.java | 143 ---------------- .../repository/BankAccountRepository.java | 9 - .../user/repository/RoleRepository.java | 9 - .../user/repository/UserRepository.java | 42 ----- .../server/user/service/UserService.java | 9 - src/main/resources/{data.sql => _data.sql} | 0 src/main/resources/application.yml | 34 ++-- .../repository/BankAccountRepositoryTest.java | 103 ++++++++++++ .../user/repository/UserRepositoryTest.java | 118 ++++++++++++++ .../repository/BankAccountRepositoryTest.java | 105 ------------ .../user/repository/UserRepositoryTest.java | 154 ------------------ src/test/resources/docker-compose.yml | 11 ++ 49 files changed, 1595 insertions(+), 753 deletions(-) delete mode 100644 src/main/java/com/totopia/server/Application.java delete mode 100644 src/main/java/com/totopia/server/ApplicationGsonExclusionStrategy.java create mode 100644 src/main/java/com/totopia/server/ServerApplication.java create mode 100644 src/main/java/com/totopia/server/auth/controller/AuthController.java create mode 100644 src/main/java/com/totopia/server/auth/payload/JwtSigninResponse.java create mode 100644 src/main/java/com/totopia/server/auth/payload/SigninRequest.java create mode 100644 src/main/java/com/totopia/server/auth/payload/SignupRequest.java delete mode 100644 src/main/java/com/totopia/server/commons/base/exception/ResourceNotFoundException.java delete mode 100644 src/main/java/com/totopia/server/commons/base/gson/annotation/Exclude.java delete mode 100644 src/main/java/com/totopia/server/commons/base/model/Base.java create mode 100644 src/main/java/com/totopia/server/commons/data/entity/DateAuditEntity.java create mode 100644 src/main/java/com/totopia/server/commons/data/entity/UserDateAuditEntity.java create mode 100644 src/main/java/com/totopia/server/commons/data/payload/ApiResponse.java create mode 100644 src/main/java/com/totopia/server/commons/exception/ResourceNotFoundException.java create mode 100644 src/main/java/com/totopia/server/config/AuditingConfig.java create mode 100644 src/main/java/com/totopia/server/config/WebMvcConfig.java create mode 100644 src/main/java/com/totopia/server/config/WebSecurityConfig.java create mode 100644 src/main/java/com/totopia/server/config/jwt/JwtAuthenticationEntryPoint.java create mode 100644 src/main/java/com/totopia/server/config/jwt/JwtAuthenticationFilter.java create mode 100644 src/main/java/com/totopia/server/config/jwt/JwtTokenProvider.java create mode 100644 src/main/java/com/totopia/server/config/security/SecurityUserDetails.java create mode 100644 src/main/java/com/totopia/server/config/security/SecurityUserDetailsService.java create mode 100644 src/main/java/com/totopia/server/init/DbInitializer.java create mode 100644 src/main/java/com/totopia/server/modules/dashboard/controller/DashboardController.java create mode 100644 src/main/java/com/totopia/server/modules/dashboard/entity/DashboardEntity.java create mode 100644 src/main/java/com/totopia/server/modules/dashboard/repository/DashboardRepository.java rename src/main/java/com/totopia/server/{ => modules}/user/controller/UserController.java (63%) create mode 100644 src/main/java/com/totopia/server/modules/user/entity/BankAccountEntity.java create mode 100644 src/main/java/com/totopia/server/modules/user/entity/RoleEntity.java create mode 100644 src/main/java/com/totopia/server/modules/user/entity/UserEntity.java create mode 100644 src/main/java/com/totopia/server/modules/user/repository/BankAccountRepository.java create mode 100644 src/main/java/com/totopia/server/modules/user/repository/RoleRepository.java create mode 100644 src/main/java/com/totopia/server/modules/user/repository/UserRepository.java create mode 100644 src/main/java/com/totopia/server/modules/user/type/RoleName.java delete mode 100644 src/main/java/com/totopia/server/user/model/BankAccount.java delete mode 100644 src/main/java/com/totopia/server/user/model/Role.java delete mode 100644 src/main/java/com/totopia/server/user/model/User.java delete mode 100644 src/main/java/com/totopia/server/user/repository/BankAccountRepository.java delete mode 100644 src/main/java/com/totopia/server/user/repository/RoleRepository.java delete mode 100644 src/main/java/com/totopia/server/user/repository/UserRepository.java delete mode 100644 src/main/java/com/totopia/server/user/service/UserService.java rename src/main/resources/{data.sql => _data.sql} (100%) create mode 100644 src/test/java/com/totopia/server/modules/user/repository/BankAccountRepositoryTest.java create mode 100644 src/test/java/com/totopia/server/modules/user/repository/UserRepositoryTest.java delete mode 100644 src/test/java/com/totopia/server/user/repository/BankAccountRepositoryTest.java delete mode 100644 src/test/java/com/totopia/server/user/repository/UserRepositoryTest.java create mode 100644 src/test/resources/docker-compose.yml diff --git a/pom.xml b/pom.xml index d54d008..27b873d 100644 --- a/pom.xml +++ b/pom.xml @@ -12,11 +12,13 @@ server 0.0.1-SNAPSHOT server - Demo project for Spring Boot + Project for Totopia server + UTF-8 + UTF-8 1.8 - 2.8.5 + 0.9.1 @@ -31,26 +33,23 @@ org.springframework.boot spring-boot-starter-web - - - - org.springframework.boot - spring-boot-starter-json - - + org.springframework.boot spring-boot-starter-websocket + + - org.springframework.kafka - spring-kafka + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + - com.google.code.gson - gson - ${gson.version} + io.jsonwebtoken + jjwt + ${jjwt.version} @@ -79,11 +78,7 @@ spring-boot-starter-test test - - org.springframework.kafka - spring-kafka-test - test - + org.springframework.security spring-security-test diff --git a/src/main/java/com/totopia/server/Application.java b/src/main/java/com/totopia/server/Application.java deleted file mode 100644 index 4c6dde2..0000000 --- a/src/main/java/com/totopia/server/Application.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.totopia.server; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; - -@SpringBootApplication -@EnableAutoConfiguration(exclude = { JacksonAutoConfiguration.class }) -public class Application { - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} diff --git a/src/main/java/com/totopia/server/ApplicationGsonExclusionStrategy.java b/src/main/java/com/totopia/server/ApplicationGsonExclusionStrategy.java deleted file mode 100644 index 3e16a42..0000000 --- a/src/main/java/com/totopia/server/ApplicationGsonExclusionStrategy.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.totopia.server; - -import com.google.gson.ExclusionStrategy; -import com.google.gson.FieldAttributes; -import com.totopia.server.commons.base.gson.annotation.Exclude; - -import org.springframework.boot.autoconfigure.gson.GsonBuilderCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class ApplicationGsonExclusionStrategy { - - @Bean - GsonBuilderCustomizer gsonBuilderCustomizer() { - return (gsonBuilder) -> gsonBuilder.addSerializationExclusionStrategy(new ExclusionStrategy() { - - @Override - public boolean shouldSkipField(FieldAttributes f) { - return f.getAnnotation(Exclude.class) != null; - } - - @Override - public boolean shouldSkipClass(Class clazz) { - return false; - } - - }); - } -} diff --git a/src/main/java/com/totopia/server/ServerApplication.java b/src/main/java/com/totopia/server/ServerApplication.java new file mode 100644 index 0000000..332a3f9 --- /dev/null +++ b/src/main/java/com/totopia/server/ServerApplication.java @@ -0,0 +1,15 @@ +package com.totopia.server; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ServerApplication { + + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + +} + + diff --git a/src/main/java/com/totopia/server/auth/controller/AuthController.java b/src/main/java/com/totopia/server/auth/controller/AuthController.java new file mode 100644 index 0000000..292bf2c --- /dev/null +++ b/src/main/java/com/totopia/server/auth/controller/AuthController.java @@ -0,0 +1,98 @@ +package com.totopia.server.auth.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; + +import javax.validation.Valid; + +import com.totopia.server.auth.payload.JwtSigninResponse; +import com.totopia.server.auth.payload.SigninRequest; +import com.totopia.server.auth.payload.SignupRequest; +import com.totopia.server.commons.data.payload.ApiResponse; +import com.totopia.server.config.jwt.JwtTokenProvider; +import com.totopia.server.modules.user.entity.RoleEntity; +import com.totopia.server.modules.user.entity.UserEntity; +import com.totopia.server.modules.user.repository.RoleRepository; +import com.totopia.server.modules.user.repository.UserRepository; +import com.totopia.server.modules.user.type.RoleName; + +import java.net.URI; +import java.util.Collections; + +/** + * Created by rajeevkumarsingh on 02/08/17. + */ +@RestController +@RequestMapping("/auth") +public class AuthController { + + @Autowired + AuthenticationManager authenticationManager; + + @Autowired + UserRepository userRepository; + + @Autowired + RoleRepository roleRepository; + + @Autowired + PasswordEncoder passwordEncoder; + + @Autowired + JwtTokenProvider tokenProvider; + + @PostMapping("/signin") + public ResponseEntity authenticateUser(@Valid @RequestBody SigninRequest signinRequest) { + + Authentication authentication = authenticationManager.authenticate( + new UsernamePasswordAuthenticationToken(signinRequest.getUsername(), signinRequest.getPassword())); + + SecurityContextHolder.getContext().setAuthentication(authentication); + + String jwt = tokenProvider.generateToken(authentication); + return ResponseEntity.ok(new JwtSigninResponse(jwt)); + } + + @PostMapping("/signup") + public ResponseEntity registerUser(@Valid @RequestBody SignupRequest signupRequest) throws Exception { + if (userRepository.existsByUsername(signupRequest.getUsername())) { + return new ResponseEntity( + ApiResponse.builder().success(false).message("Username is already taken!").build(), HttpStatus.BAD_REQUEST); + } + + if (userRepository.existsByEmail(signupRequest.getEmail())) { + return new ResponseEntity( + ApiResponse.builder().success(false).message("Email Address is already use!").build(), + HttpStatus.BAD_REQUEST); + } + + // Creating user's account + UserEntity user = UserEntity.builder().username(signupRequest.getUsername()).email(signupRequest.getEmail()) + .password(signupRequest.getPassword()).build(); + + user.setPassword(passwordEncoder.encode(user.getPassword())); + + RoleEntity userRole = roleRepository.findByName(RoleName.ROLE_USER) + .orElseThrow(() -> new Exception("User Role not set.")); + + user.setRoles(Collections.singleton(userRole)); + + UserEntity result = userRepository.save(user); + + URI location = ServletUriComponentsBuilder.fromCurrentContextPath().path("/users/{username}") + .buildAndExpand(result.getUsername()).toUri(); + + return ResponseEntity.created(location).body(new ApiResponse(true, "User registered successfully")); + } +} diff --git a/src/main/java/com/totopia/server/auth/payload/JwtSigninResponse.java b/src/main/java/com/totopia/server/auth/payload/JwtSigninResponse.java new file mode 100644 index 0000000..5ef826a --- /dev/null +++ b/src/main/java/com/totopia/server/auth/payload/JwtSigninResponse.java @@ -0,0 +1,13 @@ +package com.totopia.server.auth.payload; + +import lombok.Data; + +@Data +public class JwtSigninResponse { + private String accessToken; + private String tokenType = "Bearer"; + + public JwtSigninResponse(String accessToken) { + this.accessToken = accessToken; + } +} diff --git a/src/main/java/com/totopia/server/auth/payload/SigninRequest.java b/src/main/java/com/totopia/server/auth/payload/SigninRequest.java new file mode 100644 index 0000000..f9f8499 --- /dev/null +++ b/src/main/java/com/totopia/server/auth/payload/SigninRequest.java @@ -0,0 +1,21 @@ +package com.totopia.server.auth.payload; + +import javax.validation.constraints.NotBlank; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class SigninRequest { + @NotBlank + private String username; + + @NotBlank + private String password; + +} diff --git a/src/main/java/com/totopia/server/auth/payload/SignupRequest.java b/src/main/java/com/totopia/server/auth/payload/SignupRequest.java new file mode 100644 index 0000000..247e469 --- /dev/null +++ b/src/main/java/com/totopia/server/auth/payload/SignupRequest.java @@ -0,0 +1,28 @@ +package com.totopia.server.auth.payload; + +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + +import lombok.Data; + +@Data + +public class SignupRequest { + @NotBlank + @Size(min = 4, max = 40) + private String name; + + @NotBlank + @Size(min = 3, max = 15) + private String username; + + @NotBlank + @Size(max = 40) + @Email + private String email; + + @NotBlank + @Size(min = 6, max = 20) + private String password; +} diff --git a/src/main/java/com/totopia/server/commons/base/exception/ResourceNotFoundException.java b/src/main/java/com/totopia/server/commons/base/exception/ResourceNotFoundException.java deleted file mode 100644 index 481ff2d..0000000 --- a/src/main/java/com/totopia/server/commons/base/exception/ResourceNotFoundException.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.totopia.server.commons.base.exception; - -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ResponseStatus(HttpStatus.NOT_FOUND) -public class ResourceNotFoundException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - public ResourceNotFoundException() { - super(); - } - - public ResourceNotFoundException(String message) { - super(message); - } - - public ResourceNotFoundException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/src/main/java/com/totopia/server/commons/base/gson/annotation/Exclude.java b/src/main/java/com/totopia/server/commons/base/gson/annotation/Exclude.java deleted file mode 100644 index daf6dad..0000000 --- a/src/main/java/com/totopia/server/commons/base/gson/annotation/Exclude.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.totopia.server.commons.base.gson.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) -public @interface Exclude { -} diff --git a/src/main/java/com/totopia/server/commons/base/model/Base.java b/src/main/java/com/totopia/server/commons/base/model/Base.java deleted file mode 100644 index 536a7d3..0000000 --- a/src/main/java/com/totopia/server/commons/base/model/Base.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.totopia.server.commons.base.model; - -import lombok.*; -import org.hibernate.annotations.CreationTimestamp; - -import javax.persistence.*; -import java.util.Date; - -@MappedSuperclass -@Data -@Getter -@Setter -public abstract class Base { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Basic - @CreationTimestamp - @Temporal(TemporalType.TIMESTAMP) - @Column(name = "create_date", nullable = false) - private Date createDate; - - @Basic - @Temporal(TemporalType.TIMESTAMP) - @Column(name = "update_date", nullable = false) - private Date updateDate; -} diff --git a/src/main/java/com/totopia/server/commons/data/entity/DateAuditEntity.java b/src/main/java/com/totopia/server/commons/data/entity/DateAuditEntity.java new file mode 100644 index 0000000..d03a635 --- /dev/null +++ b/src/main/java/com/totopia/server/commons/data/entity/DateAuditEntity.java @@ -0,0 +1,40 @@ +package com.totopia.server.commons.data.entity; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import javax.persistence.EntityListeners; +import javax.persistence.MappedSuperclass; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import java.io.Serializable; +import java.util.Date; + +@MappedSuperclass +@EntityListeners(AuditingEntityListener.class) +@JsonIgnoreProperties(value = { "createdAt", "updatedAt" }, allowGetters = true) +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +public abstract class DateAuditEntity implements Serializable { + + private static final long serialVersionUID = 3495202400889041952L; + + @CreatedDate + @Temporal(TemporalType.TIMESTAMP) + private Date createdAt; + + @LastModifiedDate + @Temporal(TemporalType.TIMESTAMP) + private Date updatedAt; + +} diff --git a/src/main/java/com/totopia/server/commons/data/entity/UserDateAuditEntity.java b/src/main/java/com/totopia/server/commons/data/entity/UserDateAuditEntity.java new file mode 100644 index 0000000..b3bd322 --- /dev/null +++ b/src/main/java/com/totopia/server/commons/data/entity/UserDateAuditEntity.java @@ -0,0 +1,36 @@ +package com.totopia.server.commons.data.entity; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.LastModifiedBy; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import javax.persistence.MappedSuperclass; + +/** + * Created by rajeevkumarsingh on 19/08/17. + */ + +@MappedSuperclass +@JsonIgnoreProperties(value = { "createdBy", "updatedBy" }, allowGetters = true) +@SuperBuilder +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = false) +public abstract class UserDateAuditEntity extends DateAuditEntity { + + private static final long serialVersionUID = 6379346917688414915L; + + @CreatedBy + private Long createdBy; + + @LastModifiedBy + private Long updatedBy; + +} diff --git a/src/main/java/com/totopia/server/commons/data/payload/ApiResponse.java b/src/main/java/com/totopia/server/commons/data/payload/ApiResponse.java new file mode 100644 index 0000000..49bfbcd --- /dev/null +++ b/src/main/java/com/totopia/server/commons/data/payload/ApiResponse.java @@ -0,0 +1,15 @@ +package com.totopia.server.commons.data.payload; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class ApiResponse { + private Boolean success; + private String message; +} diff --git a/src/main/java/com/totopia/server/commons/exception/ResourceNotFoundException.java b/src/main/java/com/totopia/server/commons/exception/ResourceNotFoundException.java new file mode 100644 index 0000000..388b8ab --- /dev/null +++ b/src/main/java/com/totopia/server/commons/exception/ResourceNotFoundException.java @@ -0,0 +1,33 @@ +package com.totopia.server.commons.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(HttpStatus.NOT_FOUND) +public class ResourceNotFoundException extends RuntimeException { + private static final long serialVersionUID = 1L; + + private String resourceName; + private String fieldName; + private Object fieldValue; + + public ResourceNotFoundException(String resourceName, String fieldName, Object fieldValue) { + super(String.format("%s not found with %s : '%s'", resourceName, fieldName, fieldValue)); + + this.resourceName = resourceName; + this.fieldName = fieldName; + this.fieldValue = fieldValue; + } + + public String getResourceName() { + return resourceName; + } + + public String getFieldName() { + return fieldName; + } + + public Object getFieldValue() { + return fieldValue; + } +} diff --git a/src/main/java/com/totopia/server/config/AuditingConfig.java b/src/main/java/com/totopia/server/config/AuditingConfig.java new file mode 100644 index 0000000..f9aa10d --- /dev/null +++ b/src/main/java/com/totopia/server/config/AuditingConfig.java @@ -0,0 +1,40 @@ +package com.totopia.server.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.domain.AuditorAware; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; + +import java.util.Optional; + +import com.totopia.server.config.security.SecurityUserDetails; + +@Configuration +@EnableJpaAuditing +public class AuditingConfig { + + @Bean + public AuditorAware auditorProvider() { + return new SpringSecurityAuditAwareImpl(); + } +} + +class SpringSecurityAuditAwareImpl implements AuditorAware { + + @Override + public Optional getCurrentAuditor() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + if (authentication == null || !authentication.isAuthenticated() + || authentication instanceof AnonymousAuthenticationToken) { + return Optional.empty(); + } + + SecurityUserDetails securityUserDetails = (SecurityUserDetails) authentication.getPrincipal(); + + return Optional.ofNullable(securityUserDetails.getId()); + } +} diff --git a/src/main/java/com/totopia/server/config/WebMvcConfig.java b/src/main/java/com/totopia/server/config/WebMvcConfig.java new file mode 100644 index 0000000..7ed2dbe --- /dev/null +++ b/src/main/java/com/totopia/server/config/WebMvcConfig.java @@ -0,0 +1,16 @@ +package com.totopia.server.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +@EnableWebMvc +public class WebMvcConfig implements WebMvcConfigurer { + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**").allowedMethods("*"); + } +} diff --git a/src/main/java/com/totopia/server/config/WebSecurityConfig.java b/src/main/java/com/totopia/server/config/WebSecurityConfig.java new file mode 100644 index 0000000..e0fb738 --- /dev/null +++ b/src/main/java/com/totopia/server/config/WebSecurityConfig.java @@ -0,0 +1,66 @@ +package com.totopia.server.config; + +import com.totopia.server.config.jwt.JwtAuthenticationEntryPoint; +import com.totopia.server.config.jwt.JwtAuthenticationFilter; +import com.totopia.server.config.security.SecurityUserDetailsService; + +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.config.BeanIds; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +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.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true) +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + SecurityUserDetailsService securityUserDetailsService; + + @Autowired + private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; + + @Bean + public JwtAuthenticationFilter jwtAuthenticationFilter() { + return new JwtAuthenticationFilter(); + } + + @Override + public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception { + authenticationManagerBuilder.userDetailsService(securityUserDetailsService).passwordEncoder(passwordEncoder()); + } + + @Bean(BeanIds.AUTHENTICATION_MANAGER) + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.cors().and().csrf().disable().exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests() + .antMatchers("/", "/favicon.ico", "/**/*.png", "/**/*.gif", "/**/*.svg", "/**/*.jpg", "/**/*.html", "/**/*.css", + "/**/*.js") + .permitAll().antMatchers("/auth/**").permitAll().antMatchers("/users/**").permitAll().anyRequest() + .authenticated(); + + http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); + + } +} diff --git a/src/main/java/com/totopia/server/config/jwt/JwtAuthenticationEntryPoint.java b/src/main/java/com/totopia/server/config/jwt/JwtAuthenticationEntryPoint.java new file mode 100644 index 0000000..814e03d --- /dev/null +++ b/src/main/java/com/totopia/server/config/jwt/JwtAuthenticationEntryPoint.java @@ -0,0 +1,25 @@ +package com.totopia.server.config.jwt; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +import lombok.extern.slf4j.Slf4j; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@Component +@Slf4j +public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { + + @Override + public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, + AuthenticationException e) throws IOException, ServletException { + + log.error("Responding with unauthorized error. Message - {}", e.getMessage()); + httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage()); + } +} diff --git a/src/main/java/com/totopia/server/config/jwt/JwtAuthenticationFilter.java b/src/main/java/com/totopia/server/config/jwt/JwtAuthenticationFilter.java new file mode 100644 index 0000000..36dfa39 --- /dev/null +++ b/src/main/java/com/totopia/server/config/jwt/JwtAuthenticationFilter.java @@ -0,0 +1,66 @@ +package com.totopia.server.config.jwt; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.OncePerRequestFilter; + +import lombok.extern.slf4j.Slf4j; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.totopia.server.config.security.SecurityUserDetailsService; + +import java.io.IOException; + +@Slf4j +public class JwtAuthenticationFilter extends OncePerRequestFilter { + + @Autowired + private JwtTokenProvider tokenProvider; + + @Autowired + private SecurityUserDetailsService securityUserDetailsService; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + try { + String jwt = getJwtFromRequest(request); + + if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) { + String username = tokenProvider.getUsernameFromJWT(jwt); + + /* + * Note that you could also encode the user's username and roles inside JWT + * claims and create the UserDetails object by parsing those claims from the + * JWT. That would avoid the following database hit. It's completely up to you. + */ + UserDetails userDetails = securityUserDetailsService.loadUserByUsername(username); + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, + userDetails.getAuthorities()); + authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + + SecurityContextHolder.getContext().setAuthentication(authentication); + } + } catch (Exception ex) { + log.error("Could not set user authentication in security context", ex); + } + + filterChain.doFilter(request, response); + } + + private String getJwtFromRequest(HttpServletRequest request) { + String bearerToken = request.getHeader("Authorization"); + if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) { + return bearerToken.substring(7, bearerToken.length()); + } + return null; + } +} diff --git a/src/main/java/com/totopia/server/config/jwt/JwtTokenProvider.java b/src/main/java/com/totopia/server/config/jwt/JwtTokenProvider.java new file mode 100644 index 0000000..d9876b4 --- /dev/null +++ b/src/main/java/com/totopia/server/config/jwt/JwtTokenProvider.java @@ -0,0 +1,73 @@ +package com.totopia.server.config.jwt; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.stereotype.Component; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.SignatureException; +import io.jsonwebtoken.UnsupportedJwtException; +import lombok.extern.slf4j.Slf4j; + +import java.util.Date; +import java.util.stream.Collectors; + +import com.totopia.server.config.security.SecurityUserDetails; + +/** + * Created by rajeevkumarsingh on 19/08/17. + */ +@Component +@Slf4j +public class JwtTokenProvider { + private static final String AUTHORITIES_KEY = "authorities"; + + @Value("${app.jwt.secret}") + private String jwtSecret; + + @Value("${app.jwt.expiration}") + private int jwtExpirationInMs; + + public String generateToken(Authentication authentication) { + + SecurityUserDetails userPrincipal = (SecurityUserDetails) authentication.getPrincipal(); + + Date now = new Date(); + Date expiryDate = new Date(now.getTime() + jwtExpirationInMs); + + final String authorities = authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority) + .collect(Collectors.joining(",")); + + return Jwts.builder().setSubject(userPrincipal.getUsername()).claim(AUTHORITIES_KEY, authorities) + .setIssuedAt(new Date()).setExpiration(expiryDate).signWith(SignatureAlgorithm.HS512, jwtSecret).compact(); + } + + public String getUsernameFromJWT(String token) { + Claims claims = Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody(); + + return claims.getSubject(); + } + + public boolean validateToken(String authToken) { + try { + Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken); + return true; + } catch (SignatureException ex) { + log.error("Invalid JWT signature"); + } catch (MalformedJwtException ex) { + log.error("Invalid JWT token"); + } catch (ExpiredJwtException ex) { + log.error("Expired JWT token"); + } catch (UnsupportedJwtException ex) { + log.error("Unsupported JWT token"); + } catch (IllegalArgumentException ex) { + log.error("JWT claims string is empty."); + } + return false; + } +} diff --git a/src/main/java/com/totopia/server/config/security/SecurityUserDetails.java b/src/main/java/com/totopia/server/config/security/SecurityUserDetails.java new file mode 100644 index 0000000..fd1ad7e --- /dev/null +++ b/src/main/java/com/totopia/server/config/security/SecurityUserDetails.java @@ -0,0 +1,99 @@ +package com.totopia.server.config.security; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.totopia.server.modules.user.entity.UserEntity; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class SecurityUserDetails implements UserDetails { + private static final long serialVersionUID = 1L; + + private Long id; + + private String name; + + private String username; + + @JsonIgnore + private String email; + + @JsonIgnore + private String password; + + private Collection authorities; + + @Override + public String getUsername() { + return username; + } + + @Override + public String getPassword() { + return password; + } + + @Override + public Collection getAuthorities() { + return authorities; + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + SecurityUserDetails that = (SecurityUserDetails) o; + return Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + public static SecurityUserDetails create(UserEntity user) { + List authorities = user.getRoles().stream() + .map(role -> new SimpleGrantedAuthority(role.getName().name())).collect(Collectors.toList()); + + return SecurityUserDetails.builder().username(user.getUsername()).password(user.getPassword()) + .authorities(authorities).build(); + } + +} diff --git a/src/main/java/com/totopia/server/config/security/SecurityUserDetailsService.java b/src/main/java/com/totopia/server/config/security/SecurityUserDetailsService.java new file mode 100644 index 0000000..8d6b2fb --- /dev/null +++ b/src/main/java/com/totopia/server/config/security/SecurityUserDetailsService.java @@ -0,0 +1,36 @@ +package com.totopia.server.config.security; + +import com.totopia.server.commons.exception.ResourceNotFoundException; +import com.totopia.server.modules.user.entity.UserEntity; +import com.totopia.server.modules.user.repository.UserRepository; + +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 org.springframework.transaction.annotation.Transactional; + +@Service +public class SecurityUserDetailsService implements UserDetailsService { + @Autowired + UserRepository userRepository; + + @Override + @Transactional + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + + // Let people login with either username or email + UserEntity user = userRepository.findByUsername(username) + .orElseThrow(() -> new UsernameNotFoundException("User not found with username : " + username)); + + return SecurityUserDetails.create(user); + } + + @Transactional + public UserDetails loadUserById(Long id) { + UserEntity user = userRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("User", "id", id)); + + return SecurityUserDetails.create(user); + } +} diff --git a/src/main/java/com/totopia/server/init/DbInitializer.java b/src/main/java/com/totopia/server/init/DbInitializer.java new file mode 100644 index 0000000..a4c6030 --- /dev/null +++ b/src/main/java/com/totopia/server/init/DbInitializer.java @@ -0,0 +1,58 @@ +package com.totopia.server.init; + +import java.util.HashSet; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.totopia.server.modules.dashboard.repository.DashboardRepository; +import com.totopia.server.modules.user.entity.RoleEntity; +import com.totopia.server.modules.user.entity.UserEntity; +import com.totopia.server.modules.user.repository.RoleRepository; +import com.totopia.server.modules.user.repository.UserRepository; +import com.totopia.server.modules.user.type.RoleName; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; + +@Component +@ConditionalOnProperty(name = "app.db-init", havingValue = "true") +public class DbInitializer implements CommandLineRunner { + + @Autowired + private RoleRepository roleRepository; + + @Autowired + private UserRepository userRepository; + + @Autowired + PasswordEncoder passwordEncoder; + + @Autowired + DashboardRepository dashboardRepository; + + @Override + public void run(String... strings) throws Exception { + if (0 == roleRepository.count()) { + RoleEntity role = null; + role = RoleEntity.builder().name(RoleName.ROLE_ADMIN).build(); + roleRepository.save(role); + role = RoleEntity.builder().name(RoleName.ROLE_USER).build(); + roleRepository.save(role); + } + + if (0 == userRepository.count()) { + UserEntity user = null; + user = UserEntity.builder().username("admin").password(passwordEncoder.encode("admin")).nickname("admin") + .email("admin@example.com").roles(Stream.of(RoleEntity.builder().id(Short.valueOf((short) 1)).build()) + .collect(Collectors.toCollection(HashSet::new))) + .build(); + + userRepository.save(user); + } + + System.out.println(" -- Database has been initialized"); + } +} diff --git a/src/main/java/com/totopia/server/modules/dashboard/controller/DashboardController.java b/src/main/java/com/totopia/server/modules/dashboard/controller/DashboardController.java new file mode 100644 index 0000000..0ad8d80 --- /dev/null +++ b/src/main/java/com/totopia/server/modules/dashboard/controller/DashboardController.java @@ -0,0 +1,111 @@ +package com.totopia.server.modules.dashboard.controller; + +import java.util.List; + +import javax.transaction.Transactional; + +import com.totopia.server.commons.exception.ResourceNotFoundException; +import com.totopia.server.modules.dashboard.entity.DashboardEntity; +import com.totopia.server.modules.dashboard.repository.DashboardRepository; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class DashboardController { + @Autowired + private DashboardRepository dashboardRepository; + + @PostMapping(value = "/dashboards") + @ResponseStatus(code = HttpStatus.CREATED) + public DashboardEntity save(@RequestBody DashboardEntity dashboard) { + return dashboardRepository.save(dashboard); + } + + @PreAuthorize("hasAnyRole('ROLE_USER', 'ROLE_ADMIN', 'ROLE_SUPER_ADMIN')") + @GetMapping(value = "/dashboards") + public List all() { + return dashboardRepository.findByOrderBySortOrder(); + } + + @GetMapping(value = "/dashboards/{id}") + public DashboardEntity findById(@PathVariable Integer id) { + return dashboardRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Dashboard", "id", id)); + } + + @DeleteMapping(value = "/dashboards/{id}") + @Transactional + public ResponseEntity deleteDashboard(@PathVariable Integer id) { + + return dashboardRepository.findById(id).map(dashboard -> { + dashboardRepository.decreaseSortOrder(dashboard.getSortOrder(), (int) dashboardRepository.count()); + dashboardRepository.delete(dashboard); + + return ResponseEntity.ok().build(); + }).orElseThrow(() -> new ResourceNotFoundException("Dashboard", "id", id)); + } + + @PutMapping(value = "/dashboards/{id}") + public ResponseEntity updateDashboard(@PathVariable Integer id, + @RequestBody DashboardEntity newDashboard) { + + return dashboardRepository.findById(id).map(dashboard -> { + + dashboardRepository.save(dashboard); + return ResponseEntity.ok(dashboard); + }).orElseThrow(() -> new ResourceNotFoundException("Dashboard", "id", id)); + } + + @PutMapping(value = "/dashboards/{id}/display/{display}") + public ResponseEntity updateDashboardDisplay(@PathVariable Integer id, + @PathVariable Boolean display) { + + return dashboardRepository.findById(id).map(dashboard -> { + dashboard.setDisplay(display); + + dashboardRepository.save(dashboard); + return ResponseEntity.ok(dashboard); + }).orElseThrow(() -> new ResourceNotFoundException("Dashboard", "id", id)); + + } + + @PutMapping(value = "/dashboards/{id}/sort_order/{targetSortOrder}") + @Transactional + public ResponseEntity updateDashboardSortOrder(@PathVariable Integer id, + @PathVariable Integer targetSortOrder) { + + return dashboardRepository.findById(id).map(dashboard -> { + if (targetSortOrder.equals(dashboard.getSortOrder())) { + return ResponseEntity.ok(dashboard); + } + + if (0 > targetSortOrder || dashboardRepository.count() < targetSortOrder) { + return ResponseEntity.ok(dashboard); + } + + Integer sourceSortOrder = dashboard.getSortOrder(); + + if (targetSortOrder > sourceSortOrder) { + dashboardRepository.decreaseSortOrder(sourceSortOrder, targetSortOrder); + } else { + dashboardRepository.increaseSortOrder(sourceSortOrder, targetSortOrder); + } + + dashboard.setSortOrder(targetSortOrder); + dashboardRepository.save(dashboard); + + return ResponseEntity.ok(dashboard); + }).orElseThrow(() -> new ResourceNotFoundException("Dashboard", "id", id)); + + } +} diff --git a/src/main/java/com/totopia/server/modules/dashboard/entity/DashboardEntity.java b/src/main/java/com/totopia/server/modules/dashboard/entity/DashboardEntity.java new file mode 100644 index 0000000..12315d5 --- /dev/null +++ b/src/main/java/com/totopia/server/modules/dashboard/entity/DashboardEntity.java @@ -0,0 +1,54 @@ +package com.totopia.server.modules.dashboard.entity; + +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.totopia.server.commons.data.entity.UserDateAuditEntity; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +@Entity +@Table(name = "dashboard") +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = false) +public class DashboardEntity extends UserDateAuditEntity { + private static final long serialVersionUID = 8891163223262220481L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @Basic + @Column(name = "title", nullable = false, length = 150) + private String title; + + @Basic + @Column(name = "description", nullable = true, length = 500) + private String description; + + @Basic + @Column(name = "url", nullable = false, length = 250) + private String url; + + @Basic + @Column(name = "sort_order", nullable = false) + private Integer sortOrder; + + @Builder.Default + @Basic + @Column(name = "display", nullable = false) + private Boolean display = true; +} diff --git a/src/main/java/com/totopia/server/modules/dashboard/repository/DashboardRepository.java b/src/main/java/com/totopia/server/modules/dashboard/repository/DashboardRepository.java new file mode 100644 index 0000000..1bde25d --- /dev/null +++ b/src/main/java/com/totopia/server/modules/dashboard/repository/DashboardRepository.java @@ -0,0 +1,24 @@ +package com.totopia.server.modules.dashboard.repository; + +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 java.util.List; + +import com.totopia.server.modules.dashboard.entity.DashboardEntity; + +public interface DashboardRepository extends JpaRepository { + List findByOrderBySortOrder(); + + @Modifying + @Query("update DashboardEntity d set d.sortOrder = d.sortOrder + 1 where d.sortOrder < :sourceSortOrder and d.sortOrder >= :targetSortOrder") + int increaseSortOrder(@Param("sourceSortOrder") Integer sourceSortOrder, + @Param("targetSortOrder") Integer targetSortOrder); + + @Modifying + @Query("update DashboardEntity d set d.sortOrder = d.sortOrder - 1 where d.sortOrder > :sourceSortOrder and d.sortOrder <= :targetSortOrder") + int decreaseSortOrder(@Param("sourceSortOrder") Integer sourceSortOrder, + @Param("targetSortOrder") Integer targetSortOrder); +} diff --git a/src/main/java/com/totopia/server/user/controller/UserController.java b/src/main/java/com/totopia/server/modules/user/controller/UserController.java similarity index 63% rename from src/main/java/com/totopia/server/user/controller/UserController.java rename to src/main/java/com/totopia/server/modules/user/controller/UserController.java index 5423b22..642747e 100644 --- a/src/main/java/com/totopia/server/user/controller/UserController.java +++ b/src/main/java/com/totopia/server/modules/user/controller/UserController.java @@ -1,63 +1,62 @@ -package com.totopia.server.user.controller; - -import com.totopia.server.commons.base.exception.ResourceNotFoundException; -import com.totopia.server.user.model.User; -import com.totopia.server.user.repository.UserRepository; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class UserController { - @Autowired - private UserRepository userRepository; - - @PostMapping(value = "/users") - @ResponseStatus(code = HttpStatus.CREATED) - public User save(@RequestBody User user) { - return userRepository.save(user); - } - - @GetMapping(value = "/users") - public Page all(Pageable pageable) { - return userRepository.findAll(pageable); - } - - @GetMapping(value = "/users/{userId}") - public User findByUserId(@PathVariable Long userId) { - return userRepository.findById(userId) - .orElseThrow(() -> new ResourceNotFoundException("User [userId=" + userId + "] can't be found")); - } - - @DeleteMapping(value = "/users/{userId}") - public ResponseEntity deleteUser(@PathVariable Long userId) { - - return userRepository.findById(userId).map(user -> { - userRepository.delete(user); - return ResponseEntity.ok().build(); - }).orElseThrow(() -> new ResourceNotFoundException("User [userId=" + userId + "] can't be found")); - - } - - @PutMapping(value = "/users/{userId}") - public ResponseEntity updateUser(@PathVariable Long userId, @RequestBody User newUser) { - - return userRepository.findById(userId).map(user -> { - - userRepository.save(user); - return ResponseEntity.ok(user); - }).orElseThrow(() -> new ResourceNotFoundException("User [userId=" + userId + "] can't be found")); - - } -} +package com.totopia.server.modules.user.controller; + +import com.totopia.server.commons.exception.ResourceNotFoundException; +import com.totopia.server.modules.user.entity.UserEntity; +import com.totopia.server.modules.user.repository.UserRepository; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class UserController { + @Autowired + private UserRepository userRepository; + + @PostMapping(value = "/users") + @ResponseStatus(code = HttpStatus.CREATED) + public UserEntity save(@RequestBody UserEntity user) { + return userRepository.save(user); + } + + @GetMapping(value = "/users") + public Page all(Pageable pageable) { + return userRepository.findAll(pageable); + } + + @GetMapping(value = "/users/{userId}") + public UserEntity findByUserId(@PathVariable Long userId) { + return userRepository.findById(userId).orElseThrow(() -> new ResourceNotFoundException("User", "userId", userId)); + } + + @DeleteMapping(value = "/users/{userId}") + public ResponseEntity deleteUser(@PathVariable Long userId) { + + return userRepository.findById(userId).map(user -> { + userRepository.delete(user); + return ResponseEntity.ok().build(); + }).orElseThrow(() -> new ResourceNotFoundException("User", "userId", userId)); + + } + + @PutMapping(value = "/users/{userId}") + public ResponseEntity updateUser(@PathVariable Long userId, @RequestBody UserEntity newUser) { + + return userRepository.findById(userId).map(user -> { + + userRepository.save(user); + return ResponseEntity.ok(user); + }).orElseThrow(() -> new ResourceNotFoundException("User", "userId", userId)); + + } +} diff --git a/src/main/java/com/totopia/server/modules/user/entity/BankAccountEntity.java b/src/main/java/com/totopia/server/modules/user/entity/BankAccountEntity.java new file mode 100644 index 0000000..39e4736 --- /dev/null +++ b/src/main/java/com/totopia/server/modules/user/entity/BankAccountEntity.java @@ -0,0 +1,49 @@ +package com.totopia.server.modules.user.entity; + +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.SequenceGenerator; + +import com.totopia.server.commons.data.entity.UserDateAuditEntity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +@Entity(name = "bank_account") +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = false) +public class BankAccountEntity extends UserDateAuditEntity { + + private static final long serialVersionUID = -8628291684559836128L; + + @Id + @GeneratedValue(generator = "bank_account_generator") + @SequenceGenerator(name = "bank_account_generator", sequenceName = "bank_account_sequence", initialValue = 1) + private Long id; + + @Basic + @Column(name = "name", nullable = false, length = 100) + private String name; + + @Basic + @Column(name = "number", nullable = false, length = 100) + private String number; + + @Basic + @Column(name = "holder", nullable = false, length = 100) + private String holder; + + @Basic + @Column(name = "username", nullable = false) + private String username; + +} diff --git a/src/main/java/com/totopia/server/modules/user/entity/RoleEntity.java b/src/main/java/com/totopia/server/modules/user/entity/RoleEntity.java new file mode 100644 index 0000000..50db82f --- /dev/null +++ b/src/main/java/com/totopia/server/modules/user/entity/RoleEntity.java @@ -0,0 +1,37 @@ +package com.totopia.server.modules.user.entity; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.SequenceGenerator; + +import com.totopia.server.modules.user.type.RoleName; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Entity(name = "roles") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class RoleEntity implements Serializable { + private static final long serialVersionUID = 5100719044067326295L; + + @Id + @GeneratedValue(generator = "role_generator") + @SequenceGenerator(name = "role_generator", sequenceName = "role_sequence", initialValue = 1) + private Short id; + + @Enumerated(EnumType.STRING) + @Column(name = "name", length = 60) + private RoleName name; + +} diff --git a/src/main/java/com/totopia/server/modules/user/entity/UserEntity.java b/src/main/java/com/totopia/server/modules/user/entity/UserEntity.java new file mode 100644 index 0000000..d594015 --- /dev/null +++ b/src/main/java/com/totopia/server/modules/user/entity/UserEntity.java @@ -0,0 +1,131 @@ +package com.totopia.server.modules.user.entity; + +import java.util.Date; +import java.util.Set; + +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.UniqueConstraint; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.totopia.server.commons.data.entity.DateAuditEntity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.Builder.Default; +import lombok.experimental.SuperBuilder; + +@Entity +@Table(name = "users", uniqueConstraints = { @UniqueConstraint(columnNames = { "username" }), + @UniqueConstraint(columnNames = { "email" }) }) +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = false) +public class UserEntity extends DateAuditEntity { + private static final long serialVersionUID = 8891163223262220481L; + + @Id + @Column(name = "username", unique = true, nullable = false, length = 150) + private String username; + + @Basic + @Column(name = "password", nullable = false, length = 100) + @JsonIgnore + private String password; + + @Basic + @Column(name = "nickname", nullable = false, length = 150) + private String nickname; + + @Basic + @Column(name = "email", nullable = false, length = 100) + private String email; + + @Basic + @Column(name = "block", nullable = false) + @Default + private Boolean block = false; + + @Basic + @Column(name = "send_email", nullable = false) + @Default + private Boolean sendEmail = true; + + @Basic + @Column(name = "activation", nullable = true, length = 100) + private String activation; + + @Basic + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "last_reset_time", nullable = true) + private Date lastResetTime; + + @Basic + @Column(name = "reset_count", nullable = false) + @Default + private Long resetCount = 0L; + + @Basic + @Column(name = "otp_key", nullable = true, length = 1000) + private String otpKey; + + @Basic + @Column(name = "otep", nullable = true, length = 1000) + private String otep; + + @Basic + @Column(name = "require_reset", nullable = true) + @Default + private Boolean requireReset = false; + + @ManyToMany(fetch = FetchType.EAGER) + @JoinTable(name = "user_roles", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id")) + private Set roles; +} + +// 아이디 +// 로그인 아이디 +// 로그인 패스워드 +// 로그인 패스워드 문자 +// 이메일 +// 닉네임 +// 은행명 +// 계좌번호 +// 예금주 +// 추천인 +// 추천수 +// 게시판 제한 여부 +// 쿠폰 +// 충전방식 +// 비고 +// 종목별 베팅제한 +// 상태표기 +// 휴대폰번호 +// 추천권한 여부 +// 가입상태 +// 소속 +// 레벨 +// 보유머니 +// 포인트 +// 회원상태 +// 룰렛개수 +// 계좌순번 +// 가입날짜 +// 최근접속 날짜 +// 가입 아이피 +// 최근 접속 아이피 +// 베팅 알림 +// API 연결 diff --git a/src/main/java/com/totopia/server/modules/user/repository/BankAccountRepository.java b/src/main/java/com/totopia/server/modules/user/repository/BankAccountRepository.java new file mode 100644 index 0000000..5d9969d --- /dev/null +++ b/src/main/java/com/totopia/server/modules/user/repository/BankAccountRepository.java @@ -0,0 +1,9 @@ +package com.totopia.server.modules.user.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.totopia.server.modules.user.entity.BankAccountEntity; + +public interface BankAccountRepository extends JpaRepository { + +} diff --git a/src/main/java/com/totopia/server/modules/user/repository/RoleRepository.java b/src/main/java/com/totopia/server/modules/user/repository/RoleRepository.java new file mode 100644 index 0000000..bcf5931 --- /dev/null +++ b/src/main/java/com/totopia/server/modules/user/repository/RoleRepository.java @@ -0,0 +1,12 @@ +package com.totopia.server.modules.user.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +import com.totopia.server.modules.user.entity.RoleEntity; +import com.totopia.server.modules.user.type.RoleName; + +public interface RoleRepository extends JpaRepository { + Optional findByName(RoleName name); +} diff --git a/src/main/java/com/totopia/server/modules/user/repository/UserRepository.java b/src/main/java/com/totopia/server/modules/user/repository/UserRepository.java new file mode 100644 index 0000000..3000a10 --- /dev/null +++ b/src/main/java/com/totopia/server/modules/user/repository/UserRepository.java @@ -0,0 +1,54 @@ +package com.totopia.server.modules.user.repository; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Date; +import java.util.Optional; + +import com.totopia.server.modules.user.entity.UserEntity; + +public interface UserRepository extends JpaRepository { + + Optional findByUsername(String username); + + Boolean existsByEmail(String email); + + Optional findByEmail(String email); + + Boolean existsByUsername(String username); + + Page findAllByNickname(String nickName, Pageable pageable) throws Exception; + + // 접속 제한 상태 유저 리스트 + Page findAllByBlockTrue(Pageable pageable) throws Exception; + + // 접속 제한 상태가 아닌 유저 리스트 + Page findAllByBlockFalse(Pageable pageable) throws Exception; + + // // 어드민 유저 리스 + // Page findAllByIsAdminTrue(Pageable pageable) throws Exception; + + // 패스워드 리셋이 트루인 유저 리스 + Page findAllByRequireResetTrue(Pageable pageable) throws Exception; + + // // 어드민이 펄스이며, 활동중인 현재 회원 리스트 + // Page findAllByIsAdminFalseAndActivationEquals(String activation, + // Pageable pageable) throws Exception; + + // 날짜 검색 + Page findAllByCreatedAtBetween(Date starDate, Date endDate, Pageable pageable) throws Exception; + + Page findAllByUpdatedAtBetween(Date starDate, Date endDate, Pageable pageable) throws Exception; + + Page findAllByLastResetTimeBetween(Date starDate, Date endDate, Pageable pageable) throws Exception; + + // 현재 날짜 이후 가입된 회원의 총 수 리턴 + Long countByCreatedAtGreaterThanEqual(Date date) throws Exception; + + // 유저 그룹별 회원 리스트 + + // 유저 소속별 회원 리스트 + +} diff --git a/src/main/java/com/totopia/server/modules/user/type/RoleName.java b/src/main/java/com/totopia/server/modules/user/type/RoleName.java new file mode 100644 index 0000000..e119c70 --- /dev/null +++ b/src/main/java/com/totopia/server/modules/user/type/RoleName.java @@ -0,0 +1,5 @@ +package com.totopia.server.modules.user.type; + +public enum RoleName { + ROLE_USER, ROLE_ADMIN, ROLE_SUPER_ADMIN, +} diff --git a/src/main/java/com/totopia/server/user/model/BankAccount.java b/src/main/java/com/totopia/server/user/model/BankAccount.java deleted file mode 100644 index fe11580..0000000 --- a/src/main/java/com/totopia/server/user/model/BankAccount.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.totopia.server.user.model; - -import com.totopia.server.commons.base.model.Base; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.persistence.*; - -@Entity -@Table(name = "TBL_BANK_ACCOUNT") -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class BankAccount extends Base { -// @Id -// @GeneratedValue(generator = "bank_account_generator") -// @SequenceGenerator(name = "bank_account_generator", sequenceName = "bank_account_sequence", initialValue = 1, allocationSize = 1) -// private Long id; - - @Basic - @Column(name = "name", nullable = false, length = 100) - private String name; - - @Basic - @Column(name = "number", nullable = false, length = 100) - private String number; - - @Basic - @Column(name = "holder", nullable = false, length = 100) - private String holder; - - @Basic - @Column(name = "user_id", nullable = false) - private Long userId; - -} diff --git a/src/main/java/com/totopia/server/user/model/Role.java b/src/main/java/com/totopia/server/user/model/Role.java deleted file mode 100644 index ad95310..0000000 --- a/src/main/java/com/totopia/server/user/model/Role.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.totopia.server.user.model; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.hibernate.annotations.CreationTimestamp; - -import javax.persistence.*; -import java.io.Serializable; -import java.util.Date; - -@Entity -@Table(name = "TBL_ROLE") -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class Role implements Serializable { - private static final long serialVersionUID = 4801565634000630034L; - - @Id - @GeneratedValue(generator = "user_group_generator") - @SequenceGenerator(name = "user_group_generator", sequenceName = "user_group_sequence", initialValue = 1, allocationSize = 1) - private Integer id; - - @Basic - @Column(name = "title", nullable = false, length = 100) - private String title; - - @Basic - @Column(columnDefinition = "text", name = "description", nullable = true) - private String description; - - @Basic - @Column(name = "is_default", nullable = false, columnDefinition = "bool default false") - private Boolean isDefault; - - @Basic - @CreationTimestamp - @Temporal(TemporalType.TIMESTAMP) - @Column(name = "register_date", nullable = false) - private Date registerDate; -} diff --git a/src/main/java/com/totopia/server/user/model/User.java b/src/main/java/com/totopia/server/user/model/User.java deleted file mode 100644 index aaf2712..0000000 --- a/src/main/java/com/totopia/server/user/model/User.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.totopia.server.user.model; - -import java.io.Serializable; -import java.util.Date; - -import javax.persistence.*; - -import com.totopia.server.commons.base.gson.annotation.Exclude; - -import com.totopia.server.commons.base.model.Base; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.hibernate.annotations.CreationTimestamp; -import org.hibernate.annotations.UpdateTimestamp; - -@Entity -@Table(name = "TBL_USER") -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@AttributeOverrides({ - @AttributeOverride(name = "createDate", column = @Column(name = "registDate")), - @AttributeOverride(name = "updateDate", column = @Column(name = "lastvisitDate")), -}) -public class User extends Base implements Serializable { - private static final long serialVersionUID = 2783105197387637187L; - -// @Id -// @GeneratedValue(generator = "user_generator") -// @SequenceGenerator(name = "user_generator", sequenceName = "user_sequence", initialValue = 1000) -// private Long id; - - @Basic - @Column(name = "username", unique = true, nullable = false, length = 150) - private String username; - - @Basic - @Column(name = "password", nullable = false, length = 100) - @Exclude - private String password; - - @Transient - private String passwordConfirm; - - @Basic - @Column(name = "name", nullable = false, length = 255) - private String nickname; - - @Basic - @Column(name = "email", nullable = false, length = 100) - private String email; - - @Basic - @Column(name = "block", nullable = false, columnDefinition = "bool default false") - private Boolean block; - - @Basic - @Column(name = "is_admin", nullable = false, columnDefinition = "bool default false") - private Boolean isAdmin; - - @Basic - @Column(name = "send_email", nullable = true, columnDefinition = "bool default false") - private Boolean sendEmail; - -// @AttributeOverride(name = "createDate", column = @Column(name = "regist_date")) -// private Date registerDate; -// -// @AttributeOverride(name = "updateDate", column = @Column(name = "lastvisit_date")) -// private Date lastvisitDate; -// @Basic -// @CreationTimestamp -// @Temporal(TemporalType.TIMESTAMP) -// @Column(name = "register_date", nullable = false) -// private Date registerDate; -// -// @Basic -// @Temporal(TemporalType.TIMESTAMP) -// @Column(name = "lastvisit_date", nullable = false) -// private Date lastvisitDate; - - @Basic - @Column(name = "activation", nullable = false, length = 100) - private String activation; - - @Basic - @Temporal(TemporalType.TIMESTAMP) - @Column(name = "last_reset_time", nullable = false) - private Date lastResetTime; - - @Basic - @Column(name = "reset_count", nullable = false) - private Long resetCount; - - @Basic - @Column(name = "otp_key", nullable = false, length = 1000) - private String otpKey; - - @Basic - @Column(name = "otep", nullable = false, length = 1000) - private String otep; - - @Basic - @Column(name = "require_reset", nullable = true, columnDefinition = "bool default false") - private Boolean requireReset; - -} - -// 아이디 -// 로그인 아이디 -// 로그인 패스워드 -// 로그인 패스워드 문자 -// 이메일 -// 닉네임 -// 은행명 -// 계좌번호 -// 예금주 -// 추천인 -// 추천수 -// 게시판 제한 여부 -// 쿠폰 -// 충전방식 -// 비고 -// 종목별 베팅제한 -// 상태표기 -// 휴대폰번호 -// 추천권한 여부 -// 가입상태 -// 소속 -// 레벨 -// 보유머니 -// 포인트 -// 회원상태 -// 룰렛개수 -// 계좌순번 -// 가입날짜 -// 최근접속 날짜 -// 가입 아이피 -// 최근 접속 아이피 -// 베팅 알림 -// API 연결 diff --git a/src/main/java/com/totopia/server/user/repository/BankAccountRepository.java b/src/main/java/com/totopia/server/user/repository/BankAccountRepository.java deleted file mode 100644 index 04c914f..0000000 --- a/src/main/java/com/totopia/server/user/repository/BankAccountRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.totopia.server.user.repository; - -import com.totopia.server.user.model.BankAccount; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface BankAccountRepository extends JpaRepository { -} diff --git a/src/main/java/com/totopia/server/user/repository/RoleRepository.java b/src/main/java/com/totopia/server/user/repository/RoleRepository.java deleted file mode 100644 index e00ebd3..0000000 --- a/src/main/java/com/totopia/server/user/repository/RoleRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.totopia.server.user.repository; - -import com.totopia.server.user.model.Role; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface RoleRepository extends JpaRepository { -} diff --git a/src/main/java/com/totopia/server/user/repository/UserRepository.java b/src/main/java/com/totopia/server/user/repository/UserRepository.java deleted file mode 100644 index cdcc8e9..0000000 --- a/src/main/java/com/totopia/server/user/repository/UserRepository.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.totopia.server.user.repository; - -import com.totopia.server.user.model.User; - -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import java.util.Date; - -@Repository -public interface UserRepository extends JpaRepository { - // 회원 아이디로 조회 - User findByUsername(String userName) throws Exception; - User findByEmail(String email) throws Exception; - - Page findAllByNickname(String nickName, Pageable pageable) throws Exception; - - // 접속 제한 상태 유저 리스트 - Page findAllByBlockTrue(Pageable pageable) throws Exception; - // 접속 제한 상태가 아닌 유저 리스트 - Page findAllByBlockFalse(Pageable pageable) throws Exception; - // 어드민 유저 리스 - Page findAllByIsAdminTrue(Pageable pageable) throws Exception; - // 패스워드 리셋이 트루인 유저 리스 - Page findAllByRequireResetTrue(Pageable pageable) throws Exception; - // 어드민이 펄스이며, 활동중인 현재 회원 리스트 - Page findAllByIsAdminFalseAndActivationEquals(String activation, Pageable pageable) throws Exception; - // 날짜 검색 - Page findAllByCreateDateBetween(Date starDate, Date endDate, Pageable pageable) throws Exception; - Page findAllByUpdateDateBetween(Date starDate, Date endDate, Pageable pageable) throws Exception; - Page findAllByLastResetTimeBetween(Date starDate, Date endDate, Pageable pageable) throws Exception; - - // 현재 날짜 이후 가입된 회원의 총 수 리턴 - Long countByCreateDateGreaterThanEqual(Date date) throws Exception; - - // 유저 그룹별 회원 리스트 - - // 유저 소속별 회원 리스트 - -} diff --git a/src/main/java/com/totopia/server/user/service/UserService.java b/src/main/java/com/totopia/server/user/service/UserService.java deleted file mode 100644 index 3627f3a..0000000 --- a/src/main/java/com/totopia/server/user/service/UserService.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.totopia.server.user.service; - -import org.springframework.stereotype.Service; - -@Service -public class UserService { - - -} \ No newline at end of file diff --git a/src/main/resources/data.sql b/src/main/resources/_data.sql similarity index 100% rename from src/main/resources/data.sql rename to src/main/resources/_data.sql diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 2d2fa8a..c3fcefa 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -2,18 +2,11 @@ spring: application: name: totopia-server - http: - converters: - preferred-json-mapper: gson - h2: - console: - enabled: true - path: /h2-console datasource: driver-class-name: org.postgresql.Driver - url: jdbc:postgresql://localhost:15432/postgres - data-username: postgres - username: postgres + url: jdbc:postgresql://localhost:15432/totopia + data-username: totopia + username: totopia password: qwer5795 # JPA properties initialization-mode: never @@ -27,7 +20,11 @@ spring: hibernate: temp: use_jdbc_metadata_defaults: false - + #Jackson properties + jackson: + serialization: + WRITE_DATES_AS_TIMESTAMPS: false + time-zone: UTC # Logger configuration logging: @@ -43,3 +40,18 @@ server: port: 8088 servlet: context-path: /api + +#JWT properties +app: + db-init: true + jwt: + header: Authorization + header.prefix: Bearer + secret: mySecret + expiration: 900000 + claims.refresh.name: Refresh + #Token properties + token: + email.verification.duration=3600000 + password.reset.duration=3600000 + refresh.duration=2592000000 diff --git a/src/test/java/com/totopia/server/modules/user/repository/BankAccountRepositoryTest.java b/src/test/java/com/totopia/server/modules/user/repository/BankAccountRepositoryTest.java new file mode 100644 index 0000000..c11e9b2 --- /dev/null +++ b/src/test/java/com/totopia/server/modules/user/repository/BankAccountRepositoryTest.java @@ -0,0 +1,103 @@ +package com.totopia.server.modules.user.repository; + +import com.totopia.server.modules.user.entity.BankAccountEntity; +import com.totopia.server.modules.user.entity.UserEntity; +import org.junit.Before; +import org.junit.Ignore; +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.test.context.junit4.SpringRunner; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +@Ignore +@RunWith(SpringRunner.class) +@SpringBootTest +public class BankAccountRepositoryTest { + + @Autowired + private UserRepository userRepository; + + @Autowired + private BankAccountRepository bankAccountRepository; + + List users; + List accounts = new ArrayList<>(); + + @Before + public void setUp() throws Exception { + users = this.userRepository.findAll(); + + if (users == null) { + throw new Exception("user list Null"); + } + } + + @Test + public void testInsert() { + + BankAccountEntity bankAccount = null; + + int idx = 0; + for (UserEntity user : users) { + bankAccount = new BankAccountEntity(); + + switch (idx) { + case 0: + bankAccount.setName("국민은행"); + bankAccount.setHolder("예금주1"); + bankAccount.setNumber("123-422-23112"); + break; + case 1: + bankAccount.setName("우리은행"); + bankAccount.setHolder("예금주2"); + bankAccount.setNumber("321-555-3312-21"); + break; + case 2: + bankAccount.setName("기업은행"); + bankAccount.setHolder("예금주3"); + bankAccount.setNumber("832-2392-2392-29829"); + break; + } + idx++; + bankAccount.setUsername(user.getUsername()); + bankAccount.setUpdatedAt(new Date()); + this.bankAccountRepository.save(bankAccount); + } + } + + @Test + public void testUpdate() { + List bankAccounts = this.bankAccountRepository.findAll(); + + int idx = 0; + for (BankAccountEntity account : bankAccounts) { + + switch (idx) { + case 0: + account.setName("국민은행"); + account.setHolder("예금주1"); + account.setNumber("123-422-23112"); + break; + case 1: + account.setName("우리은행"); + account.setHolder("예금주2"); + account.setNumber("321-555-3312-21"); + break; + case 2: + account.setName("기업은행"); + account.setHolder("예금주3"); + account.setNumber("832-2392-2392-29829"); + break; + } + idx++; + account.setUsername(account.getUsername()); + + this.bankAccountRepository.save(account); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/totopia/server/modules/user/repository/UserRepositoryTest.java b/src/test/java/com/totopia/server/modules/user/repository/UserRepositoryTest.java new file mode 100644 index 0000000..9a92c44 --- /dev/null +++ b/src/test/java/com/totopia/server/modules/user/repository/UserRepositoryTest.java @@ -0,0 +1,118 @@ +package com.totopia.server.modules.user.repository; + +import com.totopia.server.modules.user.entity.UserEntity; +import org.junit.Before; +import org.junit.Ignore; +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.test.context.junit4.SpringRunner; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import static org.junit.Assert.*; + +@Ignore +@RunWith(SpringRunner.class) +@SpringBootTest +public class UserRepositoryTest { + + @Autowired + private UserRepository userRepository; + + // private User.UserBuilder user; + + private List userList = new ArrayList<>(); + + @Before + public void setUp() throws Exception { + UserEntity user = UserEntity.builder().activation("Y").block(false).email("geekdev@naver.com").nickname("admin") + .otep("").otpKey("").password("qwer5795").username("admin").requireReset(false) + .resetCount(Long.valueOf(0)).lastResetTime(new Date()).build(); + + userList.add(user); + + user = UserEntity.builder().activation("Y").block(false).email("geektest1@naver.com").nickname("test1").otep("") + .otpKey("").password("qwer5795").username("test1").requireReset(false).resetCount(Long.valueOf(0)) + .lastResetTime(new Date()).build(); + + userList.add(user); + + user = UserEntity.builder().activation("Y").block(false).email("geektest2@naver.com").nickname("test2").otep("") + .otpKey("").password("qwer5795").username("test2").requireReset(false).resetCount(Long.valueOf(0)) + .lastResetTime(new Date()).build(); + + userList.add(user); + } + + @Test + public void findByUsername() { + UserEntity admin = this.getAdmin().orElse(null); + if (admin == null) { + this.userRepository.saveAll(userList); + assertEquals("Equlas", userList.get(0).getNickname(), "admin"); + } + } + + @Test + public void findByEmail() { + UserEntity admin = this.getAdmin().orElse(null); + + if (admin != null) { + + } + } + + @Test + public void findAllByNickname() { + } + + @Test + public void findAllByBlockTrue() { + } + + @Test + public void findAllByBlockFalse() { + } + + @Test + public void findAllByIsAdminTrue() { + } + + @Test + public void findAllByRequireResetTrue() { + } + + @Test + public void findAllByIsAdminFalseAndActivationEquals() { + } + + @Test + public void findAllByRegisterDateBetween() { + } + + @Test + public void findAllByLastvisitDateBetween() { + } + + @Test + public void findAllByLastResetTimeBetween() { + } + + @Test + public void countByRegisterDateGreaterThanEqual() { + } + + private Optional getAdmin() { + try { + return this.userRepository.findByUsername("admin"); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} \ No newline at end of file diff --git a/src/test/java/com/totopia/server/user/repository/BankAccountRepositoryTest.java b/src/test/java/com/totopia/server/user/repository/BankAccountRepositoryTest.java deleted file mode 100644 index decbd1b..0000000 --- a/src/test/java/com/totopia/server/user/repository/BankAccountRepositoryTest.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.totopia.server.user.repository; - -import com.totopia.server.user.model.BankAccount; -import com.totopia.server.user.model.User; -import org.junit.Before; -import org.junit.Ignore; -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.test.context.junit4.SpringRunner; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import static org.junit.Assert.*; - -@Ignore -@RunWith(SpringRunner.class) -@SpringBootTest -public class BankAccountRepositoryTest { - - @Autowired - private UserRepository userRepository; - - @Autowired - private BankAccountRepository bankAccountRepository; - - List users; - List accounts = new ArrayList<>(); - - @Before - public void setUp() throws Exception { - users = this.userRepository.findAll(); - - if(users == null) { - throw new Exception("user list Null"); - } - } - - @Test - public void testInsert() { - - BankAccount bankAccount = null; - - int idx = 0; - for (User user : users) { - bankAccount = new BankAccount(); - - switch (idx) { - case 0: - bankAccount.setName("국민은행"); - bankAccount.setHolder("예금주1"); - bankAccount.setNumber("123-422-23112"); - break; - case 1: - bankAccount.setName("우리은행"); - bankAccount.setHolder("예금주2"); - bankAccount.setNumber("321-555-3312-21"); - break; - case 2: - bankAccount.setName("기업은행"); - bankAccount.setHolder("예금주3"); - bankAccount.setNumber("832-2392-2392-29829"); - break; - } - idx++; - bankAccount.setUserId(user.getId()); - bankAccount.setUpdateDate(new Date()); - this.bankAccountRepository.save(bankAccount); - } - } - - @Test - public void testUpdate() { - List bankAccounts = this.bankAccountRepository.findAll(); - - int idx = 0; - for (BankAccount account : bankAccounts) { - - switch (idx) { - case 0: - account.setName("국민은행"); - account.setHolder("예금주1"); - account.setNumber("123-422-23112"); - break; - case 1: - account.setName("우리은행"); - account.setHolder("예금주2"); - account.setNumber("321-555-3312-21"); - break; - case 2: - account.setName("기업은행"); - account.setHolder("예금주3"); - account.setNumber("832-2392-2392-29829"); - break; - } - idx++; - account.setUserId(account.getUserId()); - - this.bankAccountRepository.save(account); - } - } -} \ No newline at end of file diff --git a/src/test/java/com/totopia/server/user/repository/UserRepositoryTest.java b/src/test/java/com/totopia/server/user/repository/UserRepositoryTest.java deleted file mode 100644 index b965339..0000000 --- a/src/test/java/com/totopia/server/user/repository/UserRepositoryTest.java +++ /dev/null @@ -1,154 +0,0 @@ -package com.totopia.server.user.repository; - -import com.totopia.server.user.model.User; -import org.junit.Before; -import org.junit.Ignore; -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.test.context.junit4.SpringRunner; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import static org.junit.Assert.*; - - -@Ignore -@RunWith(SpringRunner.class) -@SpringBootTest -public class UserRepositoryTest { - - @Autowired - private UserRepository userRepository; - -// private User.UserBuilder user; - - private List userList = new ArrayList<>(); - - @Before - public void setUp() throws Exception { - User.UserBuilder user = User.builder() - .activation("Y") - .block(false) - .email("geekdev@naver.com") - .isAdmin(true) - .nickname("admin") - .otep("") - .otpKey("") - .password("qwer5795") - .username("admin") - .requireReset(false) - .resetCount(Long.valueOf(0)) - .lastResetTime(new Date()); - - User temp = user.build(); - temp.setUpdateDate(new Date()); - userList.add(temp); - - user = User.builder() - .activation("Y") - .block(false) - .email("geektest1@naver.com") - .isAdmin(false) - .nickname("test1") - .otep("") - .otpKey("") - .password("qwer5795") - .username("test1") - .requireReset(false) - .resetCount(Long.valueOf(0)) - .lastResetTime(new Date()); - - temp = user.build(); - temp.setUpdateDate(new Date()); - userList.add(temp); - - user = User.builder() - .activation("Y") - .block(false) - .email("geektest2@naver.com") - .isAdmin(false) - .nickname("test2") - .otep("") - .otpKey("") - .password("qwer5795") - .username("test2") - .requireReset(false) - .resetCount(Long.valueOf(0)) - .lastResetTime(new Date()); - - temp = user.build(); - temp.setUpdateDate(new Date()); - userList.add(temp); - } - - @Test - public void findByUsername() { - User admin = this.getAdmin(); - if (admin == null) { - this.userRepository.saveAll(userList); - assertEquals("Equlas", userList.get(0).getNickname(), "admin"); - } - } - - @Test - public void findByEmail() { - User admin = this.getAdmin(); - - if(admin != null) { - - } - } - - @Test - public void findAllByNickname() { - } - - @Test - public void findAllByBlockTrue() { - } - - @Test - public void findAllByBlockFalse() { - } - - @Test - public void findAllByIsAdminTrue() { - } - - @Test - public void findAllByRequireResetTrue() { - } - - @Test - public void findAllByIsAdminFalseAndActivationEquals() { - } - - @Test - public void findAllByRegisterDateBetween() { - } - - @Test - public void findAllByLastvisitDateBetween() { - } - - @Test - public void findAllByLastResetTimeBetween() { - } - - @Test - public void countByRegisterDateGreaterThanEqual() { - } - - private User getAdmin() { - try { - return this.userRepository.findByUsername("admin"); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } -} \ No newline at end of file diff --git a/src/test/resources/docker-compose.yml b/src/test/resources/docker-compose.yml new file mode 100644 index 0000000..6cf6a57 --- /dev/null +++ b/src/test/resources/docker-compose.yml @@ -0,0 +1,11 @@ +version: '3.1' + +services: + postgres: + image: postgres:11-alpine + environment: + POSTGRES_DB: totopia + POSTGRES_USER: totopia + POSTGRES_PASSWORD: qwer5795 + ports: + - '15432:5432'