Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.woozuda.backend.note.entity;

import com.woozuda.backend.global.entity.BaseTimeEntity;
import com.woozuda.backend.note.entity.converter.NoteContentConverter;
import jakarta.persistence.Column;
import jakarta.persistence.Convert;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
Expand Down Expand Up @@ -34,6 +36,7 @@ public class NoteContent extends BaseTimeEntity {
private Integer noteOrder;

@Column(length = 2000, nullable = false)
@Convert(converter = NoteContentConverter.class)
private String content; // 회고 부분 내용

private NoteContent(Integer noteOrder, String content) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.woozuda.backend.note.entity.converter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.encrypt.Encryptors;
import org.springframework.security.crypto.encrypt.TextEncryptor;
import org.springframework.security.crypto.keygen.KeyGenerators;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class AesEncryptor {

public static final String SALT_DATA_DELIMITER = "::";

private final String password;

public AesEncryptor(@Value("${aes.password}") String password) {
this.password = password;
}

public String encrypt(String plainText) {
//무작위 salt 생성
String salt = KeyGenerators.string().generateKey();
TextEncryptor encryptor = Encryptors.delux(password, salt);

// salt를 암호화된 데이터와 함께 저장
return salt + SALT_DATA_DELIMITER + encryptor.encrypt(plainText);
}

public String decrypt(String encryptedText) {
// 암호화된 데이터에서 salt 분리
String[] parts = encryptedText.split(SALT_DATA_DELIMITER, 2);
if (parts.length > 2) {
throw new IllegalArgumentException("Invalid encrypted text format");
}
if (parts.length == 1) {
return encryptedText;
}

String salt = parts[0];
String cipherText = parts[1];

TextEncryptor encryptor = Encryptors.delux(password, salt);

return encryptor.decrypt(cipherText);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.woozuda.backend.note.entity.converter;

import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
import lombok.RequiredArgsConstructor;

@Converter
@RequiredArgsConstructor
public class NoteContentConverter implements AttributeConverter<String, String> {

private final AesEncryptor aesEncryptor;

@Override
public String convertToDatabaseColumn(String attribute) {
if (attribute == null) {
return null;
}

try {
return aesEncryptor.encrypt(attribute);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

@Override
public String convertToEntityAttribute(String dbData) {
if (dbData == null) {
return null;
}

try {
return aesEncryptor.decrypt(dbData);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
3 changes: 3 additions & 0 deletions src/main/resources/application-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,6 @@ management:
endpoint:
prometheus:
enabled: true #default

aes:
password: "${aes-password}"
5 changes: 4 additions & 1 deletion src/main/resources/application-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,7 @@ management:
enabled: true #default

logging:
config: "classpath:./logback-release.xml"
config: "classpath:./logback-release.xml"

aes:
password: "${aes_password}"
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
import com.woozuda.backend.account.entity.UserEntity;
import com.woozuda.backend.diary.dto.response.SingleDiaryResponseDto;
import com.woozuda.backend.diary.entity.Diary;
import com.woozuda.backend.note.entity.converter.AesEncryptor;
import com.woozuda.backend.tag.entity.Tag;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
Expand All @@ -18,6 +20,7 @@
import static org.assertj.core.api.Assertions.assertThat;

@DataJpaTest
@MockBean(AesEncryptor.class)
@Transactional
class DiaryRepositoryTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,68 @@
import com.woozuda.backend.diary.entity.Diary;
import com.woozuda.backend.note.dto.request.NoteCondRequestDto;
import com.woozuda.backend.note.dto.response.NoteResponseDto;
import com.woozuda.backend.note.entity.*;
import com.woozuda.backend.note.entity.CommonNote;
import com.woozuda.backend.note.entity.NoteContent;
import com.woozuda.backend.note.entity.QuestionNote;
import com.woozuda.backend.note.entity.RetrospectiveNote;
import com.woozuda.backend.note.entity.converter.AesEncryptor;
import com.woozuda.backend.note.entity.converter.NoteContentConverter;
import com.woozuda.backend.question.entity.Question;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.List;

import static com.woozuda.backend.account.entity.AiType.PICTURE_NOVEL;
import static com.woozuda.backend.note.entity.type.Feeling.*;
import static com.woozuda.backend.note.entity.type.Framework.*;
import static com.woozuda.backend.note.entity.type.Feeling.ANGER;
import static com.woozuda.backend.note.entity.type.Feeling.CONTENT;
import static com.woozuda.backend.note.entity.type.Feeling.DISSATISFACTION;
import static com.woozuda.backend.note.entity.type.Feeling.JOY;
import static com.woozuda.backend.note.entity.type.Feeling.NEUTRAL;
import static com.woozuda.backend.note.entity.type.Feeling.SADNESS;
import static com.woozuda.backend.note.entity.type.Feeling.TIREDNESS;
import static com.woozuda.backend.note.entity.type.Framework.FOUR_F_S;
import static com.woozuda.backend.note.entity.type.Framework.KPT;
import static com.woozuda.backend.note.entity.type.Framework.PMI;
import static com.woozuda.backend.note.entity.type.Framework.SCS;
import static com.woozuda.backend.note.entity.type.Season.FALL;
import static com.woozuda.backend.note.entity.type.Season.WINTER;
import static com.woozuda.backend.note.entity.type.Visibility.PRIVATE;
import static com.woozuda.backend.note.entity.type.Visibility.PUBLIC;
import static com.woozuda.backend.note.entity.type.Weather.*;
import static com.woozuda.backend.note.entity.type.Weather.CLEAR;
import static com.woozuda.backend.note.entity.type.Weather.CLOUDY;
import static com.woozuda.backend.note.entity.type.Weather.RAIN;
import static com.woozuda.backend.note.entity.type.Weather.SNOW;
import static com.woozuda.backend.note.entity.type.Weather.SUNNY;
import static com.woozuda.backend.note.entity.type.Weather.THUNDERSTORM;
import static java.time.Month.DECEMBER;
import static org.assertj.core.api.Assertions.assertThat;

@DataJpaTest
@Transactional
class NoteRepositoryTest {

@TestConfiguration
static class NoteContentTestConfig {
@Bean
public AesEncryptor aesEncryptor() {
return new AesEncryptor("test-password");
}

@Bean
public NoteContentConverter noteContentConverter(AesEncryptor aesEncryptor) {
return new NoteContentConverter(aesEncryptor);
}
}

LocalDate date1 = LocalDate.of(2024, DECEMBER, 5);
LocalDate date2 = LocalDate.of(2024, DECEMBER, 6);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
package com.woozuda.backend.note.repository;

import com.woozuda.backend.note.entity.converter.AesEncryptor;
import com.woozuda.backend.question.entity.Question;
import com.woozuda.backend.question.repository.QuestionRepository;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;

import static org.assertj.core.api.Assertions.assertThat;

@DataJpaTest
@MockBean(AesEncryptor.class)
@Transactional
class QuestionRepositoryTest {

Expand Down
5 changes: 4 additions & 1 deletion src/test/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,7 @@ openai:
chat:
options:
model: "gpt-3.5-turbo" # 사용할 AI 모델 (예: gpt-3.5-turbo)
temperature: 0.6 # 생성되는 텍스트의 다양성 정도를 조절하는 파라미터 (0.0 ~ 1.0)
temperature: 0.6 # 생성되는 텍스트의 다양성 정도를 조절하는 파라미터 (0.0 ~ 1.0)

aes:
password: "aes_password"
Loading