Skip to content

[FEAT] 사용자 도서 접근 권한 정책 추가#277

Merged
kjhyeon0620 merged 2 commits into
develop-demofrom
feat/#271-book-access-policy
May 19, 2026
Merged

[FEAT] 사용자 도서 접근 권한 정책 추가#277
kjhyeon0620 merged 2 commits into
develop-demofrom
feat/#271-book-access-policy

Conversation

@kjhyeon0620
Copy link
Copy Markdown
Contributor

@kjhyeon0620 kjhyeon0620 commented May 19, 2026

📄 작업 내용 요약

  • USER 도서 접근 권한 검증 로직 추가
  • 도서 상세 조회 및 서재 등록 시 권한 검증 적용
  • 권한 없는 USER 도서 접근 시 BOOK_ACCESS_DENIED 반환

📎 Issue 번호


✅ 작업 목록

  • 기능 구현
  • 코드 리뷰 반영
  • 테스트 코드 작성
  • 문서 업데이트

📝 기타 참고사항

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 도서 접근 권한 검증 시스템 추가
    • 공개 도서와 개인 도서에 대한 접근 제어 강화
    • 서재 등록 및 도서 수정 시 권한 확인 프로세스 적용
  • 테스트

    • 접근 권한 검증 기능에 대한 포괄적 테스트 추가

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 19, 2026

Warning

Rate limit exceeded

@kjhyeon0620 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 45 minutes and 46 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 249c06d5-2652-4151-a30c-69d4103fed02

📥 Commits

Reviewing files that changed from the base of the PR and between bf8f5dd and f8c31f7.

📒 Files selected for processing (1)
  • src/test/java/app/nook/book/service/BookAccessServiceTest.java

Walkthrough

도서 접근 권한 검증을 전담하는 BookAccessService를 도입하고 기존 검증 로직을 대체합니다. 도서 조회·수정·서재 등록 흐름에 통합하며, 포괄적인 단위 및 통합 테스트를 추가합니다.

Changes

도서 접근 권한 검증 통합

Layer / File(s) Summary
권한 검증 에러 코드 및 서비스 정의
src/main/java/app/nook/book/exception/BookErrorCode.java, src/main/java/app/nook/book/service/BookAccessService.java
BOOK_ACCESS_DENIED 에러 코드를 추가하고, 도서 조회·등록·수정 권한을 검증하는 BookAccessService를 정의합니다. assertCanView, assertCanAddToLibrary, assertCanUpdate 메서드는 공개 도서(ALADIN) 여부와 생성자 일치 여부를 확인하여 권한을 판정합니다.
BookService 권한 검증 통합
src/main/java/app/nook/book/service/BookService.java
BookAccessService 의존성을 주입하고, 도서 상세 조회(getBookDetailById)와 사용자 도서 수정(updateUserBook)에서 assertCanView, assertCanUpdate를 호출하도록 변경합니다. 기존의 validateUserBookOwnership 메서드는 제거됩니다.
LibraryCommandService 권한 검증 통합
src/main/java/app/nook/library/service/LibraryCommandService.java
BookAccessService 의존성을 주입하고, registerBook 흐름에서 사용자 조회 직후 assertCanAddToLibrary를 호출하여 등록 가능 여부를 먼저 검증합니다.
BookAccessService 단위 테스트
src/test/java/app/nook/book/service/BookAccessServiceTest.java
assertCanView, assertCanAddToLibrary, assertCanUpdate 각각에 대해 성공/실패 시나리오를 검증합니다. ALADIN 도서 조회 허용, 본인 USER 도서 조회·수정·등록 허용, 타인 도서 및 익명 사용자 거부를 확인합니다.
서비스 통합 테스트 업데이트
src/test/java/app/nook/book/service/BookServiceTest.java, src/test/java/app/nook/library/service/LibraryServiceTest.java
BookAccessService 모킹과 스파이 구성을 추가하고, 다른 사용자가 생성한 도서 조회 시 BOOK_ACCESS_DENIED 예외 발생, 서재 등록 시 권한 없을 때 저장이 호출되지 않음을 검증합니다.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • UMC-NOOK/Server#267: 동일한 BookService.getBookDetail*LibraryCommandService.registerBook 흐름에서 응답 DTO의 readingStatus/bookShelfId 반환 추가와 이번 PR의 권한 검증이 함께 작동합니다.
  • UMC-NOOK/Server#208: 에러 코드 리팩토링 전반과 맞춰, 이번 PR에서 BookErrorCode 도입 및 권한 검증이 추가됩니다.

Poem

🐰 책의 문을 지키는 토끼
열쇠를 들고 권한을 묻네
본인 것만 볼 수 있도록
접근 검증, 안전하게
도서 왕국을 보호하리~

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.71% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 '[FEAT] 사용자 도서 접근 권한 정책 추가'로 변경 사항의 핵심인 도서 접근 권한 검증 기능 추가를 명확하게 설명합니다.
Linked Issues check ✅ Passed PR은 #271의 모든 기술 요구사항을 충족합니다: 도서 접근 권한 검증 로직 추가, USER 도서 생성자 본인만 접근 가능, 상세 조회 및 서재 등록 API에 권한 검증 적용, BOOK_ACCESS_DENIED 반환.
Out of Scope Changes check ✅ Passed 모든 변경사항이 도서 접근 권한 검증과 관련하여 범위 내에 있습니다. 새로운 BookAccessService 추가, 기존 검증 로직 통합, 관련 테스트 케이스 추가 등이 모두 #271의 목표와 일관성 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/#271-book-access-policy

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@JiwonLee42
Copy link
Copy Markdown
Contributor

Overall Project 67.13% 🍏
Files changed 100% 🍏

File Coverage
BookAccessService.java 100% 🍏
LibraryCommandService.java 94.66% 🍏
BookService.java 78.4% 🍏

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/test/java/app/nook/book/service/BookAccessServiceTest.java (1)

16-117: ⚡ Quick win

null 사용자에 대한 엣지 케이스 테스트를 고려하세요.

assertCanView는 익명 사용자(null)에 대한 테스트를 포함하고 있지만, assertCanAddToLibraryassertCanUpdate는 해당 엣지 케이스를 테스트하지 않습니다. 일관성 있는 테스트 커버리지를 위해 두 메서드에도 null 사용자 시나리오를 추가하는 것을 고려해보세요.

📝 추가 가능한 테스트 케이스 예시
`@Test`
`@DisplayName`("로그인 사용자가 없으면 서재 등록 권한을 차단한다")
void assertCanAddToLibrary_anonymousUser_fail() {
    Book book = createBook(SourceType.USER, 1L);
    
    assertThatThrownBy(() -> bookAccessService.assertCanAddToLibrary(null, book))
            .isInstanceOf(CustomException.class)
            .extracting(exception -> ((CustomException) exception).getErrorCode())
            .isEqualTo(BookErrorCode.BOOK_ACCESS_DENIED);
}

`@Test`
`@DisplayName`("로그인 사용자가 없으면 수정 권한을 차단한다")
void assertCanUpdate_anonymousUser_fail() {
    Book book = createBook(SourceType.USER, 1L);
    
    assertThatThrownBy(() -> bookAccessService.assertCanUpdate(null, book))
            .isInstanceOf(CustomException.class)
            .extracting(exception -> ((CustomException) exception).getErrorCode())
            .isEqualTo(BookErrorCode.BOOK_NOT_OWNED);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/app/nook/book/service/BookAccessServiceTest.java` around lines
16 - 117, Add null-user edge-case tests for assertCanAddToLibrary and
assertCanUpdate to match assertCanView coverage: create a Book via
createBook(SourceType.USER, 1L) and call
bookAccessService.assertCanAddToLibrary(null, book) expecting a CustomException
with error code BookErrorCode.BOOK_ACCESS_DENIED, and call
bookAccessService.assertCanUpdate(null, book) expecting a CustomException with
error code BookErrorCode.BOOK_NOT_OWNED; name the tests e.g.
assertCanAddToLibrary_anonymousUser_fail and assertCanUpdate_anonymousUser_fail
to mirror existing test naming.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/test/java/app/nook/book/service/BookAccessServiceTest.java`:
- Around line 63-83: Add a test in BookAccessServiceTest to verify ALADIN books
can be added to a user's library: create a User with createUser(...), create an
ALADIN Book via createBook(SourceType.ALADIN, <anyOwnerId>), then call
bookAccessService.assertCanAddToLibrary(user, book) and assert it does not throw
(use assertThatCode(...).doesNotThrowAnyException()). Ensure the new test
mirrors naming/style of existing tests (e.g., display name "ALADIN 도서는 서재 등록 권한을
허용한다") and lives alongside the other assertCanAddToLibrary tests.

---

Nitpick comments:
In `@src/test/java/app/nook/book/service/BookAccessServiceTest.java`:
- Around line 16-117: Add null-user edge-case tests for assertCanAddToLibrary
and assertCanUpdate to match assertCanView coverage: create a Book via
createBook(SourceType.USER, 1L) and call
bookAccessService.assertCanAddToLibrary(null, book) expecting a CustomException
with error code BookErrorCode.BOOK_ACCESS_DENIED, and call
bookAccessService.assertCanUpdate(null, book) expecting a CustomException with
error code BookErrorCode.BOOK_NOT_OWNED; name the tests e.g.
assertCanAddToLibrary_anonymousUser_fail and assertCanUpdate_anonymousUser_fail
to mirror existing test naming.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1706fa68-904d-4bac-beaa-98dbef54441a

📥 Commits

Reviewing files that changed from the base of the PR and between d921a70 and bf8f5dd.

📒 Files selected for processing (7)
  • src/main/java/app/nook/book/exception/BookErrorCode.java
  • src/main/java/app/nook/book/service/BookAccessService.java
  • src/main/java/app/nook/book/service/BookService.java
  • src/main/java/app/nook/library/service/LibraryCommandService.java
  • src/test/java/app/nook/book/service/BookAccessServiceTest.java
  • src/test/java/app/nook/book/service/BookServiceTest.java
  • src/test/java/app/nook/library/service/LibraryServiceTest.java

Comment thread src/test/java/app/nook/book/service/BookAccessServiceTest.java
@JiwonLee42
Copy link
Copy Markdown
Contributor

Overall Project 67.13% 🍏
Files changed 100% 🍏

File Coverage
BookAccessService.java 100% 🍏
LibraryCommandService.java 94.66% 🍏
BookService.java 78.4% 🍏

@kjhyeon0620 kjhyeon0620 merged commit c0b6692 into develop-demo May 19, 2026
5 checks passed
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.

[FEAT] 도서 접근 권한 검증 추가

2 participants