first commit
This commit is contained in:
275
app/api/admin.py
Normal file
275
app/api/admin.py
Normal file
@@ -0,0 +1,275 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import List
|
||||
from app.database import get_db
|
||||
from app.schemas.admin import (
|
||||
UserCreate, UserUpdate, UserInfo, UserListResponse,
|
||||
VMAccessCreate, VMAccessUpdate, VMAccessInfo, VMAccessListResponse,
|
||||
AdminResponse
|
||||
)
|
||||
from app.schemas.auth import CurrentUser
|
||||
from app.api.auth import get_current_user
|
||||
from app.models.user import User, UserRole
|
||||
from app.models.vm import VMAccess
|
||||
from app.utils.security import hash_password
|
||||
from app.utils.exceptions import PermissionDeniedError, NotFoundError, BadRequestError
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
def require_admin(current_user: CurrentUser = Depends(get_current_user)):
|
||||
"""관리자 권한 확인"""
|
||||
if current_user.role != "admin":
|
||||
raise PermissionDeniedError("관리자 권한이 필요합니다")
|
||||
return current_user
|
||||
|
||||
# ==================== 사용자 관리 ====================
|
||||
|
||||
@router.get("/users", response_model=UserListResponse)
|
||||
async def get_users(
|
||||
current_user: CurrentUser = Depends(require_admin),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""사용자 목록 조회"""
|
||||
users = db.query(User).all()
|
||||
|
||||
user_list = [
|
||||
UserInfo(
|
||||
id=user.id,
|
||||
username=user.username,
|
||||
email=user.email,
|
||||
full_name=user.full_name,
|
||||
role=user.role.value,
|
||||
is_active=user.is_active,
|
||||
created_at=user.created_at,
|
||||
last_login=user.last_login
|
||||
)
|
||||
for user in users
|
||||
]
|
||||
|
||||
return UserListResponse(total=len(user_list), users=user_list)
|
||||
|
||||
@router.post("/users", response_model=AdminResponse)
|
||||
async def create_user(
|
||||
user_data: UserCreate,
|
||||
current_user: CurrentUser = Depends(require_admin),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""사용자 생성"""
|
||||
# 중복 확인
|
||||
if db.query(User).filter(User.username == user_data.username).first():
|
||||
raise BadRequestError("이미 존재하는 사용자명입니다")
|
||||
|
||||
if db.query(User).filter(User.email == user_data.email).first():
|
||||
raise BadRequestError("이미 존재하는 이메일입니다")
|
||||
|
||||
# 역할 유효성 검사
|
||||
if user_data.role not in ["admin", "user"]:
|
||||
raise BadRequestError("역할은 'admin' 또는 'user'만 가능합니다")
|
||||
|
||||
# 사용자 생성
|
||||
new_user = User(
|
||||
username=user_data.username,
|
||||
email=user_data.email,
|
||||
hashed_password=hash_password(user_data.password),
|
||||
full_name=user_data.full_name,
|
||||
role=UserRole.ADMIN if user_data.role == "admin" else UserRole.USER,
|
||||
is_active=True
|
||||
)
|
||||
|
||||
db.add(new_user)
|
||||
db.commit()
|
||||
|
||||
return AdminResponse(
|
||||
success=True,
|
||||
message=f"사용자 '{user_data.username}'이(가) 생성되었습니다"
|
||||
)
|
||||
|
||||
@router.put("/users/{user_id}", response_model=AdminResponse)
|
||||
async def update_user(
|
||||
user_id: int,
|
||||
user_data: UserUpdate,
|
||||
current_user: CurrentUser = Depends(require_admin),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""사용자 정보 수정"""
|
||||
user = db.query(User).filter(User.id == user_id).first()
|
||||
if not user:
|
||||
raise NotFoundError("사용자를 찾을 수 없습니다")
|
||||
|
||||
# 이메일 중복 확인
|
||||
if user_data.email and user_data.email != user.email:
|
||||
if db.query(User).filter(User.email == user_data.email).first():
|
||||
raise BadRequestError("이미 존재하는 이메일입니다")
|
||||
user.email = user_data.email
|
||||
|
||||
# 비밀번호 변경
|
||||
if user_data.password:
|
||||
user.hashed_password = hash_password(user_data.password)
|
||||
|
||||
# 기타 정보 업데이트
|
||||
if user_data.full_name is not None:
|
||||
user.full_name = user_data.full_name
|
||||
|
||||
if user_data.role:
|
||||
if user_data.role not in ["admin", "user"]:
|
||||
raise BadRequestError("역할은 'admin' 또는 'user'만 가능합니다")
|
||||
user.role = UserRole.ADMIN if user_data.role == "admin" else UserRole.USER
|
||||
|
||||
if user_data.is_active is not None:
|
||||
user.is_active = user_data.is_active
|
||||
|
||||
db.commit()
|
||||
|
||||
return AdminResponse(
|
||||
success=True,
|
||||
message=f"사용자 '{user.username}'의 정보가 수정되었습니다"
|
||||
)
|
||||
|
||||
@router.delete("/users/{user_id}", response_model=AdminResponse)
|
||||
async def delete_user(
|
||||
user_id: int,
|
||||
current_user: CurrentUser = Depends(require_admin),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""사용자 삭제"""
|
||||
# 자기 자신은 삭제 불가
|
||||
if user_id == current_user.id:
|
||||
raise BadRequestError("자기 자신은 삭제할 수 없습니다")
|
||||
|
||||
user = db.query(User).filter(User.id == user_id).first()
|
||||
if not user:
|
||||
raise NotFoundError("사용자를 찾을 수 없습니다")
|
||||
|
||||
username = user.username
|
||||
db.delete(user)
|
||||
db.commit()
|
||||
|
||||
return AdminResponse(
|
||||
success=True,
|
||||
message=f"사용자 '{username}'이(가) 삭제되었습니다"
|
||||
)
|
||||
|
||||
# ==================== VM 접근 권한 관리 ====================
|
||||
|
||||
@router.get("/vm-access", response_model=VMAccessListResponse)
|
||||
async def get_vm_access_list(
|
||||
current_user: CurrentUser = Depends(require_admin),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""VM 접근 권한 목록 조회"""
|
||||
accesses = db.query(VMAccess).join(User).all()
|
||||
|
||||
access_list = [
|
||||
VMAccessInfo(
|
||||
id=access.id,
|
||||
user_id=access.user_id,
|
||||
username=access.user.username,
|
||||
vm_id=access.vm_id,
|
||||
node=access.node,
|
||||
vm_name=access.vm_name,
|
||||
static_ip=access.static_ip,
|
||||
rdp_username=access.rdp_username,
|
||||
rdp_port=access.rdp_port,
|
||||
is_active=access.is_active,
|
||||
created_at=access.created_at
|
||||
)
|
||||
for access in accesses
|
||||
]
|
||||
|
||||
return VMAccessListResponse(total=len(access_list), accesses=access_list)
|
||||
|
||||
@router.post("/vm-access", response_model=AdminResponse)
|
||||
async def create_vm_access(
|
||||
access_data: VMAccessCreate,
|
||||
current_user: CurrentUser = Depends(require_admin),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""VM 접근 권한 부여"""
|
||||
# 사용자 존재 확인
|
||||
user = db.query(User).filter(User.id == access_data.user_id).first()
|
||||
if not user:
|
||||
raise NotFoundError("사용자를 찾을 수 없습니다")
|
||||
|
||||
# 중복 확인
|
||||
existing = db.query(VMAccess).filter(
|
||||
VMAccess.user_id == access_data.user_id,
|
||||
VMAccess.vm_id == access_data.vm_id
|
||||
).first()
|
||||
|
||||
if existing:
|
||||
raise BadRequestError("이미 해당 사용자에게 VM 접근 권한이 있습니다")
|
||||
|
||||
# 권한 생성
|
||||
access = VMAccess(
|
||||
user_id=access_data.user_id,
|
||||
vm_id=access_data.vm_id,
|
||||
node=access_data.node,
|
||||
static_ip=access_data.static_ip,
|
||||
rdp_username=access_data.rdp_username,
|
||||
rdp_password=access_data.rdp_password,
|
||||
rdp_port=access_data.rdp_port,
|
||||
is_active=True
|
||||
)
|
||||
|
||||
db.add(access)
|
||||
db.commit()
|
||||
|
||||
return AdminResponse(
|
||||
success=True,
|
||||
message=f"사용자 '{user.username}'에게 VM {access_data.vm_id} 접근 권한이 부여되었습니다"
|
||||
)
|
||||
|
||||
@router.put("/vm-access/{access_id}", response_model=AdminResponse)
|
||||
async def update_vm_access(
|
||||
access_id: int,
|
||||
access_data: VMAccessUpdate,
|
||||
current_user: CurrentUser = Depends(require_admin),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""VM 접근 권한 수정"""
|
||||
access = db.query(VMAccess).filter(VMAccess.id == access_id).first()
|
||||
if not access:
|
||||
raise NotFoundError("접근 권한을 찾을 수 없습니다")
|
||||
|
||||
# 정보 업데이트
|
||||
if access_data.static_ip is not None:
|
||||
access.static_ip = access_data.static_ip
|
||||
|
||||
if access_data.rdp_username is not None:
|
||||
access.rdp_username = access_data.rdp_username
|
||||
|
||||
if access_data.rdp_password is not None:
|
||||
access.rdp_password = access_data.rdp_password
|
||||
|
||||
if access_data.rdp_port is not None:
|
||||
access.rdp_port = access_data.rdp_port
|
||||
|
||||
if access_data.is_active is not None:
|
||||
access.is_active = access_data.is_active
|
||||
|
||||
db.commit()
|
||||
|
||||
return AdminResponse(
|
||||
success=True,
|
||||
message=f"VM {access.vm_id} 접근 권한이 수정되었습니다"
|
||||
)
|
||||
|
||||
@router.delete("/vm-access/{access_id}", response_model=AdminResponse)
|
||||
async def delete_vm_access(
|
||||
access_id: int,
|
||||
current_user: CurrentUser = Depends(require_admin),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""VM 접근 권한 삭제"""
|
||||
access = db.query(VMAccess).filter(VMAccess.id == access_id).first()
|
||||
if not access:
|
||||
raise NotFoundError("접근 권한을 찾을 수 없습니다")
|
||||
|
||||
vm_id = access.vm_id
|
||||
db.delete(access)
|
||||
db.commit()
|
||||
|
||||
return AdminResponse(
|
||||
success=True,
|
||||
message=f"VM {vm_id} 접근 권한이 삭제되었습니다"
|
||||
)
|
||||
Reference in New Issue
Block a user