add playwright test with ldap for forgejo

This commit is contained in:
ibizaman 2025-07-24 22:44:34 +02:00 committed by Pierre Penninckx
parent 12f2b4f49e
commit 91580421be
5 changed files with 82 additions and 5 deletions

View file

@ -2213,6 +2213,9 @@
"services-forgejo-options-shb.forgejo.ldap.userGroup": [
"services-forgejo.html#services-forgejo-options-shb.forgejo.ldap.userGroup"
],
"services-forgejo-options-shb.forgejo.ldap.waitForSystemdServices": [
"services-forgejo.html#services-forgejo-options-shb.forgejo.ldap.waitForSystemdServices"
],
"services-forgejo-options-shb.forgejo.localActionRunner": [
"services-forgejo.html#services-forgejo-options-shb.forgejo.localActionRunner"
],

View file

@ -360,7 +360,7 @@ in
inherit (cfg) ensureGroups ensureUserFields ensureGroupFields;
ensureUsers = lib.mapAttrs (n: v: (lib.removeAttrs v [ "password" ]) // {
"password_file" = v.password.result.path;
"password_file" = toString v.password.result.path;
}) cfg.ensureUsers;
};
};

View file

@ -108,6 +108,16 @@ in
description = "Group users must belong to be admins.";
default = "forgejo_admin";
};
waitForSystemdServices = mkOption {
type = listOf str;
default = [];
description = ''
List of systemd services to wait on before starting.
This is needed because forgejo will try a lookup on the LDAP instance
and will abort setting up LDAP if it can't reach it.
'';
};
};
});
};
@ -392,6 +402,8 @@ in
# For cli info: https://docs.gitea.com/usage/command-line
# Security protocols in: https://codeberg.org/forgejo/forgejo/src/branch/forgejo/services/auth/source/ldap/security_protocol.go#L27-L31
(mkIf (cfg.enable && cfg.ldap.enable != false) {
systemd.services.forgejo.wants = cfg.ldap.waitForSystemdServices;
systemd.services.forgejo.after = cfg.ldap.waitForSystemdServices;
# The delimiter in the `cut` command is a TAB!
systemd.services.forgejo.preStart = let
provider = "SHB-${cfg.ldap.provider}";

View file

@ -120,22 +120,22 @@ let
+ (optionalString (hasAttr "test" nodes.server && hasAttr "login" nodes.server.test) ''
with subtest("Login from server"):
code, logs = server.execute("login_playwright")
print(logs)
try:
server.copy_from_vm("trace")
except:
print("No trace found on server")
print(logs)
if code != 0:
raise Exception("login_playwright did not succeed")
'')
+ (optionalString (hasAttr "test" nodes.client && hasAttr "login" nodes.client.test) ''
with subtest("Login from client"):
code, logs = client.execute("login_playwright")
print(logs)
try:
server.copy_from_vm("trace")
client.copy_from_vm("trace")
except:
print("No trace found on client")
print(logs)
if code != 0:
raise Exception("login_playwright did not succeed")
'')
@ -319,6 +319,7 @@ in
print(f"Page has title: {page.title()}")
exec(line)
finally:
print(f'Saving trace at trace/{i}.zip')
context.tracing.stop(path=f"trace/{i}.zip")
browser.close()
@ -401,6 +402,24 @@ in
dcdomain = "dc=example,dc=com";
ldapUserPassword.result = config.shb.hardcodedsecret.ldapUserPassword.result;
jwtSecret.result = config.shb.hardcodedsecret.jwtSecret.result;
ensureUsers = {
alice = {
email = "alice@example.com";
groups = [ "user_group" ];
password.result.path = pkgs.writeText "alicePassword" "AlicePassword";
};
bob = {
email = "bob@example.com";
groups = [ "user_group" "admin_group" ];
password.result.path = pkgs.writeText "bobPassword" "BobPassword";
};
};
ensureGroups = {
user_group = {};
admin_group = {};
};
};
};

View file

@ -118,6 +118,9 @@ let
port = config.shb.lldap.ldapPort;
dcdomain = config.shb.lldap.dcdomain;
adminPassword.result = config.shb.hardcodedsecret.forgejoLdapUserPassword.result;
waitForSystemdServices = [ "lldap.service" ];
userGroup = "user_group";
};
};
@ -200,6 +203,8 @@ in
ldap = pkgs.testers.runNixOSTest {
name = "forgejo_ldap";
interactive.sshBackdoor.enable = true;
nodes.server = {
imports = [
basic
@ -208,7 +213,45 @@ in
];
};
nodes.client = {};
nodes.client = {
imports = [
({ config, ... }: {
imports = [
testLib.baseModule
testLib.clientLoginModule
];
test = {
subdomain = "f";
};
test.login = {
startUrl = "http://${config.test.fqdn}/user/login";
usernameFieldLabelRegex = "Username or email address";
passwordFieldLabelRegex = "Password";
loginButtonNameRegex = "[sS]ign [iI]n";
testLoginWith = [
{ username = "alice"; password = "NotAlicePassword"; nextPageExpect = [
"expect(page.get_by_text('Username or password is incorrect.')).to_be_visible()"
]; }
{ username = "alice"; password = "AlicePassword"; nextPageExpect = [
"expect(page.get_by_text('Username or password is incorrect.')).not_to_be_visible()"
"expect(page.get_by_role('button', name=re.compile('Sign In'))).not_to_be_visible()"
"expect(page).to_have_title(re.compile('Dashboard'))"
]; }
{ username = "bob"; password = "NotBobPassword"; nextPageExpect = [
"expect(page.get_by_text('Username or password is incorrect.')).to_be_visible()"
]; }
{ username = "bob"; password = "BobPassword"; nextPageExpect = [
"expect(page.get_by_text('Username or password is incorrect.')).not_to_be_visible()"
"expect(page.get_by_role('button', name=re.compile('Sign In'))).not_to_be_visible()"
"expect(page).to_have_title(re.compile('Dashboard'))"
]; }
];
};
})
];
};
testScript = commonTestScript.access;
};