zioinfo-web/deploy/login_test.py
DESKTOP-TKLFCPRython 1e98f0d04a refactor: 101.79.17.164 → zioinfo.co.kr 전체 도메인 변환 + Manager UI 배포
- 37개 파일 IP → zioinfo.co.kr 치환 (소스/매뉴얼/설정/하네스)
- Manager DrConsole/NetworkConsole/CsapConsole 빌드 + /var/www/manager/ 배포
- 테스트: Manager HTTP 200, ITSM 신규 API 7개 전체 200

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 10:09:17 +09:00

141 lines
4.9 KiB
Python

#!/usr/bin/env python3
"""GUARDiA ITSM 로그인 방식 확인 및 라이선스 테스트"""
import paramiko, time, sys, json
HOST = '101.79.17.164'; USER = 'root'; PASS = '1q2w3e!Q'
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(HOST, username=USER, password=PASS, timeout=15)
sftp = client.open_sftp()
test_py = '''#!/usr/bin/env python3
import urllib.request, json
BASE = "http://localhost:8001"
# 로그인 방식 탐색
login_attempts = [
("JSON username/password", "POST", "/api/auth/login",
json.dumps({"username":"admin","password":"1111"}).encode(), "application/json"),
("JSON username/password (Admin2026)", "POST", "/api/auth/login",
json.dumps({"username":"admin","password":"Admin@2026!"}).encode(), "application/json"),
("Form data", "POST", "/api/auth/login",
"username=admin&password=1111".encode(), "application/x-www-form-urlencoded"),
]
TOKEN = None
for name, method, path, body, ct in login_attempts:
req = urllib.request.Request(f"{BASE}{path}", data=body, method=method)
req.add_header("Content-Type", ct)
try:
resp = urllib.request.urlopen(req, timeout=5)
d = json.loads(resp.read())
if "access_token" in d:
TOKEN = d["access_token"]
print(f"OK 로그인 성공 [{name}]: token={TOKEN[:20]}...")
break
else:
print(f"FAIL [{name}]: {d}")
except urllib.error.HTTPError as e:
print(f"FAIL [{name}] HTTP {e.code}: {e.read().decode()[:100]}")
if not TOKEN:
print("모든 로그인 시도 실패")
exit(1)
# 라이선스 API 테스트
def api(method, path, data=None):
url = f"{BASE}{path}"
body = json.dumps(data).encode() if data else None
req = urllib.request.Request(url, data=body, method=method)
req.add_header("Content-Type", "application/json")
req.add_header("Authorization", f"Bearer {TOKEN}")
try:
resp = urllib.request.urlopen(req, timeout=10)
return json.loads(resp.read()), resp.status
except urllib.error.HTTPError as e:
return json.loads(e.read()), e.code
print("\\n=== 라이선스 API 테스트 ===")
RESULTS = []
def test(name, fn):
try:
r = fn(); ok = True
except Exception as ex:
r = str(ex); ok = False
RESULTS.append((name, ok, str(r)[:80]))
print(f\'{"OK" if ok else "FAIL"} {name}: {str(r)[:80]}\')
return r if ok else None
# T2: 현재 상태
test("T2 라이선스 현재 상태", lambda: api("GET", "/api/license/status")[0].get("message"))
# T3: 체험 라이선스 (없으면 발급)
cur, _ = api("GET", "/api/license/status")
if not cur.get("activated"):
def t3():
r,s = api("POST", "/api/license/trial", {"customer":"지오정보기술 체험판","days":7})
return f"HTTP {s}: {r.get(\'message\', r.get(\'detail\', \'?\'))}"
test("T3 체험 라이선스 발급 (7일)", t3)
else:
RESULTS.append(("T3 체험 라이선스 발급", True, "이미 활성화됨"))
print("SKIP T3: 이미 활성화됨")
# T4: 활성화 후 상태
def t4():
r,_ = api("GET", "/api/license/status")
return f"valid={r.get(\'valid\')}, edition={r.get(\'edition\')}, days={r.get(\'days_remaining\')}"
test("T4 활성화 후 상태", t4)
# T5: 이력
def t5():
r,s = api("GET", "/api/license/history")
return f"HTTP {s}: {len(r) if isinstance(r,list) else \'?\'}건"
test("T5 라이선스 이력 조회", t5)
# T6: 잘못된 키 검증
def t6():
r,s = api("POST", "/api/license/verify", {"license_key":"invalid_key"})
return f"HTTP {s}: {r.get(\'detail\', r.get(\'message\',\'?\'))[:50]}"
test("T6 잘못된 키 검증 (400/422 예상)", t6)
# T7: Manager UI
try:
resp7 = urllib.request.urlopen("http://localhost:8090/", timeout=5)
test("T7 Manager UI", lambda: f"HTTP {resp7.status}")
except Exception as ex:
test("T7 Manager UI", lambda: f"ERROR: {str(ex)[:50]}")
# T8: Manager API
try:
resp8 = urllib.request.urlopen("http://localhost:8002/health", timeout=5)
d8 = json.loads(resp8.read())
test("T8 Manager Backend", lambda: d8.get("status","?"))
except Exception as ex:
test("T8 Manager Backend", lambda: f"ERROR: {str(ex)[:50]}")
print(f"\\n{'='*55}")
passed = sum(1 for _,ok,_ in RESULTS if ok)
print(f"결과: {passed}/{len(RESULTS)} PASS")
for name,ok,detail in RESULTS:
print(f\' {"OK" if ok else "FAIL"} {name}\')
print("="*55)
'''
with sftp.open('/tmp/test_lic2.py', 'w') as f:
f.write(test_py)
sftp.close()
chan = client.get_transport().open_session()
chan.set_combine_stderr(True)
chan.exec_command('python3 /tmp/test_lic2.py 2>&1')
start = time.time()
while not chan.exit_status_ready():
if chan.recv_ready(): sys.stdout.buffer.write(chan.recv(4096)); sys.stdout.flush()
if time.time() - start > 30: break
time.sleep(0.2)
while chan.recv_ready(): sys.stdout.buffer.write(chan.recv(4096))
sys.stdout.flush()
chan.recv_exit_status()
client.close()