어디야 관리자 권한 장기 검증
This commit is contained in:
1 parent
62d25a286b
commit
1b9e69692e
2 files changed
+74
-18
No files matched your search
@@ -26,6 +26,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
||||
|
||||
$config = custom_config();
|
||||
|
||||
const LAUNCHER_ADMIN_TICKET_TTL = 400 * 24 * 60 * 60;
|
||||
|
||||
function launcher_is_digit_password(string $password): bool
|
||||
{
|
||||
return preg_match('/^\d{4}$/', $password) === 1;
|
||||
@@ -40,33 +42,79 @@ function launcher_admin_ticket_audience(string $audience): string
|
||||
return $audience;
|
||||
}
|
||||
|
||||
function launcher_issue_admin_ticket(string $audience): string
|
||||
function launcher_current_site_admin_member_srl(): int
|
||||
{
|
||||
if (!custom_is_site_admin() || !class_exists('Context')) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$loggedInfo = Context::get('logged_info');
|
||||
return max(0, (int)($loggedInfo->member_srl ?? 0));
|
||||
}
|
||||
|
||||
function launcher_member_is_site_admin(int $memberSrl): bool
|
||||
{
|
||||
if ($memberSrl <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$autoload = dirname(__DIR__, 2) . '/common/autoload.php';
|
||||
if (!is_file($autoload)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
require_once $autoload;
|
||||
if (!class_exists('Context') || !class_exists('MemberModel')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Context::init();
|
||||
$memberInfo = MemberModel::getMemberInfoByMemberSrl($memberSrl);
|
||||
return is_object($memberInfo)
|
||||
&& (($memberInfo->is_site_admin ?? false) === true || ($memberInfo->is_admin ?? 'N') === 'Y');
|
||||
} catch (Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function launcher_issue_admin_ticket(string $audience, int $memberSrl): string
|
||||
{
|
||||
if ($memberSrl <= 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return custom_signed_cookie_payload([
|
||||
'scope' => 'launcher_admin_ticket',
|
||||
'aud' => $audience,
|
||||
'admin' => true,
|
||||
'member_srl' => $memberSrl,
|
||||
'iat' => time(),
|
||||
'exp' => time() + 300,
|
||||
'exp' => time() + LAUNCHER_ADMIN_TICKET_TTL,
|
||||
]);
|
||||
}
|
||||
|
||||
function launcher_valid_admin_ticket(string $ticket, string $audience): bool
|
||||
function launcher_validate_admin_ticket(string $ticket, string $audience): ?array
|
||||
{
|
||||
if ($ticket === '' || strlen($ticket) > 4096 || $audience === '') {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
$payload = custom_verify_signed_cookie_payload($ticket);
|
||||
if (!is_array($payload)) {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
return ($payload['scope'] ?? '') === 'launcher_admin_ticket'
|
||||
$memberSrl = (int)($payload['member_srl'] ?? 0);
|
||||
$valid = ($payload['scope'] ?? '') === 'launcher_admin_ticket'
|
||||
&& ($payload['aud'] ?? '') === $audience
|
||||
&& !empty($payload['admin'])
|
||||
&& $memberSrl > 0
|
||||
&& (int)($payload['iat'] ?? 0) <= time() + 30
|
||||
&& (int)($payload['exp'] ?? 0) >= time();
|
||||
&& (int)($payload['exp'] ?? 0) >= time()
|
||||
&& launcher_member_is_site_admin($memberSrl);
|
||||
|
||||
return $valid ? $payload : null;
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
@@ -156,7 +204,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
custom_json(['error' => 'invalid_admin_bridge_return'], 400);
|
||||
}
|
||||
|
||||
$isAdmin = custom_is_site_admin();
|
||||
$memberSrl = launcher_current_site_admin_member_srl();
|
||||
$isAdmin = $memberSrl > 0;
|
||||
if ($isAdmin) {
|
||||
custom_issue_auth_cookie(true);
|
||||
}
|
||||
@@ -164,8 +213,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
'rhymixAdmin' => $isAdmin ? '1' : '0',
|
||||
];
|
||||
if ($isAdmin) {
|
||||
$fragment['rhymixAdminTicket'] = launcher_issue_admin_ticket($audience);
|
||||
$fragment['rhymixAdminTicketExpiresIn'] = '300';
|
||||
$fragment['rhymixAdminTicket'] = launcher_issue_admin_ticket($audience, $memberSrl);
|
||||
$fragment['rhymixAdminTicketExpiresIn'] = (string)LAUNCHER_ADMIN_TICKET_TTL;
|
||||
}
|
||||
header('Location: ' . $returnUrl . '#' . http_build_query($fragment, '', '&', PHP_QUERY_RFC3986), true, 303);
|
||||
exit;
|
||||
@@ -174,11 +223,17 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
if (isset($_GET['validateAdminTicket'])) {
|
||||
$audience = launcher_admin_ticket_audience((string)($_GET['aud'] ?? ''));
|
||||
$ticket = (string)($_GET['ticket'] ?? '');
|
||||
$valid = launcher_valid_admin_ticket($ticket, $audience);
|
||||
custom_json([
|
||||
$payload = launcher_validate_admin_ticket($ticket, $audience);
|
||||
$valid = is_array($payload);
|
||||
$response = [
|
||||
'valid' => $valid,
|
||||
'admin' => $valid,
|
||||
]);
|
||||
];
|
||||
if ($valid) {
|
||||
$response['adminTicket'] = launcher_issue_admin_ticket($audience, (int)$payload['member_srl']);
|
||||
$response['adminTicketExpiresIn'] = LAUNCHER_ADMIN_TICKET_TTL;
|
||||
}
|
||||
custom_json($response);
|
||||
}
|
||||
|
||||
if (isset($_GET['session'])) {
|
||||
@@ -230,7 +285,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
}
|
||||
|
||||
if (isset($_GET['adminSession'])) {
|
||||
$isAdmin = custom_is_site_admin();
|
||||
$memberSrl = launcher_current_site_admin_member_srl();
|
||||
$isAdmin = $memberSrl > 0;
|
||||
if ($isAdmin) {
|
||||
custom_issue_auth_cookie(true);
|
||||
}
|
||||
@@ -240,8 +296,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||||
];
|
||||
$audience = launcher_admin_ticket_audience((string)($_GET['adminTicket'] ?? ''));
|
||||
if ($isAdmin && $audience !== '') {
|
||||
$response['adminTicket'] = launcher_issue_admin_ticket($audience);
|
||||
$response['adminTicketExpiresIn'] = 300;
|
||||
$response['adminTicket'] = launcher_issue_admin_ticket($audience, $memberSrl);
|
||||
$response['adminTicketExpiresIn'] = LAUNCHER_ADMIN_TICKET_TTL;
|
||||
}
|
||||
custom_json($response);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user