Skip to content

임혜민 sprint11 - #240

Open
hyemin-L wants to merge 20 commits into
codeit-bootcamp-spring:mainfrom
hyemin-L:임혜민-Sprint11

Hidden character warning

The head ref may contain hidden characters: "\uc784\ud61c\ubbfc-Sprint11"
Open

hyemin-L wants to merge 20 commits into
codeit-bootcamp-spring:mainfrom
hyemin-L:임혜민-Sprint11

Conversation

@hyemin-L

Copy link
Copy Markdown
Collaborator

요구사항

기본

기본 항목은 전부 완료했습니다.

심화

  • 심화 항목 1
  • 심화 항목 2

멘토에게

  • 셀프 코드 리뷰를 통해 질문 이어가겠습니다.
  • 다음주에 심화 과정 완료하겠습니다.

@joonfluence joonfluence left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sprint11 리뷰 요약

Sprint11 미션(테스트 코드, S3 스토리지, CI/CD, Docker 배포)을 담은 대규모 PR입니다. @Retryable+@Recover 실패 복구, presigned URL, MDC 로깅 인터셉터 등 구조 설계는 좋습니다. 다만 아래 두 가지 P1을 먼저 해결해 주세요.

P1-1. 다수 핵심 클래스 미커밋 → 컴파일 불가

PR head 트리를 직접 조회한 결과, 코드가 참조하는 다음 클래스/패키지가 저장소에 존재하지 않습니다.

  • security/ 패키지 전체 (JwtTokenProvider, JwtRegistry, DiscodeitUserDetails)
  • event/BinaryContentCreatedEvent, service/NotificationService
  • entity/Role, entity/BinaryContentStatus
  • dto/data/JwtInformation, dto/request/RoleUpdateRequest

User.javaRole/Role.USER를, BasicAuthService/S3BinaryContentStorage/BasicBinaryContentService는 위 클래스들을 직접 사용하므로 빌드가 깨집니다. git add 누락 또는 .gitignore 과다 제외로 보입니다. 누락 파일을 모두 푸시해 주세요.

P1-2. 빌드 산출물·OS 파일 커밋 (P2)

build/**/*.class, .gradle/**, .DS_Store가 다수 추적되고 있습니다(약 170여 개). .gitignore에 패턴은 있으나 이미 추적된 파일은 제외되지 않으니 git rm -r --cached build .gradle 후 정리해 주세요.

나머지 라인별 코멘트(배포 워크플로우 버그, 인가 우회, 민감정보 로깅, S3Client 재생성 등)를 함께 확인 부탁드립니다. 전반적인 설계 방향은 좋으니 위 항목만 보완되면 좋을 것 같습니다.

# 3️⃣ 새 이미지로 Task Definition 수정
- name: Update task definition image
run: |
$REPO_URI=${{ vars.ECR_REPOSITORY_URI }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1. bash 변수 할당은 $ 없이 작성해야 합니다.

Suggested change
$REPO_URI=${{ vars.ECR_REPOSITORY_URI }}
REPO_URI=${{ vars.ECR_REPOSITORY_URI }}

현재 $REPO_URI=...는 "command not found" 에러를 발생시켜 deploy 잡이 실패합니다.

echo "REPO_URI=${{ vars.ECR_REPOSITORY_URI }}" >> $GITHUB_ENV

docker tag discodeit:latest $REPO_URI:latest
docker tag discodeit:latest $REPO_URI:$COMMIT_HASH

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1. 바로 위에서 echo "REPO_URI=..." >> $GITHUB_ENV로 설정한 변수를 같은 스텝에서 $REPO_URI로 사용하고 있습니다. $GITHUB_ENV에 기록한 값은 다음 스텝부터 반영되므로 이 스텝에서는 빈 값입니다. 또한 IMAGE_TAG를 정의했지만 태그에는 미정의 변수 $COMMIT_HASH를 쓰고 있습니다. 같은 스텝 안에서 쓰려면 일반 셸 변수로 정의해서 사용하세요.

Suggested change
docker tag discodeit:latest $REPO_URI:$COMMIT_HASH
REPO_URI=${{ vars.ECR_REPOSITORY_URI }}
COMMIT_HASH=${GITHUB_SHA::7}
docker tag discodeit:latest $REPO_URI:latest
docker tag discodeit:latest $REPO_URI:$COMMIT_HASH

참고로 build-and-push 잡과 deploy 잡은 별도 러너라 env가 공유되지 않으니, deploy 잡에서도 변수를 다시 정의해야 합니다.


public UUID put(UUID binaryContentId, byte[] bytes) {
try {
Thread.sleep(3000);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2. 운영 코드의 업로드 경로에 3초 인위적 지연(Thread.sleep(3000))이 그대로 남아 있습니다. 비동기/재시도 동작 테스트용이라면 제거하거나 테스트 전용 코드로 분리해 주세요. 실제 업로드마다 3초가 추가됩니다.


@Transactional
@Override
public UserDto updateRoleInternal(RoleUpdateRequest request) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2. 인가 우회 가능. updateRole@PreAuthorize("hasRole('ADMIN')")로 보호되지만, 실제 로직인 updateRoleInternalpublic + AuthService 인터페이스에 노출되어 있고 권한 애너테이션이 없습니다. 다른 빈에서 updateRoleInternal을 직접 호출하면 권한 검사를 건너뛰고 임의 사용자의 role을 변경할 수 있습니다. internal 메서드는 private/패키지 스코프로 숨기거나 인터페이스에서 제외해 주세요. (같은 빈 내부 호출은 프록시를 거치지 않아 @PreAuthorize도 적용되지 않습니다.)

}
}

private S3Client getS3Client() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3. getS3Client()/getS3Presigner()가 put·get·download 호출마다 새 클라이언트를 생성합니다. S3Client는 thread-safe하고 생성 비용이 큰 무거운 객체이며, get/put 경로에서는 close()도 되지 않아 리소스 누수가 발생합니다. @Bean singleton으로 등록해 주입받는 형태를 권장합니다.

String key = metaData.id().toString();
String presignedUrl = generatePresignedUrl(key, metaData.contentType());

log.info("생성된 Presigned URL: {}", presignedUrl);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3. 민감정보 로깅. presigned URL은 임시 접근 권한이 담긴 민감 정보입니다. info 레벨로 운영 로그에 남기면 로그 접근자가 그대로 객체에 접근할 수 있습니다. debug로 강등하거나 제거해 주세요.

Exception e
) {

userRepository.findAll()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3. userRepository.findAll().stream().filter(role==ADMIN).findFirst()는 전체 사용자를 메모리에 적재한 뒤 필터링합니다. 사용자가 늘어나면 부담이 커집니다. findFirstByRole(Role.ADMIN) 같은 쿼리 메서드로 DB에서 직접 조회하세요.

// Validate refresh token
if (!tokenProvider.validateRefreshToken(refreshToken)
|| !jwtRegistry.hasActiveJwtInformationByRefreshToken(refreshToken)) {
log.error("Invalid or expired refresh token: {}", refreshToken);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3. 민감정보 로깅. refresh token 원문을 로그에 남기면 안 됩니다. 토큰 값 대신 사유/사용자 식별자 정도만 기록하세요.

datasource:
url: jdbc:postgresql://localhost:5432/discodeit
username: discodeit_user
password: discodeit1234

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3. dev DB 비밀번호가 하드코딩되어 있습니다(discodeit1234). 로컬 전용이라도 환경변수/.env로 분리하는 편이 안전합니다. 더불어 application.yaml의 JWT 기본 시크릿 fallback(your-access-token-secret-key-...)도 prod에서 우연히 사용되지 않도록 fallback을 제거하는 것을 권장합니다.

try {
Files.createDirectories(root);
} catch (IOException e) {
e.printStackTrace();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P4. 예외를 e.printStackTrace() 대신 SLF4J 로거(log.error(...))로 남겨 주세요. (73번 라인에도 동일.) @Retryable+@Recover 실패 복구 패턴은 S3 쪽에 잘 적용되어 있습니다 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants