Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT] private info sealing feature 5 #661

Merged
merged 8 commits into from
Jan 23, 2024
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package peer.backend.controller;

import io.jsonwebtoken.Claims;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
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 peer.backend.dto.privateinfo.InitSecretDTO;
import peer.backend.dto.privateinfo.InitTokenDTO;
import peer.backend.dto.privateinfo.PrivateTokenDTO;
import peer.backend.dto.privateinfo.MainSeedDTO;
import peer.backend.dto.privateinfo.PrivateDataDTO;
import peer.backend.entity.user.User;
import peer.backend.exception.BadRequestException;
import peer.backend.service.PrivateInfoWrappingService;

Expand All @@ -26,25 +28,31 @@ public class PrivateInfoWrappingController {
@ApiOperation(value = "", notes = "민감한 정보를 전달 시작을 알리는 API. 최초 내용 전달을 위한 key와 code를 발급한다.")
@PostMapping("/init")
public ResponseEntity<?> initKeyForPrivacy() {
InitSecretDTO result = this.privateInfoWrappingService.makeInitSecret();
InitSecretDTO result = this.privateInfoWrappingService
.makeInitSecret();
return new ResponseEntity<>(result, HttpStatus.OK);
}

@ApiOperation(value = "", notes = "민감한 정보의 송신 용으로 사용되는 API 입니다. Seed와 Key를 제공합니다.")
@PostMapping("/get")
public ResponseEntity<?> getKeysForPrivacy(@RequestBody() InitTokenDTO data) {
Claims resolved;
public ResponseEntity<?> getKeysForPrivacy
(@RequestBody() InitTokenDTO data) {
MainSeedDTO resolved;
try {
resolved = this.privateInfoWrappingService.parseInitToken(data);
resolved = this.privateInfoWrappingService
.parseInitToken(data);
} catch (BadRequestException e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<>(resolved, HttpStatus.OK);
}

@ApiOperation(value = "", notes = "민감한 정보를 위한 수신합니다.")
@PostMapping("/send")
public ResponseEntity<?> sendTokenAndKey(@RequestBody() PrivateTokenDTO token) {
return new ResponseEntity<>(HttpStatus.OK);
@PostMapping("/receive")
public ResponseEntity<?> sendTokenAndKey(Authentication auth, @RequestBody() PrivateDataDTO token) {
User user = null;
if (auth != null)
user = User.authenticationToUser(auth);
return this.privateInfoWrappingService.processDataFromToken(user, token);
}
}
5 changes: 3 additions & 2 deletions src/main/java/peer/backend/dto/privateinfo/InitSecretDTO.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package peer.backend.dto.privateinfo;

import lombok.Builder;
import lombok.Getter;
import lombok.*;

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class InitSecretDTO {
private String secret;
private Long code;
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/peer/backend/dto/privateinfo/InitTokenDTO.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package peer.backend.dto.privateinfo;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.*;

@Getter
@RequiredArgsConstructor
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class InitTokenDTO {
private String token;
private Long code;
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/peer/backend/dto/privateinfo/MainSeedDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package peer.backend.dto.privateinfo;

import lombok.*;

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MainSeedDTO {
private String seed;
private Long code;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

@Getter
@RequiredArgsConstructor
public class PrivateTokenDTO {
public class PrivateDataDTO {
private String token;
private String key;
private Long code;
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package peer.backend.dto.privateinfo.enums;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum PrivateActions {
SIGNUP(662, "SIGNUP"),
PASSWORDCHECK(1425, "PASSWORDCHECK"),
PASSWORDMODIFY(1563, "PASSWORDMODIFY");

private final int code;
private final String description;
PrivateActions(int value, String description) {
this.code = value;
this.description = description;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import peer.backend.exception.IllegalArgumentException;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class ChangePasswordRequest {

@NotBlank(message = "비밀번호를 입력하세요.")
Expand All @@ -20,4 +19,21 @@ public class ChangePasswordRequest {

@NotBlank(message = "코드는 필수입니다.")
private String code;

public ChangePasswordRequest(String password,
String code) throws IllegalArgumentException{
String errorMessage = "";
if (password.isBlank())
errorMessage = "비밀번호를 입력해야 합니다.\n";
if (!password.isBlank() && (password.length() < 8 || password.length() > 20))
errorMessage = "비밀번호는 반드시 8자 이상, 20자 이하여야 합니다.\n";
if (!password.isBlank() && !password.matches("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*])[A-Za-z\\d!@#$%^&*]{8,20}$"))
errorMessage = "비밀번호는 대소문자, 숫자, 특수문자를 포함해야 합니다.\n";
if (code.isBlank())
errorMessage = "비정상적인 접근입니다.";
if (!errorMessage.isEmpty())
throw new IllegalArgumentException(errorMessage);
this.password = password;
this.code = code;
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
package peer.backend.dto.profile.request;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import peer.backend.exception.IllegalArgumentException;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class PasswordRequest {

@NotBlank(message = "비밀번호를 입력하세요.")
@Size(min = 8, max = 20, message = "비밀번호는 반드시 8자 이상이어야 합니다.")
@Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*])[A-Za-z\\d!@#$%^&*]{8,20}$",
message = "대소문자, 숫자, 특수문자를 포함해야 합니다!")
private String password;

public PasswordRequest(String password) throws IllegalArgumentException {
String errorMessage = "";
if (password.isBlank())
errorMessage = "비밀번호를 입력해야 합니다.\n";
if (!password.isBlank() && (password.length() < 8 || password.length() > 20))
errorMessage = "비밀번호는 반드시 8자 이상, 20자 이하여야 합니다.\n";
if (!password.isBlank() && !password.matches("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*])[A-Za-z\\d!@#$%^&*]{8,20}$"))
errorMessage = "비밀번호는 대소문자, 숫자, 특수문자를 포함해야 합니다.\n";
if (!errorMessage.isEmpty())
throw new IllegalArgumentException(errorMessage);
this.password = password;
}
}
58 changes: 51 additions & 7 deletions src/main/java/peer/backend/dto/security/UserInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,15 @@
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import peer.backend.entity.user.User;
import peer.backend.exception.IllegalArgumentException;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class UserInfo {

// @NotBlank(message = "ID는 필수항목입니다.")
// private String userId;
@NotBlank(message = "이메일은 필수항목입니다.")
@Email(message = "이메일형식에 맞지 않습니다.")
private String email;
Expand All @@ -28,8 +24,8 @@ public class UserInfo {
private String password;

@NotBlank(message = "닉네임은 필수항목입니다.")
@Size(min = 2, max = 7, message = "2글자 이상 7글자 이하여야 합니다!")
@Pattern(regexp = "^[가-힣a-zA-Z0-9]{2,7}$", message = "한글, 대소문자, 숫자로만 이루어져야 합니다!")
@Size(min = 2, max = 30, message = "2글자 이상 30글자 이하여야 합니다!")
@Pattern(regexp = "^[가-힣a-zA-Z0-9]{2,30}$", message = "한글, 대소문자, 숫자로만 이루어져야 합니다!")
private String nickname;

@NotBlank(message = "이름은 필수항목입니다.")
Expand All @@ -48,6 +44,54 @@ public class UserInfo {
@Email(message = "이메일 형식에 맞지 않습니다.")
private String socialEmail;

public UserInfo(String email, String password, String nickname, String name, String socialEmail) throws IllegalArgumentException {
String errorMessage = "";
if (email.isBlank()) {
errorMessage += "이메일은 필수 항목입니다.\n";
}
if(!email.isBlank() && !email.matches("[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}")) {
errorMessage += "이메일형식에 맞지 않습니다.\n";
}
if (password.isBlank()){
errorMessage += "비밀번호는 필수항목입니다.\n";
}
if (!password.isBlank() && (password.length() < 8 || password.length() > 20)) {
errorMessage += "비밀번호는 반드시 8자 이상, 20자 이하여야 합니다.\n";
}
if (!password.isBlank() && !password.matches("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*])[A-Za-z\\d!@#$%^&*]{8,20}$")) {
errorMessage += "대소문자, 숫자, 특수문자를 포함해야 합니다!\n";
}
if (nickname.isBlank()) {
errorMessage += "닉네임은 필수항목입니다.\n";
}
if (!nickname.isBlank() && (nickname.length() < 2 || nickname.length() > 30)) {
errorMessage += "닉네임은 2글자 이상 30글자 이하여야 합니다.\n";
}
if(!nickname.isBlank() && !nickname.matches("^[가-힣a-zA-Z0-9]{2,30}$")) {
errorMessage +="한글, 대소문자, 숫자로만 이루어져야 합니다!\n";
}
if (name.isBlank()) {
errorMessage += "이름은 필수항목입니다.\n";
}
if (!name.isBlank() && (name.length() < 2 || name.length() > 4)) {
errorMessage += "이름은 2글자 이상 4글자 이하여야 합니다.\n";
}
if (!name.isBlank() && !name.matches("^[가-힣]{2,4}$")) {
errorMessage += "이름은 한글로만 이루어져야 합니다!\n";
}
if (socialEmail != null && !socialEmail.matches("[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}")) {
errorMessage += "Social 이메일이 형식에 맞지 않습니다.\n";
}
if (!errorMessage.isEmpty())
throw new IllegalArgumentException(errorMessage);

this.email = email;
this.password = password;
this.nickname = nickname;
this.name = name;
this.socialEmail = socialEmail;
}

public User convertUser() {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
return User.builder()
Expand Down
Loading