Skip to content

Commit

Permalink
feat(*): Update remediation engine to v4 (#10)
Browse files Browse the repository at this point in the history
* feat(*): Update to use remediation engine v4

* feat(metrics): Update origins count on ban
  • Loading branch information
julienloizelet authored Jan 16, 2025
1 parent cf9e25d commit e9dd878
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 9 deletions.
28 changes: 25 additions & 3 deletions Block/Adminhtml/Report/Metrics.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use CrowdSec\Engine\CapiEngine\Remediation;
use CrowdSec\Engine\Helper\Data as Helper;
use CrowdSec\Engine\Constants;
use CrowdSec\RemediationEngine\Constants as RemediationConstants;
use Magento\Backend\Block\Template;
use Magento\Backend\Block\Template\Context;
use Magento\Backend\Model\UrlInterface as BackendUrlInterface;
Expand All @@ -50,6 +51,8 @@ class Metrics extends Template
*/
private $backendUrl;

const ORIGIN_CAPI = 'CAPI';// Constants::ORIGIN_CAPI is lowercase but CrowdSec uses uppercase

/**
* @param Remediation $remediation
* @param Helper $helper
Expand All @@ -68,23 +71,42 @@ public function __construct(
$this->helper = $helper;
$this->backendUrl = $backendUrl;
$data = array_merge($data, [
'origin_capi' => Constants::ORIGIN_CAPI,
'origin_capi' => self::ORIGIN_CAPI,
'origin_lists' => Constants::ORIGIN_LISTS,
'origin_crowdsec' => Constants::ORIGIN
]);
parent::__construct($context, $data);
}

/**
* Retrieves origin count cached item
* Retrieves origins count
*
* @return array
* @throws \Psr\Cache\InvalidArgumentException
*/
public function getOriginsCount(): array
{
$result = [
self::ORIGIN_CAPI => 0,
Constants::ORIGIN_LISTS => 0,
Constants::ORIGIN => 0
];
$originsCount = $this->remediation->getOriginsCount();
foreach ($originsCount as $origin => $remediations) {
foreach ($remediations as $remediation => $count) {
if ($origin === Constants::ORIGIN) {
$result[Constants::ORIGIN] += $count;
}
if ($origin === self::ORIGIN_CAPI) {
$result[self::ORIGIN_CAPI] += $count;
}
if (strpos($origin, Constants::ORIGIN_LISTS . RemediationConstants::ORIGIN_LISTS_SEPARATOR) === 0) {
$result[Constants::ORIGIN_LISTS] += $count;
}
}
}

return $this->remediation->getOriginsCount();
return $result;
}

/**
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

---

## [?.?.?](https://github.com/crowdsecurity/magento-cs-extension/releases/tag/v?.?.?) - 202?-??-??
[_Compare with previous release_](https://github.com/crowdsecurity/magento-cs-extension/compare/v1.1.1...HEAD)

**This release is not yet published.**

### Changed

- Uses the new `crowdsec/remediation-engine` `^4.1.0` dependency instead of `^3.3.0`

---

## [1.1.1](https://github.com/crowdsecurity/magento-cs-extension/releases/tag/v1.1.1) - 2024-04-12
[_Compare with previous release_](https://github.com/crowdsecurity/magento-cs-extension/compare/v1.1.0...v1.1.1)

Expand Down
7 changes: 6 additions & 1 deletion Observer/BounceIp.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
use Magento\Framework\Event\ObserverInterface;
use CrowdSec\Engine\Helper\Data as Helper;
use CrowdSec\Engine\CapiEngine\Remediation;
use CrowdSec\RemediationEngine\Constants as RemediationConstants;
use Magento\Framework\HTTP\PhpEnvironment\Response;
use CrowdSec\Engine\Constants;
use Magento\Store\Model\StoreManagerInterface;
Expand Down Expand Up @@ -104,7 +105,8 @@ public function execute(Observer $observer): BounceIp
}

$ip = $this->helper->getRealIp();
$remediation = $this->remediation->getIpRemediation($ip);
$remediationData = $this->remediation->getIpRemediation($ip);
$remediation = $remediationData[RemediationConstants::REMEDIATION_KEY]??Constants::REMEDIATION_BYPASS;
if ($remediation === Constants::REMEDIATION_BAN) {
/**
* @var $response Response
Expand All @@ -122,6 +124,9 @@ public function execute(Observer $observer): BounceIp
}

$response->setBody($content)->setStatusCode(Http::STATUS_CODE_403);
$this->remediation->updateMetricsOriginsCount(
$remediationData[RemediationConstants::ORIGIN_KEY], $remediation
);
}
} catch (\Exception $e) {
$this->helper->getLogger()->error('Technical error while bouncing ip', ['message' => $e->getMessage()]);
Expand Down
6 changes: 3 additions & 3 deletions Test/EndToEnd/__tests__/reports.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ test.describe("Reports page", () => {
).toHaveText("0");

// Simulate a ban decision for testIp1
await runActionPage.addDecision(testIp1, "ban", ORIGIN_LISTS, 60);
await runActionPage.addDecision(testIp1, "ban", `${ORIGIN_LISTS}:tor`, 60);
await runActionPage.setForcedIp(testIp1);
await homePage.navigateTo(false);
// Reset forced ip to be able to access pages
Expand Down Expand Up @@ -197,10 +197,10 @@ test.describe("Reports page", () => {
await homePage.navigateTo();
await expect(page.locator("body")).not.toHaveText(blockRegex);
await adminCrowdSecSecurityReportPage.navigateTo();
// Local decision should be 1
// Local decision should be 0 as bypass is not counted in crowdsec origin
await expect(
page.locator("#crowdsec-engine-metrics tbody tr:first-child td.count")
).toHaveText("1");
).toHaveText("0");

// Clear cache for next tests and reinit forced test ip
await runActionPage.setForcedIp("");
Expand Down
2 changes: 1 addition & 1 deletion Test/EndToEnd/helpers/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ export const blockRegex = /has been blocked/;
export const testIp1 = "1.1.1.1";
export const ORIGIN_CROWDSEC = "crowdsec";
export const ORIGIN_LISTS = "lists";
export const ORIGIN_CAPI = "capi";
export const ORIGIN_CAPI = "CAPI";
1 change: 1 addition & 0 deletions Test/EndToEnd/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const currentDateTime = new Date().toISOString().replace(/[:.]/g, "_").slice(0,
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
timeout: 45_000,
testDir: testDir,
/* Run tests in files in parallel */
fullyParallel: false,
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"community"
],
"require": {
"crowdsec/remediation-engine": "^3.3",
"crowdsec/remediation-engine": "^4.1",
"crowdsec/magento-symfony-cache": "1.1.0 || 2.2.0 || 3.0.0"
},
"autoload": {
Expand Down

0 comments on commit e9dd878

Please sign in to comment.