Skip to content

Commit 6c9327a

Browse files
test(geolocation): Add end to end tests for geolocation
1 parent 0a7883f commit 6c9327a

File tree

7 files changed

+102
-35
lines changed

7 files changed

+102
-35
lines changed

.github/workflows/test-suite.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,16 @@ jobs:
102102
./test-init.sh
103103
chmod +x run-tests.sh
104104
105-
- name: Run End to end test
105+
- name: Run End to end test without geolocation
106106
run: |
107107
cd ${{ github.workspace }}/my-own-modules/crowdsec-php-lib/tests/end-to-end/__scripts__
108108
./run-tests.sh ci "./__tests__/1-live-mode.js"
109+
110+
- name: Run End to end test with geolocation
111+
run: |
112+
cd ${{ github.workspace }}/my-own-modules/crowdsec-php-lib
113+
sed -i 's/\x27enabled\x27 => false/\x27enabled\x27 => true/g' examples/auto-prepend/settings.php
114+
cd ${{ github.workspace }}/my-own-modules/crowdsec-php-lib/tests/end-to-end/__scripts__
115+
./run-tests.sh ci "./__tests__/2-live-mode-with-geolocation.js"
109116
110117

tests/end-to-end/__scripts__/run-tests.sh

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
YELLOW='\033[33m'
99
RESET='\033[0m'
1010
if ! ddev --version >/dev/null 2>&1; then
11-
printf "${YELLOW}Ddev is required for this script. Please see docs/ddev.md.${RESET}\n"
11+
printf "%bDdev is required for this script. Please see docs/ddev.md.%b\n" "${YELLOW}" "${RESET}"
1212
exit 1
1313
fi
1414

@@ -44,6 +44,7 @@ PHPVERSION=$(ddev exec printenv DDEV_PROJECT | sed 's/\r//g')
4444
PHP_URL=https://$HOSTNAME
4545
PROXY_IP=$(ddev find-ip ddev-router)
4646
BOUNCER_KEY=$(ddev exec grep "'api_key'" /var/www/html/my-own-modules/crowdsec-php-lib/examples/auto-prepend/settings.php | sed 's/api_key//g' | sed -e 's|[=>,"'\'']||g' | sed s/'\s'//g)
47+
GEOLOC_ENABLED=$(ddev exec grep -E "'enabled'.*,$" /var/www/html/my-own-modules/crowdsec-php-lib/examples/auto-prepend/settings.php | sed 's/enabled//g' | sed -e 's|[=>,"'\'']||g' | sed s/'\s'//g)
4748
JEST_PARAMS="--bail=true --runInBand --verbose"
4849
# If FAIL_FAST, will exit on first individual test fail
4950
# @see CustomEnvironment.js
@@ -97,18 +98,19 @@ esac
9798
# Run command
9899

99100
$COMMAND \
100-
PHP_URL=$PHP_URL \
101+
PHP_URL="$PHP_URL" \
101102
$DEBUG_STRING \
102-
BOUNCER_KEY=$BOUNCER_KEY \
103-
PROXY_IP=$PROXY_IP \
103+
BOUNCER_KEY="$BOUNCER_KEY" \
104+
PROXY_IP="$PROXY_IP" \
105+
GEOLOC_ENABLED="$GEOLOC_ENABLED" \
104106
LAPI_URL_FROM_PLAYWRIGHT=$LAPI_URL_FROM_PLAYWRIGHT \
105-
CURRENT_IP=$CURRENT_IP \
107+
CURRENT_IP="$CURRENT_IP" \
106108
TIMEOUT=$TIMEOUT \
107109
HEADLESS=$HEADLESS \
108110
FAIL_FAST=$FAIL_FAST \
109111
SLOWMO=$SLOWMO \
110112
yarn --cwd $YARN_PATH test \
111-
$JEST_PARAMS \
113+
"$JEST_PARAMS" \
112114
--json \
113-
--outputFile=./.test-results-$PHPVERSION.json \
114-
$FILE_LIST
115+
--outputFile=./.test-results-"$PHPVERSION".json \
116+
"$FILE_LIST"

tests/end-to-end/__scripts__/test-init.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
YELLOW='\033[33m'
66
RESET='\033[0m'
77
if ! ddev --version >/dev/null 2>&1; then
8-
printf "${YELLOW}Ddev is required for this script. Please see docs/ddev.md.${RESET}\n"
8+
printf "%bDdev is required for this script. Please see docs/ddev.md.%b\n" "${YELLOW}" "${RESET}"
99
exit 1
1010
fi
1111

tests/end-to-end/__tests__/1-live-mode.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ describe(`Live mode run`, () => {
2727
await publicHomepageShouldBeCaptchaWallWithMentions();
2828
});
2929

30-
3130
it("Should display a ban wall", async () => {
3231
await banIpForSeconds(15 * 60, CURRENT_IP);
3332
await publicHomepageShouldBeBanWall();
@@ -38,13 +37,10 @@ describe(`Live mode run`, () => {
3837
await publicHomepageShouldBeAccessible();
3938
});
4039

41-
4240
it("Should fallback to the selected remediation for unknown remediation", async () => {
4341
await removeAllDecisions();
4442
await addDecision(CURRENT_IP, "mfa", 15 * 60);
4543
await wait(1000);
4644
await publicHomepageShouldBeCaptchaWall();
47-
4845
});
4946
});
50-
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/* eslint-disable no-undef */
2+
const {
3+
CURRENT_IP,
4+
GEOLOC_ENABLED,
5+
GEOLOC_TEST_IP,
6+
GEOLOC_BAD_COUNTRY,
7+
} = require("../utils/constants");
8+
9+
const {
10+
publicHomepageShouldBeBanWall,
11+
publicHomepageShouldBeCaptchaWallWithMentions,
12+
publicHomepageShouldBeAccessible,
13+
publicHomepageShouldBeCaptchaWall,
14+
banIpForSeconds,
15+
captchaIpForSeconds,
16+
removeAllDecisions,
17+
wait,
18+
} = require("../utils/helpers");
19+
const { addDecision } = require("../utils/watcherClient");
20+
21+
describe(`Live mode run with geolocation`, () => {
22+
beforeAll(async () => {
23+
if (!GEOLOC_ENABLED) {
24+
const errorMessage = "Geolocation MUST be enabled to test this.";
25+
console.error(errorMessage);
26+
fail(errorMessage);
27+
}
28+
await removeAllDecisions();
29+
});
30+
31+
it("Should bypass a clean IP with a clean country", async () => {
32+
await publicHomepageShouldBeAccessible();
33+
});
34+
35+
it("Should ban a bad IP (ban) with a clean country", async () => {
36+
await banIpForSeconds(15 * 60, CURRENT_IP);
37+
await publicHomepageShouldBeBanWall();
38+
});
39+
40+
it("Should ban a clean IP with a bad country (ban)", async () => {
41+
await removeAllDecisions();
42+
await addDecision(GEOLOC_BAD_COUNTRY, "ban", 15 * 60, "Country");
43+
await wait(1000);
44+
await publicHomepageShouldBeBanWall();
45+
});
46+
47+
it("Should ban a bad IP (ban) with a bad country (captcha)", async () => {
48+
await removeAllDecisions();
49+
await addDecision(GEOLOC_BAD_COUNTRY, "captcha", 15 * 60, "Country");
50+
await addDecision(CURRENT_IP, "ban", 15 * 60);
51+
await wait(1000);
52+
await publicHomepageShouldBeBanWall();
53+
});
54+
});

tests/end-to-end/utils/constants.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ const { PHP_URL } = process.env;
22

33
const LAPI_URL_FROM_PHP = "http://crowdsec:8080";
44
const PUBLIC_URL = '/my-own-modules/crowdsec-php-lib/examples/auto-prepend/public/protected-page.php'
5+
const GEOLOC_TEST_IP = "210.249.74.42";//JP
6+
const GEOLOC_ENABLED = process.env.GEOLOC_ENABLED == "true";
7+
const GEOLOC_BAD_COUNTRY = "JP";
58
const { LAPI_URL_FROM_PLAYWRIGHT } = process.env;
69
const { BOUNCER_KEY } = process.env;
710
const WATCHER_LOGIN = "watcherLogin";
@@ -11,16 +14,20 @@ const { TIMEOUT } = process.env;
1114
const { CURRENT_IP } = process.env;
1215
const { PROXY_IP } = process.env;
1316

17+
1418
module.exports = {
1519
PHP_URL,
1620
BOUNCER_KEY,
1721
CURRENT_IP,
1822
DEBUG,
23+
GEOLOC_TEST_IP,
1924
LAPI_URL_FROM_PHP,
2025
LAPI_URL_FROM_PLAYWRIGHT,
2126
PROXY_IP,
2227
PUBLIC_URL,
2328
TIMEOUT,
2429
WATCHER_LOGIN,
2530
WATCHER_PASSWORD,
31+
GEOLOC_ENABLED,
32+
GEOLOC_BAD_COUNTRY
2633
};

tests/end-to-end/utils/watcherClient.js

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -114,27 +114,30 @@ const auth = async () => {
114114
};
115115

116116
module.exports.addDecision = async (
117-
ipOrCidr,
118-
remediation = "ban",
117+
value,
118+
remediation,
119119
durationInSeconds,
120+
scope = "Ip"
120121
) => {
121122
await auth();
122-
let startIp;
123-
let endIp;
124-
if (ipOrCidr.split("/").length === 2) {
125-
[startIp, endIp] = cidrToRange(ipOrCidr);
126-
} else {
127-
startIp = ipOrCidr;
128-
endIp = ipOrCidr;
123+
let finalScope = "Country";
124+
if(["Ip", "Range"].includes(scope)){
125+
let startIp;
126+
let endIp;
127+
if (value.split("/").length === 2) {
128+
[startIp, endIp] = cidrToRange(value);
129+
} else {
130+
startIp = value;
131+
endIp = value;
132+
}
133+
const startLongIp = ip2long(startIp);
134+
const endLongIp = ip2long(endIp);
135+
const isRange = startLongIp !== endLongIp;
136+
finalScope = isRange ? "Range" : "Ip";
129137
}
130-
const startLongIp = ip2long(startIp);
131-
const endLongIp = ip2long(endIp);
132-
const isRange = startLongIp !== endLongIp;
133-
const scenario = `add ${remediation} to ${
134-
isRange ? `range ${startIp} to ${endIp}` : `ip ${startIp}`
135-
} for ${durationInSeconds} seconds for e2e tests`;
136-
const scope = isRange ? "Range" : "Ip";
137-
const value = ipOrCidr;
138+
139+
const scenario = `add ${remediation} with scope/value ${scope}/${value} for ${durationInSeconds} seconds for e2e tests`;
140+
138141
const startAt = new Date();
139142
const stopAt = new Date();
140143
stopAt.setTime(stopAt.getTime() + durationInSeconds * 1000);
@@ -144,11 +147,9 @@ module.exports.addDecision = async (
144147
decisions: [
145148
{
146149
duration: `${durationInSeconds}s`,
147-
start_ip: startLongIp,
148150
origin: "cscli",
149151
scenario,
150-
scope,
151-
end_ip: endLongIp,
152+
scope: finalScope,
152153
type: remediation,
153154
value,
154155
},
@@ -163,7 +164,7 @@ module.exports.addDecision = async (
163164
scenario_version: "",
164165
simulated: false,
165166
source: {
166-
scope,
167+
scope: finalScope,
167168
value,
168169
},
169170
start_at: startAt.toISOString(),

0 commit comments

Comments
 (0)