최초 커밋
This commit is contained in:
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
// ✅ 타임존 설정 및 디버그용 메타 정보
|
||||
date_default_timezone_set('Asia/Seoul');
|
||||
$server_timezone = date_default_timezone_get();
|
||||
$server_time = date('Y-m-d H:i:s');
|
||||
|
||||
// ✅ Descope Management Key
|
||||
$management_key = 'P2wON5fy1K6kyia269VpeIzYP8oP:K32l5ORmzy32OvaaPvpdZsMY3JmKQb7a3vvrl10PgjlJUGk3K7EssMH3uW5VGQSbrgtEdPj';
|
||||
$headers = [
|
||||
"Authorization: Bearer $management_key",
|
||||
"Content-Type: application/json"
|
||||
];
|
||||
|
||||
$all_users = [];
|
||||
$page = 0;
|
||||
$limit = 200;
|
||||
|
||||
// ✅ 1) Descope 전체 유저 조회
|
||||
do {
|
||||
$url_users = "https://api.descope.com/v2/mgmt/user/search";
|
||||
$payload = json_encode(["limit" => $limit, "page" => $page]);
|
||||
|
||||
$ch = curl_init($url_users);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
$response = curl_exec($ch);
|
||||
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
if ($http_code !== 200) {
|
||||
echo json_encode(['status' => 'fail', 'step' => 'user_search', 'code' => $http_code, 'raw' => $response]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$res = json_decode($response, true);
|
||||
$users = $res['users'] ?? [];
|
||||
$all_users = array_merge($all_users, $users);
|
||||
$page++;
|
||||
} while (count($users) === $limit);
|
||||
|
||||
// ✅ 2) MySQL에서 최근 로그인 시간 병합
|
||||
try {
|
||||
$dbHost = getenv('G5_MYSQL_HOST') ?: getenv('MARIADB_HOST') ?: getenv('MYSQL_HOST') ?: 'localhost';
|
||||
$dbName = getenv('G5_MYSQL_DB') ?: getenv('MARIADB_DATABASE') ?: getenv('MYSQL_DATABASE') ?: 'egbim';
|
||||
$dbUser = getenv('G5_MYSQL_USER') ?: getenv('MARIADB_USER') ?: getenv('MYSQL_USER') ?: 'egbim';
|
||||
$dbPass = getenv('G5_MYSQL_PASSWORD') ?: getenv('MARIADB_PASSWORD') ?: getenv('MYSQL_PASSWORD') ?: 'baron3840!!';
|
||||
|
||||
$pdo = new PDO("mysql:host={$dbHost};dbname={$dbName};charset=utf8mb4", $dbUser, $dbPass, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
]);
|
||||
|
||||
$stmt = $pdo->query("
|
||||
SELECT login_id, MAX(user_login_time) AS last_login_time
|
||||
FROM user_program_info
|
||||
WHERE user_login_time IS NOT NULL AND user_login_time <> ''
|
||||
GROUP BY login_id
|
||||
");
|
||||
|
||||
$loginMap = [];
|
||||
while ($row = $stmt->fetch()) {
|
||||
$loginMap[$row['login_id']] = $row['last_login_time'];
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
$loginMap = [];
|
||||
}
|
||||
|
||||
// ✅ 3) 날짜 변환 함수 (KST 환경 기준 — 이중 변환 방지)
|
||||
$fmtDate = function($val) {
|
||||
if (empty($val)) return null;
|
||||
if (!is_numeric($val)) return null;
|
||||
|
||||
$ts = (float) $val;
|
||||
if ($ts > 1e12) $ts = $ts / 1000; // 밀리초 → 초 변환
|
||||
$ts = (int) round($ts);
|
||||
if ($ts <= 0) return null;
|
||||
|
||||
// ✅ UTC 기준으로 그대로 출력 (PHP의 +9h 보정 방지)
|
||||
return gmdate('Y-m-d H:i:s', $ts);
|
||||
};
|
||||
|
||||
// ✅ 4) 유저 데이터 가공
|
||||
foreach ($all_users as &$u) {
|
||||
|
||||
$u['customAttributes'] = $u['customAttributes'] ?? [];
|
||||
$u['name'] = $u['name'] ?? '';
|
||||
$u['email'] = $u['email'] ?? '';
|
||||
$u['phone'] = $u['phone'] ?? '';
|
||||
|
||||
// --- 테넌트 이름 문자열화 ---
|
||||
if (!empty($u['userTenants']) && is_array($u['userTenants'])) {
|
||||
$tenantNames = [];
|
||||
foreach ($u['userTenants'] as $t) {
|
||||
$tenantNames[] = $t['tenantName'] ?? $t['tenantId'] ?? '';
|
||||
}
|
||||
$u['tenantText'] = implode(', ', array_filter($tenantNames));
|
||||
} else {
|
||||
$u['tenantText'] = '-';
|
||||
}
|
||||
|
||||
// --- createdTime ---
|
||||
if (!empty($u['createdTime'])) {
|
||||
$u['createdTime'] = $fmtDate($u['createdTime']);
|
||||
}
|
||||
|
||||
// --- egBimLExpiryDate ---
|
||||
if (!empty($u['customAttributes']['egBimLExpiryDate'])) {
|
||||
$u['customAttributes']['egBimLExpiryDate'] = $fmtDate($u['customAttributes']['egBimLExpiryDate']);
|
||||
}
|
||||
|
||||
// --- lastSignInDate ---
|
||||
if (!empty($u['customAttributes']['lastSignInDate'])) {
|
||||
$u['customAttributes']['lastSignInDate'] = $fmtDate($u['customAttributes']['lastSignInDate']);
|
||||
}
|
||||
|
||||
// --- serverLastLogin (EGBIM DB 병합) ---
|
||||
$loginId = $u['loginIds'][0] ?? null;
|
||||
if ($loginId && isset($loginMap[$loginId])) {
|
||||
$u['customAttributes']['serverLastLogin'] = $loginMap[$loginId];
|
||||
}
|
||||
|
||||
// --- completeForm 표시를 true/false → 텍스트로 ---
|
||||
if (isset($u['customAttributes']['completeForm'])) {
|
||||
$u['customAttributes']['completeForm'] = $u['customAttributes']['completeForm'] ? '완료' : '미완료';
|
||||
}
|
||||
}
|
||||
unset($u);
|
||||
|
||||
// ✅ 5) 필터링
|
||||
$start = $_GET['start'] ?? null;
|
||||
$end = $_GET['end'] ?? null;
|
||||
$mode = $_GET['mode'] ?? 'created';
|
||||
$keyword = $_GET['keyword'] ?? '';
|
||||
$tenantFilters = isset($_GET['tenants']) ? explode(',', $_GET['tenants']) : [];
|
||||
|
||||
function normalize_ts($val) {
|
||||
$ts = (int)$val;
|
||||
if ($ts > 0 && $ts < 1e12) $ts *= 1000;
|
||||
return $ts;
|
||||
}
|
||||
|
||||
// --- 기간 필터 ---
|
||||
if ($start || $end) {
|
||||
$startTs = $start ? strtotime($start . " 00:00:00") * 1000 : null;
|
||||
$endTs = $end ? strtotime($end . " 23:59:59") * 1000 : null;
|
||||
|
||||
$all_users = array_filter($all_users, function($u) use ($startTs, $endTs, $mode) {
|
||||
$ts = 0;
|
||||
if ($mode === 'created') {
|
||||
$ts = strtotime($u['createdTime'] ?? '') * 1000;
|
||||
} elseif ($mode === 'lastSignIn') {
|
||||
$ts = strtotime($u['customAttributes']['lastSignInDate'] ?? '') * 1000;
|
||||
} elseif ($mode === 'license') {
|
||||
$ts = strtotime($u['customAttributes']['egBimLExpiryDate'] ?? '') * 1000;
|
||||
} elseif ($mode === 'serverLogin') {
|
||||
if (!empty($u['customAttributes']['serverLastLogin'])) {
|
||||
$ts = strtotime($u['customAttributes']['serverLastLogin']) * 1000;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$ts) return false;
|
||||
if ($startTs && $ts < $startTs) return false;
|
||||
if ($endTs && $ts > $endTs) return false;
|
||||
return true;
|
||||
});
|
||||
$all_users = array_values($all_users);
|
||||
}
|
||||
|
||||
// --- 테넌트 필터 ---
|
||||
if (!empty($tenantFilters)) {
|
||||
$all_users = array_filter($all_users, function($u) use ($tenantFilters) {
|
||||
$txt = $u['tenantText'] ?? '';
|
||||
foreach ($tenantFilters as $t) {
|
||||
if (stripos($txt, $t) !== false) return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
$all_users = array_values($all_users);
|
||||
}
|
||||
|
||||
// --- 키워드 필터 ---
|
||||
if ($keyword !== '') {
|
||||
$all_users = array_filter($all_users, function($u) use ($keyword) {
|
||||
$fields = [
|
||||
$u['customAttributes']['familyCompany'] ?? '',
|
||||
$u['customAttributes']['company'] ?? '',
|
||||
$u['name'] ?? '',
|
||||
$u['displayName'] ?? ''
|
||||
];
|
||||
foreach ($fields as $f) {
|
||||
if (stripos($f, $keyword) !== false) return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
$all_users = array_values($all_users);
|
||||
}
|
||||
|
||||
// --- 정렬 ---
|
||||
usort($all_users, function($a, $b) use ($mode) {
|
||||
if ($mode === 'created') {
|
||||
return strcmp($b['createdTime'] ?? '', $a['createdTime'] ?? '');
|
||||
} elseif ($mode === 'lastSignIn') {
|
||||
return strcmp($b['customAttributes']['lastSignInDate'] ?? '', $a['customAttributes']['lastSignInDate'] ?? '');
|
||||
} elseif ($mode === 'license') {
|
||||
return strcmp($b['customAttributes']['egBimLExpiryDate'] ?? '', $a['customAttributes']['egBimLExpiryDate'] ?? '');
|
||||
} elseif ($mode === 'serverLogin') {
|
||||
return strcmp($b['customAttributes']['serverLastLogin'] ?? '', $a['customAttributes']['serverLastLogin'] ?? '');
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
|
||||
// ✅ 6) 최종 응답 (타임존 정보 포함)
|
||||
echo json_encode([
|
||||
'status' => 'success', // ✅ "ok" 대신 "success"로
|
||||
'total' => count($all_users),
|
||||
'records' => $all_users,
|
||||
'msg' => '', // ✅ w2ui 기본 필드 추가
|
||||
'meta' => [
|
||||
'timezone' => $server_timezone,
|
||||
'server_time' => $server_time
|
||||
]
|
||||
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
?>
|
||||
Reference in New Issue
Block a user