Skip to content

refactor: common configuration and authentication modularization - #92

Merged
Yu-JeSeung merged 2 commits into
mainfrom
refactor/configuration_modularization
Apr 22, 2026
Merged

refactor: common configuration and authentication modularization#92
Yu-JeSeung merged 2 commits into
mainfrom
refactor/configuration_modularization

Conversation

@Yu-JeSeung

@Yu-JeSeung Yu-JeSeung commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

관련 이슈

Close #91

🎯 배경

  • 공통 설정 및 인증 모듈화를 진행하여 서비스 로직에 중복으로 작성하는 수고를 없앱니다.

🔍 주요 내용

  • core/settings.py, core/auth.py 구축하여 환경 변수 및 검증 통합

@Yu-JeSeung Yu-JeSeung self-assigned this Apr 22, 2026
@coderabbitai

coderabbitai Bot commented Apr 22, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@Yu-JeSeung has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 39 minutes and 55 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 39 minutes and 55 seconds.

⌛ 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f874b2b5-328e-4a91-8b2c-1baa634e6545

📥 Commits

Reviewing files that changed from the base of the PR and between 09e6795 and ed6430c.

📒 Files selected for processing (5)
  • LLM/OSS/Open_AI_OSS.py
  • core/__init__.py
  • core/auth.py
  • core/settings.py
  • image_analysis/timetable_analysis.py
📝 Walkthrough

개요

JWT 인증 및 구성 관리를 중앙화하기 위해 새로운 core.settingscore.auth 모듈을 도입했습니다. 기존 모듈들의 로컬 JWT 검증 로직을 제거하고 중앙화된 서비스를 통해 구성 및 인증을 처리하도록 리팩토링했습니다.

변경사항

코호트 / 파일(들) 요약
새로운 코어 인증 및 설정 인프라
core/__init__.py, core/auth.py, core/settings.py
새로운 core.auth 모듈은 JWT 토큰 검증 기능을 제공합니다. core.settings 모듈은 Settings 데이터클래스와 캐시된 get_settings() 함수를 통해 환경 변수 기반의 중앙화된 구성을 제공합니다. core/__init__.py에는 패키지 수준의 문서화 문자열이 추가되었습니다.
OSS 모듈 구성 마이그레이션
LLM/OSS/Open_AI_OSS.py
환경 변수 기반 구성 및 로컬 JWT 검증을 core.settings.get_settings()core.auth.verify_jwt_token 의존성 주입으로 대체했습니다. 로컬 JWT 디코딩 로직, 관련 임포트 및 인라인 폴백 설정을 제거하고, 런타임 구성 값들을 설정 객체에서 가져오도록 변경했습니다.
인증 검증 리팩토링
image_analysis/timetable_analysis.py, text_filtering/text_filtering.py, text_filtering/text_filtering_rule.py
각 모듈의 로컬 JWT 검증 구현과 관련된 로직을 제거하고 core.auth.verify_jwt_token 임포트로 대체했습니다. 환경 변수 기반 설정(SECRET_KEY, ALGORITHM)을 core.settings.get_settings()로 통일했습니다. 엔드포인트의 인증 흐름은 동일하게 유지되며, 파일 끝에 개행 문자를 추가했습니다.

코드 리뷰 예상 소요시간

🎯 3 (중간) | ⏱️ ~20분

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Title check ✅ Passed 제목이 PR의 주요 변경 사항인 공통 설정 및 인증 모듈화를 명확하게 요약하고 있습니다.
Description check ✅ Passed 설명에 관련 이슈, 배경, 주요 내용이 포함되어 있으나 리뷰 소요 시간 섹션이 누락되었습니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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 refactor/configuration_modularization

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.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@core/auth.py`:
- Around line 24-27: The code decodes settings.secret_key into signing_key
(padded_key, signing_key) and calls jwt.decode, but a non-base64 SECRET_KEY will
raise binascii.Error; catch binascii.Error around the base64.urlsafe_b64decode
call and convert it to a consistent authentication configuration error (e.g.,
raise a clear AuthConfigError or ValueError used by your auth flow) so the
failure is handled uniformly by the jwt.decode path; ensure the exception
message includes the problematic settings.secret_key reference and that
jwt.decode is only called when signing_key is successfully derived.

In `@core/settings.py`:
- Around line 38-48: The resolved_dept_map_path should treat a relative
dept_map_path as relative to the repo root instead of the current working
directory: update the resolved_dept_map_path property to check if dept_map_path
is provided and whether Path(self.dept_map_path).is_absolute(); if absolute,
expanduser()/resolve() as now, but if relative, join it with self.repo_root
(e.g. self.repo_root / self.dept_map_path) before resolving. Reference the
properties repo_root, resolved_dept_map_path, dept_map_path and root_base_path
when making the change.

In `@image_analysis/timetable_analysis.py`:
- Around line 16-17: After reading settings with get_settings() and assigning
SPRING_TIMETABLE_URL, validate that SPRING_TIMETABLE_URL is set
(non-empty/non-None) and fail fast if not; update timetable_analysis.py to check
the value right after SPRING_TIMETABLE_URL is assigned and raise a clear error
(e.g., ValueError or RuntimeError) or return a rejected response so the task is
not enqueued when the URL is missing, referencing get_settings and
SPRING_TIMETABLE_URL so the check is easy to locate.

In `@LLM/OSS/Open_AI_OSS.py`:
- Around line 98-99: Validate that settings.oss_api_key and settings.oss_model
are present before creating client or assigning OSS_MODEL: check both are not
None/empty at module initialization and raise a clear, descriptive exception
(e.g., ValueError) if missing, then only create client = OpenAI(...) and set
OSS_MODEL afterwards; also ensure call_oss() continues to use OSS_MODEL so it
won't encounter a late failure. This makes failures immediate and the error
message explicit rather than letting OpenAI SDK or call_oss() fail later.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f5d3da37-2f82-4a46-acb3-0c1b5990f487

📥 Commits

Reviewing files that changed from the base of the PR and between 241ca9c and 09e6795.

📒 Files selected for processing (7)
  • LLM/OSS/Open_AI_OSS.py
  • core/__init__.py
  • core/auth.py
  • core/settings.py
  • image_analysis/timetable_analysis.py
  • text_filtering/text_filtering.py
  • text_filtering/text_filtering_rule.py

Comment thread core/auth.py
Comment on lines +24 to +27
try:
padded_key = settings.secret_key + "=" * (-len(settings.secret_key) % 4)
signing_key = base64.urlsafe_b64decode(padded_key)
payload = jwt.decode(token, signing_key, algorithms=[settings.algorithm])

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 설명: Python base64 디코딩이 잘못된 설정값에서 예외를 낼 수 있음을 확인합니다.
python - <<'PY'
import base64

for value in ["abcde", "not-a-valid-base64!"]:
    padded = value + "=" * (-len(value) % 4)
    try:
        decoded = base64.urlsafe_b64decode(padded)
        print(value, "=>", decoded)
    except Exception as exc:
        print(value, "=>", type(exc).__name__, str(exc))
PY

Repository: dongsooop/AI

Length of output: 216


🏁 Script executed:

# First, let's inspect the actual core/auth.py file
head -50 core/auth.py | cat -n

Repository: dongsooop/AI

Length of output: 1637


🏁 Script executed:

# Let's also verify the exact exception type raised by base64.urlsafe_b64decode
python - <<'PY'
import base64
import binascii

# Test exact exception types
for value in ["abcde", "not-a-valid-base64!"]:
    padded = value + "=" * (-len(value) % 4)
    try:
        decoded = base64.urlsafe_b64decode(padded)
    except Exception as exc:
        print(f"Value: {value}")
        print(f"  Exception type: {type(exc).__name__}")
        print(f"  Exception module: {type(exc).__module__}")
        print(f"  Is binascii.Error: {isinstance(exc, binascii.Error)}")
        print(f"  Is ValueError: {isinstance(exc, ValueError)}")
        print(f"  Full repr: {repr(exc)}")
        print()
PY

Repository: dongsooop/AI

Length of output: 460


잘못된 base64 시크릿을 명시적으로 처리하세요.

SECRET_KEY가 base64 형식이 아닌 경우 25-26줄에서 binascii.Error 예외가 그대로 전파됩니다. 인증 설정 오류로 일관되게 처리해야 합니다.

🐛 제안 수정
 import base64
+import binascii
 
 from fastapi import HTTPException, Request
@@
     try:
         padded_key = settings.secret_key + "=" * (-len(settings.secret_key) % 4)
         signing_key = base64.urlsafe_b64decode(padded_key)
         payload = jwt.decode(token, signing_key, algorithms=[settings.algorithm])
         username = payload.get("sub")
         if username is None:
             raise HTTPException(status_code=401, detail="Invalid token: no subject")
         return username
+    except (binascii.Error, ValueError) as exc:
+        raise HTTPException(status_code=500, detail="Server auth configuration invalid") from exc
     except ExpiredSignatureError as exc:
         raise HTTPException(status_code=401, detail="Token has expired") from exc
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@core/auth.py` around lines 24 - 27, The code decodes settings.secret_key into
signing_key (padded_key, signing_key) and calls jwt.decode, but a non-base64
SECRET_KEY will raise binascii.Error; catch binascii.Error around the
base64.urlsafe_b64decode call and convert it to a consistent authentication
configuration error (e.g., raise a clear AuthConfigError or ValueError used by
your auth flow) so the failure is handled uniformly by the jwt.decode path;
ensure the exception message includes the problematic settings.secret_key
reference and that jwt.decode is only called when signing_key is successfully
derived.

Comment thread core/settings.py
Comment thread image_analysis/timetable_analysis.py
Comment thread LLM/OSS/Open_AI_OSS.py Outdated
@Yu-JeSeung
Yu-JeSeung merged commit 98e8545 into main Apr 22, 2026
1 check passed
@Yu-JeSeung
Yu-JeSeung deleted the refactor/configuration_modularization branch April 22, 2026 05:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[REFACTOR] AI 서비스 전체 코드 리팩토링 진행

1 participant