I think I found a way build a files firewall. Here’s what I’ve done …
1. Content folder
Use the public folder setup to move all files of the content
folder outside of your DocumentRoot
.
2. .htaccess
Add the following .htaccess
file to the media
folder. It will redirect all file requests back to index.php
which can then be handled by Kirby.
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_URI} ^\/media\/pages
RewriteRule ^(.*) /index.php [L]
</IfModule>
3. Hooks
Use your config file or create a custom plugin to make use of the Kirby hook system. In this case I implemented a route:before hook like this.
<?php
return [
'hooks' => [
'route:before' => function ($route, $path, $method) {
if (Str::startsWith($path, 'media/pages')) {
// e.g. allow file access for all panel users
if (kirby()->user() && kirby()->user()->role()->permissions()->for('access', 'panel')) {
return $route;
}
// e.g allow file access based on a page field called myCustomToggleField
$arguments = $route->arguments();
$filepath = $arguments[0] ?? false;
if ($filepath && $filePage = page($filepath)) {
if ($filePage->myCustomToggleField()->bool()) {
return $route;
}
}
// deny access in any other case
// Header::forbidden() does not work here?!
die('Access denied');
}
}
]
]
My tests had been successful so far but …
Did I miss something? Any feedback is highly appreciated!
Thanks in advance