Files
egbim_homepage/egbim/bbs/descope_user_list.php
2026-07-23 16:15:57 +09:00

284 lines
9.4 KiB
PHP

<?php
// header('Content-Type: application/json');
// // ✅ Descope Management Key
// $management_key = 'P2wON5fy1K6kyia269VpeIzYP8oP:K32l5ORmzy32OvaaPvpdZsMY3JmKQb7a3vvrl10PgjlJUGk3K7EssMH3uW5VGQSbrgtEdPj';
// $headers = [
// "Authorization: Bearer $management_key",
// "Content-Type: application/json"
// ];
// $all_users = [];
// $page = 0;
// $limit = 200; // Descope API 권장 최대 limit (보통 200까지 가능)
// // === 1) 모든 페이지 루프 ===
// 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);
// $fetched = count($users);
// $page++;
// } while ($fetched === $limit); // limit만큼 꽉 찼으면 다음 페이지 있음
// // === 2) 테넌트 이름 매핑 ===
// // 유저들에서 tenantId 수집
// $tenantIds = [];
// foreach ($all_users as $u) {
// if (!empty($u['tenants'])) {
// foreach ($u['tenants'] as $t) {
// if (!in_array($t['tenantId'], $tenantIds)) {
// $tenantIds[] = $t['tenantId'];
// }
// }
// }
// }
// // 테넌트 이름 가져오기
// $tenant_map = [];
// if (!empty($tenantIds)) {
// $url_tenants = "https://api.descope.com/v1/mgmt/tenant/search";
// $payload_tenant = json_encode([
// "tenantIds" => $tenantIds
// ]);
// $ch2 = curl_init($url_tenants);
// curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
// curl_setopt($ch2, CURLOPT_POSTFIELDS, $payload_tenant);
// curl_setopt($ch2, CURLOPT_HTTPHEADER, $headers);
// $response_tenants = curl_exec($ch2);
// $http_code_tenants = curl_getinfo($ch2, CURLINFO_HTTP_CODE);
// curl_close($ch2);
// if ($http_code_tenants === 200) {
// $res_tenants = json_decode($response_tenants, true);
// if (!empty($res_tenants['tenants'])) {
// foreach ($res_tenants['tenants'] as $t) {
// $tenant_map[$t['id']] = $t['name'];
// }
// }
// }
// }
// // === 3) 각 유저에 tenantName 붙이기 ===
// foreach ($all_users as &$user) {
// $user['name'] = $user['name'] ?? '';
// $user['phone'] = $user['phone'] ?? '';
// $user['customAttributes'] = $user['customAttributes'] ?? [];
// if (!empty($user['tenants'])) {
// foreach ($user['tenants'] as &$ten) {
// $ten['tenantName'] = $tenant_map[$ten['tenantId']] ?? $ten['tenantId'];
// }
// }
// }
// // === 4) 최종 응답 ===
// echo json_encode([
// 'status' => 'ok',
// 'count' => count($all_users),
// 'users' => $all_users
// ]);
?>
<?php
header('Content-Type: application/json');
// ✅ Descope Management Key
$management_key = 'P2wON5fy1K6kyia269VpeIzYP8oP:K32l5ORmzy32OvaaPvpdZsMY3JmKQb7a3vvrl10PgjlJUGk3K7EssMH3uW5VGQSbrgtEdPj'; // 실제 키 넣으세요
$headers = [
"Authorization: Bearer $management_key",
"Content-Type: application/json"
];
$all_users = [];
$page = 0;
$limit = 200;
// ✅ 전체 유저 가져오기
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);
// ✅ timestamp 보정
function normalize_ts($val) {
$ts = (int) $val;
if ($ts > 0 && $ts < 1e12) $ts *= 1000;
return $ts;
}
// ====== ✅ DB에서 최근 로그인 시간 가져오기 ======
try {
$pdo = new PDO("mysql:host=localhost;dbname=egbim;charset=utf8mb4", "egbim", "baron3840!!", [
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'];
}
// Descope 유저 리스트와 merge
foreach ($all_users as &$u) {
$loginId = $u['loginIds'][0] ?? null;
$u['customAttributes']['serverLastLogin'] =
($loginId && isset($loginMap[$loginId])) ? $loginMap[$loginId] : null;
}
unset($u);
} catch (Exception $e) {
// DB 오류 시 무시하고 진행
}
// ✅ 기간 필터
$start = $_GET['start'] ?? null;
$end = $_GET['end'] ?? null;
$mode = $_GET['mode'] ?? 'created';
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 = normalize_ts($u['createdTime'] ?? 0);
} elseif ($mode === 'lastSignIn') {
$ts = normalize_ts($u['customAttributes']['lastSignInDate'] ?? 0);
} elseif ($mode === 'license') {
$ts = normalize_ts($u['customAttributes']['egBimLExpiryDate'] ?? 0);
} elseif ($mode === 'serverLogin') {
// ✅ EGBIM 최근 로그인 (DB에서 가져온 값은 문자열로 가정)
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);
}
// ✅ 테넌트 필터
$tenantFilters = isset($_GET['tenants']) ? explode(',', $_GET['tenants']) : [];
if (!empty($tenantFilters)) {
$all_users = array_filter($all_users, function($u) use ($tenantFilters) {
if (!empty($u['userTenants']) && is_array($u['userTenants'])) {
foreach ($u['userTenants'] as $t) {
$tName = $t['tenantName'] ?? '';
foreach ($tenantFilters as $f) {
if (strcasecmp($tName, $f) === 0) return true;
}
}
}
return false;
});
$all_users = array_values($all_users);
}
// ✅ 키워드 검색 (소속 가족사 / 외부회사 / 이름 / DisplayName)
$keyword = $_GET['keyword'] ?? '';
if ($keyword !== '') {
$all_users = array_filter($all_users, function($u) use ($keyword) {
$fc = $u['customAttributes']['familyCompany'] ?? '';
$comp = $u['customAttributes']['company'] ?? '';
$name = $u['name'] ?? '';
$disp = $u['displayName'] ?? '';
return (
stripos($fc, $keyword) !== false ||
stripos($comp, $keyword) !== false ||
stripos($name, $keyword) !== false ||
stripos($disp, $keyword) !== false
);
});
$all_users = array_values($all_users);
}
// ✅ 정렬 (최신순)
usort($all_users, function($a, $b) use ($mode) {
if ($mode === 'created') {
return ($b['createdTime'] ?? 0) <=> ($a['createdTime'] ?? 0);
} elseif ($mode === 'lastSignIn') {
return ($b['customAttributes']['lastSignInDate'] ?? 0) <=> ($a['customAttributes']['lastSignInDate'] ?? 0);
} elseif ($mode === 'license') {
return ($b['customAttributes']['egBimLExpiryDate'] ?? 0) <=> ($a['customAttributes']['egBimLExpiryDate'] ?? 0);
} elseif ($mode === 'serverLogin') {
$aTs = !empty($a['customAttributes']['serverLastLogin']) ? strtotime($a['customAttributes']['serverLastLogin']) : 0;
$bTs = !empty($b['customAttributes']['serverLastLogin']) ? strtotime($b['customAttributes']['serverLastLogin']) : 0;
return $bTs <=> $aTs;
}
return 0;
});
// ✅ 최종 응답
echo json_encode([
'status' => 'ok',
'count' => count($all_users),
'users' => $all_users,
'filters'=> [
'start' => $start,
'end' => $end,
'mode' => $mode,
'keyword' => $keyword
]
], JSON_UNESCAPED_UNICODE);