diff --git a/.github/workflows/end-to-end-auto-prepend-test-suite.yml b/.github/workflows/end-to-end-auto-prepend-test-suite.yml
index 4915569..0b1e5d1 100644
--- a/.github/workflows/end-to-end-auto-prepend-test-suite.yml
+++ b/.github/workflows/end-to-end-auto-prepend-test-suite.yml
@@ -39,7 +39,7 @@ jobs:
steps:
- name: Install Magento 2 with DDEV
- uses: julienloizelet/magento2-ddev-installation@v2.1.0
+ uses: julienloizelet/magento2-ddev-installation@v2.1.1
with:
php_version: ${{ matrix.php-version }}
magento_version: ${{ matrix.m2-version }}
diff --git a/.github/workflows/end-to-end-test-suite.yml b/.github/workflows/end-to-end-test-suite.yml
index 0c86271..cacc7a9 100644
--- a/.github/workflows/end-to-end-test-suite.yml
+++ b/.github/workflows/end-to-end-test-suite.yml
@@ -44,7 +44,7 @@ jobs:
steps:
- name: Install Magento 2 with DDEV
- uses: julienloizelet/magento2-ddev-installation@v2.1.0
+ uses: julienloizelet/magento2-ddev-installation@v2.1.1
with:
php_version: ${{ matrix.php-version }}
magento_version: ${{ matrix.m2-version }}
diff --git a/.github/workflows/installation-and-varnish-test-suite.yml b/.github/workflows/installation-and-varnish-test-suite.yml
index 751e78d..d357218 100644
--- a/.github/workflows/installation-and-varnish-test-suite.yml
+++ b/.github/workflows/installation-and-varnish-test-suite.yml
@@ -42,7 +42,7 @@ jobs:
steps:
- name: Install Magento 2 with DDEV
- uses: julienloizelet/magento2-ddev-installation@v2.1.0
+ uses: julienloizelet/magento2-ddev-installation@v2.1.1
id: magento2-install
with:
php_version: ${{ matrix.php-version }}
diff --git a/.github/workflows/keepalive.yml b/.github/workflows/keepalive.yml
new file mode 100644
index 0000000..c98254c
--- /dev/null
+++ b/.github/workflows/keepalive.yml
@@ -0,0 +1,26 @@
+name: Keep Alive
+on:
+
+ schedule:
+ - cron: '0 3 * * 4'
+
+permissions:
+ contents: write
+
+jobs:
+ keep-alive:
+
+ name: Keep Alive
+ runs-on: ubuntu-latest
+
+ steps:
+
+ - name: Clone project files
+ uses: actions/checkout@v3
+
+ # keepalive-workflow adds a dummy commit if there's no other action here, keeps
+ # GitHub from turning off tests after 60 days
+ - uses: gautamkrishnar/keepalive-workflow@v1
+ with:
+ commit_message: "chore(*): Automated commit to keep the repository active"
+ time_elapsed: 50
diff --git a/.github/workflows/static-and-unit-test-suite.yml b/.github/workflows/static-and-unit-test-suite.yml
index 0bd27dd..2d98cc7 100644
--- a/.github/workflows/static-and-unit-test-suite.yml
+++ b/.github/workflows/static-and-unit-test-suite.yml
@@ -5,6 +5,8 @@ on:
- main
paths-ignore:
- '**.md'
+ schedule:
+ - cron: '25 02 * * THU'
workflow_dispatch:
permissions:
@@ -39,7 +41,7 @@ jobs:
steps:
- name: Install Magento 2 with DDEV
- uses: julienloizelet/magento2-ddev-installation@v2.1.0
+ uses: julienloizelet/magento2-ddev-installation@v2.1.1
with:
php_version: ${{ matrix.php-version }}
magento_version: ${{ matrix.m2-version }}
diff --git a/Block/Adminhtml/System/Config/Connection/Ping.php b/Block/Adminhtml/System/Config/Connection/Ping.php
index 057afa4..f7acba4 100644
--- a/Block/Adminhtml/System/Config/Connection/Ping.php
+++ b/Block/Adminhtml/System/Config/Connection/Ping.php
@@ -89,6 +89,20 @@ class Ping extends Button
*/
protected $_useCurlField = 'crowdsec_bouncer_general_connection_use_curl';
+ /**
+ * Api timeout field name
+ *
+ * @var string
+ */
+ protected $_apiTimeoutField = 'crowdsec_bouncer_general_connection_api_timeout';
+
+ /**
+ * Api connect timeout field name
+ *
+ * @var string
+ */
+ protected $_apiConnectTimeoutField = 'crowdsec_bouncer_general_connection_api_connect_timeout';
+
/** @var string */
protected $template = 'CrowdSec_Bouncer::system/config/connection/ping.phtml';
/** @var string */
@@ -174,11 +188,32 @@ public function getUseCurlField(): string
return $this->_useCurlField;
}
+ /**
+ * Get api timeout field Name
+ *
+ * @return string
+ */
+ public function getApiTimeoutField(): string
+ {
+ return $this->_apiTimeoutField;
+ }
+
+ /**
+ * Get api connect timeout field Name
+ *
+ * @return string
+ */
+ public function getApiConnectTimeoutField(): string
+ {
+ return $this->_apiConnectTimeoutField;
+ }
+
/**
* Get the button and scripts contents
*
* @param AbstractElement $element
* @return string
+ * @throws \InvalidArgumentException
*/
protected function _getElementHtml(AbstractElement $element): string
{
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d5a2684..5b8ab24 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,34 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+The [public API](https://semver.org/spec/v2.0.0.html#spec-item-1) for this project is defined by the set of
+functions provided by the module.
+
+
+## [2.1.0](https://github.com/crowdsecurity/cs-magento-bouncer/releases/tag/v2.1.0) - 2024-01-??
+[_Compare with previous release_](https://github.com/crowdsecurity/cs-magento-bouncer/compare/v2.0.0...v2.1.0)
+
+
+### Changed
+
+- Encrypt bouncer key in database
+
+### Removed
+
+- Removed Events log feature
+
+### Added
+
+- Add `api_connect_timeout` configuration for `Curl` request handler
+- Add `api_timeout` configuration
+
+### Fixed
+
+- Allow `crowdsec/symfony-cache:3.0.0` dependency to avoid composer conflict with some Magento 2.4.6 patch versions
+
+---
+
+
## [2.0.0](https://github.com/crowdsecurity/cs-magento-bouncer/releases/tag/v2.0.0) - 2023-03-23
[_Compare with previous release_](https://github.com/crowdsecurity/cs-magento-bouncer/compare/v1.5.0...v2.0.0)
diff --git a/Constants.php b/Constants.php
index 306ac6d..28bee29 100644
--- a/Constants.php
+++ b/Constants.php
@@ -33,7 +33,7 @@ class Constants extends LibConstants
{
/** @var string The last version of this library */
- public const VERSION = 'v2.0.0';
+ public const VERSION = 'v2.1.0';
/** @var string The user agent used to send request to Local API */
public const BASE_USER_AGENT = 'Magento 2 CrowdSec Bouncer/'.self::VERSION;
diff --git a/Controller/Adminhtml/System/Config/Connection/Ping.php b/Controller/Adminhtml/System/Config/Connection/Ping.php
index f08dcf2..81e6cd6 100644
--- a/Controller/Adminhtml/System/Config/Connection/Ping.php
+++ b/Controller/Adminhtml/System/Config/Connection/Ping.php
@@ -56,16 +56,18 @@ class Ping extends Action implements HttpPostActionInterface
protected $helper;
/**
+ * Constructor method.
+ *
* @param Context $context
* @param JsonFactory $resultJsonFactory
* @param RegistryBouncer $registryBouncer
* @param Helper $helper
*/
public function __construct(
- Context $context,
- JsonFactory $resultJsonFactory,
+ Context $context,
+ JsonFactory $resultJsonFactory,
RegistryBouncer $registryBouncer,
- Helper $helper
+ Helper $helper
) {
parent::__construct($context);
$this->resultJsonFactory = $resultJsonFactory;
@@ -73,6 +75,28 @@ public function __construct(
$this->helper = $helper;
}
+ /**
+ * Create main suffixe message
+ *
+ * @param string $authType
+ * @param bool $useCurl
+ * @return string
+ */
+ private function getMainSuffixeMessage(string $authType, bool $useCurl): string
+ {
+ $suffixMessageMain = ($authType === Constants::AUTH_TLS) ?
+ 'Auth type: TLS
Url: %1
Cert: %2
Key: %3
Verify peer: %4
+CA cert: %5
Use cURL: %6
Api timeout: %7' :
+ 'Auth type: Api key
Url: %1
Api key: %2
Use cURL: %3
Api timeout: %4';
+
+ if ($useCurl) {
+ $suffixMessageMain .= ($authType === Constants::AUTH_TLS) ? '
+ Api connection timeout: %8' : '
Api connection timeout: %5';
+ }
+
+ return $suffixMessageMain;
+ }
+
/**
* Test connection
*
@@ -83,7 +107,9 @@ public function execute(): Json
{
$useCurl = "";
$tlsVerifyPeer = "";
- $authType ="";
+ $authType = "";
+ $apiTimeout = "";
+ $apiConnectTimeout = "";
try {
$baseUri = $this->getRequest()->getParam('api_url');
$authType = $this->getRequest()->getParam('auth_type');
@@ -93,8 +119,13 @@ public function execute(): Json
$tlsCaCert =
($authType === Constants::AUTH_TLS) ? $this->getRequest()->getParam('tls_ca_cert_path', "") : "";
$userAgent = Constants::BASE_USER_AGENT;
- $apiKey = ($authType === Constants::AUTH_KEY) ? $this->getRequest()->getParam('bouncer_key') : "";
+ $apiKey = ($authType === Constants::AUTH_KEY) ?
+ $this->getRequest()->getParam('bouncer_key')
+ : "";
$useCurl = (bool)$this->getRequest()->getParam('use_curl', false);
+ $apiTimeout = (int)$this->getRequest()->getParam('api_timeout', Constants::API_TIMEOUT);
+ $apiConnectTimeout =
+ (int)$this->getRequest()->getParam('api_connect_timeout', Constants::API_CONNECT_TIMEOUT);
$configs = $this->helper->getBouncerConfigs();
$currentConfigs = [
'api_url' => $baseUri,
@@ -105,10 +136,12 @@ public function execute(): Json
'tls_ca_cert_path' => $this->helper->getVarFullPath($tlsCaCert),
'api_user_agent' => $userAgent,
'api_key' => $apiKey,
- 'use_curl' => $useCurl
+ 'use_curl' => $useCurl,
+ 'api_timeout' => $apiTimeout,
+ 'api_connect_timeout' => $apiConnectTimeout,
];
- $useCurl = $useCurl ? __('true') : __('false');
+ $useCurlMessage = $useCurl ? __('true') : __('false');
$tlsVerifyPeer = $tlsVerifyPeer ? __('true') : __('false');
$finalConfigs = array_merge($configs, $currentConfigs);
$bouncer = $this->registryBouncer->create([
@@ -133,19 +166,25 @@ public function execute(): Json
$resultJson = $this->resultJsonFactory->create();
+ $suffixMessageMain = $this->getMainSuffixeMessage($authType, $useCurl);
+
$suffixMessage = ($authType === Constants::AUTH_TLS) ? '
' . __(
- 'Auth type: TLS
Url: %1
Cert: %2
Key: %3
Verify peer: %4
CA cert: %5
Use cURL: %6',
+ $suffixMessageMain,
$baseUri ?? "",
$tlsCert ?? "",
$tlsKey ?? "",
$tlsVerifyPeer,
$tlsCaCert ?? "",
- $useCurl
+ $useCurlMessage ?? "",
+ $apiTimeout,
+ $apiConnectTimeout
) : '
' . __(
- 'Auth type: Api key
Url: %1
Api key: %2
Use cURL: %3',
+ $suffixMessageMain,
$baseUri ?? "",
$apiKey ?? "",
- $useCurl
+ $useCurlMessage ?? "",
+ $apiTimeout,
+ $apiConnectTimeout
);
return $resultJson->setData([
diff --git a/Event/Event.php b/Event/Event.php
deleted file mode 100644
index 8a38989..0000000
--- a/Event/Event.php
+++ /dev/null
@@ -1,130 +0,0 @@
-helper = $helper;
- }
-
- /**
- * Common data for all events
- *
- * @return array
- */
- public function getBaseData(): array
- {
- return [
- 'type' => $this->type,
- 'ip' => $this->helper->getRemoteIp(),
- 'x-forwarded-for-ip' => $this->helper->getForwarderForIp(),
- 'bouncer_agent' => Constants::BASE_USER_AGENT,
- ];
- }
-
- /**
- * Retrieve json schema from some file
- *
- * @param string $path
- * @return SchemaContract
- * @throws InvalidValue
- * @throws \Swaggest\JsonSchema\Exception
- */
- public function getJsonSchema(string $path = __DIR__ . DIRECTORY_SEPARATOR . 'event.json'): SchemaContract
- {
- if (!isset($this->jsonSchema[$path])) {
- $schemaData = json_decode("{\"\$ref\": \"file://$path\"}");
- $this->jsonSchema[$path] = Schema::import($schemaData);
- }
-
- return $this->jsonSchema[$path];
- }
-
- /**
- * Check if data event is compliant with json schema
- *
- * @param array $eventData
- * @return bool
- * @throws LogicException
- */
- public function validateEvent(array $eventData): bool
- {
- $result = false;
- try {
- $schema = $this->getJsonSchema();
- $schema->in((object)$eventData);
- $result = true;
- } catch (Exception $e) {
- $this->helper->debug('Error while validating event', [
- 'type' => 'M2_EXCEPTION_WHILE_VALIDATING_EVENT',
- 'message' => $e->getMessage(),
- 'code' => $e->getCode(),
- 'file' => $e->getFile(),
- 'line' => $e->getLine(),
- ]);
- }
-
- return $result;
- }
-}
diff --git a/Event/EventInterface.php b/Event/EventInterface.php
deleted file mode 100644
index be10fb2..0000000
--- a/Event/EventInterface.php
+++ /dev/null
@@ -1,47 +0,0 @@
- null,
'api_key' => null,
'use_curl' => null,
+ 'api_timeout' => null,
+ 'api_connect_timeout' => null,
'is_admin_enabled' => null,
'is_api_enabled' => null,
'is_debug_log' => null,
@@ -152,7 +132,6 @@ class Config extends AbstractHelper
'forced_test_forwarded_ip' => null,
'can_display_errors' => null,
'is_prod_log_disabled' => null,
- 'is_events_log_enabled' => [],
'is_stream_mode' => null,
'refresh_cron_expr' => null,
'prune_cron_expr' => null,
@@ -175,6 +154,14 @@ class Config extends AbstractHelper
'bouncing_level' => null,
'remediation_fallback' => null
];
+ /**
+ * @var DirectoryList
+ */
+ private $directoryList;
+ /**
+ * @var Json
+ */
+ private $serializer;
/**
* Data constructor.
@@ -184,8 +171,8 @@ class Config extends AbstractHelper
* @param DirectoryList $directoryList
*/
public function __construct(
- Context $context,
- Json $serializer,
+ Context $context,
+ Json $serializer,
DirectoryList $directoryList
) {
parent::__construct($context);
@@ -194,17 +181,18 @@ public function __construct(
}
/**
- * Get api url config
+ * Get display errors config
*
- * @return string
+ * @return bool
*/
- public function getApiUrl(): string
+ public function canDisplayErrors(): bool
{
- if (!isset($this->_globals['api_url'])) {
- $this->_globals['api_url'] = trim((string)$this->scopeConfig->getValue(self::XML_PATH_API_URL));
+ if (!isset($this->_globals['can_display_errors'])) {
+ $this->_globals['can_display_errors'] =
+ (bool)$this->scopeConfig->getValue(self::XML_PATH_ADVANCED_DISPLAY_ERRORS);
}
- return (string)$this->_globals['api_url'];
+ return (bool)$this->_globals['can_display_errors'];
}
/**
@@ -222,170 +210,174 @@ public function getApiAuthType(): string
}
/**
- * Get api key config
+ * Get api connection timeout config
*
- * @return string
+ * @return int
*/
- public function getApiKey(): string
+ public function getApiConnectTimeout(): int
{
- if (!isset($this->_globals['api_key'])) {
- $this->_globals['api_key'] = trim((string)$this->scopeConfig->getValue(self::XML_PATH_API_KEY));
+ if (!isset($this->_globals['api_connect_timeout'])) {
+ $this->_globals['api_connect_timeout'] = (int)$this->scopeConfig->getValue(
+ self::XML_PATH_API_CONNECT_TIMEOUT
+ );
}
- return (string)$this->_globals['api_key'];
+ return (int)$this->_globals['api_connect_timeout'];
}
/**
- * Get use curl config
+ * Get api key config
*
- * @return bool
+ * @return string
*/
- public function isUseCurl(): bool
+ public function getApiKey(): string
{
- if (!isset($this->_globals['use_curl'])) {
- $this->_globals['use_curl'] = (bool)$this->scopeConfig->getValue(self::XML_PATH_USE_CURL);
+ if (!isset($this->_globals['api_key'])) {
+ $this->_globals['api_key'] = (string)$this->scopeConfig->getValue(self::XML_PATH_API_KEY);
}
- return (bool)$this->_globals['use_curl'];
+ return (string)$this->_globals['api_key'];
}
/**
- * Get enabled config for front
+ * Get api timeout config
*
- * @return bool
+ * @return int
*/
- public function isFrontEnabled(): bool
+ public function getApiTimeout(): int
{
- if (!isset($this->_storeviews['is_front_enabled'])) {
- $this->_storeviews['is_front_enabled'] = (bool)$this->scopeConfig->getValue(
- self::XML_PATH_FRONT_ENABLED,
- ScopeInterface::SCOPE_STORE
- );
+ if (!isset($this->_globals['api_timeout'])) {
+ $this->_globals['api_timeout'] = (int)$this->scopeConfig->getValue(self::XML_PATH_API_TIMEOUT);
}
- return (bool)$this->_storeviews['is_front_enabled'];
+ return (int)$this->_globals['api_timeout'];
}
/**
- * Get enabled config for admin
+ * Get api url config
*
- * @return bool
+ * @return string
*/
- public function isAdminEnabled(): bool
+ public function getApiUrl(): string
{
- if (!isset($this->_globals['is_admin_enabled'])) {
- $this->_globals['is_admin_enabled'] = (bool)$this->scopeConfig->getValue(self::XML_PATH_ADMIN_ENABLED);
+ if (!isset($this->_globals['api_url'])) {
+ $this->_globals['api_url'] = trim((string)$this->scopeConfig->getValue(self::XML_PATH_API_URL));
}
- return (bool)$this->_globals['is_admin_enabled'];
+ return (string)$this->_globals['api_url'];
}
/**
- * Get enabled config for api
+ * Get bad ip cache duration config
*
- * @return bool
+ * @return int
*/
- public function isApiEnabled(): bool
+ public function getBadIpCacheDuration(): int
{
- if (!isset($this->_globals['is_api_enabled'])) {
- $this->_globals['is_api_enabled'] = (bool)$this->scopeConfig->getValue(self::XML_PATH_API_ENABLED);
+ if (!isset($this->_globals['bad_ip_duration'])) {
+ $this->_globals['bad_ip_duration'] = (int)$this->scopeConfig->getValue(
+ self::XML_PATH_ADVANCED_CACHE_BAD
+ );
}
- return (bool)$this->_globals['is_api_enabled'];
+ return (int)$this->_globals['bad_ip_duration'];
}
/**
- * Get debug log enabled config
+ * Get bouncing level config
*
- * @return bool
+ * @return string
*/
- public function isDebugLog(): bool
+ public function getBouncingLevel(): string
{
- if (!isset($this->_globals['is_debug_log'])) {
- $this->_globals['is_debug_log'] = (bool)$this->scopeConfig->getValue(self::XML_PATH_ADVANCED_DEBUG_LOG);
+ if (!isset($this->_storeviews['bouncing_level'])) {
+ $this->_storeviews['bouncing_level'] = $this->scopeConfig->getValue(
+ self::XML_PATH_BOUNCING_LEVEL,
+ ScopeInterface::SCOPE_STORE
+ );
}
- return (bool)$this->_globals['is_debug_log'];
+ return (string)$this->_storeviews['bouncing_level'];
}
/**
- * Get prod log deactivation config
+ * Get cache technology config
*
- * @return bool
+ * @return string
*/
- public function isProdLogDisabled(): bool
+ public function getCacheTechnology(): string
{
- if (!isset($this->_globals['is_prod_log_disabled'])) {
- $this->_globals['is_prod_log_disabled'] =
- (bool)$this->scopeConfig->getValue(self::XML_PATH_ADVANCED_DISABLE_PROD_LOG);
+ if (!isset($this->_globals['cache_technology'])) {
+ $this->_globals['cache_technology'] = (string)$this->scopeConfig->getValue(
+ self::XML_PATH_ADVANCED_CACHE_TECHNOLOGY
+ );
}
- return (bool)$this->_globals['is_prod_log_disabled'];
+ return (string)$this->_globals['cache_technology'];
}
/**
- * Get events log enabled config
+ * Get captcha cache duration config
*
- * @param string $process
- * @return bool
+ * @return int
*/
- public function isEventsLogEnabled(string $process): bool
+ public function getCaptchaCacheDuration(): int
{
- if (!isset($this->_globals['is_events_log_enabled'][$process])) {
- $enabled = (bool)$this->scopeConfig->getValue(self::XML_PATH_EVENTS_LOG_ROOT . 'enabled');
- $this->_globals['is_events_log_enabled'][$process] =
- $enabled && $this->scopeConfig->getValue(self::XML_PATH_EVENTS_LOG_ROOT . $process);
+ if (!isset($this->_globals['captcha_duration'])) {
+ $this->_globals['captcha_duration'] = (int)$this->scopeConfig->getValue(
+ self::XML_PATH_ADVANCED_CACHE_CAPTCHA
+ );
}
- return (bool)$this->_globals['is_events_log_enabled'][$process];
+ return (int)$this->_globals['captcha_duration'];
}
/**
- * Get display errors config
+ * Get clean ip cache duration config
*
- * @return bool
+ * @return int
*/
- public function canDisplayErrors(): bool
+ public function getCleanIpCacheDuration(): int
{
- if (!isset($this->_globals['can_display_errors'])) {
- $this->_globals['can_display_errors'] =
- (bool)$this->scopeConfig->getValue(self::XML_PATH_ADVANCED_DISPLAY_ERRORS);
+ if (!isset($this->_globals['clean_ip_duration'])) {
+ $this->_globals['clean_ip_duration'] = (int)$this->scopeConfig->getValue(
+ self::XML_PATH_ADVANCED_CACHE_CLEAN
+ );
}
- return (bool)$this->_globals['can_display_errors'];
+ return (int)$this->_globals['clean_ip_duration'];
}
/**
- * Get bouncing level config
+ * Get forced test forwarded ip config
*
* @return string
*/
- public function getBouncingLevel(): string
+ public function getForcedTestForwardedIp(): string
{
- if (!isset($this->_storeviews['bouncing_level'])) {
- $this->_storeviews['bouncing_level'] = $this->scopeConfig->getValue(
- self::XML_PATH_BOUNCING_LEVEL,
- ScopeInterface::SCOPE_STORE
+ if (!isset($this->_globals['forced_test_forwarded_ip'])) {
+ $this->_globals['forced_test_forwarded_ip'] = (string)$this->scopeConfig->getValue(
+ self::XML_PATH_ADVANCED_FORCED_TEST_FWD_IP
);
}
- return (string)$this->_storeviews['bouncing_level'];
+ return (string)$this->_globals['forced_test_forwarded_ip'];
}
/**
- * Get the absolute path of a var file
+ * Get forced test ip config
*
- * @param string $relativePath
* @return string
- * @throws BouncerException
*/
- public function getVarFullPath(string $relativePath): string
+ public function getForcedTestIp(): string
{
- try {
- return $this->directoryList->getPath(DirectoryList::VAR_DIR) . '/' . ltrim($relativePath, '/');
- } catch (Exception $e) {
- throw new BouncerException($e->getMessage());
+ if (!isset($this->_globals['forced_test_ip'])) {
+ $this->_globals['forced_test_ip'] = (string)$this->scopeConfig->getValue(
+ self::XML_PATH_ADVANCED_FORCED_TEST_IP
+ );
}
+
+ return (string)$this->_globals['forced_test_ip'];
}
/**
@@ -421,78 +413,67 @@ public function getGeolocation(): array
}
/**
- * Get TLS authentication config
+ * Get geolocation cache duration config
*
- * @return array
- * @throws BouncerException
+ * @return int
*/
- public function getTLS(): array
+ public function getGeolocationCacheDuration(): int
{
- if (!isset($this->_globals['tls'])) {
-
- $result = [
- 'tls_cert_path' => $this->getVarFullPath(
- (string)$this->scopeConfig->getValue(self::XML_PATH_API_TLS_CERT)
- ),
- 'tls_key_path' => $this->getVarFullPath(
- (string)$this->scopeConfig->getValue(self::XML_PATH_API_TLS_KEY)
- ),
- 'tls_verify_peer' => (bool)$this->scopeConfig->getValue(self::XML_PATH_API_TLS_VERIFY_PEER),
- 'tls_ca_cert_path' => $this->getVarFullPath(
- (string)$this->scopeConfig->getValue(self::XML_PATH_API_TLS_CA_CERT)
- )
- ];
-
- $this->_globals['tls'] = $result;
+ if (!isset($this->_globals['geolocation_duration'])) {
+ $this->_globals['geolocation_duration'] = (int)$this->scopeConfig->getValue(
+ self::XML_PATH_ADVANCED_CACHE_GEO
+ );
}
- return (array)$this->_globals['tls'];
+ return (int)$this->_globals['geolocation_duration'];
}
/**
- * Get forced test ip config
+ * Get Memcached DSN config
*
* @return string
*/
- public function getForcedTestIp(): string
+ public function getMemcachedDSN(): string
{
- if (!isset($this->_globals['forced_test_ip'])) {
- $this->_globals['forced_test_ip'] = (string)$this->scopeConfig->getValue(
- self::XML_PATH_ADVANCED_FORCED_TEST_IP
+ if (!isset($this->_globals['memcached_dsn'])) {
+ $this->_globals['memcached_dsn'] = (string)$this->scopeConfig->getValue(
+ self::XML_PATH_ADVANCED_CACHE_MEMCACHED_DSN
);
}
- return (string)$this->_globals['forced_test_ip'];
+ return (string)$this->_globals['memcached_dsn'];
}
/**
- * Get forced test forwarded ip config
+ * Get pruning cron schedule expression config
*
* @return string
*/
- public function getForcedTestForwardedIp(): string
+ public function getPruneCronExpr(): string
{
- if (!isset($this->_globals['forced_test_forwarded_ip'])) {
- $this->_globals['forced_test_forwarded_ip'] = (string)$this->scopeConfig->getValue(
- self::XML_PATH_ADVANCED_FORCED_TEST_FWD_IP
+ if (!isset($this->_globals['prune_cron_expr'])) {
+ $this->_globals['prune_cron_expr'] = (string)$this->scopeConfig->getValue(
+ self::XML_PATH_ADVANCED_PRUNE_CRON_EXPR
);
}
- return (string)$this->_globals['forced_test_forwarded_ip'];
+ return (string)$this->_globals['prune_cron_expr'];
}
/**
- * Get stream mode config
+ * Get Redis DSN config
*
- * @return bool
+ * @return string
*/
- public function isStreamModeEnabled(): bool
+ public function getRedisDSN(): string
{
- if (!isset($this->_globals['is_stream_mode'])) {
- $this->_globals['is_stream_mode'] = (bool)$this->scopeConfig->getValue(self::XML_PATH_ADVANCED_MODE_STREAM);
+ if (!isset($this->_globals['redis_dsn'])) {
+ $this->_globals['redis_dsn'] = (string)$this->scopeConfig->getValue(
+ self::XML_PATH_ADVANCED_CACHE_REDIS_DSN
+ );
}
- return (bool)$this->_globals['is_stream_mode'];
+ return (string)$this->_globals['redis_dsn'];
}
/**
@@ -512,165 +493,183 @@ public function getRefreshCronExpr(): string
}
/**
- * Get pruning cron schedule expression config
+ * Get bouncing level config
*
* @return string
*/
- public function getPruneCronExpr(): string
+ public function getRemediationFallback(): string
{
- if (!isset($this->_globals['prune_cron_expr'])) {
- $this->_globals['prune_cron_expr'] = (string)$this->scopeConfig->getValue(
- self::XML_PATH_ADVANCED_PRUNE_CRON_EXPR
+ if (!isset($this->_storeviews['remediation_fallback'])) {
+ $this->_storeviews['remediation_fallback'] = $this->scopeConfig->getValue(
+ self::XML_PATH_ADVANCED_REMEDIATION_FALLBACK,
+ ScopeInterface::SCOPE_STORE
);
}
- return (string)$this->_globals['prune_cron_expr'];
+ return (string)$this->_storeviews['remediation_fallback'];
}
/**
- * Get cache technology config
+ * Get TLS authentication config
*
- * @return string
+ * @return array
+ * @throws BouncerException
*/
- public function getCacheTechnology(): string
+ public function getTLS(): array
{
- if (!isset($this->_globals['cache_technology'])) {
- $this->_globals['cache_technology'] = (string)$this->scopeConfig->getValue(
- self::XML_PATH_ADVANCED_CACHE_TECHNOLOGY
- );
+ if (!isset($this->_globals['tls'])) {
+ $result = [
+ 'tls_cert_path' => $this->getVarFullPath(
+ (string)$this->scopeConfig->getValue(self::XML_PATH_API_TLS_CERT)
+ ),
+ 'tls_key_path' => $this->getVarFullPath(
+ (string)$this->scopeConfig->getValue(self::XML_PATH_API_TLS_KEY)
+ ),
+ 'tls_verify_peer' => (bool)$this->scopeConfig->getValue(self::XML_PATH_API_TLS_VERIFY_PEER),
+ 'tls_ca_cert_path' => $this->getVarFullPath(
+ (string)$this->scopeConfig->getValue(self::XML_PATH_API_TLS_CA_CERT)
+ )
+ ];
+
+ $this->_globals['tls'] = $result;
}
- return (string)$this->_globals['cache_technology'];
+ return (array)$this->_globals['tls'];
}
/**
- * Get Redis DSN config
+ * Get trusted forwarded ips config
*
- * @return string
+ * @return array
+ * @throws InvalidArgumentException
*/
- public function getRedisDSN(): string
+ public function getTrustedForwardedIps(): array
{
- if (!isset($this->_globals['redis_dsn'])) {
- $this->_globals['redis_dsn'] = (string)$this->scopeConfig->getValue(
- self::XML_PATH_ADVANCED_CACHE_REDIS_DSN
- );
+ if (!isset($this->_globals['trusted_forwarded_ip'])) {
+ $trustedForwardedIps = $this->scopeConfig->getValue(self::TRUSTED_FORWARD_IPS_PATH);
+
+ $this->_globals['trusted_forwarded_ip'] =
+ !empty($trustedForwardedIps) ? $this->serializer->unserialize($trustedForwardedIps) : [];
}
- return (string)$this->_globals['redis_dsn'];
+ return (array)$this->_globals['trusted_forwarded_ip'];
}
/**
- * Get Memcached DSN config
+ * Get the absolute path of a var file
*
+ * @param string $relativePath
* @return string
+ * @throws BouncerException
*/
- public function getMemcachedDSN(): string
+ public function getVarFullPath(string $relativePath): string
{
- if (!isset($this->_globals['memcached_dsn'])) {
- $this->_globals['memcached_dsn'] = (string)$this->scopeConfig->getValue(
- self::XML_PATH_ADVANCED_CACHE_MEMCACHED_DSN
- );
+ try {
+ return $this->directoryList->getPath(DirectoryList::VAR_DIR) . '/' . ltrim($relativePath, '/');
+ } catch (Exception $e) {
+ throw new BouncerException($e->getMessage());
}
-
- return (string)$this->_globals['memcached_dsn'];
}
/**
- * Get clean ip cache duration config
+ * Get enabled config for admin
*
- * @return int
+ * @return bool
*/
- public function getCleanIpCacheDuration(): int
+ public function isAdminEnabled(): bool
{
- if (!isset($this->_globals['clean_ip_duration'])) {
- $this->_globals['clean_ip_duration'] = (int)$this->scopeConfig->getValue(
- self::XML_PATH_ADVANCED_CACHE_CLEAN
- );
+ if (!isset($this->_globals['is_admin_enabled'])) {
+ $this->_globals['is_admin_enabled'] = (bool)$this->scopeConfig->getValue(self::XML_PATH_ADMIN_ENABLED);
}
- return (int)$this->_globals['clean_ip_duration'];
+ return (bool)$this->_globals['is_admin_enabled'];
}
/**
- * Get bad ip cache duration config
+ * Get enabled config for api
*
- * @return int
+ * @return bool
*/
- public function getBadIpCacheDuration(): int
+ public function isApiEnabled(): bool
{
- if (!isset($this->_globals['bad_ip_duration'])) {
- $this->_globals['bad_ip_duration'] = (int)$this->scopeConfig->getValue(
- self::XML_PATH_ADVANCED_CACHE_BAD
- );
+ if (!isset($this->_globals['is_api_enabled'])) {
+ $this->_globals['is_api_enabled'] = (bool)$this->scopeConfig->getValue(self::XML_PATH_API_ENABLED);
}
- return (int)$this->_globals['bad_ip_duration'];
+ return (bool)$this->_globals['is_api_enabled'];
}
/**
- * Get captcha cache duration config
+ * Get debug log enabled config
*
- * @return int
+ * @return bool
*/
- public function getCaptchaCacheDuration(): int
+ public function isDebugLog(): bool
{
- if (!isset($this->_globals['captcha_duration'])) {
- $this->_globals['captcha_duration'] = (int)$this->scopeConfig->getValue(
- self::XML_PATH_ADVANCED_CACHE_CAPTCHA
- );
+ if (!isset($this->_globals['is_debug_log'])) {
+ $this->_globals['is_debug_log'] = (bool)$this->scopeConfig->getValue(self::XML_PATH_ADVANCED_DEBUG_LOG);
}
- return (int)$this->_globals['captcha_duration'];
+ return (bool)$this->_globals['is_debug_log'];
}
/**
- * Get geolocation cache duration config
+ * Get enabled config for front
*
- * @return int
+ * @return bool
*/
- public function getGeolocationCacheDuration(): int
+ public function isFrontEnabled(): bool
{
- if (!isset($this->_globals['geolocation_duration'])) {
- $this->_globals['geolocation_duration'] = (int)$this->scopeConfig->getValue(
- self::XML_PATH_ADVANCED_CACHE_GEO
+ if (!isset($this->_storeviews['is_front_enabled'])) {
+ $this->_storeviews['is_front_enabled'] = (bool)$this->scopeConfig->getValue(
+ self::XML_PATH_FRONT_ENABLED,
+ ScopeInterface::SCOPE_STORE
);
}
- return (int)$this->_globals['geolocation_duration'];
+ return (bool)$this->_storeviews['is_front_enabled'];
}
/**
- * Get bouncing level config
+ * Get prod log deactivation config
*
- * @return string
+ * @return bool
*/
- public function getRemediationFallback(): string
+ public function isProdLogDisabled(): bool
{
- if (!isset($this->_storeviews['remediation_fallback'])) {
- $this->_storeviews['remediation_fallback'] = $this->scopeConfig->getValue(
- self::XML_PATH_ADVANCED_REMEDIATION_FALLBACK,
- ScopeInterface::SCOPE_STORE
- );
+ if (!isset($this->_globals['is_prod_log_disabled'])) {
+ $this->_globals['is_prod_log_disabled'] =
+ (bool)$this->scopeConfig->getValue(self::XML_PATH_ADVANCED_DISABLE_PROD_LOG);
}
- return (string)$this->_storeviews['remediation_fallback'];
+ return (bool)$this->_globals['is_prod_log_disabled'];
}
/**
- * Get trusted forwarded ips config
+ * Get stream mode config
*
- * @return array
- * @throws InvalidArgumentException
+ * @return bool
*/
- public function getTrustedForwardedIps(): array
+ public function isStreamModeEnabled(): bool
{
- if (!isset($this->_globals['trusted_forwarded_ip'])) {
- $trustedForwardedIps = $this->scopeConfig->getValue(self::TRUSTED_FORWARD_IPS_PATH);
+ if (!isset($this->_globals['is_stream_mode'])) {
+ $this->_globals['is_stream_mode'] = (bool)$this->scopeConfig->getValue(self::XML_PATH_ADVANCED_MODE_STREAM);
+ }
- $this->_globals['trusted_forwarded_ip'] =
- !empty($trustedForwardedIps) ? $this->serializer->unserialize($trustedForwardedIps) : [];
+ return (bool)$this->_globals['is_stream_mode'];
+ }
+
+ /**
+ * Get use curl config
+ *
+ * @return bool
+ */
+ public function isUseCurl(): bool
+ {
+ if (!isset($this->_globals['use_curl'])) {
+ $this->_globals['use_curl'] = (bool)$this->scopeConfig->getValue(self::XML_PATH_USE_CURL);
}
- return (array)$this->_globals['trusted_forwarded_ip'];
+ return (bool)$this->_globals['use_curl'];
}
}
diff --git a/Helper/Data.php b/Helper/Data.php
index 1faaee0..08bdee0 100644
--- a/Helper/Data.php
+++ b/Helper/Data.php
@@ -33,7 +33,6 @@
use LogicException;
use Magento\Framework\App\Helper\Context;
use Magento\Framework\App\Area;
-use Magento\Framework\Exception\FileSystemException;
use Magento\Store\Model\ScopeInterface;
use CrowdSec\Bouncer\Logger\Logger;
use CrowdSec\Bouncer\Logger\Handlers\DebugFactory as DebugHandler;
@@ -135,7 +134,7 @@ public function error($message, array $context = []): void
*
* @return array
* @throws LogicException
- * @throws FileSystemException|BouncerException
+ * @throws BouncerException
*/
public function getBouncerConfigs(): array
{
@@ -154,7 +153,8 @@ public function getBouncerConfigs(): array
'api_key' => $this->getApiKey(),
'user_agent_version' => Constants::VERSION,
'user_agent_suffix' => 'Magento2',
- 'api_timeout' => Constants::API_TIMEOUT,
+ 'api_timeout' => $this->getApiTimeout(),
+ 'api_connect_timeout' => $this->getApiConnectTimeout(),
'use_curl' => $this->isUseCurl(),
// Debug
'debug_mode' => $this->isDebugLog(),
diff --git a/Helper/Event.php b/Helper/Event.php
deleted file mode 100644
index 6404729..0000000
--- a/Helper/Event.php
+++ /dev/null
@@ -1,74 +0,0 @@
-_eventLogger = $eventLogger;
- }
-
- /**
- * Event Loger getter
- *
- * @return EventLogger
- */
- public function getEventLogger(): EventLogger
- {
- return $this->_eventLogger;
- }
-}
diff --git a/Logger/EventLogger.php b/Logger/EventLogger.php
deleted file mode 100644
index 05768f8..0000000
--- a/Logger/EventLogger.php
+++ /dev/null
@@ -1,32 +0,0 @@
-response) {
$noCacheControl = 'no-store, no-cache, must-revalidate, max-age=0,post-check=0, pre-check=0';
diff --git a/Observer/Customer.php b/Observer/Customer.php
deleted file mode 100644
index a1cec22..0000000
--- a/Observer/Customer.php
+++ /dev/null
@@ -1,73 +0,0 @@
- (string)$customer->getId()] : [];
- }
-
- /**
- * Event observer execution
- *
- * @param Observer $observer
- * @return $this
- * @throws LogicException
- */
- public function execute(Observer $observer): Customer
- {
- if ($this->helper->isEventsLogEnabled($this->process)) {
- $customer = $observer->getCustomer();
- $baseData = $this->getBaseData();
- $dataObjects = ['customer' => $customer];
- $eventData = $this->getEventData($dataObjects);
- $finalData = array_merge($baseData, $eventData);
- if ($this->validateEvent($finalData)) {
- $this->helper->getEventLogger()->info('', $finalData);
- }
-
- }
-
- return $this;
- }
-}
diff --git a/Observer/Customer/Login.php b/Observer/Customer/Login.php
deleted file mode 100644
index c44d676..0000000
--- a/Observer/Customer/Login.php
+++ /dev/null
@@ -1,43 +0,0 @@
- (string) $order->getIncrementId(),
- 'customer_id' => (string) $order->getCustomerId(),
- 'quote_id' => (string) $order->getQuoteId(),
- ] : [];
- }
-
- /**
- * Event observer execution
- *
- * @param Observer $observer
- * @return $this
- * @throws LogicException
- */
- public function execute(Observer $observer): Order
- {
- if ($this->helper->isEventsLogEnabled($this->process)) {
- $order = $observer->getOrder();
- $baseData = $this->getBaseData();
- $dataObjects = ['order' => $order];
- $eventData = $this->getEventData($dataObjects);
- $finalData = array_merge($baseData, $eventData);
- if ($this->validateEvent($finalData)) {
- $this->helper->getEventLogger()->info('', $finalData);
- }
- }
-
- return $this;
- }
-}
diff --git a/Observer/Order/PlaceAfter.php b/Observer/Order/PlaceAfter.php
deleted file mode 100644
index c859d73..0000000
--- a/Observer/Order/PlaceAfter.php
+++ /dev/null
@@ -1,43 +0,0 @@
- $payment->getMethod()] : [];
- }
-
- /**
- * Event observer execution
- *
- * @param Observer $observer
- * @return $this
- * @throws LogicException
- */
- public function execute(Observer $observer): Payment
- {
- if ($this->helper->isEventsLogEnabled($this->process)) {
- $payment = $observer->getPayment();
- $baseData = $this->getBaseData();
- $dataObjects = ['payment' => $payment];
- $eventData = $this->getEventData($dataObjects);
- $finalData = array_merge($baseData, $eventData);
- if ($this->validateEvent($finalData)) {
- $this->helper->getEventLogger()->info('', $finalData);
- }
- }
-
- return $this;
- }
-}
diff --git a/Observer/Payment/PlaceEnd.php b/Observer/Payment/PlaceEnd.php
deleted file mode 100644
index d094447..0000000
--- a/Observer/Payment/PlaceEnd.php
+++ /dev/null
@@ -1,43 +0,0 @@
- (string) $product->getId()] : [];
- $quoteItemData = $quoteItem ? ['quote_id' => (string) $quoteItem->getQuoteId()] : [];
-
- return array_merge($productData, $quoteItemData);
- }
-
- /**
- * Event observer execution
- *
- * @param Observer $observer
- * @return $this
- * @throws LogicException
- */
- public function execute(Observer $observer): Quote
- {
- if ($this->helper->isEventsLogEnabled($this->process)) {
- $product = $observer->getProduct();
- $quoteItem = $observer->getQuoteItem();
- $baseData = $this->getBaseData();
- $dataObjects = ['product' => $product, 'quote_item' => $quoteItem];
- $eventData = $this->getEventData($dataObjects);
- $finalData = array_merge($baseData, $eventData);
- if ($this->validateEvent($finalData)) {
- $this->helper->getEventLogger()->info('', $finalData);
- }
- }
-
- return $this;
- }
-}
diff --git a/Observer/Quote/AddProductAfter.php b/Observer/Quote/AddProductAfter.php
deleted file mode 100644
index c52b77e..0000000
--- a/Observer/Quote/AddProductAfter.php
+++ /dev/null
@@ -1,42 +0,0 @@
-helper->isEventsLogEnabled($this->process)) {
- $baseData = $this->getBaseData();
- $eventData = $this->getEventData();
- $finalData = array_merge($baseData, $eventData);
- if ($this->validateEvent($finalData)) {
- $this->helper->getEventLogger()->info('', $finalData);
- }
- }
-
- return $this;
- }
-}
diff --git a/Observer/User/LoginFailed.php b/Observer/User/LoginFailed.php
deleted file mode 100644
index 8c6a1b8..0000000
--- a/Observer/User/LoginFailed.php
+++ /dev/null
@@ -1,42 +0,0 @@
-messageManager = $messageManager;
$this->helper = $helper;
@@ -98,9 +98,9 @@ public function __construct(
* @return array[]
* @throws BouncerException
*/
- protected function _getTLS($subject, $isTLS)
+ protected function _getTLS($subject, $isTLS): array
{
- $result = ['old'=>[], 'new' => []];
+ $result = ['old' => [], 'new' => []];
if ($isTLS) {
$oldTls = $this->helper->getTLS();
$oldTlsCert = $oldTls['tls_cert_path'];
@@ -128,7 +128,6 @@ protected function _getTLS($subject, $isTLS)
];
$result['old'] = $oldTls;
-
}
return $result;
@@ -282,10 +281,10 @@ private function getCurrentValue($subject, $saved)
* @throws BouncerException|CacheException
*/
public function _handleStreamMode(
- bool $oldStreamMode,
- bool $newStreamMode,
- bool $refreshCronExprChanged,
- bool $cacheChanged,
+ bool $oldStreamMode,
+ bool $newStreamMode,
+ bool $refreshCronExprChanged,
+ bool $cacheChanged,
string $newCacheSystem,
string $newRedisDsn,
string $newMemcachedDsn,
@@ -329,10 +328,10 @@ public function _handleStreamMode(
* @throws CacheException
*/
protected function _handleRefresh(
- bool $oldStreamMode,
- bool $newStreamMode,
- bool $refreshCronExprChanged,
- bool $cacheChanged,
+ bool $oldStreamMode,
+ bool $newStreamMode,
+ bool $refreshCronExprChanged,
+ bool $cacheChanged,
string $newCacheSystem,
string $newRedisDsn,
string $newMemcachedDsn,
@@ -367,9 +366,9 @@ protected function _handleRefresh(
* @throws BouncerException
*/
protected function _handleRefreshCronExpr(
- bool $oldStreamMode,
- bool $newStreamMode,
- bool $cronExprChanged,
+ bool $oldStreamMode,
+ bool $newStreamMode,
+ bool $cronExprChanged,
string $newCronExpr
) {
if ($oldStreamMode !== $newStreamMode && $newStreamMode === false && $newCronExpr !== self::CRON_DISABLE) {
@@ -390,7 +389,7 @@ protected function _handleRefreshCronExpr(
$this->helper->validateCronExpr($newCronExpr);
} catch (Exception $e) {
$this->messageManager->getMessages(true);
- throw new BouncerException("Refresh cron expression ($newCronExpr) is not valid: ". $e->getMessage());
+ throw new BouncerException("Refresh cron expression ($newCronExpr) is not valid: " . $e->getMessage());
}
}
}
@@ -408,7 +407,7 @@ protected function _handleRefreshCronExpr(
protected function _handlePruneCronExpr(
string $oldCacheSystem,
string $newCacheSystem,
- bool $cronExprChanged,
+ bool $cronExprChanged,
string $newCronExpr
) {
if ($oldCacheSystem !== $newCacheSystem &&
@@ -431,7 +430,7 @@ protected function _handlePruneCronExpr(
$this->helper->validateCronExpr($newCronExpr);
} catch (Exception $e) {
$this->messageManager->getMessages(true);
- throw new BouncerException("Pruning cron expression ($newCronExpr) is not valid: ". $e->getMessage());
+ throw new BouncerException("Pruning cron expression ($newCronExpr) is not valid: " . $e->getMessage());
}
}
}
@@ -450,12 +449,12 @@ protected function _handleConnectionChanges(
) {
// Test connection if params changed
if ($oldConnection != $newConnection && !empty($newConnection['api_url'])) {
- $finalApiKey = $newConnection['api_key']??"";
- $finalCert = $newConnection['tls']['tls_cert_path']??"";
- $finalKey = $newConnection['tls']['tls_key_path']??"" ;
- $finalVerify = $newConnection['tls']['tls_verify_peer']??false;
- $finalCaCert = $newConnection['tls']['tls_ca_cert_path']??"";
- $finalUseCurl = $newConnection['use_curl']??false;
+ $finalApiKey = $newConnection['api_key'] ?? "";
+ $finalCert = $newConnection['tls']['tls_cert_path'] ?? "";
+ $finalKey = $newConnection['tls']['tls_key_path'] ?? "";
+ $finalVerify = $newConnection['tls']['tls_verify_peer'] ?? false;
+ $finalCaCert = $newConnection['tls']['tls_ca_cert_path'] ?? "";
+ $finalUseCurl = $newConnection['use_curl'] ?? false;
try {
$configs = $this->helper->getBouncerConfigs();
$currentConfigs = [
@@ -480,10 +479,10 @@ protected function _handleConnectionChanges(
$message = 'Connection test failed with
auth_type=' . $newConnection['auth_type']
. '
url=' . $newConnection['api_url']
. '
use curl=' . (!empty($finalUseCurl) ? 'true' : 'false')
- . '
api key=' . ($finalApiKey ?? "")
+ . '
api key=******'
. '
tls cert path=' . ($finalCert ?? "")
. '
tls key path=' . ($finalKey ?? "")
- . '
tls ca cert path=' . ($finalCaCert?? "")
+ . '
tls ca cert path=' . ($finalCaCert ?? "")
. '
tls verify peer=' . (!empty($finalVerify) ? 'true' : 'false')
. '
: ';
throw new BouncerException($message . $e->getMessage());
@@ -504,8 +503,8 @@ protected function _handleConnectionChanges(
* @throws LogicException
*/
protected function _handleNewClearCache(
- bool $oldStreamMode,
- bool $newStreamMode,
+ bool $oldStreamMode,
+ bool $newStreamMode,
string $newCacheSystem,
string $newRedisDsn,
string $newMemcachedDsn,
@@ -536,7 +535,7 @@ protected function _handleNewClearCache(
* @throws LogicException
*/
protected function _handleOldClearCache(
- bool $cacheChanged,
+ bool $cacheChanged,
string $oldCacheSystem,
string $oldMemcachedDsn,
string $oldRedisDsn,
@@ -558,7 +557,7 @@ protected function _handleOldClearCache(
* @throws InvalidArgumentException|LogicException|BouncerException
*/
protected function _handleTestCache(
- bool $cacheChanged,
+ bool $cacheChanged,
string $cacheSystem,
string $memcachedDsn,
string $redisDsn,
@@ -726,7 +725,7 @@ private function hasDsnChanged(
* @return void
*/
private function displayCacheClearMessage(
- bool $clearCacheResult,
+ bool $clearCacheResult,
Phrase $cacheLabel,
Phrase $preMessage = null
): void {
diff --git a/Plugin/Customer/AccountCreatePostController.php b/Plugin/Customer/AccountCreatePostController.php
deleted file mode 100644
index 3ed5ee6..0000000
--- a/Plugin/Customer/AccountCreatePostController.php
+++ /dev/null
@@ -1,81 +0,0 @@
-helper->isEventsLogEnabled($this->process)) {
- $baseData = $this->getBaseData();
- $eventData = $this->getEventData();
- $finalData = array_merge($baseData, $eventData);
- if ($this->validateEvent($finalData)) {
- $this->helper->getEventLogger()->info('', $finalData);
- }
- }
- }
-}
diff --git a/Plugin/Customer/AccountManagement.php b/Plugin/Customer/AccountManagement.php
deleted file mode 100644
index c7651ec..0000000
--- a/Plugin/Customer/AccountManagement.php
+++ /dev/null
@@ -1,80 +0,0 @@
-helper->isEventsLogEnabled($this->process)) {
- $baseData = $this->getBaseData();
- $eventData = $this->getEventData();
- $finalData = array_merge($baseData, $eventData);
- if ($this->validateEvent($finalData)) {
- $this->helper->getEventLogger()->info('', $finalData);
- }
- }
- }
-}
diff --git a/Setup/Patch/Data/EncryptBouncerKey.php b/Setup/Patch/Data/EncryptBouncerKey.php
new file mode 100644
index 0000000..a78c427
--- /dev/null
+++ b/Setup/Patch/Data/EncryptBouncerKey.php
@@ -0,0 +1,82 @@
+encryptor = $encryptor;
+ $this->moduleDataSetup = $moduleDataSetup;
+ }
+
+ /**
+ * Apply patch.
+ *
+ * @return void
+ */
+ public function apply()
+ {
+ $bouncerKeyPath = Config::XML_PATH_API_KEY;
+ $configTable = $this->moduleDataSetup->getTable('core_config_data');
+ $select = $this->moduleDataSetup->getConnection()->select()
+ ->from($configTable)
+ ->where('path = ?', $bouncerKeyPath);
+ $config = $this->moduleDataSetup->getConnection()->fetchAll($select);
+ if (!empty($config)) {
+ $value = $config[0]['value'] ?? '';
+ if ($value) {
+ $this->moduleDataSetup->getConnection()->update(
+ $configTable,
+ ['value' => $this->encryptor->encrypt($value)],
+ ['path = ?' => $bouncerKeyPath]
+ );
+ }
+ }
+ }
+
+ /**
+ * Retrieve dependencies.
+ *
+ * @return array|string[]
+ */
+ public static function getDependencies()
+ {
+ return [];
+ }
+
+ /**
+ * Retrieve aliases
+ *
+ * @return array|string[]
+ */
+ public function getAliases()
+ {
+ return [];
+ }
+}
diff --git a/Test/EndToEnd/__scripts__/run-tests.sh b/Test/EndToEnd/__scripts__/run-tests.sh
index 3100a27..9366bee 100755
--- a/Test/EndToEnd/__scripts__/run-tests.sh
+++ b/Test/EndToEnd/__scripts__/run-tests.sh
@@ -43,7 +43,7 @@ HOSTNAME=$(ddev exec printenv DDEV_HOSTNAME | sed 's/\r//g')
M2VERSION=$(ddev exec printenv DDEV_PROJECT | sed 's/\r//g')
M2_URL=https://$HOSTNAME
PROXY_IP=$(ddev find-ip ddev-router)
-BOUNCER_KEY=$(ddev exec bin/magento config:show crowdsec_bouncer/general/connection/api_key | sed 's/\r//g')
+BOUNCER_KEY=$(ddev exec cat .ddev/commands/host/bouncer_key_plain.txt | sed 's/\r//g')
JEST_PARAMS="--bail=true --runInBand --verbose"
TLS_PATH="crowdsec/tls" # Relative to var path
# If FAIL_FAST, will exit on first individual test fail
@@ -68,7 +68,7 @@ case $TYPE in
"docker")
DEBUG_STRING=""
- YARN_PATH="./var/www/html/my-own-modules/crowdsec-bouncer/Test/EndToEnd"
+ YARN_PATH="./my-own-modules/crowdsec-bouncer/Test/EndToEnd"
COMMAND="ddev exec -s playwright yarn --cwd ${YARN_PATH} cross-env"
LAPI_URL_FROM_PLAYWRIGHT=https://crowdsec:8080
CURRENT_IP=$(ddev find-ip playwright)
@@ -80,7 +80,7 @@ case $TYPE in
"ci")
DEBUG_STRING="DEBUG=pw:api"
- YARN_PATH="./var/www/html/my-own-modules/crowdsec-bouncer/Test/EndToEnd"
+ YARN_PATH="./my-own-modules/crowdsec-bouncer/Test/EndToEnd"
COMMAND="ddev exec -s playwright xvfb-run --auto-servernum -- yarn --cwd ${YARN_PATH} cross-env"
LAPI_URL_FROM_PLAYWRIGHT=https://crowdsec:8080
CURRENT_IP=$(ddev find-ip playwright)
diff --git a/Test/EndToEnd/__scripts__/test-init.sh b/Test/EndToEnd/__scripts__/test-init.sh
index ec1ec06..2cf030e 100755
--- a/Test/EndToEnd/__scripts__/test-init.sh
+++ b/Test/EndToEnd/__scripts__/test-init.sh
@@ -9,5 +9,5 @@ if ! ddev --version >/dev/null 2>&1; then
exit 1
fi
-ddev exec -s playwright yarn --cwd ./var/www/html/my-own-modules/crowdsec-bouncer/Test/EndToEnd --force && \
+ddev exec -s playwright yarn --cwd ./my-own-modules/crowdsec-bouncer/Test/EndToEnd --force && \
ddev exec -s playwright yarn global add cross-env
diff --git a/Test/EndToEnd/__tests__/2-live-mode.js b/Test/EndToEnd/__tests__/2-live-mode.js
index 1f2eadd..b8a1cd9 100644
--- a/Test/EndToEnd/__tests__/2-live-mode.js
+++ b/Test/EndToEnd/__tests__/2-live-mode.js
@@ -200,7 +200,11 @@ describe(`Test cURL in Live mode`, () => {
await page.click("#crowdsec_bouncer_general_connection_test");
await expect(page).toMatchText(
"#lapi_ping_result",
- /Connection test result: success.*Use cURL: true/,
+ /Use cURL: true/,
+ );
+ await expect(page).toMatchText(
+ "#lapi_ping_result",
+ /Connection test result: success/,
);
await onAdminSaveSettings();
});
@@ -291,7 +295,11 @@ describe(`Test TLS auth in Live mode`, () => {
await wait(2000);
await expect(page).toMatchText(
"#lapi_ping_result",
- /Connection test result: success.*Auth type: TLS.*Use cURL: true/,
+ /Connection test result: success.*Auth type: TLS/,
+ );
+ await expect(page).toMatchText(
+ "#lapi_ping_result",
+ /Use cURL: true/,
);
// Good settings with curl
@@ -313,7 +321,11 @@ describe(`Test TLS auth in Live mode`, () => {
await expect(page).toMatchText(
"#lapi_ping_result",
- /Connection test result: success.*Auth type: TLS.*Use cURL: true/,
+ /Connection test result: success.*Auth type: TLS/,
+ );
+ await expect(page).toMatchText(
+ "#lapi_ping_result",
+ /Use cURL: true/,
);
// Good settings without curl
@@ -326,7 +338,11 @@ describe(`Test TLS auth in Live mode`, () => {
await expect(page).toMatchText(
"#lapi_ping_result",
- /Connection test result: success.*Auth type: TLS.*Use cURL: false/,
+ /Connection test result: success.*Auth type: TLS/,
+ );
+ await expect(page).toMatchText(
+ "#lapi_ping_result",
+ /Use cURL: false/,
);
await onAdminSaveSettings();
diff --git a/Test/EndToEnd/__tests__/6-events.js b/Test/EndToEnd/__tests__/6-events.js
deleted file mode 100644
index fc2edde..0000000
--- a/Test/EndToEnd/__tests__/6-events.js
+++ /dev/null
@@ -1,375 +0,0 @@
-/* eslint-disable no-undef */
-const {
- removeAllDecisions,
- onLoginPageLoginAsAdmin,
- goToAdmin,
- goToPublicPage,
- setDefaultConfig,
- goToSettingsPage,
- deleteFileContent,
- getFileContent,
- fillInput,
- fillByName,
- selectByName,
- selectElement,
- onAdminSaveSettings,
- wait,
- flushCache,
-} = require("../utils/helpers");
-
-const { CURRENT_IP, PROXY_IP, EVENT_LOG_PATH } = require("../utils/constants");
-
-const CURRENT_TIME = `${Date.now()}`;
-const FIRSTNAME = `E2EFirstname-${CURRENT_TIME}`;
-const LASTNAME = `E2ELastname-${CURRENT_TIME}`;
-const EMAIL = `${FIRSTNAME}${LASTNAME}@crowdsec.net`;
-const PASSWORD = `PwD-${CURRENT_TIME}`;
-const STREET = "Street";
-const CITY = "City";
-const POSTCODE = "12345";
-const PHONE = "0607080910";
-
-describe(`Log events in front`, () => {
- beforeAll(async () => {
- await goToAdmin();
- await onLoginPageLoginAsAdmin();
- await removeAllDecisions();
- await setDefaultConfig();
- });
-
- beforeEach(async () => {
- await deleteFileContent(EVENT_LOG_PATH);
- const logContent = await getFileContent(EVENT_LOG_PATH);
- await expect(logContent).toBe("");
- });
-
- it("Should create and login a customer", async () => {
- await goToPublicPage("/customer/account/create");
- await fillInput("firstname", FIRSTNAME);
- await fillInput("lastname", LASTNAME);
- await fillInput("email_address", EMAIL);
- await fillInput("password", PASSWORD);
- await fillInput("password-confirmation", PASSWORD);
- await page.click(".action.submit.primary");
-
- await expect(page).toMatchText(
- ".message-success",
- /Thank you for registering/,
- );
- const logContent = await getFileContent(EVENT_LOG_PATH);
- await expect(logContent).toMatch(
- new RegExp(
- `{"type":"CUSTOMER_REGISTER_PROCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}"`,
- ),
- );
- await expect(logContent).toMatch(
- new RegExp(
- `{"type":"CUSTOMER_REGISTER_SUCCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}"`,
- ),
- );
- await expect(logContent).toMatch(
- `{"type":"CUSTOMER_LOGIN_SUCCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}"`,
- );
- });
-
- it("Should Log out and failed registering with same email", async () => {
- await page.click(".action.switch");
- await page.click('li.authorization-link:has-text("Sign Out")');
-
- await goToPublicPage("/customer/account/create");
-
- await fillInput("firstname", FIRSTNAME);
- await fillInput("lastname", LASTNAME);
- await fillInput("email_address", EMAIL);
- await fillInput("password", PASSWORD);
- await fillInput("password-confirmation", PASSWORD);
- await page.click(".action.submit.primary");
-
- await expect(page).toMatchText(
- ".message-error",
- /There is already an account with this email address./,
- );
- const logContent = await getFileContent(EVENT_LOG_PATH);
- await expect(logContent).toMatch(
- `{"type":"CUSTOMER_REGISTER_PROCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}"`,
- );
- await expect(logContent).not.toMatch(
- `{"type":"CUSTOMER_REGISTER_SUCCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}"`,
- );
- });
-
- it("Should not log register process if configuration disabled", async () => {
- await goToSettingsPage();
- await selectElement(
- "crowdsec_bouncer_events_log_customer_register",
- "0",
- );
- await onAdminSaveSettings();
- await goToPublicPage("/customer/account/create");
-
- await fillInput("firstname", FIRSTNAME);
- await fillInput("lastname", LASTNAME);
- await fillInput("email_address", EMAIL);
- await fillInput("password", PASSWORD);
- await fillInput("password-confirmation", PASSWORD);
- await page.click(".action.submit.primary");
-
- await expect(page).toMatchText(
- ".message-error",
- /There is already an account with this email address./,
- );
- const logContent = await getFileContent(EVENT_LOG_PATH);
- await expect(logContent).not.toMatch(
- `{"type":"CUSTOMER_REGISTER_PROCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}"`,
- );
- });
-
- it("Should login ", async () => {
- await page.click('li.authorization-link:has-text("Sign In")');
-
- await fillInput("email", EMAIL);
- await fillInput("pass", PASSWORD);
- await page.click(".action.login.primary");
- await wait(2000);
-
- await expect(page).toMatchText(".welcome > span", /Welcome/);
- const logContent = await getFileContent(EVENT_LOG_PATH);
- await expect(logContent).toMatch(
- `{"type":"CUSTOMER_LOGIN_PROCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}"`,
- );
- await expect(logContent).toMatch(
- `{"type":"CUSTOMER_LOGIN_SUCCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}"`,
- );
- });
-
- it("Should not log login if configuration disabled", async () => {
- await page.click(".action.switch");
- await page.click('li.authorization-link:has-text("Sign Out")');
-
- await goToSettingsPage();
- await selectElement("crowdsec_bouncer_events_log_customer_login", "0");
- await onAdminSaveSettings();
-
- await goToPublicPage("/customer/account/create");
-
- await page.click('li.authorization-link:has-text("Sign In")');
-
- await fillInput("email", EMAIL);
- await fillInput("pass", PASSWORD);
- await page.click(".action.login.primary");
- await wait(2000);
- await expect(page).toMatchText(".welcome > span", /Welcome/);
- const logContent = await getFileContent(EVENT_LOG_PATH);
- await expect(logContent).not.toMatch(
- `{"type":"CUSTOMER_LOGIN_PROCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}"`,
- );
- await expect(logContent).not.toMatch(
- `{"type":"CUSTOMER_LOGIN_SUCCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}"`,
- );
- });
-
- it("Should add to cart", async () => {
- await goToPublicPage("/simple-product-10.html");
- await page.click("#product-addtocart-button");
-
- await expect(page).toMatchText(
- ".message-success",
- /You added Simple Product 10/,
- );
- const logContent = await getFileContent(EVENT_LOG_PATH);
- await expect(logContent).toMatch(
- `{"type":"ADD_TO_CART_PROCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}"`,
- );
- await expect(logContent).toMatch(
- `{"type":"ADD_TO_CART_SUCCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}"`,
- );
- });
-
- it("Should not log add to cart if disabled configuration", async () => {
- await goToSettingsPage();
- await selectElement("crowdsec_bouncer_events_log_add_to_cart", "0");
- await onAdminSaveSettings();
-
- await goToPublicPage("/simple-product-10.html");
- await page.click("#product-addtocart-button");
-
- await expect(page).toMatchText(
- ".message-success",
- /You added Simple Product 10/,
- );
- const logContent = await getFileContent(EVENT_LOG_PATH);
- await expect(logContent).not.toMatch(
- `{"type":"ADD_TO_CART_PROCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}"`,
- );
- await expect(logContent).not.toMatch(
- `{"type":"ADD_TO_CART_SUCCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}"`,
- );
- });
-
- it("Should place order", async () => {
- await goToPublicPage("/checkout");
-
- await wait(2000);
- await fillByName("city", CITY);
- await fillByName("postcode", POSTCODE);
- await fillByName("telephone", PHONE);
- await selectByName("country_id", "FR");
- await fillByName("street\\[0\\]", STREET);
- await page.click(".action.continue.primary");
-
- await page.click(".action.primary.checkout");
-
- await wait(2000);
- await expect(page).toMatchTitle("Success Page");
- const logContent = await getFileContent(EVENT_LOG_PATH);
- await expect(logContent).toMatch(
- new RegExp(
- `{"type":"PAYMENT_PROCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}",.*,"payment_method":"checkmo"`,
- ),
- );
- await expect(logContent).toMatch(
- new RegExp(
- `{"type":"PAYMENT_SUCCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}",.*,"payment_method":"checkmo"`,
- ),
- );
- const element = await page.$(".order-number");
-
- let incrementId = await element.innerText();
- incrementId = incrementId
- .replace("", "")
- .replace("", "");
- await expect(logContent).toMatch(
- new RegExp(
- `{"type":"ORDER_PROCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}",.*,"order_id":"${incrementId}","customer_id":".*","quote_id":".*"`,
- ),
- );
- await expect(logContent).toMatch(
- new RegExp(
- `{"type":"ORDER_SUCCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}",.*,"order_id":"${incrementId}","customer_id":".*","quote_id":".*"`,
- ),
- );
- });
-
- it("Should not log place order if configuration disabled", async () => {
- await goToSettingsPage();
- await selectElement("crowdsec_bouncer_events_log_order", "0");
- await onAdminSaveSettings();
-
- await goToPublicPage("/simple-product-10.html");
- await page.click("#product-addtocart-button");
-
- await expect(page).toMatchText(
- ".message-success",
- /You added Simple Product 10/,
- );
-
- await goToPublicPage("/checkout");
-
- await wait(2000);
- await page.click(".action.continue.primary");
-
- await page.click(".action.primary.checkout");
-
- await wait(2000);
- await expect(page).toMatchTitle("Success Page");
- const logContent = await getFileContent(EVENT_LOG_PATH);
- await expect(logContent).not.toMatch(
- new RegExp(
- `{"type":"PAYMENT_PROCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}",.*,"payment_method":"checkmo"`,
- ),
- );
- await expect(logContent).not.toMatch(
- new RegExp(
- `{"type":"PAYMENT_SUCCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}",.*,"payment_method":"checkmo"`,
- ),
- );
- const element = await page.$(".order-number");
-
- let incrementId = await element.innerText();
- incrementId = incrementId
- .replace("", "")
- .replace("", "");
- await expect(logContent).not.toMatch(
- new RegExp(
- `{"type":"ORDER_PROCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}",.*,"order_id":"${incrementId}","customer_id":".*","quote_id":".*"`,
- ),
- );
- await expect(logContent).not.toMatch(
- new RegExp(
- `{"type":"ORDER_SUCCESS","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}",.*,"order_id":"${incrementId}","customer_id":".*","quote_id":".*"`,
- ),
- );
- });
-});
-
-describe(`Log events in admin`, () => {
- beforeEach(async () => {
- await deleteFileContent(EVENT_LOG_PATH);
- const logContent = await getFileContent(EVENT_LOG_PATH);
- await expect(logContent).toBe("");
- });
-
- it("Should log failed admin user login", async () => {
- await goToAdmin("admin/auth/logout/");
- await expect(page).toMatchText(
- ".message-success",
- /You have logged out/,
- );
- await page.fill("#username", "BAD_USER");
- await page.fill("#login", "BAD_PASSWORD");
- await page.click(".action-login");
-
- await expect(page).toHaveSelector(".message-error");
- const logContent = await getFileContent(EVENT_LOG_PATH);
- await expect(logContent).toMatch(
- `{"type":"ADMIN_LOGIN_FAILED","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}"`,
- );
- });
-
- it("Should not log if main configuration is disabled", async () => {
- await goToAdmin();
- await onLoginPageLoginAsAdmin();
- await goToSettingsPage();
- await selectElement("crowdsec_bouncer_events_log_enabled", "0");
- await onAdminSaveSettings();
-
- await goToAdmin("admin/auth/logout/");
- await expect(page).toMatchText(
- ".message-success",
- /You have logged out/,
- );
- await page.fill("#username", "BAD_USER");
- await page.fill("#login", "BAD_PASSWORD");
- await page.click(".action-login");
-
- await expect(page).toHaveSelector(".message-error");
- const logContent = await getFileContent(EVENT_LOG_PATH);
- await expect(logContent).not.toMatch(
- `{"type":"ADMIN_LOGIN_FAILED","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}"`,
- );
- });
-
- it("Should not log failed admin user login if disabled configuration", async () => {
- await goToAdmin();
- await onLoginPageLoginAsAdmin();
- await goToSettingsPage();
- await selectElement("crowdsec_bouncer_events_log_enabled", "1");
- await selectElement("crowdsec_bouncer_events_log_admin_login", "0");
- await onAdminSaveSettings();
-
- await goToAdmin("admin/auth/logout/");
- await expect(page).toMatchText(
- ".message-success",
- /You have logged out/,
- );
- await page.fill("#username", "BAD_USER");
- await page.fill("#login", "BAD_PASSWORD");
- await page.click(".action-login");
-
- await expect(page).toHaveSelector(".message-error");
- const logContent = await getFileContent(EVENT_LOG_PATH);
- await expect(logContent).not.toMatch(
- `{"type":"ADMIN_LOGIN_FAILED","ip":"${PROXY_IP}","x-forwarded-for-ip":"${CURRENT_IP}"`,
- );
- });
-});
diff --git a/Test/EndToEnd/utils/constants.js b/Test/EndToEnd/utils/constants.js
index d728c6a..2a57f21 100644
--- a/Test/EndToEnd/utils/constants.js
+++ b/Test/EndToEnd/utils/constants.js
@@ -11,7 +11,6 @@ const { TIMEOUT } = process.env;
const { CURRENT_IP } = process.env;
const { PROXY_IP } = process.env;
const DEBUG_LOG_PATH = `${__dirname}/../../../../../var/log/crowdsec-bouncer-debug.log`;
-const EVENT_LOG_PATH = `${__dirname}/../../../../../var/log/crowdsec-events.log`;
const JAPAN_IP = "210.249.74.42";
const FRANCE_IP = "78.119.253.85";
const { VAR_PATH, TLS_PATH } = process.env;
@@ -28,7 +27,6 @@ module.exports = {
ADMIN_LOGIN,
ADMIN_PASSWORD,
DEBUG_LOG_PATH,
- EVENT_LOG_PATH,
M2_URL,
BOUNCER_KEY,
CURRENT_IP,
diff --git a/Test/EndToEnd/utils/helpers.js b/Test/EndToEnd/utils/helpers.js
index 809872c..4e40a9f 100644
--- a/Test/EndToEnd/utils/helpers.js
+++ b/Test/EndToEnd/utils/helpers.js
@@ -53,18 +53,12 @@ const ensureConfigVisibilty = async () => {
if (!visible) {
await page.click("#crowdsec_bouncer_advanced-head");
}
- visible = await page.isVisible("#crowdsec_bouncer_events");
- if (!visible) {
- await page.click("#crowdsec_bouncer_events-head");
- }
visible = await page.isVisible("#crowdsec_bouncer_general");
await expect(visible).toBeTruthy();
visible = await page.isVisible("#crowdsec_bouncer_theme");
await expect(visible).toBeTruthy();
visible = await page.isVisible("#crowdsec_bouncer_advanced");
await expect(visible).toBeTruthy();
- visible = await page.isVisible("#crowdsec_bouncer_events");
- await expect(visible).toBeTruthy();
};
const onAdminGoToSettingsPage = async (direct = true) => {
@@ -173,13 +167,6 @@ const setDefaultConfig = async (save = true, direct = true) => {
await selectElement("crowdsec_bouncer_advanced_debug_log", "1");
await selectElement("crowdsec_bouncer_advanced_debug_display_errors", "1");
await fillInput("crowdsec_bouncer_advanced_debug_forced_test_ip", "");
- // Events
- await selectElement("crowdsec_bouncer_events_log_enabled", "1");
- await selectElement("crowdsec_bouncer_events_log_customer_register", "1");
- await selectElement("crowdsec_bouncer_events_log_customer_login", "1");
- await selectElement("crowdsec_bouncer_events_log_admin_login", "1");
- await selectElement("crowdsec_bouncer_events_log_add_to_cart", "1");
- await selectElement("crowdsec_bouncer_events_log_order", "1");
if (save) {
await onAdminSaveSettings();
diff --git a/composer.json b/composer.json
index af173fc..a811c3f 100644
--- a/composer.json
+++ b/composer.json
@@ -2,7 +2,7 @@
"name": "crowdsec/magento2-module-bouncer",
"description": "The Bouncer module for Magento 2 allows rejecting IP detected as malicious by CrowdSec",
"type": "magento2-module",
- "version": "2.0.0",
+ "version": "2.1.0",
"minimum-stability": "stable",
"license": "MIT",
"authors": [
@@ -28,9 +28,9 @@
],
"require": {
"magento/framework": ">=102",
- "crowdsec/bouncer": "^1.2.0",
+ "crowdsec/bouncer": "^2.1.0",
"swaggest/json-schema": "0.12.39",
- "crowdsec/magento-symfony-cache": "1.1.0 || 2.2.0"
+ "crowdsec/magento-symfony-cache": "1.1.0 || 2.2.0 || 3.0.0"
},
"autoload": {
"files": [
diff --git a/doc/TECHNICAL_NOTES.md b/doc/TECHNICAL_NOTES.md
index 7c177cd..ddd1d9a 100644
--- a/doc/TECHNICAL_NOTES.md
+++ b/doc/TECHNICAL_NOTES.md
@@ -24,31 +24,6 @@ This extension is mainly based on the CrowdSec Bouncer PHP library. It is an ope
[here](https://github.com/crowdsecurity/php-cs-bouncer).
-## Events logging
-
-Events logging feature is essentially based on Magento 2 event and observer pattern. Please look at `etc/frontend/events.xml` and `etc/events.xml` files for more details.
-
-We are using the following events:
-
-- `backend_auth_user_login_failed`
-- `checkout_cart_product_add_after`
-- `checkout_cart_product_add_before`
-- `customer_login`
-- `customer_register_success`
-- `sales_order_place_before`
-- `sales_order_payment_place_end`
-- `sales_order_payment_place_start`
-- `sales_order_place_after`
-
-Additionally, as there is sometimes no available event, we use the Magento 2 plugin (interceptor) pattern.
-Please look at `etc/frontend/di.xml` and `etc/di.xml` files for more details.
-
-We are using `before` plugins for the following methods:
-
-- `Magento\Customer\Model\AccountManagement::authenticate`
-- `Magento\Customer\Controller\Account\CreatePost::execute`
-
-
## Full Page Cache
In Magento 2, the full page cache is implemented via a plugin on the front controller (`vendor/magento/module-page-cache/Model/App/FrontController/BuiltinPlugin.php::aroundDispatch`).
@@ -81,24 +56,30 @@ As Magento 2.2 is not compatible with PHP 7.2 until [2.2.9](https://github.com/m
## Why `crowdsec/magento-symfony-cache` ?
-This `CrowdSec_Bouncer` module depends on the [CrowdSec PHP library `crowdsec/bouncer`](https://github.com/crowdsecurity/php-cs-bouncer) that comes with`symfony/cache` as dependency (`v5` or `v6`).
+The [Magento 2 `CrowdSec_Bouncer` module](https://github.com/crowdsecurity/cs-magento-bouncer/) depends on the
+[CrowdSec PHP library `crowdsec/bouncer`](https://github.com/crowdsecurity/php-cs-bouncer) that comes with
+`symfony/cache` as dependency (`v5` or `v6`).
+With Magento `2.4.4` and `2.4.5`, a fresh installation on PHP 8 will lock a `3.0.0` version of `psr/cache`.
+And it will also install a `v2.2.11` version of `web-token/jwt-framework` that locks a `v4.4.45` version of
+`symfony/http-kernel`.
-Since Magento `2.4.4`, a fresh installation on PHP 8 will lock a `3.0.0` version of `psr/cache`. And it also installs a `v2.2.11` version of `web-token/jwt-framework` that locks a `v4.4.45` version of`symfony/http-kernel`.
-
-As a `v5` version of `symfony/cache` required `^1.0|^2.0` version of `psr/cache`, and a `v6` version of `symfony/cache` conflicts with `symfony/http-kernel` <5.4, it is impossible to require any version of the`symfony/cache` package.
+As a `v5` version of `symfony/cache` required `^1.0|^2.0` version of `psr/cache`, and a `v6` version of
+`symfony/cache` conflicts with `symfony/http-kernel` <5.4, it is impossible to require any version of the
+`symfony/cache` package.
That's why we needed to create a fork of `symfony/cache` that we called `crowdsec/magento-symfony-cache`.
-The `v1` version of `crowdsec/magento-symfony-cache` only requires some specific `5.x.y` version of `symfony/cache`and is only available for PHP < `8.0.2`.
-
-For PHP >= `8.0.2`, we provide a compatible `v2` version of `crowdsec/magento-symfony-cache`.
-This `v2` version replaces the specified `5.x.y` version of `symfony/cache` : we use a copy of `5.x.y` files and allow `psr/cache` `3.0`. We also copy some `6.0.z` files to have compatible PHP 8 method signatures.
+The `v1` version of `crowdsec/magento-symfony-cache` only requires some specific `5.x.y` version of `symfony/cache`
+and is only available for PHP < `8.0.2`.
+For PHP >= `8.0.2`, we provide a compatible `v2` version of
+`crowdsec/magento-symfony-cache`.
+The `v2` version replaces the specified `5.x.y` version of `symfony/cache` : we use a copy of `5.x.y` files and
+allow `psr/cache` `3.0`. We also copy some `6.0.z` files to have compatible PHP 8 method signatures.
-_Update_: Since Magento `2.4.6`, it is possible to install `symfony/cache` because the required version of
-`web-token/jwt-framework` is `3.1`. But, in order to keep compatibility with `2.4.4` and `2.4.5`, we have to
-keep this `crowdsec/magento-symfony-cache` dependency.
+Since Magento `2.4.6`, it is possible to install `symfony/cache` without this dependency hell. That's why we provide
+an alternative `v3` version that is just a mirror of `symfony/cache`. Whenever it is possible, composer will pick up this version and just use the original `symfony/cache` package.
diff --git a/doc/USER_GUIDE.md b/doc/USER_GUIDE.md
index fb03cd8..8fe3d65 100644
--- a/doc/USER_GUIDE.md
+++ b/doc/USER_GUIDE.md
@@ -62,7 +62,8 @@ On the other hand, all texts are also fully customizable. This will allow you, f
This module comes with configurations that you will find under `Stores → Configurations → Security → CrowdSec Bouncer` admin section.
-These configurations are divided in four main parts : `General Settings`, `Theme customizations`, `Advanced settings` and `Events`.
+These configurations are divided in three main parts : `General Settings`, `Theme customizations` and `Advanced
+settings`.
#### General Settings
@@ -147,6 +148,21 @@ By default, `file_get_contents` method is used to call Local API. This method re
Here, you can choose to use `cURL` requests instead. Beware that in this case, you need to have php `cURL` extension installed and enabled on your system.
+***
+
+`Connection details → Global timeout` (`global` scope)
+
+In seconds. The global timeout when calling Local API. If set to 0, timeout will be unlimited.
+
+
+***
+
+
+`Connection details → Connection timeout` (`global` scope)
+
+In seconds. **Only for curl**. The timeout for the connection phase when calling Local API. If set to a 0, timeout will be unlimited.
+
+
**N.B** : Even before saving configuration, you can check if your settings are correct by clicking on the test button.
@@ -384,48 +400,6 @@ For test purpose only. This IP will be used instead of the current `X-Forwarded-
***
-#### Events
-
-
-In the `Events` part, you can enable business events logging. Using it in combination to a specific CrowdSec scenario allows detecting suspicious behavior as credential or credit card stuffing.
-
-![Events](images/screenshots/config-event.jpg)
-
-***
-
-`Logging → Enable events log` (`global` scope)
-
-If enabled, logs will be written in a `var/log/crowdsec-events.log` file.
-
-***
-
-`Logging → Track customer registration` (`global` scope)
-
-Will be used to detect suspicious account creation.
-
-***
-
-`Logging → Track customer login` (`global` scope)
-
-Will be used to detect credential stuffing.
-
-***
-
-`Logging → Track admin user login` (`global` scope)
-
-Will be used to detect admin brute attacks.
-
-***
-
-`Logging → Track add to cart process` (`global` scope)
-
-Will be used to detect suspicious behaviour with add to cart action.
-
-***
-
-`Logging → Track order process` (`global` scope)
-
-Will be used to detect suspicious behaviour, as credit card stuffing, on order action.
### Auto Prepend File mode
diff --git a/doc/images/screenshots/config-connection-details.jpg b/doc/images/screenshots/config-connection-details.jpg
index e09e4df..485c51e 100644
Binary files a/doc/images/screenshots/config-connection-details.jpg and b/doc/images/screenshots/config-connection-details.jpg differ
diff --git a/etc/adminhtml/events.xml b/etc/adminhtml/events.xml
deleted file mode 100755
index 8c6aa57..0000000
--- a/etc/adminhtml/events.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
-
diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml
index da3fe4b..2ccfa43 100644
--- a/etc/adminhtml/system.xml
+++ b/etc/adminhtml/system.xml
@@ -53,10 +53,11 @@
CrowdSec\Bouncer\Model\Config\Source\ConnexionType
-
+
cscli bouncers add magento2-bouncer]]>
required-entry
+ Magento\Config\Model\Config\Backend\Encrypted
api_key
@@ -101,7 +102,20 @@
Magento\Config\Model\Config\Source\Yesno
cURL instead of file_get_contents.]]>
-
+
+
+
+ required-entry validate-digits
+
+
+
+
+
+ 1
+
+ required-entry validate-digits
+
+
Test connection
CrowdSec\Bouncer\Block\Adminhtml\System\Config\Connection\Ping
@@ -490,62 +504,6 @@
-
-
- 1
-
-
-
-
- When enabled, you can choose which processes to track.]]>
- 1
-
-
- Magento\Config\Model\Config\Source\Yesno
-
-
-
-
- Magento\Config\Model\Config\Source\Yesno
-
-
- 1
-
-
-
-
- Magento\Config\Model\Config\Source\Yesno
-
-
- 1
-
-
-
-
- Magento\Config\Model\Config\Source\Yesno
-
-
- 1
-
-
-
-
- Magento\Config\Model\Config\Source\Yesno
-
-
- 1
-
-
-
-
- Magento\Config\Model\Config\Source\Yesno
-
-
- 1
-
-
-
-
diff --git a/etc/config.xml b/etc/config.xml
index 3a49a88..16e433f 100644
--- a/etc/config.xml
+++ b/etc/config.xml
@@ -32,6 +32,9 @@
api_key
+ 60
+ 10
+
normal_bouncing
@@ -81,15 +84,6 @@
86400
-
-
- 1
- 1
- 1
- 1
- 1
-
-
diff --git a/etc/di.xml b/etc/di.xml
index e43746d..474d85e 100755
--- a/etc/di.xml
+++ b/etc/di.xml
@@ -27,7 +27,7 @@
*/
-->
+ xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
@@ -42,25 +42,9 @@
-
-
- crowdsec-events
-
- - CrowdSec\Bouncer\Logger\Handlers\Event
-
-
-
-
-
-
-
-
-
-
-
diff --git a/etc/events.xml b/etc/events.xml
deleted file mode 100755
index a1ea96c..0000000
--- a/etc/events.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/etc/frontend/di.xml b/etc/frontend/di.xml
index 29e6f99..3856dc6 100755
--- a/etc/frontend/di.xml
+++ b/etc/frontend/di.xml
@@ -27,7 +27,7 @@
*/
-->
+ xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
diff --git a/etc/frontend/events.xml b/etc/frontend/events.xml
deleted file mode 100755
index fee5869..0000000
--- a/etc/frontend/events.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/view/adminhtml/templates/system/config/connection/old/ping.phtml b/view/adminhtml/templates/system/config/connection/old/ping.phtml
index 8cf24e1..a7568f3 100644
--- a/view/adminhtml/templates/system/config/connection/old/ping.phtml
+++ b/view/adminhtml/templates/system/config/connection/old/ping.phtml
@@ -44,7 +44,9 @@
tls_key_path: $('= $block->escapeJs($block->getTlsKeyPathField()) ?>').value,
tls_verify_peer: $('= $block->escapeJs($block->getTlsVerifyPeerField()) ?>').value,
tls_ca_cert_path: $('= $block->escapeJs($block->getTlsCaCertPathField()) ?>').value,
- use_curl: $('= $block->escapeJs($block->getUseCurlField()) ?>').value
+ use_curl: $('= $block->escapeJs($block->getUseCurlField()) ?>').value,
+ api_connect: $('= $block->escapeJs($block->getApiTimeoutField()) ?>').value,
+ api_connect_timeout: $('= $block->escapeJs($block->getApiConnectTimeoutField()) ?>').value
};
new Ajax.Request('= $block->escapeJs($block->escapeUrl($block->getAjaxUrl())) ?>', {
diff --git a/view/adminhtml/templates/system/config/connection/ping.phtml b/view/adminhtml/templates/system/config/connection/ping.phtml
index 9259b8b..442252e 100644
--- a/view/adminhtml/templates/system/config/connection/ping.phtml
+++ b/view/adminhtml/templates/system/config/connection/ping.phtml
@@ -35,6 +35,8 @@
$ajaxUrl = $escaper->escapeJs($block->getAjaxUrl());
$errorMessage = $escaper->escapeJs($escaper->escapeHtml(__('Error during CrowdSec Connection ping.')));
$urlField = $escaper->escapeJs($block->getUrlField());
+$apiTimeoutField = $escaper->escapeJs($block->getApiTimeoutField());
+$apiConnectTimeoutField = $escaper->escapeJs($block->getApiConnectTimeoutField());
$authField = $escaper->escapeJs($block->getAuthTypeField());
$tlsCertField = $escaper->escapeJs($block->getTlsCertPathField());
$tlsKeyField = $escaper->escapeJs($block->getTlsKeyPathField());
@@ -58,7 +60,9 @@ require(['prototype'], function(){
tls_verify_peer: $('{$tlsVerifyPeerField}').value,
tls_ca_cert_path: $('{$tlsCaCertField}').value,
bouncer_key: $('{$keyField}').value,
- use_curl: $('{$useCurlField}').value
+ use_curl: $('{$useCurlField}').value,
+ api_timeout: $('{$apiTimeoutField}').value,
+ api_connect_timeout: $('{$apiConnectTimeoutField}').value
};
new Ajax.Request('{$ajaxUrl}', {