최초 커밋
This commit is contained in:
@@ -0,0 +1,283 @@
|
||||
<?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);
|
||||
Reference in New Issue
Block a user