Integrate Dokuwiki ACL for file endpoint
This commit is contained in:
107
file.php
107
file.php
@@ -13,90 +13,35 @@ global $INPUT;
|
||||
$syntax = plugin_load('syntax', 'luxtools');
|
||||
if (!$syntax) die('plugin disabled?');
|
||||
|
||||
/**
|
||||
* Enforce a simple allowlist based access check.
|
||||
*
|
||||
* The allowlist supports entries separated by commas, whitespace or newlines.
|
||||
* - "alice" allows a specific user
|
||||
* - "@admins" allows a DokuWiki group
|
||||
*
|
||||
* If the allowlist is empty, any authenticated user is allowed.
|
||||
* Anonymous access is always denied.
|
||||
*
|
||||
* @param string $allowListRaw
|
||||
* @return void
|
||||
*/
|
||||
function luxtools_require_access(string $allowListRaw): void
|
||||
{
|
||||
global $INPUT, $USERINFO;
|
||||
|
||||
// We need a logged-in user for any access.
|
||||
$user = '';
|
||||
try {
|
||||
$user = (string)$INPUT->server->str('REMOTE_USER');
|
||||
} catch (Throwable $e) {
|
||||
$user = (string)($_SERVER['REMOTE_USER'] ?? '');
|
||||
}
|
||||
$user = trim($user);
|
||||
|
||||
if ($user === '') {
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
http_status(403);
|
||||
echo 'forbidden';
|
||||
exit;
|
||||
}
|
||||
|
||||
$allowListRaw = trim($allowListRaw);
|
||||
if ($allowListRaw === '') {
|
||||
return; // any authenticated user
|
||||
}
|
||||
|
||||
$tokens = preg_split('/[\s,;]+/', $allowListRaw, -1, PREG_SPLIT_NO_EMPTY);
|
||||
if (!is_array($tokens) || $tokens === []) {
|
||||
// If configured but empty after parsing, be conservative.
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
http_status(403);
|
||||
echo 'forbidden';
|
||||
exit;
|
||||
}
|
||||
|
||||
$groups = [];
|
||||
if (is_array($USERINFO) && isset($USERINFO['grps']) && is_array($USERINFO['grps'])) {
|
||||
$groups = $USERINFO['grps'];
|
||||
}
|
||||
|
||||
$allowed = false;
|
||||
foreach ($tokens as $t) {
|
||||
$t = trim((string)$t);
|
||||
if ($t === '') continue;
|
||||
|
||||
if ($t[0] === '@') {
|
||||
$g = trim(substr($t, 1));
|
||||
if ($g !== '' && in_array($g, $groups, true)) {
|
||||
$allowed = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if ($t === $user) {
|
||||
$allowed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$allowed) {
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
http_status(403);
|
||||
echo 'forbidden';
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$pathUtil = new Path($syntax->getConf('paths'));
|
||||
$path = $INPUT->str('root') . $INPUT->str('file');
|
||||
|
||||
// Enforce access before doing any filesystem work.
|
||||
luxtools_require_access((string)$syntax->getConf('access_allow'));
|
||||
// Require the user to be able to read the page that rendered the link.
|
||||
$pageId = (string)$INPUT->str('id');
|
||||
if (function_exists('cleanID')) {
|
||||
$pageId = (string)cleanID($pageId);
|
||||
}
|
||||
|
||||
if ($pageId === '') {
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
http_status(403);
|
||||
echo 'forbidden';
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!function_exists('auth_quickaclcheck') || !defined('AUTH_READ')) {
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
http_status(403);
|
||||
echo 'forbidden';
|
||||
exit;
|
||||
}
|
||||
|
||||
if (auth_quickaclcheck($pageId) < AUTH_READ) {
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
http_status(403);
|
||||
echo 'forbidden';
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a file to the client with basic caching headers.
|
||||
|
||||
Reference in New Issue
Block a user