From cb0a588a9c7a03a019047810f39d521f91e53b9c Mon Sep 17 00:00:00 2001 From: curry772 Date: Thu, 23 Jul 2026 09:10:27 +0900 Subject: [PATCH] =?UTF-8?q?ToolsController(/manage/tools)=20Postman=20?= =?UTF-8?q?=EC=BB=AC=EB=A0=89=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit base64/hex 변환, DAMO 및 EncryptionManager 암복호화, 배포 버전 조회 API를 기존 CryptoModuleManage/SessionCacheManage 컬렉션과 동일한 스타일로 샘플링. Co-Authored-By: Claude Sonnet 5 --- postman/ToolsManage.postman_collection.json | 353 ++++++++++++++++++++ 1 file changed, 353 insertions(+) create mode 100644 postman/ToolsManage.postman_collection.json diff --git a/postman/ToolsManage.postman_collection.json b/postman/ToolsManage.postman_collection.json new file mode 100644 index 0000000..6c08af8 --- /dev/null +++ b/postman/ToolsManage.postman_collection.json @@ -0,0 +1,353 @@ +{ + "info": { + "_postman_id": "d4a8b2f0-5e3c-4d21-9f0a-tools-manage-0001", + "name": "ToolsManage API (/manage/tools)", + "description": "base64/hex 변환, DAMO 및 EncryptionManager 암복호화 테스트, 배포 버전 확인용 유틸리티 API 샘플 모음.\n\n사용 전 확인사항:\n1. Collection Variables 의 baseUrl 을 실제 서버 주소로 변경\n2. DAMO/EncryptionManager 암복호화는 각 실행 순서(암호화 → 복호화)를 지켜야 체이닝 변수가 채워짐\n3. EncryptionManager 는 encryptYN=N 환경에서는 encrypt/decrypt가 원문을 그대로 반환한다(정상 동작). 먼저 '상태 조회'로 확인할 것\n4. /manage/tools/version 은 eapim-online(WAR 루트) build.gradle의 generateVersionInfo 태스크가 생성한 version.info 리소스가 있어야 success=true로 응답한다. 재빌드 없이 IDE에서 바로 기동한 로컬 환경 등에서는 success=false + message로 응답하며, 이는 정상 동작이다.", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "variable": [ + { "key": "baseUrl", "value": "http://localhost:8080", "type": "string" }, + { "key": "charset", "value": "UTF-8", "type": "string" }, + { "key": "plainText", "value": "테스트 평문입니다", "type": "string" }, + { "key": "base64EncodedText", "value": "", "type": "string" }, + { "key": "hexEncodedText", "value": "", "type": "string" }, + { "key": "damoCipherText", "value": "", "type": "string" }, + { "key": "encManagerCipherText", "value": "", "type": "string" } + ], + "item": [ + { + "name": "1. Base64 / Hex 변환", + "item": [ + { + "name": "문자열 → Base64 인코딩", + "request": { + "method": "POST", + "header": [{ "key": "Content-Type", "value": "application/json" }], + "body": { + "mode": "raw", + "raw": "{\n \"text\": \"{{plainText}}\",\n \"charset\": \"{{charset}}\"\n}" + }, + "url": { + "raw": "{{baseUrl}}/manage/tools/base64/encode", + "host": ["{{baseUrl}}"], + "path": ["manage", "tools", "base64", "encode"] + }, + "description": "charset(생략 시 UTF-8) 기준으로 문자열을 바이트로 변환한 뒤 Base64로 인코딩한다." + }, + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "const json = pm.response.json();", + "pm.test('status 200', () => pm.response.to.have.status(200));", + "pm.test('success = true', () => pm.expect(json.success).to.eql(true));", + "pm.test('data는 문자열', () => pm.expect(json.data).to.be.a('string'));", + "pm.collectionVariables.set('base64EncodedText', json.data);" + ] + } + } + ] + }, + { + "name": "Base64 → 문자열 디코딩 (위 인코딩 결과 사용)", + "request": { + "method": "POST", + "header": [{ "key": "Content-Type", "value": "application/json" }], + "body": { + "mode": "raw", + "raw": "{\n \"text\": \"{{base64EncodedText}}\",\n \"charset\": \"{{charset}}\"\n}" + }, + "url": { + "raw": "{{baseUrl}}/manage/tools/base64/decode", + "host": ["{{baseUrl}}"], + "path": ["manage", "tools", "base64", "decode"] + }, + "description": "바로 위 '문자열 → Base64 인코딩' 요청에서 저장한 base64EncodedText를 디코딩하여 원문과 일치하는지 확인한다. 반드시 인코딩 요청을 먼저 실행할 것." + }, + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "const json = pm.response.json();", + "pm.test('status 200', () => pm.response.to.have.status(200));", + "pm.test('success = true', () => pm.expect(json.success).to.eql(true));", + "pm.test('원문과 일치 (라운드트립)', () => pm.expect(json.data).to.eql(pm.collectionVariables.get('plainText')));" + ] + } + } + ] + }, + { + "name": "문자열 → Hex 인코딩", + "request": { + "method": "POST", + "header": [{ "key": "Content-Type", "value": "application/json" }], + "body": { + "mode": "raw", + "raw": "{\n \"text\": \"{{plainText}}\",\n \"charset\": \"{{charset}}\"\n}" + }, + "url": { + "raw": "{{baseUrl}}/manage/tools/hex/encode", + "host": ["{{baseUrl}}"], + "path": ["manage", "tools", "hex", "encode"] + }, + "description": "charset(생략 시 UTF-8) 기준으로 문자열을 바이트로 변환한 뒤 대문자 Hex 문자열로 인코딩한다." + }, + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "const json = pm.response.json();", + "pm.test('status 200', () => pm.response.to.have.status(200));", + "pm.test('success = true', () => pm.expect(json.success).to.eql(true));", + "pm.test('data는 문자열', () => pm.expect(json.data).to.be.a('string'));", + "pm.collectionVariables.set('hexEncodedText', json.data);" + ] + } + } + ] + }, + { + "name": "Hex → 문자열 디코딩 (위 인코딩 결과 사용)", + "request": { + "method": "POST", + "header": [{ "key": "Content-Type", "value": "application/json" }], + "body": { + "mode": "raw", + "raw": "{\n \"text\": \"{{hexEncodedText}}\",\n \"charset\": \"{{charset}}\"\n}" + }, + "url": { + "raw": "{{baseUrl}}/manage/tools/hex/decode", + "host": ["{{baseUrl}}"], + "path": ["manage", "tools", "hex", "decode"] + }, + "description": "바로 위 '문자열 → Hex 인코딩' 요청에서 저장한 hexEncodedText를 디코딩하여 원문과 일치하는지 확인한다. 반드시 인코딩 요청을 먼저 실행할 것." + }, + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "const json = pm.response.json();", + "pm.test('status 200', () => pm.response.to.have.status(200));", + "pm.test('success = true', () => pm.expect(json.success).to.eql(true));", + "pm.test('원문과 일치 (라운드트립)', () => pm.expect(json.data).to.eql(pm.collectionVariables.get('plainText')));" + ] + } + } + ] + } + ] + }, + { + "name": "2. DAMO 암복호화 (DamoManager 직접 호출)", + "item": [ + { + "name": "암호화 (encrypt)", + "request": { + "method": "POST", + "header": [{ "key": "Content-Type", "value": "application/json" }], + "body": { + "mode": "raw", + "raw": "{\n \"text\": \"{{plainText}}\"\n}" + }, + "url": { + "raw": "{{baseUrl}}/manage/tools/damo/encrypt", + "host": ["{{baseUrl}}"], + "path": ["manage", "tools", "damo", "encrypt"] + }, + "description": "com.eactive.ext.djb.DamoManager를 직접 호출한다. EncryptionManager의 encryptYN 설정과 무관하게 항상 실제 암호화가 수행된다." + }, + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "const json = pm.response.json();", + "pm.test('status 200', () => pm.response.to.have.status(200));", + "pm.test('success = true', () => pm.expect(json.success).to.eql(true));", + "pm.test('data는 문자열', () => pm.expect(json.data).to.be.a('string'));", + "pm.test('평문과 달라야 함', () => pm.expect(json.data).to.not.eql(pm.collectionVariables.get('plainText')));", + "pm.collectionVariables.set('damoCipherText', json.data);" + ] + } + } + ] + }, + { + "name": "복호화 (decrypt) — 위 암호화 결과 사용", + "request": { + "method": "POST", + "header": [{ "key": "Content-Type", "value": "application/json" }], + "body": { + "mode": "raw", + "raw": "{\n \"text\": \"{{damoCipherText}}\"\n}" + }, + "url": { + "raw": "{{baseUrl}}/manage/tools/damo/decrypt", + "host": ["{{baseUrl}}"], + "path": ["manage", "tools", "damo", "decrypt"] + }, + "description": "바로 위 '암호화 (encrypt)' 요청에서 저장한 damoCipherText를 복호화하여 원문과 일치하는지 확인한다. 반드시 암호화 요청을 먼저 실행할 것." + }, + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "const json = pm.response.json();", + "pm.test('status 200', () => pm.response.to.have.status(200));", + "pm.test('success = true', () => pm.expect(json.success).to.eql(true));", + "pm.test('원문과 일치 (라운드트립)', () => pm.expect(json.data).to.eql(pm.collectionVariables.get('plainText')));" + ] + } + } + ] + } + ] + }, + { + "name": "3. EncryptionManager 암복호화 (운영 설정 반영)", + "item": [ + { + "name": "현재 설정 상태 조회", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{baseUrl}}/manage/tools/encryption-manager/status", + "host": ["{{baseUrl}}"], + "path": ["manage", "tools", "encryption-manager", "status"] + }, + "description": "encryptYN/dbEncryptSolutionName/encryptEnabled를 조회한다. encryptYN=N이면 아래 encrypt/decrypt가 원문을 그대로 반환하는 것이 정상 동작이니 먼저 이 값을 확인할 것." + }, + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "const json = pm.response.json();", + "pm.test('status 200', () => pm.response.to.have.status(200));", + "pm.test('success = true', () => pm.expect(json.success).to.eql(true));", + "pm.test('encryptYN 존재', () => pm.expect(json.data.encryptYN).to.exist);", + "pm.test('encryptEnabled는 boolean', () => pm.expect(json.data.encryptEnabled).to.be.a('boolean'));", + "console.log('EncryptionManager 상태:', JSON.stringify(json.data));" + ] + } + } + ] + }, + { + "name": "암호화 (encrypt)", + "request": { + "method": "POST", + "header": [{ "key": "Content-Type", "value": "application/json" }], + "body": { + "mode": "raw", + "raw": "{\n \"text\": \"{{plainText}}\"\n}" + }, + "url": { + "raw": "{{baseUrl}}/manage/tools/encryption-manager/encrypt", + "host": ["{{baseUrl}}"], + "path": ["manage", "tools", "encryption-manager", "encrypt"] + }, + "description": "실제 운영 코드가 사용하는 EncryptionManager.encryptDBData를 그대로 호출한다. encryptYN=N 환경에서는 원문이 그대로 반환된다(정상 동작)." + }, + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "const json = pm.response.json();", + "pm.test('status 200', () => pm.response.to.have.status(200));", + "pm.test('success = true', () => pm.expect(json.success).to.eql(true));", + "pm.test('data는 문자열', () => pm.expect(json.data).to.be.a('string'));", + "pm.collectionVariables.set('encManagerCipherText', json.data);" + ] + } + } + ] + }, + { + "name": "복호화 (decrypt) — 위 암호화 결과 사용", + "request": { + "method": "POST", + "header": [{ "key": "Content-Type", "value": "application/json" }], + "body": { + "mode": "raw", + "raw": "{\n \"text\": \"{{encManagerCipherText}}\"\n}" + }, + "url": { + "raw": "{{baseUrl}}/manage/tools/encryption-manager/decrypt", + "host": ["{{baseUrl}}"], + "path": ["manage", "tools", "encryption-manager", "decrypt"] + }, + "description": "바로 위 '암호화 (encrypt)' 요청에서 저장한 encManagerCipherText를 복호화한다. encryptYN 설정값과 무관하게 encrypt→decrypt 라운드트립 결과는 항상 원문과 같아야 한다(활성 시 실제 복호화, 비활성 시 원문 그대로 통과). 반드시 암호화 요청을 먼저 실행할 것." + }, + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "const json = pm.response.json();", + "pm.test('status 200', () => pm.response.to.have.status(200));", + "pm.test('success = true', () => pm.expect(json.success).to.eql(true));", + "pm.test('원문과 일치 (라운드트립)', () => pm.expect(json.data).to.eql(pm.collectionVariables.get('plainText')));" + ] + } + } + ] + } + ] + }, + { + "name": "4. 버전 정보", + "item": [ + { + "name": "배포 버전 조회", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{baseUrl}}/manage/tools/version", + "host": ["{{baseUrl}}"], + "path": ["manage", "tools", "version"] + }, + "description": "eapim-online(WAR를 만드는 루트 프로젝트) build.gradle의 generateVersionInfo 태스크가 생성한 version.info(git describe 결과, buildTime)를 반환한다. 재빌드 없이 IDE에서 바로 기동한 로컬 환경 등 파일이 없으면 success=false + message로 응답하며, 이는 정상 동작이다(서버 500 아님)." + }, + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "const json = pm.response.json();", + "pm.test('status 200', () => pm.response.to.have.status(200));", + "if (json.success) {", + " pm.test('version 존재', () => pm.expect(json.data.version).to.be.a('string'));", + " pm.test('buildTime 존재', () => pm.expect(json.data.buildTime).to.be.a('string'));", + "} else {", + " pm.test('미생성 환경은 message 포함', () => pm.expect(json.message).to.be.a('string'));", + " console.log('version.info 없음:', json.message);", + "}" + ] + } + } + ] + } + ] + } + ] +}