Skip to content

Commit e2a4e79

Browse files
committed
OF-3366: Add a test for FAST token rotation
1 parent 2423c4f commit e2a4e79

5 files changed

Lines changed: 205 additions & 1 deletion

File tree

.github/actions/conversationstest-action/run-tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
55
REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
66
if [ -z "${1:-}" ]; then
77
echo "Usage: run-tests.sh <tag>" >&2
8-
echo "Available tags: demoboot, sasl2" >&2
8+
echo "Available tags: demoboot, sasl2, fast-rotation" >&2
99
exit 1
1010
fi
1111
INCLUDE_TAGS="$1"

.github/workflows/continuous-integration-workflow.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,9 @@ jobs:
354354
- name: sasl2
355355
maestro-tags: sasl2
356356
config-file: build/ci/conversations/configs/sasl2.xml
357+
- name: fast-rotation
358+
maestro-tags: fast-rotation
359+
config-file: build/ci/conversations/configs/fast-rotation.xml
357360

358361
steps:
359362
- name: Checkout local actions and test flows # Do this _before_ untarring the distribution, as the checkout will empty the directory prior to the checkout!
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<jive>
3+
<adminConsole>
4+
<port>9090</port>
5+
<securePort>9091</securePort>
6+
</adminConsole>
7+
<connectionProvider>
8+
<className>org.jivesoftware.database.EmbeddedConnectionProvider</className>
9+
</connectionProvider>
10+
<autosetup>
11+
<run>true</run>
12+
<locale>en</locale>
13+
<xmpp>
14+
<auth>
15+
<anonymous>true</anonymous>
16+
</auth>
17+
<domain>example.org</domain>
18+
<fqdn>example.org</fqdn>
19+
</xmpp>
20+
<database>
21+
<mode>embedded</mode>
22+
</database>
23+
<admin>
24+
<email>admin@example.com</email>
25+
<password>admin</password>
26+
</admin>
27+
<users>
28+
<user1>
29+
<username>john</username>
30+
<password>secret</password>
31+
<name>John Doe</name>
32+
<email>john.doe@example.com</email>
33+
<roster>
34+
<item1>
35+
<jid>jane@example.org</jid>
36+
<nickname>Jane</nickname>
37+
</item1>
38+
<item2>
39+
<jid>juan@example.org</jid>
40+
<nickname>Juan</nickname>
41+
</item2>
42+
</roster>
43+
</user1>
44+
<user2>
45+
<username>jane</username>
46+
<password>secret</password>
47+
<name>Jane Doe</name>
48+
<email>jane.doe@example.com</email>
49+
<roster>
50+
<item1>
51+
<jid>john@example.org</jid>
52+
<nickname>John</nickname>
53+
</item1>
54+
<item2>
55+
<jid>juan@example.org</jid>
56+
<nickname>Juan</nickname>
57+
</item2>
58+
</roster>
59+
</user2>
60+
<user3>
61+
<username>juan</username>
62+
<password>secret</password>
63+
<name>Juan Doe</name>
64+
<email>juan.doe@example.com</email>
65+
<roster>
66+
<item1>
67+
<jid>john@example.org</jid>
68+
<nickname>John</nickname>
69+
</item1>
70+
<item2>
71+
<jid>jane@example.org</jid>
72+
<nickname>Jane</nickname>
73+
</item2>
74+
</roster>
75+
</user3>
76+
</users>
77+
</autosetup>
78+
<!-- Enable SASL2 (xmpp.auth.sasl2). TLS is required too, but is satisfied by the CI server's self-signed certificate. -->
79+
<xmpp>
80+
<auth>
81+
<sasl2>true</sasl2>
82+
</auth>
83+
<!--
84+
Force FAST token rotation on every reconnect: rotation happens whenever the time left
85+
before expiry is <= the rotation threshold. Setting the threshold >= the expiry means
86+
that's true from the moment a token is issued, without waiting on the real (multi-day)
87+
defaults.
88+
-->
89+
<fast>
90+
<token>
91+
<expiry>1</expiry> <!-- days -->
92+
<rotation-threshold>48</rotation-threshold> <!-- hours -->
93+
</token>
94+
</fast>
95+
</xmpp>
96+
</jive>

build/ci/conversations/flows/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ Flows are tagged by which config they need, not by feature: `fast.yaml` is tagge
3737
and reuses `configs/sasl2.xml`, since FAST (XEP-0484) is only advertised as a SASL2 inline
3838
feature and needs no config of its own — `xmpp.fast.enabled` defaults to `true`.
3939

40+
`fast-rotation.yaml` needs its own config (`configs/fast-rotation.xml`): FAST token rotation
41+
happens once the time left before expiry drops to or below the rotation threshold, but the
42+
real defaults are multi-day, so the config sets the threshold >= the expiry to make rotation
43+
happen on every reconnect instead of waiting on the clock.
44+
4045
### 2. Start an Android emulator
4146

4247
Launch an emulator with API 34 and x86_64 architecture. With Maestro installed, you can create or
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
appId: eu.siacs.conversations
2+
name: FAST token rotation
3+
tags:
4+
- fast-rotation
5+
onFlowStart:
6+
- runScript: scripts/checkHealth.js
7+
---
8+
9+
- runScript: scripts/startSession.js
10+
11+
- runFlow:
12+
file: subflows/login.yaml
13+
14+
- runFlow:
15+
file: subflows/dismiss-onboarding-dialogs.yaml
16+
17+
- assertVisible: "Once you start a new conversation.*"
18+
19+
# The initial, password-based login should obtain and cache a FAST (XEP-0484) token
20+
- runScript:
21+
file: scripts/checkForLogs.js
22+
env:
23+
PATTERN: 'jane@example\.org: storing hashed token Mechanism\['
24+
25+
# A freshly issued token starts in a "new" slot, and is only promoted to "current" the first
26+
# time it's actually used - the rotation-threshold check (see configs/fast-rotation.xml, which
27+
# forces it to always be due) only applies to a "current" token. So it's this token's SECOND
28+
# use, not its first, where the server should rotate it.
29+
30+
# Reconnect #1: first use of the initial token - promotes it, no rotation expected yet.
31+
- runScript: scripts/startSession.js
32+
33+
- launchApp
34+
35+
- assertVisible: "Once you start a new conversation.*"
36+
37+
- runScript:
38+
file: scripts/checkForLogs.js
39+
env:
40+
PATTERN: 'jane@example\.org.*quick start with HT'
41+
MAX_ATTEMPTS: 30
42+
DELAY_MS: 1000
43+
44+
- runScript:
45+
file: scripts/checkForLogs.js
46+
env:
47+
PATTERN: 'jane@example\.org.*logged in \(using SASL_2\)'
48+
MAX_ATTEMPTS: 30
49+
DELAY_MS: 1000
50+
51+
# Reconnect #2: second use of that same token - now "current", so the server should rotate it.
52+
- runScript: scripts/startSession.js
53+
54+
- launchApp
55+
56+
- assertVisible: "Once you start a new conversation.*"
57+
58+
- runScript:
59+
file: scripts/checkForLogs.js
60+
env:
61+
PATTERN: 'jane@example\.org.*quick start with HT'
62+
MAX_ATTEMPTS: 30
63+
DELAY_MS: 1000
64+
65+
- runScript:
66+
file: scripts/checkForLogs.js
67+
env:
68+
PATTERN: 'jane@example\.org.*logged in \(using SASL_2\)'
69+
MAX_ATTEMPTS: 30
70+
DELAY_MS: 1000
71+
72+
- runScript:
73+
file: scripts/checkForLogs.js
74+
env:
75+
PATTERN: 'jane@example\.org: storing hashed token Mechanism\['
76+
MAX_ATTEMPTS: 30
77+
DELAY_MS: 1000
78+
79+
# Reconnect #3: proves the rotated token was actually persisted and is usable - if rotation had
80+
# silently broken (e.g. the replacement was never stored, or was stored but unusable), this
81+
# reconnect would fail FAST and fall back to a password prompt instead.
82+
- runScript: scripts/startSession.js
83+
84+
- launchApp
85+
86+
- assertVisible: "Once you start a new conversation.*"
87+
88+
- runScript:
89+
file: scripts/checkForLogs.js
90+
env:
91+
PATTERN: 'jane@example\.org.*quick start with HT'
92+
MAX_ATTEMPTS: 30
93+
DELAY_MS: 1000
94+
95+
- runScript:
96+
file: scripts/checkForLogs.js
97+
env:
98+
PATTERN: 'jane@example\.org.*logged in \(using SASL_2\)'
99+
MAX_ATTEMPTS: 30
100+
DELAY_MS: 1000

0 commit comments

Comments
 (0)