feat(admin): add proxy-only auth bypass and configurable auth header (closes #28)
This commit is contained in:
@@ -54,11 +54,22 @@ class AdminController
|
||||
{
|
||||
header('Content-Type: application/json');
|
||||
$config = AdminModel::getConfig();
|
||||
|
||||
// If an error was encountered, send a 500 status.
|
||||
|
||||
if (isset($config['error'])) {
|
||||
http_response_code(500);
|
||||
}
|
||||
|
||||
if (!isset($config['loginOptions']) || !is_array($config['loginOptions'])) {
|
||||
$config['loginOptions'] = [];
|
||||
}
|
||||
if (!array_key_exists('authBypass', $config['loginOptions'])) {
|
||||
$config['loginOptions']['authBypass'] = false;
|
||||
}
|
||||
if (!array_key_exists('authHeaderName', $config['loginOptions'])) {
|
||||
$config['loginOptions']['authHeaderName'] = 'X-Remote-User';
|
||||
}
|
||||
// ← END INSERT
|
||||
|
||||
echo json_encode($config);
|
||||
exit;
|
||||
}
|
||||
@@ -203,6 +214,12 @@ class AdminController
|
||||
$sharedMaxUploadSize = filter_var($data['features']['sharedMaxUploadSize'], FILTER_VALIDATE_INT);
|
||||
}
|
||||
|
||||
$authBypass = filter_var(
|
||||
$data['loginOptions']['authBypass'] ?? false,
|
||||
FILTER_VALIDATE_BOOLEAN
|
||||
);
|
||||
$authHeaderName = trim($data['loginOptions']['authHeaderName'] ?? '') ?: 'X-Remote-User';
|
||||
|
||||
$configUpdate = [
|
||||
'header_title' => $headerTitle,
|
||||
'oidc' => [
|
||||
@@ -215,6 +232,8 @@ class AdminController
|
||||
'disableFormLogin' => $disableFormLogin,
|
||||
'disableBasicAuth' => $disableBasicAuth,
|
||||
'disableOIDCLogin' => $disableOIDCLogin,
|
||||
'authBypass' => $authBypass,
|
||||
'authHeaderName' => $authHeaderName,
|
||||
],
|
||||
'globalOtpauthUrl' => $globalOtpauthUrl,
|
||||
'enableWebDAV' => $enableWebDAV,
|
||||
|
||||
@@ -342,48 +342,48 @@ class AuthController
|
||||
public function checkAuth(): void
|
||||
{
|
||||
|
||||
// 1) Remember-me re-login
|
||||
if (empty($_SESSION['authenticated']) && !empty($_COOKIE['remember_me_token'])) {
|
||||
$payload = AuthModel::validateRememberToken($_COOKIE['remember_me_token']);
|
||||
if ($payload) {
|
||||
$old = $_SESSION['csrf_token'] ?? bin2hex(random_bytes(32));
|
||||
session_regenerate_id(true);
|
||||
$_SESSION['csrf_token'] = $old;
|
||||
$_SESSION['authenticated'] = true;
|
||||
$_SESSION['username'] = $payload['username'];
|
||||
$_SESSION['isAdmin'] = !empty($payload['isAdmin']);
|
||||
$_SESSION['folderOnly'] = $payload['folderOnly'] ?? false;
|
||||
$_SESSION['readOnly'] = $payload['readOnly'] ?? false;
|
||||
$_SESSION['disableUpload'] = $payload['disableUpload'] ?? false;
|
||||
// regenerate CSRF if you use one
|
||||
|
||||
// 1) Remember-me re-login
|
||||
if (empty($_SESSION['authenticated']) && !empty($_COOKIE['remember_me_token'])) {
|
||||
$payload = AuthModel::validateRememberToken($_COOKIE['remember_me_token']);
|
||||
if ($payload) {
|
||||
$old = $_SESSION['csrf_token'] ?? bin2hex(random_bytes(32));
|
||||
session_regenerate_id(true);
|
||||
$_SESSION['csrf_token'] = $old;
|
||||
$_SESSION['authenticated'] = true;
|
||||
$_SESSION['username'] = $payload['username'];
|
||||
$_SESSION['isAdmin'] = !empty($payload['isAdmin']);
|
||||
$_SESSION['folderOnly'] = $payload['folderOnly'] ?? false;
|
||||
$_SESSION['readOnly'] = $payload['readOnly'] ?? false;
|
||||
$_SESSION['disableUpload'] = $payload['disableUpload'] ?? false;
|
||||
// regenerate CSRF if you use one
|
||||
|
||||
// TOTP enabled? (same logic as below)
|
||||
$usersFile = USERS_DIR . USERS_FILE;
|
||||
$totp = false;
|
||||
if (file_exists($usersFile)) {
|
||||
foreach (file($usersFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
|
||||
$parts = explode(':', trim($line));
|
||||
if ($parts[0] === $_SESSION['username'] && !empty($parts[3])) {
|
||||
$totp = true;
|
||||
break;
|
||||
|
||||
// TOTP enabled? (same logic as below)
|
||||
$usersFile = USERS_DIR . USERS_FILE;
|
||||
$totp = false;
|
||||
if (file_exists($usersFile)) {
|
||||
foreach (file($usersFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
|
||||
$parts = explode(':', trim($line));
|
||||
if ($parts[0] === $_SESSION['username'] && !empty($parts[3])) {
|
||||
$totp = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
'authenticated' => true,
|
||||
'csrf_token' => $_SESSION['csrf_token'],
|
||||
'isAdmin' => $_SESSION['isAdmin'],
|
||||
'totp_enabled' => $totp,
|
||||
'username' => $_SESSION['username'],
|
||||
'folderOnly' => $_SESSION['folderOnly'],
|
||||
'readOnly' => $_SESSION['readOnly'],
|
||||
'disableUpload' => $_SESSION['disableUpload']
|
||||
]);
|
||||
exit();
|
||||
echo json_encode([
|
||||
'authenticated' => true,
|
||||
'csrf_token' => $_SESSION['csrf_token'],
|
||||
'isAdmin' => $_SESSION['isAdmin'],
|
||||
'totp_enabled' => $totp,
|
||||
'username' => $_SESSION['username'],
|
||||
'folderOnly' => $_SESSION['folderOnly'],
|
||||
'readOnly' => $_SESSION['readOnly'],
|
||||
'disableUpload' => $_SESSION['disableUpload']
|
||||
]);
|
||||
exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$usersFile = USERS_DIR . USERS_FILE;
|
||||
|
||||
@@ -453,11 +453,11 @@ class AuthController
|
||||
if (empty($_SESSION['csrf_token'])) {
|
||||
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
|
||||
}
|
||||
|
||||
|
||||
// 2) Emit headers
|
||||
header('Content-Type: application/json');
|
||||
header('X-CSRF-Token: ' . $_SESSION['csrf_token']);
|
||||
|
||||
|
||||
// 3) Return JSON payload
|
||||
echo json_encode([
|
||||
'csrf_token' => $_SESSION['csrf_token'],
|
||||
|
||||
@@ -16,10 +16,14 @@ class AdminModel
|
||||
$unit = strtolower(substr($val, -1));
|
||||
$num = (int) rtrim($val, 'bkmgtpezyBKMGTPESY');
|
||||
switch ($unit) {
|
||||
case 'g': return $num * 1024 ** 3;
|
||||
case 'm': return $num * 1024 ** 2;
|
||||
case 'k': return $num * 1024;
|
||||
default: return $num;
|
||||
case 'g':
|
||||
return $num * 1024 ** 3;
|
||||
case 'm':
|
||||
return $num * 1024 ** 2;
|
||||
case 'k':
|
||||
return $num * 1024;
|
||||
default:
|
||||
return $num;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +67,24 @@ class AdminModel
|
||||
$configUpdate['sharedMaxUploadSize'] = $sms;
|
||||
}
|
||||
|
||||
// ── NEW: normalize authBypass & authHeaderName ─────────────────────────
|
||||
if (!isset($configUpdate['loginOptions']['authBypass'])) {
|
||||
$configUpdate['loginOptions']['authBypass'] = false;
|
||||
}
|
||||
$configUpdate['loginOptions']['authBypass'] = (bool)$configUpdate['loginOptions']['authBypass'];
|
||||
|
||||
if (
|
||||
!isset($configUpdate['loginOptions']['authHeaderName'])
|
||||
|| !is_string($configUpdate['loginOptions']['authHeaderName'])
|
||||
|| trim($configUpdate['loginOptions']['authHeaderName']) === ''
|
||||
) {
|
||||
$configUpdate['loginOptions']['authHeaderName'] = 'X-Remote-User';
|
||||
} else {
|
||||
$configUpdate['loginOptions']['authHeaderName'] =
|
||||
trim($configUpdate['loginOptions']['authHeaderName']);
|
||||
}
|
||||
// ───────────────────────────────────────────────────────────────────────────
|
||||
|
||||
// Convert configuration to JSON.
|
||||
$plainTextConfig = json_encode($configUpdate, JSON_PRETTY_PRINT);
|
||||
if ($plainTextConfig === false) {
|
||||
@@ -128,6 +150,19 @@ class AdminModel
|
||||
$config['loginOptions']['disableOIDCLogin'] = (bool)$config['loginOptions']['disableOIDCLogin'];
|
||||
}
|
||||
|
||||
if (!array_key_exists('authBypass', $config['loginOptions'])) {
|
||||
$config['loginOptions']['authBypass'] = false;
|
||||
} else {
|
||||
$config['loginOptions']['authBypass'] = (bool)$config['loginOptions']['authBypass'];
|
||||
}
|
||||
if (
|
||||
!array_key_exists('authHeaderName', $config['loginOptions'])
|
||||
|| !is_string($config['loginOptions']['authHeaderName'])
|
||||
|| trim($config['loginOptions']['authHeaderName']) === ''
|
||||
) {
|
||||
$config['loginOptions']['authHeaderName'] = 'X-Remote-User';
|
||||
}
|
||||
|
||||
// Default values for other keys
|
||||
if (!isset($config['globalOtpauthUrl'])) {
|
||||
$config['globalOtpauthUrl'] = "";
|
||||
@@ -166,4 +201,4 @@ class AdminModel
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user