Skip to content
Open
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
82c286f
Update gitignore to account for python assets
denisonbarbosa Sep 4, 2025
ccefbbd
Add e2e tests for the msentraid broker
denisonbarbosa Sep 4, 2025
29276e1
Add some documentation for the tests requirements
denisonbarbosa Sep 4, 2025
577d58e
Add script utility to run the tests
denisonbarbosa Sep 4, 2025
cd750f3
Update tests syntax to cover latest YARF changes
denisonbarbosa Sep 23, 2025
d83f0af
Rename directory to match broker name
denisonbarbosa Oct 15, 2025
b3f4ec1
Extract BrowserWindow to generic file
denisonbarbosa Oct 15, 2025
4a7a178
Update test_run script and documentation to represent current format
denisonbarbosa Oct 15, 2025
3dedd8e
Reorganize resource directory structure
denisonbarbosa Oct 22, 2025
f91af83
Fix code navigation
adombeck Oct 22, 2025
05f73bc
Fix run_tests.sh exiting with 0 even if tests failed
adombeck Oct 23, 2025
1775ebc
Fix name of the browser_login.py script in broker.resource
adombeck Oct 23, 2025
1146ae5
Use "StringUtils.First Match" instead of "StringUtils.FirstMatch"
adombeck Oct 23, 2025
7d0f822
Fix import path in browser_login.py
adombeck Oct 23, 2025
49a1341
Use "./" instead of "${CURDIR}/" in robot framework import paths
adombeck Oct 23, 2025
b7e5aff
Consistently use "[Arguments]" instead of "[arguments]"
adombeck Oct 23, 2025
5ad1646
Print output of browser_login.py on failure
adombeck Oct 23, 2025
6093c3b
e2e-runner: Use automatically assigned VNC port
adombeck Oct 23, 2025
d13f080
run_tests.sh: Support specifying more than one test to run
adombeck Oct 23, 2025
c59cf2d
run_tests.sh: Support passing arguments to yarf
adombeck Oct 23, 2025
1dd4626
run_tests.sh: Create temporary run dir below e2e-tests/.runs/
adombeck Oct 23, 2025
9379e39
e2e-tests: Provide script for provisioning the VM
adombeck Oct 23, 2025
81816f9
run_tests: Set -o pipefail
adombeck Oct 23, 2025
7f15d8f
e2e-tests: Add setup_yarf.sh
adombeck Oct 23, 2025
dc566bb
fixup! e2e-tests: Provide script for provisioning the VM
adombeck Oct 23, 2025
f4fcba0
refactor: Rename RUN_ONSCREEN -> SHOW_WEBVIEW
adombeck Oct 23, 2025
8fb2eee
run_tests.sh: Add command-line arguments and a usage message
adombeck Oct 23, 2025
a55071a
fixup! Print output of browser_login.py on failure
adombeck Oct 23, 2025
c4dc0e0
fixup! e2e-tests: Add setup_yarf.sh
adombeck Oct 23, 2025
91625fc
fixup! e2e-tests: Add setup_yarf.sh
adombeck Oct 23, 2025
809ff78
fixup! run_tests.sh: Add command-line arguments and a usage message
adombeck Oct 23, 2025
dd85ff6
fixup! c4dc0e0ccb1a1912c1284ab965d0afcbdc2d87f3
adombeck Oct 23, 2025
3f2cad7
Improve naming consistency
denisonbarbosa Oct 23, 2025
ae133cd
Rename scripts to use - instead of _
denisonbarbosa Oct 23, 2025
9bcf9c6
Update documentation to consider latest changes
denisonbarbosa Oct 23, 2025
4aefdc6
fixup! e2e-tests: Provide script for provisioning the VM
adombeck Oct 23, 2025
b3f0043
ci: Add "Shell: Code sanity" job
adombeck Oct 23, 2025
1dcbd50
run-tests.sh: Fix "test_result: unbound variable"
adombeck Oct 23, 2025
12bbb3e
e2e-tests: Log video of webview on error
adombeck Oct 24, 2025
3df1bef
e2e-tests: Make browser_login.py more robust
adombeck Oct 24, 2025
e6d0d4b
Fix shellcheck warning
adombeck Oct 24, 2025
ff78cbc
Update system time when first logging in the VM
denisonbarbosa Oct 24, 2025
740aa91
e2e-tests/browser-login: Use argparse to parse input arguments
3v1n0 Oct 24, 2025
605aa83
e2e-tests/browser-login: Use C locale by default
3v1n0 Oct 24, 2025
ee1edf8
e2e-tests/browser-login: Automatically compute the snapshot index
3v1n0 Oct 24, 2025
5aba600
e2e-tests/browser_window: Clarify the usage of the overlay
3v1n0 Oct 24, 2025
eb5b25b
e2e-tests/browser_window: Use stronger JS code to check for text
3v1n0 Oct 24, 2025
b99578e
e2e-tests/brower_window: Use multi-line imports from gi
3v1n0 Oct 24, 2025
1033a01
e2e-tests: Grab default only after the widget is part of a window
3v1n0 Oct 24, 2025
3ce35be
e2e-tests/browser_window: Improve the JS injection code
3v1n0 Oct 24, 2025
d150900
e2e-tests: Clarify that we are not looking for *visible* text yet
3v1n0 Oct 24, 2025
7234026
e2e-tests/browser_window: Remove unused code
3v1n0 Oct 24, 2025
89be4fb
e2e-tests: Move snapshot functionality to browser window
3v1n0 Oct 24, 2025
6e69e9c
e2e-tests/browser_login: Take a window snapshot on failure
3v1n0 Oct 24, 2025
9081430
e2e-tests/browser_window: Use native Gdk functions to create surface
3v1n0 Oct 24, 2025
021f883
e2e-tests/browser_window: Save snapshots in threads
3v1n0 Oct 25, 2025
1817de1
e2e-tests/browser-window: Add utility function to connect to draw events
3v1n0 Oct 25, 2025
9a34dc6
e2e-tests/browser-window: Support full video recording
3v1n0 Oct 25, 2025
3604e73
e2e-tests/browser-login: Run again offscreen by default
3v1n0 Oct 25, 2025
1e6b111
e2e-tests/browser-login: Destroy browser on cleanup
3v1n0 Oct 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ jobs:
golangci-lint-configfile: ".golangci.yaml"
tools-directory: "tools"

shell-sanity:
name: "Shell: Code sanity"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Run ShellCheck
uses: ludeeus/action-shellcheck@master

go-tests:
name: "Go: Tests"
runs-on: ubuntu-24.04 # ubuntu-latest-runner
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
cmd/authd-oidc/authd-oidc
/authd-msentraid
cmd/authd-oidc/authd-msentraid
__pycache__

# Test binary, built with `go test -c`
*.test
Expand Down
3 changes: 3 additions & 0 deletions e2e-tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/vm/.artifacts/
/.yarf/

28 changes: 28 additions & 0 deletions e2e-tests/resources/authd-msentraid/Browser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import os

from robot.api.deco import keyword, library # type: ignore
from robot.libraries.Process import Process
from robot.api import logger

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))

def run_command(command: str, *arguments):
result = Process().run_process(command, *arguments)
if result.rc == 0:
return

cmd = command if not arguments else f"{command} {' '.join(arguments)}"
message = (f"Command '{cmd}' failed:\n"
f"--- stdout ---\n{result.stdout}\n"
f"--- stderr ---\n{result.stderr}")
logger.error(message)
raise RuntimeError(f"Command '{cmd}' failed")


@library
class Browser:
@keyword
async def login(self, username: str, password: str, usercode: str, output_dir: str = "."):
"""Perform device authentication with the given username, password and usercode."""
login_script = os.path.join(SCRIPT_DIR, "browser_login.py")
run_command(login_script, username, password, usercode, output_dir)
296 changes: 296 additions & 0 deletions e2e-tests/resources/authd-msentraid/broker.resource
Original file line number Diff line number Diff line change
@@ -0,0 +1,296 @@
*** Settings ***
Documentation MS Entra ID specific resources for the tests

Resource kvm.resource
Resource ../authd/utils.resource
Library ./Browser.py AS Browser
Library Hid.py AS Hid

*** Variables ***
${ENTRAID_RESOURCES} ${CURDIR}

${AUTHD_BROKER_CFG} /etc/authd/brokers.d/msentraid.conf
${ENTRAID_BROKER_CFG} /var/snap/authd-msentraid/current/broker.conf
${ENTRAID_BROKER_CFG_DIR} /var/snap/authd-msentraid/current/broker.conf.d


*** Keywords ***
Enable Edge Broker
Open Terminal In Sudo Mode
Run Command In Terminal snap refresh authd-msentraid --edge
Close Terminal In Sudo Mode


Disable Broker And Purge Config
Open Terminal In Sudo Mode
Run Command In Terminal snap stop authd-msentraid
Run Command In Terminal rm ${AUTHD_BROKER_CFG}
Run Command In Terminal systemctl restart authd.service
Close Terminal In Sudo Mode


Log In With Remote User Through CLI: QR Code
[Arguments] ${username} ${local_password}
Start Log In With Remote User Through CLI: QR Code ${username}
Select Provider
Continue Log In With Remote User: Log In On External Browser ${username}
Continue Log In With Remote User Through CLI: Define Local Password ${username} ${local_password}


Start Log In With Remote User Through CLI: QR Code
[Arguments] ${username}
Hid.Type String machinectl login
Hid.Keys Combo Return
Match Text ubuntu login: 60
Hid.Type String ${username}
Hid.Keys Combo Return

# Check that the provider selection contains the Entra ID provider
Match Text Select your provider 15


Select Provider
# Check that the provider selection contains the Entra ID provider
Match Text Select your provider 15
Match Text 2. Microsoft Entra ID

# Select the Entra ID provider
Hid.Type String 2
Builtin.Sleep 2

Regenerate QR Code
# As long as we are in the login process, we can regenerate the QR code
Match Text Request new login code 30
Hid.Keys Combo Return
Match Text https://microsoft.com/devicelogin 15


Continue Log In With Remote User: Log In On External Browser
[Arguments] ${username}
# Wait until the verification URL and login code are displayed
Match Text https://microsoft.com/devicelogin
# Read the user code.
${text} = Read Text
${user_code} = StringUtils.First Match (https://)?microsoft.com/devicelogin\n((Login code: )?([A-Z0-9]+)) ${text}

Browser.Login ${username} %{E2E_PASSWORD} ${user_code} ${OUTPUT DIR}
Builtin.Sleep 5


Continue Log In With Remote User Through CLI: Define Local Password
[Arguments] ${username} ${local_password}
# The terminal should now be visible and focused again.
# Check that we're prompted to set a local password.
Match Text New password: 60

# Set a local password
Hid.Type String ${local_password}
Hid.Keys Combo Return

# Confirm the local password
Match Text Confirm password:
Hid.Type String ${local_password}
Hid.Keys Combo Return

# Wait for the login to complete
${timeout_sec} = Set Variable 30
Match Text ${username}@ubuntu ${timeout_sec}


Log In With Remote User Through CLI: Local Password
[Arguments] ${username} ${local_password}
Hid.Type String machinectl login
Hid.Keys Combo Return
Match Text ubuntu login: 60
Hid.Type String ${username}
Hid.Keys Combo Return
Builtin.Sleep 2
Match Text Enter your local password: 30
Hid.Type String ${local_password}
Hid.Keys Combo Return
Builtin.Sleep 2
Match Text ${username}@ubuntu:~$ 30


# Uses sed to change the broker configuration.
# It should match both commented and uncommented lines.
# The full commands looks like:
# sed -i 's/#*${config_key} = .*/${config_key} = ${config_value}/g' ${ENTRAID_BROKER_CFG}
Change Broker Configuration
[Arguments] ${config_key} ${config_value}
Open Terminal In Sudo Mode
Hid.Type String sed -i 's/#*${config_key} = .*/${config_key} = ${config_value}/g' ${ENTRAID_BROKER_CFG}
Hid.Keys Combo Return
Run Command In Terminal snap restart authd-msentraid
Close Terminal In Sudo Mode


# Pretty much the same as the function above, but since YARF does not have support for
# shifted characters yet, we need to do some workarounds.
Change allowed_users In Broker Configuration
[Arguments] ${config_value}
Run Command In Terminal sudo sed -i 's/#*allowed_users = .*/allowed_users = ${config_value}/g' ${ENTRAID_BROKER_CFG}
Run Command In Terminal snap restart authd-msentraid


Comment Key In Broker Configuration
[Arguments] ${config_key}
Run Command In Terminal sudo sed -i 's/#*${config_key} = .*/#${config_key} = .*/g' ${ENTRAID_BROKER_CFG}
Run Command In Terminal snap restart authd-msentraid


Log In With Remote User Through SSH: QR Code
[Arguments] ${username} ${local_password}
Start Log In With Remote User Through SSH: QR Code ${username}
Select Provider through SSH
Continue Log In With Remote User: Log In On External Browser ${username}
Continue Log In With Remote User Through SSH: QR Code
Continue Log In With Remote User Through SSH: Define Local Password ${username} ${local_password}


Start Log In With Remote User Through SSH: QR Code
[Arguments] ${username}
Hid.Type String ssh ${username}@localhost
Hid.Keys Combo Return
Builtin.Sleep 2
Hid.Type String yes
Hid.Keys Combo Return


Select Provider through SSH
Match Text 2. Microsoft Entra ID 30
Match Text Choose your provider: 30
Hid.Type String 2
Hid.Keys Combo Return


Continue Log In With Remote User Through SSH: QR Code
Match Text Choose action: 30
Hid.Type String 1
Hid.Keys Combo Return


Continue Log In With Remote User Through SSH: Define Local Password
[Arguments] ${username} ${local_password}
Match Text Create a local password: 30
Hid.Type String ${local_password}
Hid.Keys Combo Return

Match Text Confirm Password: 30
Hid.Type String ${local_password}
Hid.Keys Combo Return

Match Text ${username}@ubuntu:~$ 30


Log In With Remote User Through SSH: Local Password
[Arguments] ${username} ${local_password}
Hid.Type String ssh ${username}@localhost
Hid.Keys Combo Return
Match Text Enter your local password: 30
Hid.Type String ${local_password}
Hid.Keys Combo Return
Match Text ${username}@ubuntu:~$ 30


Log In With Remote User Through GDM: QR Code
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yay!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, isn't this common to all brokers?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of. The broker name on the list of brokers will change, and if we ever release brokers with different authentication modes, it will complicate things (if we move this to authd.resource), so I think it's better to keep it this way for now

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, but the GDM ui won't change depending on that

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to keep authentication-related "functions" in their respective brokers' resources. I know it will create some code duplication, but a little copy here keeps things easier to understand and to find.

[Arguments] ${username} ${local_password}
Start Log In With Remote User Through GDM: QR Code ${username}
Select Broker Through GDM
Continue Log In With Remote User: Log In On External Browser ${username}
Continue Log In With Remote User Through GDM: Define Local Password ${local_password}



Start Log In With Remote User Through GDM: QR Code
[Arguments] ${username}
Match Text Not listed 180
Move Pointer To Not Listed
Left Button Click

# Enter the username
Match Text Username
Hid.Type String ${username}
Hid.Keys Combo Return


Select Broker Through GDM
Match Text Select the broker 30
Move Pointer To Microsoft Entra ID
Left Button Click
Builtin.Sleep 1


Continue Log In With Remote User Through GDM: Define Local Password
[Arguments] ${local_password}
Match Text Create a local password 30
Hid.Type String ${local_password}
Hid.Keys Combo Return

Match Text Please, type the new passphrase again 30
Hid.Type String ${local_password}
Hid.Keys Combo Return

Hid.Move Pointer To Proportional 0 1
Match Text Show Apps 60


Log In With Remote User Through GDM: Local Password
[Arguments] ${username} ${local_password}
Match Text Not listed 180
Move Pointer To Not Listed
Left Button Click
# Enter the username
Match Text Username
Hid.Type String ${username}
Hid.Keys Combo Return

# Enter the password
Match Text Password
Hid.Type String ${local_password}
Hid.Keys Combo Return

Hid.Move Pointer To Proportional 0 1
Match Text Show Apps 60


Check User Information
[Arguments] ${username}
Match Text ${username}:x: 30


Check User Groups
[Arguments] ${username} ${remote_group}
Match Text ${username} sudo ${remote_group} 30


Check Configuration Value
[Arguments] ${config_key} ${expected_value}
Hid.Type String cat ${ENTRAID_BROKER_CFG}
# TODO: Even though the Hid.Type String works for most characters now, it seems like there are still issues with
# some special characters like `|`, so we still need the workaround here.
Hid.Keys Combo Shift_L |
Hid.Type String grep ${config_key}
Hid.Keys Combo Return
Match Text ${expected_value} 30


Check If Owner Was Registered
[Arguments] ${username}
Hid.Type String cat ${ENTRAID_BROKER_CFG_DIR}/20-owner-autoregistration.conf
Hid.Keys Combo Return
Match Text owner = ${username} 30


Check Home Directory
[Arguments] ${username}
Hid.Type String echo $HOME
Hid.Keys Combo Return
Match Text /home/${username} 30
Hid.Type String ls -l
Hid.Keys Combo Return
Match Text ${username} ${username}


Check That Remote User Is Not Allowed To Log In
Match Text authentication failure: user not allowed in broker configuration 60
Loading
Loading