284 lines
9.4 KiB
PHP
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);
|