diff --git a/src/main/webapp/WEB-INF/jsp/site/mnt/sec/dormantStatus/list.jsp b/src/main/webapp/WEB-INF/jsp/site/mnt/sec/dormantStatus/list.jsp index 19c1d71..685cb1d 100644 --- a/src/main/webapp/WEB-INF/jsp/site/mnt/sec/dormantStatus/list.jsp +++ b/src/main/webapp/WEB-INF/jsp/site/mnt/sec/dormantStatus/list.jsp @@ -113,6 +113,7 @@ function fn_rowAction(accountId, ty) { .btn_zone .cnt { font-size:13px; } .btn3 { display:inline-block; padding:3px 10px; border:1px solid #888; background:#f5f5f5; font-size:12px; color:#333; text-decoration:none; } .btn3.red { border-color:#c25b5b; color:#c25b5b; } +.btn3.mini { padding:1px 6px; font-size:11px; } .guide { margin:10px 0; padding:10px 12px; border:1px solid #e5d9a8; background:#fdfaef; font-size:12px; line-height:1.7; } .msg { margin:10px 0; padding:10px 12px; border:1px solid #9ec2e8; background:#f2f8fd; font-size:12px; color:#20509e; } @@ -136,8 +137,8 @@ function fn_rowAction(accountId, ty) { - - +
장기 미사용 계정 요약
+
장기 미사용 관리자 계정 요약
@@ -218,8 +219,8 @@ function fn_rowAction(accountId, ty) { 선택 말소 - - +
장기 미사용 계정 현황 목록
+ @@ -279,10 +280,10 @@ function fn_rowAction(accountId, ty) {
장기 미사용 관리자 계정 현황 목록
- ', 'D'); return false;">말소 + ', 'D'); return false;">말소 - ', 'L'); return false;">잠금 + ', 'L'); return false;">잠금 - diff --git a/src/script/mysql/dml/privacy.menu_dormant_status_insert_mysql.sql b/src/script/mysql/dml/privacy.menu_dormant_status_insert_mysql.sql index 5ba91ff..ed3cc03 100644 --- a/src/script/mysql/dml/privacy.menu_dormant_status_insert_mysql.sql +++ b/src/script/mysql/dml/privacy.menu_dormant_status_insert_mysql.sql @@ -13,7 +13,7 @@ -- ├ 롤관리 (9100034, EgovRoleList) -- ├ 권한 신청·승인 (9100035, AuthorRequestList) -- ├ 권한변경 이력조회 (9100036, AuthorHistoryList) --- └ 미사용계정 현황 (9100037, DormantStatusList) ← 신규 +-- └ 미사용 관리자 계정 현황 (9100037, DormantStatusList) ← 신규 -- -- [노출권한] IS_AUTHENTICATED_FULLY, ROLE_ADMIN (형제 메뉴들과 동일) -- @@ -34,8 +34,8 @@ -- [1] 프로그램(URL) 등록 ※ 메뉴보다 먼저(FK: COMTNMENUINFO.PROGRM_FILE_NM → COMTNPROGRMLIST) -- ───────────────────────────────────────────────────────────── INSERT INTO COMTNPROGRMLIST (PROGRM_FILE_NM, PROGRM_STRE_PATH, PROGRM_KOREAN_NM, PROGRM_DC, URL) -SELECT 'DormantStatusList', '/mnt/sec/dormantStatus/', '장기 미사용계정 현황', - '장기 미사용 계정 현황 조회(SFR-002 #11)', '/mnt/sec/dormantStatus/listView.do?page=9100037' +SELECT 'DormantStatusList', '/mnt/sec/dormantStatus/', '장기 미사용 관리자 계정 현황', + '장기 미사용 관리자 계정 현황 조회(SFR-002 #11)', '/mnt/sec/dormantStatus/listView.do?page=9100037' FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM COMTNPROGRMLIST WHERE PROGRM_FILE_NM = 'DormantStatusList'); @@ -43,10 +43,27 @@ SELECT 'DormantStatusList', '/mnt/sec/dormantStatus/', '장기 미사용계정 -- [2] 메뉴 등록 : 권한관리(9100030) 하위, 권한변경 이력조회(ord 6) 다음(ord 7) -- ───────────────────────────────────────────────────────────── INSERT INTO COMTNMENUINFO (MENU_NM, PROGRM_FILE_NM, MENU_NO, UPPER_MENU_NO, MENU_ORDR, MENU_DC, RELATE_IMAGE_PATH, RELATE_IMAGE_NM) -SELECT '미사용계정 현황', 'DormantStatusList', 9100037, 9100030, 7, '장기 미사용 계정 현황 조회', '/', '/' +SELECT '미사용 관리자 계정 현황', 'DormantStatusList', 9100037, 9100030, 7, '장기 미사용 관리자 계정 현황 조회', '/', '/' FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM COMTNMENUINFO WHERE MENU_NO = 9100037); +-- ───────────────────────────────────────────────────────────── +-- [2-1] 명칭 정정(2026-08-10, 재실행 안전) : 관리자(EMP) 전용 화면임을 메뉴명에 명시 +-- — 이미 9100037 이 위 INSERT 로 적재된 환경(로컬 등)은 NOT EXISTS 가드 때문에 +-- INSERT 값이 반영되지 않으므로 이 UPDATE 가 실제 적용 지점이다. UPDATE 는 +-- 값이 이미 같아도 재실행 무해(멱등). +-- — 한글 리터럴은 mysql.exe(git-bash) 로 직접 실행 시 이중 인코딩 위험이 있다. +-- 적용 시 UNHEX 우회를 권장한다(hex 값은 아래 파이썬으로 생성): +-- python3 -c "print('미사용 관리자 계정 현황'.encode('utf-8').hex().upper())" +-- python3 -c "print('장기 미사용 관리자 계정 현황 조회'.encode('utf-8').hex().upper())" +-- ───────────────────────────────────────────────────────────── +UPDATE COMTNMENUINFO SET MENU_NM = '미사용 관리자 계정 현황' WHERE MENU_NO = 9100037; +UPDATE COMTNPROGRMLIST SET PROGRM_KOREAN_NM = '장기 미사용 관리자 계정 현황', + PROGRM_DC = '장기 미사용 관리자 계정 현황 조회(SFR-002 #11)' + WHERE PROGRM_FILE_NM = 'DormantStatusList'; +-- [적용 후 검증] SELECT MENU_NM FROM COMTNMENUINFO WHERE MENU_NO=9100037; +-- SELECT HEX(MENU_NM) FROM COMTNMENUINFO WHERE MENU_NO=9100037; -- EA/EB/EC/ED 로 시작해야 정상 + -- ───────────────────────────────────────────────────────────── -- [3] 권한↔메뉴 노출 매핑 (형제 메뉴들과 동일한 2개 권한) -- ───────────────────────────────────────────────────────────── diff --git a/src/script/mysql/privacy.install_mysql.sql b/src/script/mysql/privacy.install_mysql.sql index 1b8464d..cd855b3 100644 --- a/src/script/mysql/privacy.install_mysql.sql +++ b/src/script/mysql/privacy.install_mysql.sql @@ -886,6 +886,29 @@ CREATE TABLE IF NOT EXISTS ACCOUNT_ACTION_HISTORY ( COMMENT='장기 미사용 계정 조치(잠금/말소) 이력(개인정보보호 SFR-002 #11)'; +-- ───────────────────────────────────────────────────────────── +-- [privacy.login_lock_exempt_create_mysql.sql] +-- ───────────────────────────────────────────────────────────── +-- ===================================================================== +-- 로그인 실패 계정잠금 예외 : LOGIN_LOCK_EXEMPT (화이트리스트, SER-001 24) +-- --------------------------------------------------------------------- +-- 인증 실패 5회 잠금은 userSe 구분 없이 전 계정에 적용되고, 잠금 해제 화면도 +-- 관리자 로그인이 있어야 들어갈 수 있어 최고관리자가 잠기면 아무도 해제할 수 없다. +-- 이 테이블은 그 break-glass 통로다. 잠금 '판정'만 면제하며, 실패 이력(LOGIN_HISTORY) +-- 적재와 2차 인증(OTP)은 예외 계정에도 그대로 적용된다. +-- 시드 없음 — 예외 대상 ID는 관리자 화면(접근통제 정책)에서 운영팀이 직접 등록한다. +-- ===================================================================== + +CREATE TABLE IF NOT EXISTS LOGIN_LOCK_EXEMPT ( + EXEMPT_ID VARCHAR(20) NOT NULL COMMENT '잠금 예외 대상 계정ID(COMTNEMPLYRINFO.EMPLYR_ID)', + EXEMPT_RESN VARCHAR(500) NOT NULL COMMENT '예외 등록 사유(필수 - 감사 대응)', + REG_ID VARCHAR(20) NULL COMMENT '등록한 관리자 계정ID', + REG_DT DATETIME NULL COMMENT '등록일시', + PRIMARY KEY (EXEMPT_ID) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 + COMMENT='로그인 실패 계정잠금 예외 계정(개인정보보호 SER-001 24, 최고관리자 잠김 방지)'; + + -- ===================================================================== -- PART 2. DML (기준/시드 데이터) ※ 멱등: NOT EXISTS 가드로 중복 적재 방지 -- 수록: PDAL_JOB_MAPPING(업무유형 매핑 13행), ACCOUNT_MNG_POLICY(기본정책 1행) @@ -976,7 +999,7 @@ INSERT INTO COMTNPROGRMLIST (PROGRM_FILE_NM, PROGRM_STRE_PATH, PROGRM_KOREAN_NM, SELECT * FROM ( SELECT 'AuthorRequestList' AS PROGRM_FILE_NM, '/mnt/sec/authorRequest/' AS PROGRM_STRE_PATH, '개인정보취급자 권한 관리' AS PROGRM_KOREAN_NM, '개인정보취급자 권한 관리(SFR-001 #46)' AS PROGRM_DC, '/mnt/sec/authorRequest/listView.do?page=9100035' AS URL UNION ALL SELECT 'AuthorHistoryList', '/mnt/sec/authorHistory/', '권한변경 이력조회', '권한변경 이력조회·검색·다운로드(SFR-001 #6)', '/mnt/sec/authorHistory/listView.do?page=9100036' UNION ALL - SELECT 'DormantStatusList', '/mnt/sec/dormantStatus/', '장기 미사용계정 현황', '장기 미사용 계정 현황 조회(SFR-002 #11)', '/mnt/sec/dormantStatus/listView.do?page=9100037' UNION ALL + SELECT 'DormantStatusList', '/mnt/sec/dormantStatus/', '장기 미사용 관리자 계정 현황', '장기 미사용 관리자 계정 현황 조회(SFR-002 #11)', '/mnt/sec/dormantStatus/listView.do?page=9100037' UNION ALL SELECT 'AccountPolicySet', '/mnt/sec/accountPolicy/', '계정 관리 정책 설정', '장기 미사용 계정 관리 정책 설정(SFR-002 #13)', '/mnt/sec/accountPolicy/policyView.do?page=9100038' ) seed WHERE NOT EXISTS (SELECT 1 FROM COMTNPROGRMLIST p WHERE p.PROGRM_FILE_NM = seed.PROGRM_FILE_NM); @@ -986,11 +1009,20 @@ INSERT INTO COMTNMENUINFO (MENU_NM, PROGRM_FILE_NM, MENU_NO, UPPER_MENU_NO, MENU SELECT * FROM ( SELECT '개인정보취급자 권한 관리' AS MENU_NM, 'AuthorRequestList' AS PROGRM_FILE_NM, 9100035 AS MENU_NO, 9100030 AS UPPER_MENU_NO, 5 AS MENU_ORDR, '개인정보취급자 권한 부여·변경·말소 현황 및 승인 처리' AS MENU_DC, '/' AS RELATE_IMAGE_PATH, '/' AS RELATE_IMAGE_NM UNION ALL SELECT '권한변경 이력조회', 'AuthorHistoryList', 9100036, 9100030, 6, '권한변경 이력조회·검색·다운로드', '/', '/' UNION ALL - SELECT '미사용계정 현황', 'DormantStatusList', 9100037, 9100030, 7, '장기 미사용 계정 현황 조회', '/', '/' UNION ALL + SELECT '미사용 관리자 계정 현황', 'DormantStatusList', 9100037, 9100030, 7, '장기 미사용 관리자 계정 현황 조회', '/', '/' UNION ALL SELECT '계정 관리 정책', 'AccountPolicySet', 9100038, 9100030, 8, '장기 미사용 계정 관리 정책 설정', '/', '/' ) seed WHERE NOT EXISTS (SELECT 1 FROM COMTNMENUINFO m WHERE m.MENU_NO = seed.MENU_NO); +-- ── [2-1] 명칭 정정(2026-08-10, 재실행 안전/멱등) — 9100037 이 관리자(EMP) 전용 화면임을 명시. +-- 이미 9100037 이 위 INSERT 로 적재된 환경은 NOT EXISTS 가드 때문에 INSERT 값이 +-- 반영되지 않으므로 이 UPDATE 가 실제 적용 지점이다. 한글 리터럴은 UNHEX 우회 권장 +-- (python3 -c "print('미사용 관리자 계정 현황'.encode('utf-8').hex().upper())"). +UPDATE COMTNMENUINFO SET MENU_NM = '미사용 관리자 계정 현황' WHERE MENU_NO = 9100037; +UPDATE COMTNPROGRMLIST SET PROGRM_KOREAN_NM = '장기 미사용 관리자 계정 현황', + PROGRM_DC = '장기 미사용 관리자 계정 현황 조회(SFR-002 #11)' + WHERE PROGRM_FILE_NM = 'DormantStatusList'; + -- ── [3] 권한↔메뉴 노출 매핑 (4건 × 2권한, FK 안전) ── INSERT INTO COMTNMENUCREATDTLS (MENU_NO, AUTHOR_CODE) SELECT seed.menu_no, g.ac