Skip to content

Commit 2b6ba78

Browse files
feat(walls): Use twig for ban and captcha walls templating
1 parent e403b5a commit 2b6ba78

15 files changed

+261
-235
lines changed

.github/workflows/test-suite.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333

3434
- name: Install DDEV
3535
env:
36-
DDEV_VERSION: v1.20.0
36+
DDEV_VERSION: v1.21.1
3737
run: |
3838
# @see https://ddev.readthedocs.io/en/stable/#installationupgrade-script-linux-and-macos-armarm64-and-amd64-architectures
3939
sudo apt-get -qq update

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,10 @@
3939
}
4040
],
4141
"require": {
42-
"php": "^7.2 || ^8.0",
42+
"php": ">=7.2.5",
4343
"symfony/config": "^4.4.27 || ^5.2 || ^6.0",
4444
"symfony/cache": "^5.4.11 || ^6.0.11",
45+
"twig/twig": "^3.4.2",
4546
"monolog/monolog": "^1.17 || ^2.1",
4647
"gregwar/captcha": "^1.1",
4748
"mlocati/ip-lib": "^1.18",

docs/DEVELOPER.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@ For a quick start, follow the below steps.
7272

7373
#### DDEV installation
7474

75-
This project is fully compatible with DDEV 1.20.0, and it is recommended to use this specific version.
75+
This project is fully compatible with DDEV 1.21.1, and it is recommended to use this specific version.
7676
For the DDEV installation, please follow the [official instructions](https://ddev.readthedocs.io/en/stable/#installation).
7777
On a Linux distribution, you can run:
7878
```
7979
sudo apt-get -qq update
8080
sudo apt-get -qq -y install libnss3-tools
8181
curl -LO https://raw.githubusercontent.com/drud/ddev/master/scripts/install_ddev.sh
82-
bash install_ddev.sh v1.20.0
82+
bash install_ddev.sh v1.21.1
8383
rm install_ddev.sh
8484
```
8585

src/Bouncer.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22

33
namespace CrowdSecBouncer;
44

5-
require_once __DIR__ . '/templates/captcha.php';
6-
require_once __DIR__ . '/templates/access-forbidden.php';
7-
85
use CrowdSecBouncer\Fixes\Gregwar\Captcha\CaptchaBuilder;
96
use CrowdSecBouncer\RestClient\AbstractClient;
107
use ErrorException;
@@ -167,11 +164,9 @@ public static function getAccessForbiddenHtmlTemplate(array $config): string
167164
$configuration = new TemplateConfiguration();
168165
$processor = new Processor();
169166
$config = $processor->processConfiguration($configuration, [$config]);
167+
$template = new Template('ban.html.twig');
170168

171-
ob_start();
172-
displayAccessForbiddenTemplate($config);
173-
174-
return ob_get_clean();
169+
return $template->render($config);
175170
}
176171

177172
/**
@@ -188,11 +183,16 @@ public static function getCaptchaHtmlTemplate(
188183
$configuration = new TemplateConfiguration();
189184
$processor = new Processor();
190185
$config = $processor->processConfiguration($configuration, [$config]);
191-
192-
ob_start();
193-
displayCaptchaTemplate($error, $captchaImageSrc, $captchaResolutionFormUrl, $config);
194-
195-
return ob_get_clean();
186+
$template = new Template('captcha.html.twig');
187+
188+
return $template->render(array_merge(
189+
$config,
190+
[
191+
'error' => $error,
192+
'captcha_img' => $captchaImageSrc,
193+
'captcha_resolution_url' => $captchaResolutionFormUrl
194+
]
195+
));
196196
}
197197

198198
/**

src/Constants.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,7 @@ class Constants
105105

106106
/** @var string The "disabled" x-forwarded-for setting */
107107
public const X_FORWARDED_DISABLED = 'no_forward';
108+
109+
/** @var string Path for html templates folder (e.g. ban and captcha wall) */
110+
public const TEMPLATES_DIR = __DIR__ . "/templates";
108111
}

src/Template.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace CrowdSecBouncer;
4+
5+
use Twig\Loader\FilesystemLoader;
6+
use Twig\Environment;
7+
use Twig\TemplateWrapper;
8+
9+
/**
10+
* The template engine.
11+
*
12+
* @author CrowdSec team
13+
*
14+
* @see https://crowdsec.net CrowdSec Official Website
15+
*
16+
* @copyright Copyright (c) 2020+ CrowdSec
17+
* @license MIT License
18+
*/
19+
class Template
20+
{
21+
/** @var TemplateWrapper */
22+
private $template;
23+
24+
public function __construct(string $path, string $templatesDir = Constants::TEMPLATES_DIR, array $options = [])
25+
{
26+
$loader = new FilesystemLoader($templatesDir);
27+
$env = new Environment($loader, $options);
28+
$this->template = $env->load($path);
29+
}
30+
31+
public function render(array $config = []): string
32+
{
33+
return $this->template->render(['config' => $config]);
34+
}
35+
}

src/templates/_base.php

Lines changed: 0 additions & 148 deletions
This file was deleted.

src/templates/access-forbidden.php

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/templates/ban.html.twig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
{% include('partials/head.html.twig') with {'tab_title': config.text.ban_wall.tab_title} %}
5+
</head>
6+
<body>
7+
<div class="container">
8+
<div class="main">
9+
<h1>{{ config.text.ban_wall.title | e }}</h1>
10+
<p class="desc">{{ config.text.ban_wall.subtitle }}</p>
11+
{% if config.text.ban_wall.footer is not empty %}
12+
<p class="footer">{{ config.text.ban_wall.footer | e }}</p>
13+
{% endif %}
14+
{% if config.hide_crowdsec_mentions is empty %}
15+
{% include('partials/mentions.html.twig') %}
16+
{% endif %}
17+
</div>
18+
</div>
19+
</body>
20+
</html>

src/templates/captcha.html.twig

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
{% include('partials/head.html.twig') with {'tab_title': config.text.captcha_wall.tab_title} %}
5+
{% include('partials/captcha-js.html.twig') %}
6+
</head>
7+
<body>
8+
<div class="container">
9+
<div class="main">
10+
<h1>
11+
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="exclamation-triangle" role="img"
12+
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class="warning">
13+
<path fill="#f39b2f"
14+
d="M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"></path>
15+
</svg>
16+
{{ config.text.captcha_wall.title |e }}
17+
</h1>
18+
<p class="desc">{{ config.text.captcha_wall.subtitle |e }}</p>
19+
20+
<img src="{{ config.captcha_img }}" alt="captcha"/>
21+
<p><small><a id="refresh_link" href="#"
22+
onclick="newImage()">{{ config.text.captcha_wall.refresh_image_link |e }}</a></small></p>
23+
24+
<form method="post" id="captcha" action="#">
25+
<script>document.querySelector("#captcha").setAttribute("action", "{{config.captcha_resolution_url}}")</script>
26+
<input type="text" name="phrase" placeholder="{{ config.text.captcha_wall.captcha_placeholder |e }}" autofocus
27+
autocomplete="off"/>
28+
<input type="hidden" name="crowdsec_captcha" value="1">
29+
<input type="hidden" name="refresh" value="0" id="refresh">
30+
{% if config.error is not empty %}
31+
<p class="error">{{ config.text.captcha_wall.error_message |e }}</p>
32+
{% endif %}
33+
<button type="submit">{{ config.text.captcha_wall.send_button |e }}</button>
34+
</form>
35+
{% if config.text.ban_wall.footer is not empty %}
36+
<p class="footer">{{ config.text.ban_wall.footer | e }}</p>
37+
{% endif %}
38+
{% if config.hide_crowdsec_mentions is empty %}
39+
{% include('partials/mentions.html.twig') %}
40+
{% endif %}
41+
</div>
42+
</div>
43+
</body>
44+
</html>

0 commit comments

Comments
 (0)