BARON-SSO 로그인 연동
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/common.php';
|
||||
|
||||
auth_session_start_if_needed();
|
||||
|
||||
$site = ($_GET['site'] ?? 'egbim') === 'eng' ? 'eng' : 'egbim';
|
||||
$returnUrl = trim((string) ($_GET['return_url'] ?? auth_site_qna_url($site)));
|
||||
|
||||
if (!auth_baron_is_configured()) {
|
||||
auth_script_redirect('BARON-SSO 설정이 아직 완료되지 않았습니다.', auth_site_base_url($site) . '/index.php');
|
||||
}
|
||||
|
||||
$config = auth_baron_config();
|
||||
$statePayload = auth_baron_state_payload($site, $returnUrl);
|
||||
$state = auth_store_baron_state($statePayload);
|
||||
|
||||
$query = http_build_query([
|
||||
'client_id' => $config['client_id'],
|
||||
'response_type' => 'code',
|
||||
'redirect_uri' => auth_baron_redirect_uri(),
|
||||
'scope' => $config['scope'],
|
||||
'state' => $state,
|
||||
'nonce' => $statePayload['nonce'],
|
||||
]);
|
||||
|
||||
header('Location: ' . $config['authorize_endpoint'] . '?' . $query, true, 302);
|
||||
exit;
|
||||
?>
|
||||
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/common.php';
|
||||
|
||||
auth_session_start_if_needed();
|
||||
|
||||
$error = trim((string) ($_GET['error'] ?? ''));
|
||||
$state = trim((string) ($_GET['state'] ?? ''));
|
||||
$code = trim((string) ($_GET['code'] ?? ''));
|
||||
|
||||
$fallbackSite = 'egbim';
|
||||
|
||||
if ($error !== '') {
|
||||
auth_script_redirect('BARON-SSO 로그인에 실패했습니다: ' . $error, auth_site_base_url($fallbackSite) . '/index.php');
|
||||
}
|
||||
|
||||
if ($state === '' || $code === '') {
|
||||
auth_script_redirect('BARON-SSO 응답값이 올바르지 않습니다.', auth_site_base_url($fallbackSite) . '/index.php');
|
||||
}
|
||||
|
||||
$statePayload = auth_consume_baron_state($state);
|
||||
if ($statePayload === null) {
|
||||
auth_script_redirect('BARON-SSO state 검증에 실패했습니다.', auth_site_base_url($fallbackSite) . '/index.php');
|
||||
}
|
||||
|
||||
$site = ($statePayload['site'] ?? 'egbim') === 'eng' ? 'eng' : 'egbim';
|
||||
$redirectUrl = $statePayload['return_url'] ?? auth_site_qna_url($site);
|
||||
$config = auth_baron_config();
|
||||
|
||||
if (!auth_baron_is_configured()) {
|
||||
auth_script_redirect('BARON-SSO 설정이 아직 완료되지 않았습니다.', auth_site_base_url($site) . '/index.php');
|
||||
}
|
||||
|
||||
$tokenRequestData = [
|
||||
'grant_type' => 'authorization_code',
|
||||
'redirect_uri' => auth_baron_redirect_uri(),
|
||||
'code' => $code,
|
||||
];
|
||||
|
||||
$basicAuthUser = null;
|
||||
$basicAuthPassword = null;
|
||||
|
||||
if ($config['client_auth_method'] === 'post') {
|
||||
$tokenRequestData['client_id'] = $config['client_id'];
|
||||
$tokenRequestData['client_secret'] = $config['client_secret'];
|
||||
} else {
|
||||
$tokenRequestData['client_id'] = $config['client_id'];
|
||||
$basicAuthUser = $config['client_id'];
|
||||
$basicAuthPassword = $config['client_secret'];
|
||||
}
|
||||
|
||||
$tokenResponse = auth_http_post_form(
|
||||
$config['token_endpoint'],
|
||||
$tokenRequestData,
|
||||
[],
|
||||
$basicAuthUser,
|
||||
$basicAuthPassword
|
||||
);
|
||||
|
||||
if ($tokenResponse['error'] !== '') {
|
||||
auth_script_redirect('BARON-SSO 토큰 요청에 실패했습니다.', auth_site_base_url($site) . '/index.php');
|
||||
}
|
||||
|
||||
$tokenData = json_decode($tokenResponse['body'], true);
|
||||
if ($tokenResponse['http_code'] < 200 || $tokenResponse['http_code'] >= 300 || !is_array($tokenData)) {
|
||||
if (auth_is_local_debug()) {
|
||||
$debugMessage = sprintf(
|
||||
'BARON token error HTTP %d | body=%s',
|
||||
$tokenResponse['http_code'],
|
||||
auth_compact_debug_value((string) $tokenResponse['body'])
|
||||
);
|
||||
auth_script_redirect($debugMessage, auth_site_base_url($site) . '/index.php');
|
||||
}
|
||||
|
||||
auth_script_redirect('BARON-SSO 토큰 응답을 처리할 수 없습니다.', auth_site_base_url($site) . '/index.php');
|
||||
}
|
||||
|
||||
$claims = [];
|
||||
$idToken = trim((string) ($tokenData['id_token'] ?? ''));
|
||||
if ($idToken !== '') {
|
||||
$claims = auth_jwt_payload($idToken);
|
||||
}
|
||||
|
||||
if ($config['userinfo_endpoint'] !== '' && !empty($tokenData['access_token'])) {
|
||||
$userInfoResponse = auth_http_get_json($config['userinfo_endpoint'], (string) $tokenData['access_token']);
|
||||
$userInfoData = json_decode($userInfoResponse['body'], true);
|
||||
if ($userInfoResponse['http_code'] >= 200 && $userInfoResponse['http_code'] < 300 && is_array($userInfoData)) {
|
||||
$claims = array_merge($claims, $userInfoData);
|
||||
}
|
||||
}
|
||||
|
||||
$user = auth_baron_user_from_claims($claims);
|
||||
if (empty($user['userId']) || empty($user['loginIds'])) {
|
||||
auth_script_redirect('BARON-SSO 사용자 정보를 확인할 수 없습니다.', auth_site_base_url($site) . '/index.php');
|
||||
}
|
||||
|
||||
$normalizedUser = auth_apply_user_session($user, 'baron', [
|
||||
'baron_access_token' => (string) ($tokenData['access_token'] ?? ''),
|
||||
'baron_id_token' => $idToken,
|
||||
]);
|
||||
|
||||
setcookie('descope_login_id', '', auth_cookie_options(time() - 42000));
|
||||
setcookie('descope_user_id', '', auth_cookie_options(time() - 42000));
|
||||
setcookie('descope_user_name', '', auth_cookie_options(time() - 42000));
|
||||
setcookie('descope_user_email', '', auth_cookie_options(time() - 42000));
|
||||
setcookie('descope_user_phone', '', auth_cookie_options(time() - 42000));
|
||||
setcookie('descope_custom_attributes', '', auth_cookie_options(time() - 42000));
|
||||
setcookie('descope_role_names', '', auth_cookie_options(time() - 42000));
|
||||
auth_set_descope_session_cookies($normalizedUser);
|
||||
auth_set_baron_session_cookies($normalizedUser, $claims);
|
||||
|
||||
$clientSessionPayload = [
|
||||
'loginId' => (string) ($normalizedUser['loginIds'][0] ?? ''),
|
||||
'descopeUserId' => (string) ($normalizedUser['userId'] ?? ''),
|
||||
'userName' => (string) ($normalizedUser['name'] ?? ''),
|
||||
'phone' => (string) ($normalizedUser['phone'] ?? ''),
|
||||
'company' => (string) ($normalizedUser['customAttributes']['company'] ?? ''),
|
||||
'familyCompany' => (string) ($normalizedUser['customAttributes']['familyCompany'] ?? ''),
|
||||
'team' => (string) ($normalizedUser['customAttributes']['team'] ?? ''),
|
||||
'position' => (string) ($normalizedUser['customAttributes']['position'] ?? ''),
|
||||
'familyUniqueKey' => (string) ($normalizedUser['customAttributes']['familyUniqueKey'] ?? ''),
|
||||
'userRole' => (string) (($normalizedUser['roleNames'][0] ?? '')),
|
||||
'authProvider' => 'baron',
|
||||
'sessionJwt' => $idToken !== '' ? $idToken : (string) ($tokenData['access_token'] ?? ''),
|
||||
'baronClaims' => json_encode($claims, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
|
||||
];
|
||||
|
||||
$jsonPayload = json_encode($clientSessionPayload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
$jsonRedirectUrl = json_encode($redirectUrl, JSON_UNESCAPED_SLASHES);
|
||||
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
echo <<<HTML
|
||||
<!doctype html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate">
|
||||
<meta http-equiv="Pragma" content="no-cache">
|
||||
<meta http-equiv="Expires" content="0">
|
||||
<title>Signing in...</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
(function () {
|
||||
var payload = {$jsonPayload} || {};
|
||||
var redirectUrl = {$jsonRedirectUrl};
|
||||
|
||||
Object.keys(payload).forEach(function (key) {
|
||||
var value = payload[key];
|
||||
if (typeof value === 'string' && value !== '') {
|
||||
sessionStorage.setItem(key, value);
|
||||
localStorage.setItem(key, value);
|
||||
} else {
|
||||
sessionStorage.removeItem(key);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
window.dispatchEvent(new CustomEvent('descope-auth-changed', {
|
||||
detail: { loginId: payload.loginId || '' }
|
||||
}));
|
||||
} catch (e) {}
|
||||
|
||||
window.location.replace(redirectUrl);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
HTML;
|
||||
exit;
|
||||
?>
|
||||
+790
@@ -0,0 +1,790 @@
|
||||
<?php
|
||||
|
||||
function auth_session_start_if_needed(): void
|
||||
{
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
}
|
||||
|
||||
function auth_cookie_options(int $expires): array
|
||||
{
|
||||
return [
|
||||
'expires' => $expires,
|
||||
'path' => '/',
|
||||
'samesite' => 'Lax',
|
||||
];
|
||||
}
|
||||
|
||||
function auth_json_cookie_encode($value): string
|
||||
{
|
||||
return base64_encode(json_encode($value, JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
|
||||
function auth_json_cookie_decode(string $value, $default)
|
||||
{
|
||||
if ($value === '') {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$decoded = base64_decode($value, true);
|
||||
if ($decoded === false) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$json = json_decode($decoded, true);
|
||||
|
||||
return $json === null ? $default : $json;
|
||||
}
|
||||
|
||||
function auth_current_host(): string
|
||||
{
|
||||
return $_SERVER['HTTP_HOST'] ?? 'eg-bim.com';
|
||||
}
|
||||
|
||||
function auth_current_scheme(): string
|
||||
{
|
||||
$https = $_SERVER['HTTPS'] ?? '';
|
||||
$forwardedProto = $_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '';
|
||||
|
||||
if ($https === 'on' || $https === '1' || strtolower((string) $forwardedProto) === 'https') {
|
||||
return 'https';
|
||||
}
|
||||
|
||||
return 'http';
|
||||
}
|
||||
|
||||
function auth_absolute_url(string $path): string
|
||||
{
|
||||
return auth_current_scheme() . '://' . auth_current_host() . $path;
|
||||
}
|
||||
|
||||
function auth_site_base_url(string $site): string
|
||||
{
|
||||
return $site === 'eng' ? '/eng' : '/egbim';
|
||||
}
|
||||
|
||||
function auth_site_qna_url(string $site): string
|
||||
{
|
||||
return auth_site_base_url($site) . '/bbs/descope_qa_list.php';
|
||||
}
|
||||
|
||||
function auth_baron_config(): array
|
||||
{
|
||||
$scopes = trim((string) (getenv('BARON_SSO_SCOPE') ?: 'openid profile email'));
|
||||
|
||||
return [
|
||||
'client_id' => trim((string) getenv('BARON_SSO_CLIENT_ID')),
|
||||
'client_secret' => trim((string) getenv('BARON_SSO_CLIENT_SECRET')),
|
||||
'authorize_endpoint' => trim((string) getenv('BARON_SSO_AUTHORIZE_ENDPOINT')),
|
||||
'token_endpoint' => trim((string) getenv('BARON_SSO_TOKEN_ENDPOINT')),
|
||||
'userinfo_endpoint' => trim((string) getenv('BARON_SSO_USERINFO_ENDPOINT')),
|
||||
'issuer' => trim((string) getenv('BARON_SSO_ISSUER')),
|
||||
'redirect_uri' => trim((string) getenv('BARON_SSO_REDIRECT_URI')),
|
||||
'scope' => $scopes,
|
||||
'client_auth_method' => trim((string) (getenv('BARON_SSO_CLIENT_AUTH_METHOD') ?: 'basic')),
|
||||
];
|
||||
}
|
||||
|
||||
function auth_baron_redirect_uri(): string
|
||||
{
|
||||
$config = auth_baron_config();
|
||||
if ($config['redirect_uri'] !== '') {
|
||||
return $config['redirect_uri'];
|
||||
}
|
||||
|
||||
return auth_absolute_url('/auth/callback');
|
||||
}
|
||||
|
||||
function auth_baron_is_configured(): bool
|
||||
{
|
||||
$config = auth_baron_config();
|
||||
|
||||
return $config['client_id'] !== ''
|
||||
&& $config['client_secret'] !== ''
|
||||
&& $config['authorize_endpoint'] !== ''
|
||||
&& $config['token_endpoint'] !== '';
|
||||
}
|
||||
|
||||
function auth_normalize_user(array $user): array
|
||||
{
|
||||
$loginIds = $user['loginIds'] ?? [];
|
||||
if (!is_array($loginIds)) {
|
||||
$loginIds = [];
|
||||
}
|
||||
|
||||
$loginId = trim((string) ($loginIds[0] ?? $user['loginId'] ?? $user['email'] ?? ''));
|
||||
if ($loginId !== '' && empty($loginIds)) {
|
||||
$loginIds = [$loginId];
|
||||
}
|
||||
|
||||
$customAttributes = $user['customAttributes'] ?? [];
|
||||
$roleNames = $user['roleNames'] ?? [];
|
||||
|
||||
return [
|
||||
'userId' => trim((string) ($user['userId'] ?? $loginId)),
|
||||
'loginIds' => $loginIds,
|
||||
'name' => trim((string) ($user['name'] ?? '')),
|
||||
'email' => trim((string) ($user['email'] ?? $loginId)),
|
||||
'phone' => trim((string) ($user['phone'] ?? '')),
|
||||
'customAttributes' => is_array($customAttributes) ? $customAttributes : [],
|
||||
'roleNames' => is_array($roleNames) ? $roleNames : [],
|
||||
];
|
||||
}
|
||||
|
||||
function auth_descope_user_from_cookies(): ?array
|
||||
{
|
||||
$loginId = trim((string) ($_COOKIE['descope_login_id'] ?? ''));
|
||||
if ($loginId === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return auth_normalize_user([
|
||||
'userId' => trim((string) ($_COOKIE['descope_user_id'] ?? $loginId)),
|
||||
'loginIds' => [$loginId],
|
||||
'name' => trim((string) ($_COOKIE['descope_user_name'] ?? '')),
|
||||
'email' => trim((string) ($_COOKIE['descope_user_email'] ?? $loginId)),
|
||||
'phone' => trim((string) ($_COOKIE['descope_user_phone'] ?? '')),
|
||||
'customAttributes' => auth_json_cookie_decode((string) ($_COOKIE['descope_custom_attributes'] ?? ''), []),
|
||||
'roleNames' => auth_json_cookie_decode((string) ($_COOKIE['descope_role_names'] ?? ''), []),
|
||||
]);
|
||||
}
|
||||
|
||||
function auth_baron_user_from_cookies(): ?array
|
||||
{
|
||||
$encodedUser = (string) ($_COOKIE['baron_user'] ?? '');
|
||||
if ($encodedUser === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$user = auth_json_cookie_decode($encodedUser, []);
|
||||
if (!is_array($user) || empty($user)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return auth_normalize_user($user);
|
||||
}
|
||||
|
||||
function auth_restore_user_session(): void
|
||||
{
|
||||
auth_session_start_if_needed();
|
||||
|
||||
if (!empty($_SESSION['user']['userId'])) {
|
||||
$_SESSION['user'] = auth_normalize_user($_SESSION['user']);
|
||||
return;
|
||||
}
|
||||
|
||||
$user = auth_baron_user_from_cookies();
|
||||
if ($user === null) {
|
||||
$user = auth_descope_user_from_cookies();
|
||||
}
|
||||
|
||||
if ($user !== null) {
|
||||
$_SESSION['user'] = $user;
|
||||
}
|
||||
}
|
||||
|
||||
function auth_apply_user_session(array $user, string $provider, array $tokens = []): array
|
||||
{
|
||||
auth_session_start_if_needed();
|
||||
session_regenerate_id(true);
|
||||
|
||||
$normalizedUser = auth_normalize_user($user);
|
||||
|
||||
$_SESSION['user'] = $normalizedUser;
|
||||
$_SESSION['auth_provider'] = $provider;
|
||||
|
||||
foreach ($tokens as $key => $value) {
|
||||
$_SESSION[$key] = $value;
|
||||
}
|
||||
|
||||
return $normalizedUser;
|
||||
}
|
||||
|
||||
function auth_set_descope_session_cookies(array $user): void
|
||||
{
|
||||
$normalizedUser = auth_normalize_user($user);
|
||||
$expire = time() + 86400;
|
||||
$cookieOptions = auth_cookie_options($expire);
|
||||
|
||||
setcookie('descope_login_id', (string) ($normalizedUser['loginIds'][0] ?? ''), $cookieOptions);
|
||||
setcookie('descope_user_id', (string) $normalizedUser['userId'], $cookieOptions);
|
||||
setcookie('descope_user_name', (string) $normalizedUser['name'], $cookieOptions);
|
||||
setcookie('descope_user_email', (string) $normalizedUser['email'], $cookieOptions);
|
||||
setcookie('descope_user_phone', (string) $normalizedUser['phone'], $cookieOptions);
|
||||
setcookie('descope_custom_attributes', auth_json_cookie_encode($normalizedUser['customAttributes']), $cookieOptions);
|
||||
setcookie('descope_role_names', auth_json_cookie_encode($normalizedUser['roleNames']), $cookieOptions);
|
||||
}
|
||||
|
||||
function auth_set_baron_session_cookies(array $user, array $claims = []): void
|
||||
{
|
||||
$normalizedUser = auth_normalize_user($user);
|
||||
$expire = time() + 86400;
|
||||
$cookieOptions = auth_cookie_options($expire);
|
||||
|
||||
setcookie('baron_user', auth_json_cookie_encode($normalizedUser), $cookieOptions);
|
||||
setcookie('baron_claims', auth_json_cookie_encode($claims), $cookieOptions);
|
||||
setcookie('baron_provider', 'baron', $cookieOptions);
|
||||
}
|
||||
|
||||
function auth_clear_all_cookies(): void
|
||||
{
|
||||
$expired = auth_cookie_options(time() - 42000);
|
||||
|
||||
foreach ([
|
||||
'PHPSESSID',
|
||||
'G5sessphp',
|
||||
'descope_login_id',
|
||||
'descope_user_id',
|
||||
'descope_user_name',
|
||||
'descope_user_email',
|
||||
'descope_user_phone',
|
||||
'descope_custom_attributes',
|
||||
'descope_role_names',
|
||||
'baron_user',
|
||||
'baron_claims',
|
||||
'baron_provider',
|
||||
] as $cookieName) {
|
||||
setcookie($cookieName, '', $expired);
|
||||
}
|
||||
}
|
||||
|
||||
function auth_admin_emails(): array
|
||||
{
|
||||
return [
|
||||
'b23008@baroncs.co.kr',
|
||||
'kjy0426@hanmaceng.co.kr',
|
||||
'b24014@hanmaceng.co.kr',
|
||||
'b23065@hanmaceng.co.kr',
|
||||
'shyeom1@samaneng.com',
|
||||
'cjy627@hanmaceng.co.kr',
|
||||
'b23072@hanmaceng.co.kr',
|
||||
'cozyjin@hanmaceng.co.kr',
|
||||
'm24031@hanmaceng.co.kr',
|
||||
'b24051@hanmaceng.co.kr',
|
||||
'rmsgud1202@hanmaceng.co.kr',
|
||||
'm21318@hanmaceng.co.kr',
|
||||
'b21367@hanmaceng.co.kr',
|
||||
'b25023@hanmaceng.co.kr',
|
||||
'sdi9429@naver.com',
|
||||
'junsuy@hanmail.net',
|
||||
'ilphilo92@gmail.com',
|
||||
];
|
||||
}
|
||||
|
||||
function auth_normalize_identity(string $value): string
|
||||
{
|
||||
return strtolower(trim($value));
|
||||
}
|
||||
|
||||
function auth_is_admin_login(string $loginId): bool
|
||||
{
|
||||
$normalizedLoginId = auth_normalize_identity($loginId);
|
||||
if ($normalizedLoginId === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (auth_admin_emails() as $adminLoginId) {
|
||||
if ($normalizedLoginId === auth_normalize_identity($adminLoginId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function auth_is_admin_user(array $user, ?string $loginId = null): bool
|
||||
{
|
||||
$candidates = [];
|
||||
|
||||
if ($loginId !== null) {
|
||||
$candidates[] = $loginId;
|
||||
}
|
||||
|
||||
$loginIds = $user['loginIds'] ?? [];
|
||||
if (is_array($loginIds)) {
|
||||
foreach ($loginIds as $candidate) {
|
||||
if (is_string($candidate)) {
|
||||
$candidates[] = $candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$candidates[] = (string) ($user['email'] ?? '');
|
||||
|
||||
$customAttributes = $user['customAttributes'] ?? [];
|
||||
if (is_array($customAttributes)) {
|
||||
$candidates[] = (string) ($customAttributes['employeeId'] ?? '');
|
||||
$candidates[] = (string) ($customAttributes['familyUniqueKey'] ?? '');
|
||||
}
|
||||
|
||||
foreach ($candidates as $candidate) {
|
||||
if (auth_is_admin_login((string) $candidate)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$roleNames = $user['roleNames'] ?? [];
|
||||
if (is_array($roleNames)) {
|
||||
foreach ($roleNames as $roleName) {
|
||||
$normalizedRole = auth_normalize_identity((string) $roleName);
|
||||
if ($normalizedRole === 'super' || $normalizedRole === 'admin' || $normalizedRole === 'administrator') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function auth_sync_gnuboard_session(): array
|
||||
{
|
||||
auth_restore_user_session();
|
||||
|
||||
$loginIds = $_SESSION['user']['loginIds'] ?? [];
|
||||
$loginId = (is_array($loginIds) && !empty($loginIds)) ? trim((string) $loginIds[0]) : '';
|
||||
$userName = trim((string) ($_SESSION['user']['name'] ?? ''));
|
||||
$userEmail = trim((string) ($_SESSION['user']['email'] ?? ''));
|
||||
$isAdmin = !empty($_SESSION['user']) && is_array($_SESSION['user'])
|
||||
? auth_is_admin_user($_SESSION['user'], $loginId)
|
||||
: false;
|
||||
|
||||
if ($loginId !== '') {
|
||||
$_SESSION['ss_mb_id'] = $loginId;
|
||||
$_SESSION['ss_mb_level'] = $isAdmin ? 10 : 2;
|
||||
|
||||
return [
|
||||
'loginId' => $loginId,
|
||||
'isAdmin' => $isAdmin,
|
||||
'is_member' => true,
|
||||
'is_admin' => $isAdmin ? 'super' : '',
|
||||
'member' => [
|
||||
'mb_id' => $loginId,
|
||||
'mb_name' => $userName !== '' ? $userName : $loginId,
|
||||
'mb_email' => $userEmail,
|
||||
'mb_level' => $_SESSION['ss_mb_level'],
|
||||
'mb_nick' => $userName !== '' ? $userName : $loginId,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
unset($_SESSION['ss_mb_id'], $_SESSION['ss_mb_level']);
|
||||
|
||||
return [
|
||||
'loginId' => '',
|
||||
'isAdmin' => false,
|
||||
'is_member' => false,
|
||||
'is_admin' => '',
|
||||
'member' => [],
|
||||
];
|
||||
}
|
||||
|
||||
function auth_url_is_safe(string $url, string $site): bool
|
||||
{
|
||||
if ($url === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strpos($url, '://') !== false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return strpos($url, auth_site_base_url($site) . '/') === 0;
|
||||
}
|
||||
|
||||
function auth_baron_state_payload(string $site, string $returnUrl): array
|
||||
{
|
||||
return [
|
||||
'site' => $site,
|
||||
'return_url' => auth_url_is_safe($returnUrl, $site) ? $returnUrl : auth_site_qna_url($site),
|
||||
'nonce' => bin2hex(random_bytes(16)),
|
||||
'created_at' => time(),
|
||||
];
|
||||
}
|
||||
|
||||
function auth_store_baron_state(array $payload): string
|
||||
{
|
||||
auth_session_start_if_needed();
|
||||
|
||||
$state = bin2hex(random_bytes(16));
|
||||
$_SESSION['baron_oauth_state'] = [
|
||||
'value' => $state,
|
||||
'payload' => $payload,
|
||||
];
|
||||
|
||||
return $state;
|
||||
}
|
||||
|
||||
function auth_consume_baron_state(string $state): ?array
|
||||
{
|
||||
auth_session_start_if_needed();
|
||||
|
||||
$stored = $_SESSION['baron_oauth_state'] ?? null;
|
||||
unset($_SESSION['baron_oauth_state']);
|
||||
|
||||
if (!is_array($stored) || ($stored['value'] ?? '') !== $state) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$payload = $stored['payload'] ?? null;
|
||||
|
||||
return is_array($payload) ? $payload : null;
|
||||
}
|
||||
|
||||
function auth_http_post_form(string $url, array $data, array $headers = [], ?string $username = null, ?string $password = null): array
|
||||
{
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
|
||||
|
||||
$mergedHeaders = array_merge([
|
||||
'Accept: application/json',
|
||||
'Content-Type: application/x-www-form-urlencoded',
|
||||
], $headers);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $mergedHeaders);
|
||||
|
||||
if ($username !== null) {
|
||||
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
curl_setopt($ch, CURLOPT_USERPWD, $username . ':' . ($password ?? ''));
|
||||
}
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return [
|
||||
'body' => $response === false ? '' : $response,
|
||||
'http_code' => $httpCode,
|
||||
'error' => $error,
|
||||
];
|
||||
}
|
||||
|
||||
function auth_http_get_json(string $url, string $accessToken): array
|
||||
{
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Accept: application/json',
|
||||
'Authorization: Bearer ' . $accessToken,
|
||||
]);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return [
|
||||
'body' => $response === false ? '' : $response,
|
||||
'http_code' => $httpCode,
|
||||
'error' => $error,
|
||||
];
|
||||
}
|
||||
|
||||
function auth_jwt_payload(string $jwt): array
|
||||
{
|
||||
$parts = explode('.', $jwt);
|
||||
if (count($parts) < 2) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$payload = strtr($parts[1], '-_', '+/');
|
||||
$padding = strlen($payload) % 4;
|
||||
if ($padding > 0) {
|
||||
$payload .= str_repeat('=', 4 - $padding);
|
||||
}
|
||||
|
||||
$decoded = base64_decode($payload, true);
|
||||
if ($decoded === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$json = json_decode($decoded, true);
|
||||
|
||||
return is_array($json) ? $json : [];
|
||||
}
|
||||
|
||||
function auth_first_non_empty_string(...$values): string
|
||||
{
|
||||
foreach ($values as $value) {
|
||||
if (is_string($value)) {
|
||||
$trimmed = trim($value);
|
||||
if ($trimmed !== '') {
|
||||
return $trimmed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function auth_claim_list($value): array
|
||||
{
|
||||
if (is_array($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$stringValue = trim((string) $value);
|
||||
if ($stringValue === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [$stringValue];
|
||||
}
|
||||
|
||||
function auth_extract_phone_from_claims(array $claims): string
|
||||
{
|
||||
$profile = isset($claims['profile']) && is_array($claims['profile']) ? $claims['profile'] : [];
|
||||
$phones = auth_claim_list($claims['phones'] ?? ($profile['phones'] ?? []));
|
||||
|
||||
foreach ($phones as $phoneEntry) {
|
||||
if (is_array($phoneEntry)) {
|
||||
$candidate = auth_first_non_empty_string(
|
||||
$phoneEntry['value'] ?? '',
|
||||
$phoneEntry['phone_number'] ?? '',
|
||||
$phoneEntry['number'] ?? ''
|
||||
);
|
||||
if ($candidate !== '') {
|
||||
return $candidate;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$candidate = trim((string) $phoneEntry);
|
||||
if ($candidate !== '') {
|
||||
return $candidate;
|
||||
}
|
||||
}
|
||||
|
||||
return auth_first_non_empty_string(
|
||||
$claims['phone_number'] ?? '',
|
||||
$claims['phone'] ?? '',
|
||||
$profile['phone_number'] ?? '',
|
||||
$profile['phone'] ?? ''
|
||||
);
|
||||
}
|
||||
|
||||
function auth_extract_company_fields(array $claims): array
|
||||
{
|
||||
$company = auth_first_non_empty_string(
|
||||
$claims['company'] ?? '',
|
||||
$claims['company_name'] ?? '',
|
||||
$claims['organization'] ?? '',
|
||||
$claims['organization_name'] ?? '',
|
||||
$claims['tenant_name'] ?? ''
|
||||
);
|
||||
$familyCompany = auth_first_non_empty_string(
|
||||
$claims['familyCompany'] ?? '',
|
||||
$claims['family_company'] ?? '',
|
||||
$claims['group_name'] ?? '',
|
||||
$claims['affiliate'] ?? ''
|
||||
);
|
||||
$team = auth_first_non_empty_string(
|
||||
$claims['team'] ?? '',
|
||||
$claims['department'] ?? '',
|
||||
$claims['dept'] ?? '',
|
||||
$claims['division'] ?? '',
|
||||
$claims['org_unit'] ?? ''
|
||||
);
|
||||
|
||||
$tenants = auth_claim_list($claims['tenants'] ?? []);
|
||||
|
||||
$primaryTenant = null;
|
||||
$tenantId = trim((string) ($claims['tenant_id'] ?? ''));
|
||||
|
||||
foreach ($tenants as $tenantKey => $tenant) {
|
||||
if (!is_array($tenant)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$candidateId = trim((string) ($tenant['id'] ?? (is_string($tenantKey) ? $tenantKey : '')));
|
||||
if (($tenant['isPrimary'] ?? false) === true || ($tenant['representative'] ?? false) === true || ($tenantId !== '' && $candidateId === $tenantId)) {
|
||||
$primaryTenant = $tenant;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($primaryTenant === null) {
|
||||
foreach ($tenants as $tenant) {
|
||||
if (is_array($tenant)) {
|
||||
$primaryTenant = $tenant;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($primaryTenant)) {
|
||||
$companyAncestor = '';
|
||||
$familyCompanyAncestor = '';
|
||||
$departmentAncestor = '';
|
||||
|
||||
$ancestors = $primaryTenant['ancestors'] ?? [];
|
||||
if (is_array($ancestors)) {
|
||||
foreach ($ancestors as $ancestor) {
|
||||
if (!is_array($ancestor)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ancestorType = strtoupper(trim((string) ($ancestor['type'] ?? '')));
|
||||
$ancestorName = trim((string) ($ancestor['name'] ?? ''));
|
||||
if ($ancestorName === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($companyAncestor === '' && $ancestorType === 'COMPANY') {
|
||||
$companyAncestor = $ancestorName;
|
||||
}
|
||||
|
||||
if ($familyCompanyAncestor === '' && $ancestorType === 'COMPANY_GROUP') {
|
||||
$familyCompanyAncestor = $ancestorName;
|
||||
}
|
||||
|
||||
if ($ancestorType === 'ORGANIZATION') {
|
||||
$departmentAncestor = $ancestorName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$company = auth_first_non_empty_string(
|
||||
$company,
|
||||
$companyAncestor,
|
||||
trim((string) ($primaryTenant['name'] ?? ''))
|
||||
);
|
||||
|
||||
$familyCompany = auth_first_non_empty_string(
|
||||
$familyCompany,
|
||||
$companyAncestor,
|
||||
$familyCompanyAncestor,
|
||||
$company
|
||||
);
|
||||
|
||||
$team = auth_first_non_empty_string(
|
||||
$team,
|
||||
$departmentAncestor,
|
||||
trim((string) ($primaryTenant['name'] ?? ''))
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($tenants as $tenant) {
|
||||
if (!is_array($tenant)) {
|
||||
if ($company === '') {
|
||||
$company = trim((string) $tenant);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($company === '') {
|
||||
$company = auth_first_non_empty_string(
|
||||
$tenant['name'] ?? '',
|
||||
$tenant['display_name'] ?? '',
|
||||
$tenant['company'] ?? '',
|
||||
$tenant['company_name'] ?? '',
|
||||
$tenant['organization'] ?? ''
|
||||
);
|
||||
}
|
||||
|
||||
if ($familyCompany === '') {
|
||||
$familyCompany = auth_first_non_empty_string(
|
||||
$tenant['familyCompany'] ?? '',
|
||||
$tenant['family_company'] ?? '',
|
||||
$tenant['group_name'] ?? '',
|
||||
$tenant['affiliate'] ?? ''
|
||||
);
|
||||
}
|
||||
|
||||
if ($team === '') {
|
||||
$team = auth_first_non_empty_string(
|
||||
$tenant['team'] ?? '',
|
||||
$tenant['department'] ?? '',
|
||||
$tenant['dept'] ?? '',
|
||||
$tenant['division'] ?? '',
|
||||
$tenant['org_unit'] ?? ''
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'company' => $company,
|
||||
'familyCompany' => $familyCompany,
|
||||
'team' => $team,
|
||||
];
|
||||
}
|
||||
|
||||
function auth_baron_user_from_claims(array $claims): array
|
||||
{
|
||||
$profile = isset($claims['profile']) && is_array($claims['profile']) ? $claims['profile'] : [];
|
||||
$email = trim((string) ($claims['email'] ?? $profile['email'] ?? $claims['upn'] ?? $claims['preferred_username'] ?? $claims['sub'] ?? ''));
|
||||
$name = trim((string) ($claims['name'] ?? $profile['name'] ?? $claims['display_name'] ?? $claims['preferred_username'] ?? $email));
|
||||
$phone = auth_extract_phone_from_claims($claims);
|
||||
$companyFields = auth_extract_company_fields($claims);
|
||||
$company = $companyFields['company'];
|
||||
$familyCompany = $companyFields['familyCompany'];
|
||||
$team = $companyFields['team'];
|
||||
$employeeId = trim((string) ($claims['employee_id'] ?? $profile['employee_id'] ?? $claims['employeeId'] ?? $claims['familyUniqueKey'] ?? ''));
|
||||
$status = trim((string) ($claims['status'] ?? $profile['status'] ?? ''));
|
||||
$tenants = auth_claim_list($claims['tenants'] ?? []);
|
||||
$secondaryEmails = auth_claim_list($claims['secondary_emails'] ?? $claims['secondaryEmails'] ?? ($profile['secondary_emails'] ?? []));
|
||||
$roles = auth_claim_list($claims['roles'] ?? $claims['roleNames'] ?? []);
|
||||
$position = auth_first_non_empty_string(
|
||||
$claims['position'] ?? '',
|
||||
$profile['position'] ?? ''
|
||||
);
|
||||
|
||||
foreach ($tenants as $tenant) {
|
||||
if (!is_array($tenant)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($position === '') {
|
||||
$position = auth_first_non_empty_string(
|
||||
$tenant['grade'] ?? '',
|
||||
$tenant['position'] ?? ''
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return auth_normalize_user([
|
||||
'userId' => trim((string) ($claims['sub'] ?? $email)),
|
||||
'loginIds' => $email !== '' ? [$email] : [],
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'phone' => $phone,
|
||||
'customAttributes' => [
|
||||
'company' => $company,
|
||||
'familyCompany' => $familyCompany,
|
||||
'team' => $team,
|
||||
'position' => $position,
|
||||
'employeeId' => $employeeId,
|
||||
'familyUniqueKey' => $employeeId,
|
||||
'status' => $status,
|
||||
'tenants' => $tenants,
|
||||
'secondaryEmails' => $secondaryEmails,
|
||||
],
|
||||
'roleNames' => $roles,
|
||||
]);
|
||||
}
|
||||
|
||||
function auth_script_redirect(string $message, string $redirectUrl): void
|
||||
{
|
||||
$safeMessage = htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
|
||||
$safeUrl = htmlspecialchars($redirectUrl, ENT_QUOTES, 'UTF-8');
|
||||
|
||||
echo "<script>alert('{$safeMessage}'); window.location.href = '{$safeUrl}';</script>";
|
||||
exit;
|
||||
}
|
||||
|
||||
function auth_is_local_debug(): bool
|
||||
{
|
||||
return (getenv('APP_ENV') ?: '') === 'local';
|
||||
}
|
||||
|
||||
function auth_compact_debug_value(string $value, int $maxLength = 300): string
|
||||
{
|
||||
$value = preg_replace('/\s+/', ' ', trim($value)) ?? '';
|
||||
if (strlen($value) <= $maxLength) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return substr($value, 0, $maxLength) . '...';
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/common.php';
|
||||
|
||||
auth_session_start_if_needed();
|
||||
|
||||
if (!auth_is_local_debug()) {
|
||||
http_response_code(404);
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Content-Type: application/json; charset=UTF-8');
|
||||
|
||||
$baronClaims = auth_json_cookie_decode((string) ($_COOKIE['baron_claims'] ?? ''), []);
|
||||
$baronUser = auth_baron_user_from_cookies();
|
||||
$sessionUser = $_SESSION['user'] ?? [];
|
||||
|
||||
echo json_encode([
|
||||
'auth_provider' => $_SESSION['auth_provider'] ?? '',
|
||||
'session_user' => is_array($sessionUser) ? $sessionUser : [],
|
||||
'baron_user_cookie' => $baronUser,
|
||||
'baron_claims_cookie' => is_array($baronClaims) ? $baronClaims : [],
|
||||
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
exit;
|
||||
Reference in New Issue
Block a user