/** * 권한 체크 미들웨어 * 3단계 권한 체계 적용: SUPER_ADMIN / COMPANY_ADMIN / USER */ import { Request, Response, NextFunction } from "express"; import { PersonBean } from "../types/auth"; import { isSuperAdmin, isCompanyAdmin, isAdmin, canExecuteDDL, canManageUsers, canManageCompanySettings, canManageCompanies, canAccessCompanyData, PermissionLevel, createPermissionError, } from "../utils/permissionUtils"; import { logger } from "../utils/logger"; /** * 인증된 요청 타입 */ export interface AuthenticatedRequest extends Request { user?: PersonBean; } /** * 슈퍼관리자 권한 필수 미들웨어 */ export const requireSuperAdmin = ( req: AuthenticatedRequest, res: Response, next: NextFunction ): void => { try { if (!req.user) { logger.warn("슈퍼관리자 권한 필요 - 인증되지 않은 사용자", { ip: req.ip, url: req.originalUrl, }); res.status(401).json({ success: false, error: { code: "AUTHENTICATION_REQUIRED", details: "인증이 필요합니다.", }, }); return; } if (!isSuperAdmin(req.user)) { logger.warn("슈퍼관리자 권한 부족", { userId: req.user.userId, companyCode: req.user.companyCode, userType: req.user.userType, ip: req.ip, url: req.originalUrl, }); res.status(403).json(createPermissionError(PermissionLevel.SUPER_ADMIN)); return; } logger.info("슈퍼관리자 권한 확인 완료", { userId: req.user.userId, url: req.originalUrl, }); next(); } catch (error) { logger.error("슈퍼관리자 권한 확인 중 오류:", error); res.status(500).json({ success: false, error: { code: "AUTHORIZATION_ERROR", details: "권한 확인 중 오류가 발생했습니다.", }, }); } }; /** * 관리자 권한 필수 미들웨어 (슈퍼관리자 + 회사관리자) */ export const requireAdmin = ( req: AuthenticatedRequest, res: Response, next: NextFunction ): void => { try { if (!req.user) { res.status(401).json({ success: false, error: { code: "AUTHENTICATION_REQUIRED", details: "인증이 필요합니다.", }, }); return; } if (!isAdmin(req.user)) { logger.warn("관리자 권한 부족", { userId: req.user.userId, userType: req.user.userType, companyCode: req.user.companyCode, ip: req.ip, url: req.originalUrl, }); res .status(403) .json(createPermissionError(PermissionLevel.COMPANY_ADMIN)); return; } logger.info("관리자 권한 확인 완료", { userId: req.user.userId, userType: req.user.userType, url: req.originalUrl, }); next(); } catch (error) { logger.error("관리자 권한 확인 중 오류:", error); res.status(500).json({ success: false, error: { code: "AUTHORIZATION_ERROR", details: "권한 확인 중 오류가 발생했습니다.", }, }); } }; /** * 회사 데이터 접근 권한 체크 미들웨어 * req.params.companyCode 또는 req.query.companyCode 확인 */ export const requireCompanyAccess = ( req: AuthenticatedRequest, res: Response, next: NextFunction ): void => { try { if (!req.user) { res.status(401).json({ success: false, error: { code: "AUTHENTICATION_REQUIRED", details: "인증이 필요합니다.", }, }); return; } const targetCompanyCode = (req.params.companyCode as string) || (req.query.companyCode as string) || (req.body.companyCode as string); if (!targetCompanyCode) { res.status(400).json({ success: false, error: { code: "COMPANY_CODE_REQUIRED", details: "회사 코드가 필요합니다.", }, }); return; } if (!canAccessCompanyData(req.user, targetCompanyCode)) { logger.warn("회사 데이터 접근 권한 없음", { userId: req.user.userId, userCompanyCode: req.user.companyCode, targetCompanyCode, ip: req.ip, url: req.originalUrl, }); res.status(403).json({ success: false, error: { code: "COMPANY_ACCESS_DENIED", details: "해당 회사의 데이터에 접근할 권한이 없습니다.", }, }); return; } next(); } catch (error) { logger.error("회사 데이터 접근 권한 확인 중 오류:", error); res.status(500).json({ success: false, error: { code: "AUTHORIZATION_ERROR", details: "권한 확인 중 오류가 발생했습니다.", }, }); } }; /** * 사용자 관리 권한 체크 미들웨어 */ export const requireUserManagement = ( req: AuthenticatedRequest, res: Response, next: NextFunction ): void => { try { if (!req.user) { res.status(401).json({ success: false, error: { code: "AUTHENTICATION_REQUIRED", details: "인증이 필요합니다.", }, }); return; } const targetCompanyCode = (req.params.companyCode as string) || (req.query.companyCode as string) || (req.body.companyCode as string); if (!canManageUsers(req.user, targetCompanyCode)) { logger.warn("사용자 관리 권한 없음", { userId: req.user.userId, userCompanyCode: req.user.companyCode, targetCompanyCode, ip: req.ip, url: req.originalUrl, }); res.status(403).json({ success: false, error: { code: "USER_MANAGEMENT_DENIED", details: "사용자 관리 권한이 없습니다.", }, }); return; } next(); } catch (error) { logger.error("사용자 관리 권한 확인 중 오류:", error); res.status(500).json({ success: false, error: { code: "AUTHORIZATION_ERROR", details: "권한 확인 중 오류가 발생했습니다.", }, }); } }; /** * 회사 설정 변경 권한 체크 미들웨어 */ export const requireCompanySettingsManagement = ( req: AuthenticatedRequest, res: Response, next: NextFunction ): void => { try { if (!req.user) { res.status(401).json({ success: false, error: { code: "AUTHENTICATION_REQUIRED", details: "인증이 필요합니다.", }, }); return; } const targetCompanyCode = (req.params.companyCode as string) || (req.query.companyCode as string) || (req.body.companyCode as string); if (!canManageCompanySettings(req.user, targetCompanyCode)) { logger.warn("회사 설정 변경 권한 없음", { userId: req.user.userId, userCompanyCode: req.user.companyCode, targetCompanyCode, ip: req.ip, url: req.originalUrl, }); res.status(403).json({ success: false, error: { code: "COMPANY_SETTINGS_DENIED", details: "회사 설정 변경 권한이 없습니다.", }, }); return; } next(); } catch (error) { logger.error("회사 설정 변경 권한 확인 중 오류:", error); res.status(500).json({ success: false, error: { code: "AUTHORIZATION_ERROR", details: "권한 확인 중 오류가 발생했습니다.", }, }); } }; /** * 회사 생성/삭제 권한 체크 미들웨어 (슈퍼관리자 전용) */ export const requireCompanyManagement = ( req: AuthenticatedRequest, res: Response, next: NextFunction ): void => { try { if (!req.user) { res.status(401).json({ success: false, error: { code: "AUTHENTICATION_REQUIRED", details: "인증이 필요합니다.", }, }); return; } if (!canManageCompanies(req.user)) { logger.warn("회사 관리 권한 없음", { userId: req.user.userId, userType: req.user.userType, companyCode: req.user.companyCode, ip: req.ip, url: req.originalUrl, }); res.status(403).json({ success: false, error: { code: "COMPANY_MANAGEMENT_DENIED", details: "회사 생성/삭제는 최고 관리자만 가능합니다.", }, }); return; } next(); } catch (error) { logger.error("회사 관리 권한 확인 중 오류:", error); res.status(500).json({ success: false, error: { code: "AUTHORIZATION_ERROR", details: "권한 확인 중 오류가 발생했습니다.", }, }); } }; /** * DDL 실행 권한 체크 미들웨어 (슈퍼관리자 전용) */ export const requireDDLPermission = ( req: AuthenticatedRequest, res: Response, next: NextFunction ): void => { try { if (!req.user) { res.status(401).json({ success: false, error: { code: "AUTHENTICATION_REQUIRED", details: "인증이 필요합니다.", }, }); return; } if (!canExecuteDDL(req.user)) { logger.warn("DDL 실행 권한 없음", { userId: req.user.userId, userType: req.user.userType, companyCode: req.user.companyCode, ip: req.ip, url: req.originalUrl, }); res.status(403).json({ success: false, error: { code: "DDL_EXECUTION_DENIED", details: "DDL 실행은 최고 관리자만 가능합니다. 데이터베이스 스키마 변경은 company_code가 '*'이고 user_type이 'SUPER_ADMIN'인 사용자만 수행할 수 있습니다.", }, }); return; } logger.info("DDL 실행 권한 확인 완료", { userId: req.user.userId, url: req.originalUrl, }); next(); } catch (error) { logger.error("DDL 실행 권한 확인 중 오류:", error); res.status(500).json({ success: false, error: { code: "AUTHORIZATION_ERROR", details: "권한 확인 중 오류가 발생했습니다.", }, }); } };