feat: 완전한 사용자 관리 및 로그 모니터링 시스템 구현
Some checks failed
SonarQube Analysis / SonarQube Scan (push) Has been cancelled
Some checks failed
SonarQube Analysis / SonarQube Scan (push) Has been cancelled
- 시스템 관리자/관리자 권한별 대시보드 기능 추가 - 사용자 관리 페이지: 계정 생성, 역할 변경, 사용자 삭제 - 시스템 로그 페이지: 로그인 로그, 시스템 오류 로그 조회 - 로그 모니터링 대시보드: 실시간 통계, 최근 활동, 오류 모니터링 - 프론트엔드 ErrorBoundary 및 오류 로깅 시스템 통합 - 계정 설정 페이지: 프로필 업데이트, 비밀번호 변경 - 3단계 권한 시스템 (system/admin/user) 완전 구현 - 시스템 관리자 계정 생성 기능 (hyungi/000000) - 로그인 페이지 테스트 계정 안내 제거 - API 오류 수정: CORS, 이메일 검증, User 모델 import 등
This commit is contained in:
197
backend/scripts/create_system_admin.py
Executable file
197
backend/scripts/create_system_admin.py
Executable file
@@ -0,0 +1,197 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
시스템 관리자 계정 생성 스크립트
|
||||
최초 설치 시 시스템 관리자 계정을 생성합니다.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import getpass
|
||||
from datetime import datetime
|
||||
|
||||
# 프로젝트 루트를 Python 경로에 추가
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from sqlalchemy import create_engine, text
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from app.config import get_settings
|
||||
from app.auth.models import User, UserRepository
|
||||
from app.database import Base
|
||||
|
||||
def create_system_admin():
|
||||
"""시스템 관리자 계정 생성"""
|
||||
|
||||
print("=" * 60)
|
||||
print("🔧 TK-MP 시스템 관리자 계정 생성")
|
||||
print("=" * 60)
|
||||
|
||||
# 설정 로드
|
||||
settings = get_settings()
|
||||
|
||||
# 데이터베이스 연결
|
||||
try:
|
||||
engine = create_engine(settings.database_url)
|
||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
db = SessionLocal()
|
||||
|
||||
print("✅ 데이터베이스 연결 성공")
|
||||
|
||||
# 테이블 생성 (필요한 경우)
|
||||
Base.metadata.create_all(bind=engine)
|
||||
print("✅ 데이터베이스 테이블 확인/생성 완료")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 데이터베이스 연결 실패: {str(e)}")
|
||||
return False
|
||||
|
||||
# 기존 시스템 관리자 확인
|
||||
try:
|
||||
user_repo = UserRepository(db)
|
||||
existing_admin = db.query(User).filter(User.role == 'system').first()
|
||||
|
||||
if existing_admin:
|
||||
print(f"⚠️ 시스템 관리자가 이미 존재합니다: {existing_admin.username}")
|
||||
response = input("새로운 시스템 관리자를 추가로 생성하시겠습니까? (y/N): ").lower()
|
||||
if response != 'y':
|
||||
print("❌ 작업이 취소되었습니다.")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 기존 관리자 확인 실패: {str(e)}")
|
||||
return False
|
||||
|
||||
# 사용자 입력 받기
|
||||
print("\n📝 시스템 관리자 정보를 입력해주세요:")
|
||||
print("-" * 40)
|
||||
|
||||
try:
|
||||
# 사용자명 입력
|
||||
while True:
|
||||
username = input("사용자명 (영문/숫자, 3-20자): ").strip()
|
||||
if not username:
|
||||
print("❌ 사용자명을 입력해주세요.")
|
||||
continue
|
||||
if len(username) < 3 or len(username) > 20:
|
||||
print("❌ 사용자명은 3-20자여야 합니다.")
|
||||
continue
|
||||
if not username.replace('_', '').isalnum():
|
||||
print("❌ 사용자명은 영문, 숫자, 언더스코어만 사용 가능합니다.")
|
||||
continue
|
||||
|
||||
# 중복 확인
|
||||
existing_user = user_repo.find_by_username(username)
|
||||
if existing_user:
|
||||
print("❌ 이미 존재하는 사용자명입니다.")
|
||||
continue
|
||||
|
||||
break
|
||||
|
||||
# 이름 입력
|
||||
while True:
|
||||
name = input("이름 (한글/영문, 2-50자): ").strip()
|
||||
if not name:
|
||||
print("❌ 이름을 입력해주세요.")
|
||||
continue
|
||||
if len(name) < 2 or len(name) > 50:
|
||||
print("❌ 이름은 2-50자여야 합니다.")
|
||||
continue
|
||||
break
|
||||
|
||||
# 이메일 입력 (선택사항)
|
||||
email = input("이메일 (선택사항): ").strip()
|
||||
if email and '@' not in email:
|
||||
print("⚠️ 올바르지 않은 이메일 형식입니다. 빈 값으로 설정합니다.")
|
||||
email = None
|
||||
|
||||
# 비밀번호 입력
|
||||
while True:
|
||||
password = getpass.getpass("비밀번호 (8자 이상): ")
|
||||
if len(password) < 8:
|
||||
print("❌ 비밀번호는 8자 이상이어야 합니다.")
|
||||
continue
|
||||
|
||||
password_confirm = getpass.getpass("비밀번호 확인: ")
|
||||
if password != password_confirm:
|
||||
print("❌ 비밀번호가 일치하지 않습니다.")
|
||||
continue
|
||||
|
||||
break
|
||||
|
||||
# 부서/직책 입력 (선택사항)
|
||||
department = input("부서 (선택사항): ").strip() or None
|
||||
position = input("직책 (선택사항): ").strip() or None
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n❌ 작업이 취소되었습니다.")
|
||||
return False
|
||||
|
||||
# 입력 정보 확인
|
||||
print("\n📋 입력된 정보:")
|
||||
print("-" * 40)
|
||||
print(f"사용자명: {username}")
|
||||
print(f"이름: {name}")
|
||||
print(f"이메일: {email or '(없음)'}")
|
||||
print(f"부서: {department or '(없음)'}")
|
||||
print(f"직책: {position or '(없음)'}")
|
||||
print(f"역할: 시스템 관리자")
|
||||
|
||||
response = input("\n위 정보로 시스템 관리자를 생성하시겠습니까? (y/N): ").lower()
|
||||
if response != 'y':
|
||||
print("❌ 작업이 취소되었습니다.")
|
||||
return False
|
||||
|
||||
# 사용자 생성
|
||||
try:
|
||||
# 사용자 객체 생성
|
||||
user = User(
|
||||
username=username,
|
||||
name=name,
|
||||
email=email,
|
||||
role='system',
|
||||
access_level='system',
|
||||
department=department,
|
||||
position=position,
|
||||
is_active=True
|
||||
)
|
||||
|
||||
# 비밀번호 설정
|
||||
user.set_password(password)
|
||||
|
||||
# 데이터베이스에 저장
|
||||
db.add(user)
|
||||
db.commit()
|
||||
db.refresh(user)
|
||||
|
||||
print(f"✅ 시스템 관리자 계정이 생성되었습니다!")
|
||||
print(f" - 사용자 ID: {user.user_id}")
|
||||
print(f" - 사용자명: {user.username}")
|
||||
print(f" - 이름: {user.name}")
|
||||
print(f" - 생성일시: {user.created_at}")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
print(f"❌ 사용자 생성 실패: {str(e)}")
|
||||
return False
|
||||
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
def main():
|
||||
"""메인 함수"""
|
||||
try:
|
||||
success = create_system_admin()
|
||||
if success:
|
||||
print("\n🎉 시스템 관리자 계정 생성이 완료되었습니다!")
|
||||
print("이제 이 계정으로 로그인하여 다른 사용자를 관리할 수 있습니다.")
|
||||
else:
|
||||
print("\n❌ 시스템 관리자 계정 생성에 실패했습니다.")
|
||||
sys.exit(1)
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n💥 예상치 못한 오류가 발생했습니다: {str(e)}")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user