feat: 사용자별 페이지 접근 권한 시스템 구현

- 기존 4단계 권한을 admin/user 2단계로 단순화
- 페이지별 세부 접근 권한 관리 시스템 추가
- 부적합 조회 시 일반 사용자는 본인 등록 건만 조회 가능하도록 제한
- 관리자 전용 전체 부적합 조회 API 추가 (/api/issues/admin/all)

Backend Changes:
- models.py: UserPagePermission 모델 추가, UserRole 단순화
- page_permissions.py: 페이지 권한 관리 API 라우터 추가
- auth.py: 사용자 목록 조회 및 비밀번호 초기화 API 추가
- issues.py: 권한별 부적합 조회 제한 로직 구현
- 마이그레이션: 010~012 권한 시스템 관련 DB 스키마 변경
This commit is contained in:
Hyungi Ahn
2025-10-25 08:59:52 +09:00
parent 41b557a709
commit b68bf78e40
8 changed files with 676 additions and 8 deletions

View File

@@ -1,4 +1,4 @@
from sqlalchemy import Column, Integer, BigInteger, String, DateTime, Float, Boolean, Text, ForeignKey, Enum
from sqlalchemy import Column, Integer, BigInteger, String, DateTime, Float, Boolean, Text, ForeignKey, Enum, Index
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from datetime import datetime, timezone, timedelta
@@ -14,8 +14,8 @@ def get_kst_now():
Base = declarative_base()
class UserRole(str, enum.Enum):
admin = "admin"
user = "user"
admin = "admin" # 관리자
user = "user" # 일반 사용자
class IssueStatus(str, enum.Enum):
new = "new"
@@ -44,6 +44,28 @@ class User(Base):
issues = relationship("Issue", back_populates="reporter")
daily_works = relationship("DailyWork", back_populates="created_by")
projects = relationship("Project", back_populates="created_by")
page_permissions = relationship("UserPagePermission", back_populates="user", foreign_keys="UserPagePermission.user_id")
class UserPagePermission(Base):
__tablename__ = "user_page_permissions"
id = Column(Integer, primary_key=True, index=True)
user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False)
page_name = Column(String(50), nullable=False)
can_access = Column(Boolean, default=False)
granted_by_id = Column(Integer, ForeignKey("users.id"))
granted_at = Column(DateTime, default=get_kst_now)
notes = Column(Text)
# Relationships
user = relationship("User", back_populates="page_permissions", foreign_keys=[user_id])
granted_by = relationship("User", foreign_keys=[granted_by_id], post_update=True)
# Unique constraint
__table_args__ = (
Index('idx_user_page_permissions_user_id', 'user_id'),
Index('idx_user_page_permissions_page_name', 'page_name'),
)
class Issue(Base):
__tablename__ = "issues"

View File

@@ -5,7 +5,7 @@ import uvicorn
from database.database import engine, get_db
from database.models import Base
from routers import auth, issues, daily_work, reports, projects
from routers import auth, issues, daily_work, reports, projects, page_permissions
from services.auth_service import create_admin_user
# 데이터베이스 테이블 생성
@@ -36,6 +36,7 @@ app.include_router(issues.router)
app.include_router(daily_work.router)
app.include_router(reports.router)
app.include_router(projects.router)
app.include_router(page_permissions.router)
# 시작 시 관리자 계정 생성
@app.on_event("startup")

View File

@@ -0,0 +1,15 @@
-- 부적합 카테고리에 'etc' (기타) 값 추가
-- 백엔드 코드와 데이터베이스 enum 타입 불일치 해결
-- issuecategory enum 타입에 'etc' 값 추가
ALTER TYPE issuecategory ADD VALUE 'etc';
-- 확인 쿼리 (주석)
-- SELECT enumlabel FROM pg_enum WHERE enumtypid = (SELECT oid FROM pg_type WHERE typname = 'issuecategory') ORDER BY enumsortorder;
-- 이제 사용 가능한 카테고리:
-- 1. material_missing (자재누락)
-- 2. design_error (설계미스)
-- 3. incoming_defect (입고자재 불량)
-- 4. inspection_miss (검사미스)
-- 5. etc (기타) ✅ 새로 추가됨

View File

@@ -0,0 +1,137 @@
-- 권한 시스템 개선 마이그레이션
-- 새로운 사용자 역할 추가 및 개별 권한 테이블 생성
-- 1. 새로운 사용자 역할 추가
ALTER TYPE userrole ADD VALUE 'super_admin';
ALTER TYPE userrole ADD VALUE 'manager';
-- 2. 사용자별 개별 권한 테이블 생성
CREATE TABLE IF NOT EXISTS user_permissions (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
permission VARCHAR(50) NOT NULL,
granted BOOLEAN DEFAULT TRUE,
granted_by_id INTEGER REFERENCES users(id),
granted_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
revoked_at TIMESTAMP WITH TIME ZONE,
notes TEXT,
UNIQUE(user_id, permission)
);
-- 3. 인덱스 생성
CREATE INDEX IF NOT EXISTS idx_user_permissions_user_id ON user_permissions(user_id);
CREATE INDEX IF NOT EXISTS idx_user_permissions_permission ON user_permissions(permission);
CREATE INDEX IF NOT EXISTS idx_user_permissions_granted ON user_permissions(granted);
-- 4. 기본 권한 설정 (기존 관리자에게 super_admin 권한 부여)
UPDATE users SET role = 'super_admin' WHERE username = 'hyungi';
-- 5. 권한 확인 함수 생성
CREATE OR REPLACE FUNCTION check_user_permission(p_user_id INTEGER, p_permission VARCHAR)
RETURNS BOOLEAN AS $$
DECLARE
user_role userrole;
has_permission BOOLEAN := FALSE;
BEGIN
-- 사용자 역할 가져오기
SELECT role INTO user_role FROM users WHERE id = p_user_id AND is_active = TRUE;
IF user_role IS NULL THEN
RETURN FALSE;
END IF;
-- super_admin은 모든 권한 보유
IF user_role = 'super_admin' THEN
RETURN TRUE;
END IF;
-- 개별 권한 확인
SELECT granted INTO has_permission
FROM user_permissions
WHERE user_id = p_user_id
AND permission = p_permission
AND granted = TRUE
AND revoked_at IS NULL;
-- 개별 권한이 없으면 역할 기반 기본 권한 확인
IF has_permission IS NULL THEN
-- 기본 권한 매트릭스
CASE
WHEN p_permission IN ('issues.create', 'issues.view') THEN
has_permission := TRUE; -- 모든 사용자
WHEN p_permission IN ('issues.edit', 'issues.review', 'daily_work.create', 'daily_work.view', 'daily_work.edit') THEN
has_permission := user_role IN ('admin', 'manager'); -- 관리자, 매니저
WHEN p_permission IN ('projects.create', 'projects.edit', 'issues.delete', 'daily_work.delete') THEN
has_permission := user_role = 'admin'; -- 관리자만
WHEN p_permission IN ('projects.delete', 'users.create', 'users.edit', 'users.delete', 'users.change_role') THEN
has_permission := user_role = 'super_admin'; -- 최고 관리자만
ELSE
has_permission := FALSE;
END CASE;
END IF;
RETURN COALESCE(has_permission, FALSE);
END;
$$ LANGUAGE plpgsql;
-- 6. 권한 부여 함수 생성
CREATE OR REPLACE FUNCTION grant_user_permission(
p_user_id INTEGER,
p_permission VARCHAR,
p_granted_by_id INTEGER,
p_notes TEXT DEFAULT NULL
)
RETURNS BOOLEAN AS $$
BEGIN
INSERT INTO user_permissions (user_id, permission, granted, granted_by_id, notes)
VALUES (p_user_id, p_permission, TRUE, p_granted_by_id, p_notes)
ON CONFLICT (user_id, permission)
DO UPDATE SET
granted = TRUE,
granted_by_id = p_granted_by_id,
granted_at = NOW(),
revoked_at = NULL,
notes = p_notes;
RETURN TRUE;
END;
$$ LANGUAGE plpgsql;
-- 7. 권한 취소 함수 생성
CREATE OR REPLACE FUNCTION revoke_user_permission(
p_user_id INTEGER,
p_permission VARCHAR,
p_revoked_by_id INTEGER,
p_notes TEXT DEFAULT NULL
)
RETURNS BOOLEAN AS $$
BEGIN
UPDATE user_permissions
SET granted = FALSE,
revoked_at = NOW(),
notes = p_notes
WHERE user_id = p_user_id
AND permission = p_permission;
RETURN TRUE;
END;
$$ LANGUAGE plpgsql;
-- 8. 사용자 권한 목록 조회 뷰 생성
CREATE OR REPLACE VIEW user_permissions_view AS
SELECT
u.id as user_id,
u.username,
u.full_name,
u.role,
up.permission,
up.granted,
up.granted_at,
up.revoked_at,
granted_by.username as granted_by_username,
up.notes
FROM users u
LEFT JOIN user_permissions up ON u.id = up.user_id
LEFT JOIN users granted_by ON up.granted_by_id = granted_by.id
WHERE u.is_active = TRUE
ORDER BY u.username, up.permission;

View File

@@ -0,0 +1,111 @@
-- 권한 시스템 단순화
-- admin/user 구조로 변경하고 페이지별 접근 권한으로 변경
-- 1. 기존 복잡한 권한 테이블 삭제하고 단순한 페이지 권한 테이블로 변경
DROP TABLE IF EXISTS user_permissions CASCADE;
-- 2. 페이지별 접근 권한 테이블 생성
CREATE TABLE user_page_permissions (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
page_name VARCHAR(50) NOT NULL,
can_access BOOLEAN DEFAULT FALSE,
granted_by_id INTEGER REFERENCES users(id),
granted_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
notes TEXT,
UNIQUE(user_id, page_name)
);
-- 3. 인덱스 생성
CREATE INDEX IF NOT EXISTS idx_user_page_permissions_user_id ON user_page_permissions(user_id);
CREATE INDEX IF NOT EXISTS idx_user_page_permissions_page_name ON user_page_permissions(page_name);
-- 4. 기존 복잡한 함수들 삭제
DROP FUNCTION IF EXISTS check_user_permission(INTEGER, VARCHAR);
DROP FUNCTION IF EXISTS grant_user_permission(INTEGER, VARCHAR, INTEGER, TEXT);
DROP FUNCTION IF EXISTS revoke_user_permission(INTEGER, VARCHAR, INTEGER, TEXT);
-- 5. 단순한 페이지 접근 권한 체크 함수
CREATE OR REPLACE FUNCTION check_page_access(p_user_id INTEGER, p_page_name VARCHAR)
RETURNS BOOLEAN AS $$
DECLARE
user_role userrole;
has_access BOOLEAN := FALSE;
BEGIN
-- 사용자 역할 가져오기
SELECT role INTO user_role FROM users WHERE id = p_user_id AND is_active = TRUE;
IF user_role IS NULL THEN
RETURN FALSE;
END IF;
-- admin은 모든 페이지 접근 가능
IF user_role = 'admin' THEN
RETURN TRUE;
END IF;
-- 일반 사용자는 개별 페이지 권한 확인
SELECT can_access INTO has_access
FROM user_page_permissions
WHERE user_id = p_user_id
AND page_name = p_page_name;
-- 권한이 설정되지 않은 경우 기본값 (부적합 등록/조회만 허용)
IF has_access IS NULL THEN
CASE p_page_name
WHEN 'issues_create' THEN has_access := TRUE;
WHEN 'issues_view' THEN has_access := TRUE;
ELSE has_access := FALSE;
END CASE;
END IF;
RETURN COALESCE(has_access, FALSE);
END;
$$ LANGUAGE plpgsql;
-- 6. 페이지 권한 부여 함수
CREATE OR REPLACE FUNCTION grant_page_access(
p_user_id INTEGER,
p_page_name VARCHAR,
p_can_access BOOLEAN,
p_granted_by_id INTEGER,
p_notes TEXT DEFAULT NULL
)
RETURNS BOOLEAN AS $$
BEGIN
INSERT INTO user_page_permissions (user_id, page_name, can_access, granted_by_id, notes)
VALUES (p_user_id, p_page_name, p_can_access, p_granted_by_id, p_notes)
ON CONFLICT (user_id, page_name)
DO UPDATE SET
can_access = p_can_access,
granted_by_id = p_granted_by_id,
granted_at = NOW(),
notes = p_notes;
RETURN TRUE;
END;
$$ LANGUAGE plpgsql;
-- 7. 사용자 페이지 권한 조회 뷰
CREATE OR REPLACE VIEW user_page_access_view AS
SELECT
u.id as user_id,
u.username,
u.full_name,
u.role,
upp.page_name,
upp.can_access,
upp.granted_at,
granted_by.username as granted_by_username,
upp.notes
FROM users u
LEFT JOIN user_page_permissions upp ON u.id = upp.user_id
LEFT JOIN users granted_by ON upp.granted_by_id = granted_by.id
WHERE u.is_active = TRUE
ORDER BY u.username, upp.page_name;
-- 8. 기존 super_admin, manager 역할을 admin으로 변경
UPDATE users SET role = 'admin' WHERE role IN ('super_admin', 'manager');
-- 9. 기존 뷰 삭제
DROP VIEW IF EXISTS user_permissions_view;

View File

@@ -2,6 +2,7 @@ from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from sqlalchemy.orm import Session
from typing import List
from pydantic import BaseModel
from database.database import get_db
from database.models import User, UserRole
@@ -61,6 +62,15 @@ async def login(form_data: OAuth2PasswordRequestForm = Depends(), db: Session =
async def read_users_me(current_user: User = Depends(get_current_user)):
return current_user
@router.get("/users", response_model=List[schemas.User])
async def get_all_users(
current_admin: User = Depends(get_current_admin),
db: Session = Depends(get_db)
):
"""모든 사용자 목록 조회 (관리자 전용)"""
users = db.query(User).filter(User.is_active == True).all()
return users
@router.post("/users", response_model=schemas.User)
async def create_user(
user: schemas.UserCreate,
@@ -153,3 +163,24 @@ async def change_password(
db.commit()
return {"detail": "Password changed successfully"}
class PasswordReset(BaseModel):
new_password: str
@router.post("/users/{user_id}/reset-password")
async def reset_user_password(
user_id: int,
password_reset: PasswordReset,
current_admin: User = Depends(get_current_admin),
db: Session = Depends(get_db)
):
"""사용자 비밀번호 초기화 (관리자 전용)"""
db_user = db.query(User).filter(User.id == user_id).first()
if not db_user:
raise HTTPException(status_code=404, detail="User not found")
# 새 비밀번호로 업데이트
db_user.hashed_password = get_password_hash(password_reset.new_password)
db.commit()
return {"detail": f"Password reset successfully for user {db_user.username}"}

View File

@@ -6,7 +6,7 @@ from datetime import datetime
from database.database import get_db
from database.models import Issue, IssueStatus, User, UserRole
from database import schemas
from routers.auth import get_current_user
from routers.auth import get_current_user, get_current_admin
from services.file_service import save_base64_image, delete_file
router = APIRouter(prefix="/api/issues", tags=["issues"])
@@ -54,8 +54,30 @@ async def read_issues(
):
query = db.query(Issue)
# 모든 사용자가 모든 이슈를 조회 가능
# (필터링 제거 - 협업을 위해 모두가 볼 수 있어야 함)
# 권한별 조회 제한
if current_user.role == UserRole.admin:
# 관리자는 모든 이슈 조회 가능
pass
else:
# 일반 사용자는 본인이 등록한 이슈만 조회 가능
query = query.filter(Issue.reporter_id == current_user.id)
if status:
query = query.filter(Issue.status == status)
issues = query.offset(skip).limit(limit).all()
return issues
@router.get("/admin/all", response_model=List[schemas.Issue])
async def read_all_issues_admin(
skip: int = 0,
limit: int = 100,
status: Optional[IssueStatus] = None,
current_admin: User = Depends(get_current_admin),
db: Session = Depends(get_db)
):
"""관리자 전용: 모든 부적합 조회"""
query = db.query(Issue)
if status:
query = query.filter(Issue.status == status)
@@ -73,7 +95,12 @@ async def read_issue(
if not issue:
raise HTTPException(status_code=404, detail="Issue not found")
# 모든 사용자가 모든 이슈를 조회 가능 (협업을 위해)
# 권한별 조회 제한
if current_user.role != UserRole.admin and issue.reporter_id != current_user.id:
raise HTTPException(
status_code=403,
detail="본인이 등록한 부적합만 조회할 수 있습니다."
)
return issue

View File

@@ -0,0 +1,324 @@
"""
페이지 권한 관리 API 라우터
사용자별 페이지 접근 권한을 관리하는 엔드포인트들
"""
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from typing import List, Optional
from pydantic import BaseModel
from database.database import get_db
from database.models import User, UserPagePermission, UserRole
from routers.auth import get_current_user
router = APIRouter(prefix="/api", tags=["page-permissions"])
# Pydantic 모델들
class PagePermissionRequest(BaseModel):
user_id: int
page_name: str
can_access: bool
notes: Optional[str] = None
class PagePermissionResponse(BaseModel):
id: int
user_id: int
page_name: str
can_access: bool
granted_by_id: Optional[int]
granted_at: str
notes: Optional[str]
class Config:
from_attributes = True
class UserPagePermissionSummary(BaseModel):
user_id: int
username: str
full_name: Optional[str]
role: str
permissions: List[PagePermissionResponse]
# 기본 페이지 목록
DEFAULT_PAGES = {
'issues_create': {'title': '부적합 등록', 'default_access': True},
'issues_view': {'title': '부적합 조회', 'default_access': True},
'issues_manage': {'title': '부적합 관리', 'default_access': False},
'projects_manage': {'title': '프로젝트 관리', 'default_access': False},
'daily_work': {'title': '일일 공수', 'default_access': False},
'reports': {'title': '보고서', 'default_access': False}
}
@router.post("/page-permissions/grant")
async def grant_page_permission(
request: PagePermissionRequest,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""페이지 권한 부여/취소"""
# 관리자만 권한 설정 가능
if current_user.role != UserRole.admin:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="관리자만 권한을 설정할 수 있습니다."
)
# 대상 사용자 확인
target_user = db.query(User).filter(User.id == request.user_id).first()
if not target_user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="사용자를 찾을 수 없습니다."
)
# 유효한 페이지명 확인
if request.page_name not in DEFAULT_PAGES:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="유효하지 않은 페이지명입니다."
)
# 기존 권한 확인
existing_permission = db.query(UserPagePermission).filter(
UserPagePermission.user_id == request.user_id,
UserPagePermission.page_name == request.page_name
).first()
if existing_permission:
# 기존 권한 업데이트
existing_permission.can_access = request.can_access
existing_permission.granted_by_id = current_user.id
existing_permission.notes = request.notes
db.commit()
db.refresh(existing_permission)
return {"message": "권한이 업데이트되었습니다.", "permission_id": existing_permission.id}
else:
# 새 권한 생성
new_permission = UserPagePermission(
user_id=request.user_id,
page_name=request.page_name,
can_access=request.can_access,
granted_by_id=current_user.id,
notes=request.notes
)
db.add(new_permission)
db.commit()
db.refresh(new_permission)
return {"message": "권한이 설정되었습니다.", "permission_id": new_permission.id}
@router.get("/users/{user_id}/page-permissions", response_model=List[PagePermissionResponse])
async def get_user_page_permissions(
user_id: int,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""특정 사용자의 페이지 권한 목록 조회"""
# 관리자이거나 본인의 권한만 조회 가능
if current_user.role != UserRole.admin and current_user.id != user_id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="권한이 없습니다."
)
# 사용자 존재 확인
user = db.query(User).filter(User.id == user_id).first()
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="사용자를 찾을 수 없습니다."
)
# 사용자의 페이지 권한 조회
permissions = db.query(UserPagePermission).filter(
UserPagePermission.user_id == user_id
).all()
return permissions
@router.get("/page-permissions/check/{user_id}/{page_name}")
async def check_page_access(
user_id: int,
page_name: str,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""특정 사용자의 특정 페이지 접근 권한 확인"""
# 사용자 존재 확인
user = db.query(User).filter(User.id == user_id).first()
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="사용자를 찾을 수 없습니다."
)
# admin은 모든 페이지 접근 가능
if user.role == UserRole.admin:
return {"can_access": True, "reason": "admin_role"}
# 유효한 페이지명 확인
if page_name not in DEFAULT_PAGES:
return {"can_access": False, "reason": "invalid_page"}
# 개별 권한 확인
permission = db.query(UserPagePermission).filter(
UserPagePermission.user_id == user_id,
UserPagePermission.page_name == page_name
).first()
if permission:
return {
"can_access": permission.can_access,
"reason": "explicit_permission",
"granted_at": permission.granted_at.isoformat() if permission.granted_at else None
}
# 기본 권한 확인
default_access = DEFAULT_PAGES[page_name]['default_access']
return {
"can_access": default_access,
"reason": "default_permission"
}
@router.get("/page-permissions/all-users", response_model=List[UserPagePermissionSummary])
async def get_all_users_permissions(
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""모든 사용자의 페이지 권한 요약 조회 (관리자용)"""
if current_user.role != UserRole.admin:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="관리자만 접근할 수 있습니다."
)
# 모든 사용자 조회
users = db.query(User).filter(User.is_active == True).all()
result = []
for user in users:
# 각 사용자의 권한 조회
permissions = db.query(UserPagePermission).filter(
UserPagePermission.user_id == user.id
).all()
result.append(UserPagePermissionSummary(
user_id=user.id,
username=user.username,
full_name=user.full_name,
role=user.role.value,
permissions=permissions
))
return result
@router.get("/page-permissions/available-pages")
async def get_available_pages(
current_user: User = Depends(get_current_user)
):
"""사용 가능한 페이지 목록 조회"""
return {
"pages": DEFAULT_PAGES,
"total_count": len(DEFAULT_PAGES)
}
@router.delete("/page-permissions/{permission_id}")
async def delete_page_permission(
permission_id: int,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""페이지 권한 삭제 (기본값으로 되돌림)"""
if current_user.role != UserRole.admin:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="관리자만 권한을 삭제할 수 있습니다."
)
# 권한 조회
permission = db.query(UserPagePermission).filter(
UserPagePermission.id == permission_id
).first()
if not permission:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="권한을 찾을 수 없습니다."
)
# 권한 삭제
db.delete(permission)
db.commit()
return {"message": "권한이 삭제되었습니다. 기본값이 적용됩니다."}
class BulkPermissionRequest(BaseModel):
user_id: int
permissions: List[dict] # [{"page_name": "issues_manage", "can_access": true}, ...]
@router.post("/page-permissions/bulk-grant")
async def bulk_grant_permissions(
request: BulkPermissionRequest,
db: Session = Depends(get_db),
current_user: User = Depends(get_current_user)
):
"""사용자의 여러 페이지 권한을 일괄 설정"""
if current_user.role != UserRole.admin:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="관리자만 권한을 설정할 수 있습니다."
)
# 대상 사용자 확인
target_user = db.query(User).filter(User.id == request.user_id).first()
if not target_user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="사용자를 찾을 수 없습니다."
)
updated_permissions = []
for perm_data in request.permissions:
page_name = perm_data.get('page_name')
can_access = perm_data.get('can_access', False)
# 유효한 페이지명 확인
if page_name not in DEFAULT_PAGES:
continue
# 기존 권한 확인
existing_permission = db.query(UserPagePermission).filter(
UserPagePermission.user_id == request.user_id,
UserPagePermission.page_name == page_name
).first()
if existing_permission:
# 기존 권한 업데이트
existing_permission.can_access = can_access
existing_permission.granted_by_id = current_user.id
updated_permissions.append(existing_permission)
else:
# 새 권한 생성
new_permission = UserPagePermission(
user_id=request.user_id,
page_name=page_name,
can_access=can_access,
granted_by_id=current_user.id
)
db.add(new_permission)
updated_permissions.append(new_permission)
db.commit()
return {
"message": f"{len(updated_permissions)}개의 권한이 설정되었습니다.",
"updated_count": len(updated_permissions)
}