Skip to content

Commit bd11e2a

Browse files
authored
Merge pull request #12 from crowdsecurity/customize-colors
user can customize public pages
2 parents a31ed90 + 2262e8d commit bd11e2a

File tree

12 files changed

+342
-18
lines changed

12 files changed

+342
-18
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
}
1010
],
1111
"require": {
12-
"crowdsec/bouncer": "^0.8.6"
12+
"crowdsec/bouncer": "^0.9.0"
1313
},
1414
"require-dev": {
1515
"bramus/monolog-colored-line-formatter": "^3.0",

composer.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/workflows.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
git checkout -b <branch-name>
55
git commit # as much as necessary.
66

7+
# If the bouncer version has been bumped
8+
# Update <project>/composer.json with the last version then:
9+
export CONTAINER_NAME=`echo "wordpress$WORDPRESS_VERSION" | tr . -`
10+
docker-compose exec $CONTAINER_NAME composer update --working-dir /var/www/html/wp-content/plugins/cs-wordpress-bouncer --prefer-source
11+
712
# Rename branch if necessary
813
git branch -m <new-name>
914
git push origin :<old-name> && git push -u origin <new-name>

inc/admin/init.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
require_once __DIR__.'/notice.php';
44

5-
require_once __DIR__.'/advanced-settings.php';
65
require_once __DIR__.'/settings.php';
6+
require_once __DIR__.'/theme.php';
7+
require_once __DIR__.'/advanced-settings.php';
78

89
add_action('admin_notices', [new AdminNotice(), 'displayAdminNotice']);
910

@@ -232,12 +233,16 @@ function addFieldSelect(string $optionName, string $label, string $optionGroup,
232233
add_menu_page('CrowdSec Plugin', 'CrowdSec', 'manage_options', 'crowdsec_plugin', function () {
233234
require_once CROWDSEC_PLUGIN_PATH.'/inc/templates/settings.php';
234235
}, 'dashicons-shield', 110);
236+
add_submenu_page('crowdsec_plugin', 'Theme customization', 'Theme customization', 'manage_options', 'crowdsec_theme_settings', function () {
237+
require_once CROWDSEC_PLUGIN_PATH.'/inc/templates/theme.php';
238+
});
235239
add_submenu_page('crowdsec_plugin', 'Advanced', 'Advanced', 'manage_options', 'crowdsec_advanced_settings', function () {
236240
require_once CROWDSEC_PLUGIN_PATH.'/inc/templates/advanced-settings.php';
237241
});
238242

239243
add_action('admin_init', function () {
240244
adminSettings();
245+
themeSettings();
241246
adminAdvancedSettings();
242247
});
243248
});

inc/admin/theme.php

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
function themeSettings()
4+
{
5+
/******************************************
6+
** Section "Captcha wall text contents" **
7+
*****************************************/
8+
9+
add_settings_section('crowdsec_theme_captcha_texts', 'Adapt the wording of the Captcha Wall', function () {
10+
echo 'You can customize the text display on the captcha wall.';
11+
}, 'crowdsec_theme_settings');
12+
13+
// Field "crowdsec_theme_text_captcha_wall_tab_title"
14+
addFieldString('crowdsec_theme_text_captcha_wall_tab_title', 'Browser tab text', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_captcha_texts', function ($input) {
15+
return $input;
16+
}, '<p>The text in the browser tab of the captcha wall page.</p>', 'Tab text', 'width: 150px;', 'text');
17+
18+
// Field "crowdsec_theme_text_captcha_wall_title"
19+
addFieldString('crowdsec_theme_text_captcha_wall_title', 'Title text', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_captcha_texts', function ($input) {
20+
return $input;
21+
}, '<p>The title text of the captcha wall page.</p>', 'Subtitle text', '', 'text');
22+
23+
// Field "crowdsec_theme_text_captcha_wall_subtitle"
24+
addFieldString('crowdsec_theme_text_captcha_wall_subtitle', 'Subtitle text', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_captcha_texts', function ($input) {
25+
return $input;
26+
}, '<p>The subtitle text of the captcha wall page.</p>', 'Subtitle text', '', 'text');
27+
28+
// Field "crowdsec_theme_text_captcha_wall_refresh_image_link"
29+
addFieldString('crowdsec_theme_text_captcha_wall_refresh_image_link', 'Refresh image text', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_captcha_texts', function ($input) {
30+
return $input;
31+
}, '<p>The "refresh image" text of the captcha wall page.</p>', 'Refresh image text', '', 'text');
32+
33+
// Field "crowdsec_theme_text_captcha_wall_captcha_placeholder"
34+
addFieldString('crowdsec_theme_text_captcha_wall_captcha_placeholder', 'Input placeholder', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_captcha_texts', function ($input) {
35+
return $input;
36+
}, '<p>The "refresh image" text of the captcha wall page.</p>', 'Captcha input placeholder', '', 'text');
37+
38+
// Field "crowdsec_theme_text_captcha_wall_send_button"
39+
addFieldString('crowdsec_theme_text_captcha_wall_send_button', 'Send button text', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_captcha_texts', function ($input) {
40+
return $input;
41+
}, '<p>The "refresh image" text of the captcha wall page.</p>', 'Send button text', '', 'text');
42+
43+
// Field "crowdsec_theme_text_captcha_wall_error_message"
44+
addFieldString('crowdsec_theme_text_captcha_wall_error_message', 'Error message', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_captcha_texts', function ($input) {
45+
return $input;
46+
}, '<p>The "error message" text of the captcha wall page when a captcha is not successfuly resolved.</p>', 'Error message', '', 'text');
47+
48+
// Field "crowdsec_theme_text_captcha_wall_footer"
49+
addFieldString('crowdsec_theme_text_captcha_wall_footer', 'Footer custom message', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_captcha_texts', function ($input) {
50+
return $input;
51+
}, '<p>You can add a custom footer text.</p>', 'Custom footer text', '', 'text');
52+
53+
/**************************************
54+
** Section "Ban wall text contents" **
55+
*************************************/
56+
57+
add_settings_section('crowdsec_theme_ban_texts', 'Adapt the wording of the Ban Wall', function () {
58+
echo 'You can customize the text display on the ban wall.';
59+
}, 'crowdsec_theme_settings');
60+
61+
// Field "crowdsec_theme_text_ban_wall_tab_title"
62+
addFieldString('crowdsec_theme_text_ban_wall_tab_title', 'Browser tab text', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_ban_texts', function ($input) {
63+
return $input;
64+
}, '<p>The text in the browser tab of the ban wall page.</p>', 'Tab text', 'width: 150px;', 'text');
65+
66+
// Field "crowdsec_theme_text_ban_wall_title"
67+
addFieldString('crowdsec_theme_text_ban_wall_title', 'Title text', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_ban_texts', function ($input) {
68+
return $input;
69+
}, '<p>The title text of the ban wall page.</p>', 'Subtitle text', '', 'text');
70+
71+
// Field "crowdsec_theme_text_ban_wall_subtitle"
72+
addFieldString('crowdsec_theme_text_ban_wall_subtitle', 'Subtitle text', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_ban_texts', function ($input) {
73+
return $input;
74+
}, '<p>The subtitle text of the ban wall page.</p>', 'Subtitle text', '', 'text');
75+
76+
// Field "crowdsec_theme_text_ban_wall_footer"
77+
addFieldString('crowdsec_theme_text_ban_wall_footer', 'Footer custom message', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_ban_texts', function ($input) {
78+
return $input;
79+
}, '<p>You can add a custom footer text.</p>', 'Custom footer text', '', 'text');
80+
81+
/**********************
82+
** Section "Colors" **
83+
*********************/
84+
85+
add_settings_section('crowdsec_theme_colors', 'Use your own colors!', function () {
86+
echo 'You can customize remediation wall colors (ban wall and captcha wall).';
87+
}, 'crowdsec_theme_settings');
88+
89+
// Field "crowdsec_theme_color_text_primary"
90+
addFieldString('crowdsec_theme_color_text_primary', 'Primary text color', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_colors', function ($input) {
91+
return $input;
92+
}, '<p>The color used for primary text on the two pages.</p>', 'CSS color', 'width: 100px;', 'text');
93+
94+
// Field "crowdsec_theme_color_text_secondary"
95+
addFieldString('crowdsec_theme_color_text_secondary', 'Secondary text color', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_colors', function ($input) {
96+
return $input;
97+
}, '<p>The color used for secondary text on the two pages.</p>', 'CSS color', 'width: 100px;', 'text');
98+
99+
// Field "crowdsec_theme_color_text_button"
100+
addFieldString('crowdsec_theme_color_text_button', 'Button text color', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_colors', function ($input) {
101+
return $input;
102+
}, '<p>The color of the text of the button on the captcha wall page.</p>', 'CSS color', 'width: 100px;', 'text');
103+
104+
// Field "crowdsec_theme_color_text_error_message"
105+
addFieldString('crowdsec_theme_color_text_error_message', 'Error message text color', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_colors', function ($input) {
106+
return $input;
107+
}, '<p>The color used for the error message (when captcha resolution failed).</p>', 'CSS color', 'width: 100px;', 'text');
108+
109+
// Field "crowdsec_theme_color_background_page"
110+
addFieldString('crowdsec_theme_color_background_page', 'Page background color', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_colors', function ($input) {
111+
return $input;
112+
}, '<p>The background color used of the two pages.</p>', 'CSS color', 'width: 100px;', 'text');
113+
114+
// Field "crowdsec_theme_color_background_container"
115+
addFieldString('crowdsec_theme_color_background_container', 'Container background color', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_colors', function ($input) {
116+
return $input;
117+
}, '<p>The background color used for the central block on the two pages</p>', 'CSS color', 'width: 100px;', 'text');
118+
119+
// Field "crowdsec_theme_color_background_button"
120+
addFieldString('crowdsec_theme_color_background_button', 'Button background color', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_colors', function ($input) {
121+
return $input;
122+
}, '<p>The background color used for the captcha validation button.</p>', 'CSS color', 'width: 100px;', 'text');
123+
124+
// Field "crowdsec_theme_color_background_button_hover"
125+
addFieldString('crowdsec_theme_color_background_button_hover', 'Button background color (hover)', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_colors', function ($input) {
126+
return $input;
127+
}, '<p>The background color used for the captcha validation button when it\'s hover.</p>', 'CSS color', 'width: 100px;', 'text');
128+
129+
/**************************
130+
** Section "Custom CSS" **
131+
*************************/
132+
133+
add_settings_section('crowdsec_theme_css', 'Use your own CSS code!', function () {
134+
echo 'You can customize remediation walls with CSS code (ban wall and captcha wall).';
135+
}, 'crowdsec_theme_settings');
136+
137+
// Field "crowdsec_theme_custom_css"
138+
addFieldString('crowdsec_theme_custom_css', 'Custom CSS code', 'crowdsec_plugin_theme_settings', 'crowdsec_theme_settings', 'crowdsec_theme_css', function ($input) {
139+
return $input;
140+
}, '<p>The CSS code to use in the remediation wall (ban wall and captcha wall).</p>', 'CSS code...', '', 'text');
141+
}

inc/bounce-current-ip.php

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,69 @@ function shouldTrustXforwardedFor(string $ip): bool
3737
function displayCaptchaWall()
3838
{
3939
header('HTTP/1.0 401 Unauthorized');
40-
echo Bouncer::getCaptchaHtmlTemplate($_SESSION['crowdsec_captcha_resolution_failed'], $_SESSION['crowdsec_captcha_inline_image'], '', !get_option('crowdsec_hide_mentions'));
40+
$config = [
41+
'hide_crowdsec_mentions' => (bool) get_option('crowdsec_hide_mentions'),
42+
'color' => [
43+
'text' => [
44+
'primary' => wp_specialchars_decode(get_option('crowdsec_theme_color_text_primary'), \ENT_QUOTES),
45+
'secondary' => wp_specialchars_decode(get_option('crowdsec_theme_color_text_secondary'), \ENT_QUOTES),
46+
'button' => wp_specialchars_decode(get_option('crowdsec_theme_color_text_button'), \ENT_QUOTES),
47+
'error_message' => wp_specialchars_decode(get_option('crowdsec_theme_color_text_error_message'), \ENT_QUOTES),
48+
],
49+
'background' => [
50+
'page' => wp_specialchars_decode(get_option('crowdsec_theme_color_background_page'), \ENT_QUOTES),
51+
'container' => wp_specialchars_decode(get_option('crowdsec_theme_color_background_container'), \ENT_QUOTES),
52+
'button' => wp_specialchars_decode(get_option('crowdsec_theme_color_background_button'), \ENT_QUOTES),
53+
'button_hover' => wp_specialchars_decode(get_option('crowdsec_theme_color_background_button_hover'), \ENT_QUOTES),
54+
],
55+
],
56+
'text' => [
57+
'captcha_wall' => [
58+
'tab_title' => wp_specialchars_decode(get_option('crowdsec_theme_text_captcha_wall_tab_title'), \ENT_QUOTES),
59+
'title' => wp_specialchars_decode(get_option('crowdsec_theme_text_captcha_wall_title'), \ENT_QUOTES),
60+
'subtitle' => wp_specialchars_decode(get_option('crowdsec_theme_text_captcha_wall_subtitle'), \ENT_QUOTES),
61+
'refresh_image_link' => wp_specialchars_decode(get_option('crowdsec_theme_text_captcha_wall_refresh_image_link'), \ENT_QUOTES),
62+
'captcha_placeholder' => wp_specialchars_decode(get_option('crowdsec_theme_text_captcha_wall_captcha_placeholder'), \ENT_QUOTES),
63+
'send_button' => wp_specialchars_decode(get_option('crowdsec_theme_text_captcha_wall_send_button'), \ENT_QUOTES),
64+
'error_message' => wp_specialchars_decode(get_option('crowdsec_theme_text_captcha_wall_error_message'), \ENT_QUOTES),
65+
'footer' => wp_specialchars_decode(get_option('crowdsec_theme_text_captcha_wall_footer'), \ENT_QUOTES),
66+
],
67+
],
68+
'custom_css' => get_option('crowdsec_theme_custom_css'),
69+
];
70+
echo Bouncer::getCaptchaHtmlTemplate($_SESSION['crowdsec_captcha_resolution_failed'], $_SESSION['crowdsec_captcha_inline_image'], '', $config);
4171
die();
4272
}
4373

4474
function handleBanRemediation()
4575
{
4676
header('HTTP/1.0 403 Forbidden');
47-
echo Bouncer::getAccessForbiddenHtmlTemplate(!get_option('crowdsec_hide_mentions'));
77+
$config = [
78+
'hide_crowdsec_mentions' => (bool) get_option('crowdsec_hide_mentions'),
79+
'color' => [
80+
'text' => [
81+
'primary' => wp_specialchars_decode(get_option('crowdsec_theme_color_text_primary', \ENT_QUOTES)),
82+
'secondary' => wp_specialchars_decode(get_option('crowdsec_theme_color_text_secondary', \ENT_QUOTES)),
83+
'error_message' => wp_specialchars_decode(get_option('crowdsec_theme_color_text_error_message', \ENT_QUOTES)),
84+
],
85+
'background' => [
86+
'page' => wp_specialchars_decode(get_option('crowdsec_theme_color_background_page', \ENT_QUOTES)),
87+
'container' => wp_specialchars_decode(get_option('crowdsec_theme_color_background_container', \ENT_QUOTES)),
88+
'button' => wp_specialchars_decode(get_option('crowdsec_theme_color_background_button', \ENT_QUOTES)),
89+
'button_hover' => wp_specialchars_decode(get_option('crowdsec_theme_color_background_button_hover', \ENT_QUOTES)),
90+
],
91+
],
92+
'text' => [
93+
'ban_wall' => [
94+
'tab_title' => wp_specialchars_decode(get_option('crowdsec_theme_text_ban_wall_tab_title', \ENT_QUOTES)),
95+
'title' => wp_specialchars_decode(get_option('crowdsec_theme_text_ban_wall_title', \ENT_QUOTES)),
96+
'subtitle' => wp_specialchars_decode(get_option('crowdsec_theme_text_ban_wall_subtitle', \ENT_QUOTES)),
97+
'footer' => wp_specialchars_decode(get_option('crowdsec_theme_text_ban_wall_footer', \ENT_QUOTES)),
98+
],
99+
],
100+
'custom_css' => wp_specialchars_decode(get_option('crowdsec_theme_custom_css', \ENT_QUOTES)),
101+
];
102+
echo Bouncer::getAccessForbiddenHtmlTemplate($config);
48103
die();
49104
}
50105

0 commit comments

Comments
 (0)