Reluma
October 28, 2022, 9:05am
1
Hi!
I’m working on a clients’ area and i follow this recipe Restricting access to your site | Kirby CMS
it works perfectly!
My idea would be to improve the plugin by extending the firewall to all the files contained in the children of the clients’ area page.
my current files-firewall/index.php plugin:
Kirby::plugin('cookbook/files-firewall', [
'routes' => [
[
'pattern' => 'clients-area/(:any)',
'action' => function ($filename) {
if (kirby()->user() &&
($page = page('clients-area')) &&
$file = $page->files()->findBy('filename', $filename)) {
return $file->download();
}
return site()->errorPage();
}
]
],
...
...
but i have no idea how to apply this to all subfolders, for example:
clients-area/child1
clients-area/child2
etc.
my idea, definitely wrong:
Kirby::plugin('cookbook/files-firewall', [
'routes' => [
[
'pattern' => 'clients-area/(:any)',
'action' => function ($filename) {
if (kirby()->user() &&
($page = page('clients-area')) &&
$file = $page->files()->findBy('filename', $filename)) {
return $file->download();
}
return site()->errorPage();
}
],
[
'pattern' => 'clients-area/(:any)/(:any)',
'action' => function ($filename2) {
if (kirby()->user() &&
($page2 = isChildOf('clients-area')) &&
$file2 = $page2->files()->findBy('filename', $filename2)) {
return $file2->download();
}
return site()->errorPage();
}
],
],
...
...
I understand that the problem is in ‘pattern’, but I am not very good with this.
do you have any suggestions for me? Thank you so much!
Since you want to get at the subpage here, you need to path to the subpage
'pattern' => 'clients-area/(:any)/(:any)',
'action' => function ($slug, $filename2) {
if (kirby()->user() &&
($page2 = page('clients-area/' . $slug)) &&
$file2 = $page2->files()->findBy('filename', $filename2)) {
return $file2->download();
}
return site()->errorPage();
}
Reluma
October 28, 2022, 9:44am
3
I think you missed a round bracket after $slug, now it works but in the child page return error page 404.
texnixe
October 28, 2022, 10:05am
4
Which child page? Do you mean that a page clients-area/something
can have children as well?
Reluma
October 28, 2022, 11:00am
5
no, clients-area has files and children. The child page of clients-area has only files.
for example
clients-area has files like document.pdf
clients-area/document.pdf
works
clients-area child has files like document.pdf
clients-area/child1/anotherdocument.pdf
now, all children return 404
texnixe
October 28, 2022, 11:21am
6
Reluma:
[
'pattern' => 'clients-area/(:any)',
'action' => function ($filename) {
if (kirby()->user() &&
($page = page('clients-area')) &&
$file = $page->files()->findBy('filename', $filename)) {
return $file->download();
}
return site()->errorPage();
}
],
That’s probably because of this route, because you send them to the error page. Instead you should check if $filename is a page, if so, return the page. Then check if $filename is a file and return the file for download. As the last step, return the error page.
Reluma
November 2, 2022, 4:31pm
7
I have made several attempts but I have not found a working solution. The one that comes closest is this, which works and protects all the files contained in the children but does not protect in reserved-area files.
‘routes’ => [
[
'pattern' => 'clients-area/(:any)/(:any)',
'action' => function ($slug, $filename) {
if (kirby()->user() &&
($page = page('clients-area/' . $slug)) &&
$file = $page->files()->findBy('filename', $filename)) {
return $file->download();
}
return site()->errorPage();
}
],
],
based on your suggestions, I had thought something like this, but doesn’t work
[
‘pattern’ => ‘clients-area/(:any)/(:any)’,
‘action’ => function ($slug, $filename) {
if (kirby()->user() && $path = page('clients-area/' . $filename)) {
return $path;
}
if (kirby()->user() &&
($page = page('clients-area')) &&
$file = $page->files()->findBy('filename', $filename)) {
return $file->download();
}
return site()->errorPage();
}
],
Reluma:
[
'pattern' => 'clients-area/(:any)',
'action' => function ($filename) {
if (kirby()->user() &&
($page = page('clients-area')) &&
$file = $page->files()->findBy('filename', $filename)) {
return $file->download();
}
return site()->errorPage();
}
],
As I wrote above, I think this route needs a change, not the one with the two placeholders.
[
'pattern' => 'clients-area/(:any)',
'action' => function ($filename) {
if ($page = page('clients-area/' . $filename)) { // maybe check for logged-in user as well if this is protected
return $page;
}
if (kirby()->user() &&
($page = page('clients-area')) &&
$file = $page->files()->findBy('filename', $filename)) {
return $file->download();
}
return site()->errorPage();
}
],
Reluma
November 3, 2022, 8:38pm
9
'routes' => [
// clients-area page
[
'pattern' => 'clients-area/(:any)',
'action' => function ($filename) {
if
(kirby()->user() && // not necessary
($page = page('clients-area/' . $filename))) {
return $page;
}
if (kirby()->user() &&
($page = page('clients-area')) &&
$file = $page->files()->findBy('filename', $filename)) {
return $file->download();
}
return site()->errorPage();
}
],
// all the clients-area children
[
'pattern' => 'clients-area/(:any)/(:any)',
'action' => function ($slug, $filename) {
if (kirby()->user() &&
($page = page('clients-area/' . $slug)) &&
$file = $page->files()->findBy('filename', $filename)) {
return $file->download();
}
return site()->errorPage();
}
],
],
thank you for your time,
this works perfectly!