41 lines
1.2 KiB
Python
41 lines
1.2 KiB
Python
|
|
"""파일 경로 접근 제어."""
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
|
||
|
|
def validate_paths(
|
||
|
|
changed_paths: list[str],
|
||
|
|
writable: list[str],
|
||
|
|
blocked: list[str],
|
||
|
|
) -> list[str]:
|
||
|
|
"""변경된 파일 경로들을 검증한다.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
changed_paths: 변경된 파일 경로 목록.
|
||
|
|
writable: 쓰기 허용 경로 접두사 목록.
|
||
|
|
blocked: 차단 경로 목록 (정확 일치 또는 접두사).
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
위반 사항 메시지 목록. 빈 리스트이면 모든 경로 통과.
|
||
|
|
"""
|
||
|
|
errors: list[str] = []
|
||
|
|
|
||
|
|
for path in changed_paths:
|
||
|
|
normalized = path.lstrip("./")
|
||
|
|
|
||
|
|
blocked_match = False
|
||
|
|
for b in blocked:
|
||
|
|
b_normalized = b.lstrip("./")
|
||
|
|
if normalized == b_normalized or normalized.startswith(b_normalized + "/"):
|
||
|
|
errors.append(f"BLOCKED: '{path}' is in blocked_paths ({b})")
|
||
|
|
blocked_match = True
|
||
|
|
break
|
||
|
|
|
||
|
|
if blocked_match:
|
||
|
|
continue
|
||
|
|
|
||
|
|
is_writable = any(normalized.startswith(w.lstrip("./")) for w in writable)
|
||
|
|
if not is_writable:
|
||
|
|
errors.append(f"NOT_WRITABLE: '{path}' is not in writable_paths")
|
||
|
|
|
||
|
|
return errors
|