nextcloud: fix ldap and sso integration and add playwright tests
This commit is contained in:
parent
7717e39671
commit
ebd39bbe73
6 changed files with 221 additions and 30 deletions
|
|
@ -77,6 +77,15 @@
|
||||||
"blocks-authelia-options-shb.authelia.enable": [
|
"blocks-authelia-options-shb.authelia.enable": [
|
||||||
"blocks-authelia.html#blocks-authelia-options-shb.authelia.enable"
|
"blocks-authelia.html#blocks-authelia-options-shb.authelia.enable"
|
||||||
],
|
],
|
||||||
|
"blocks-authelia-options-shb.authelia.extraDefinitions": [
|
||||||
|
"blocks-authelia.html#blocks-authelia-options-shb.authelia.extraDefinitions"
|
||||||
|
],
|
||||||
|
"blocks-authelia-options-shb.authelia.extraOidcClaimsPolicies": [
|
||||||
|
"blocks-authelia.html#blocks-authelia-options-shb.authelia.extraOidcClaimsPolicies"
|
||||||
|
],
|
||||||
|
"blocks-authelia-options-shb.authelia.extraOidcScopes": [
|
||||||
|
"blocks-authelia.html#blocks-authelia-options-shb.authelia.extraOidcScopes"
|
||||||
|
],
|
||||||
"blocks-authelia-options-shb.authelia.ldapHostname": [
|
"blocks-authelia-options-shb.authelia.ldapHostname": [
|
||||||
"blocks-authelia.html#blocks-authelia-options-shb.authelia.ldapHostname"
|
"blocks-authelia.html#blocks-authelia-options-shb.authelia.ldapHostname"
|
||||||
],
|
],
|
||||||
|
|
@ -3041,6 +3050,9 @@
|
||||||
"services-nextcloudserver-options-shb.nextcloud.apps.sso": [
|
"services-nextcloudserver-options-shb.nextcloud.apps.sso": [
|
||||||
"services-nextcloud.html#services-nextcloudserver-options-shb.nextcloud.apps.sso"
|
"services-nextcloud.html#services-nextcloudserver-options-shb.nextcloud.apps.sso"
|
||||||
],
|
],
|
||||||
|
"services-nextcloudserver-options-shb.nextcloud.apps.sso.adminGroup": [
|
||||||
|
"services-nextcloud.html#services-nextcloudserver-options-shb.nextcloud.apps.sso.adminGroup"
|
||||||
|
],
|
||||||
"services-nextcloudserver-options-shb.nextcloud.apps.sso.authorization_policy": [
|
"services-nextcloudserver-options-shb.nextcloud.apps.sso.authorization_policy": [
|
||||||
"services-nextcloud.html#services-nextcloudserver-options-shb.nextcloud.apps.sso.authorization_policy"
|
"services-nextcloud.html#services-nextcloudserver-options-shb.nextcloud.apps.sso.authorization_policy"
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,24 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extraOidcClaimsPolicies = lib.mkOption {
|
||||||
|
description = "Extra OIDC claims policies.";
|
||||||
|
type = lib.types.attrsOf lib.types.attrs;
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
extraOidcScopes = lib.mkOption {
|
||||||
|
description = "Extra OIDC scopes.";
|
||||||
|
type = lib.types.attrsOf lib.types.attrs;
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
extraDefinitions = lib.mkOption {
|
||||||
|
description = "Extra definitions.";
|
||||||
|
type = lib.types.attrsOf lib.types.attrs;
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
|
||||||
oidcClients = lib.mkOption {
|
oidcClients = lib.mkOption {
|
||||||
description = "OIDC clients";
|
description = "OIDC clients";
|
||||||
default = [
|
default = [
|
||||||
|
|
@ -205,13 +223,13 @@ in
|
||||||
|
|
||||||
scopes = lib.mkOption {
|
scopes = lib.mkOption {
|
||||||
type = lib.types.listOf lib.types.str;
|
type = lib.types.listOf lib.types.str;
|
||||||
description = "Scopes to ask for";
|
description = "Scopes to ask for. See https://www.authelia.com/integration/openid-connect/openid-connect-1.0-claims";
|
||||||
example = [ "openid" "profile" "email" "groups" ];
|
example = [ "openid" "profile" "email" "groups" ];
|
||||||
default = [];
|
default = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
claims_policy = lib.mkOption {
|
claims_policy = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.nullOr lib.types.str;
|
||||||
description = ''
|
description = ''
|
||||||
Claim policy.
|
Claim policy.
|
||||||
|
|
||||||
|
|
@ -387,11 +405,6 @@ in
|
||||||
user = "uid=admin,ou=people,${cfg.dcdomain}";
|
user = "uid=admin,ou=people,${cfg.dcdomain}";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
# This should go away at some point.
|
|
||||||
# https://www.authelia.com/integration/openid-connect/openid-connect-1.0-claims/#restore-functionality-prior-to-claims-parameter
|
|
||||||
identity_providers.oidc = {
|
|
||||||
claims_policies.default.id_token = [ "email" "preferred_username" "name" "groups" ];
|
|
||||||
};
|
|
||||||
totp = {
|
totp = {
|
||||||
disable = "false";
|
disable = "false";
|
||||||
issuer = fqdnWithPort;
|
issuer = fqdnWithPort;
|
||||||
|
|
@ -465,6 +478,17 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
log.level = if cfg.debug then "debug" else "info";
|
log.level = if cfg.debug then "debug" else "info";
|
||||||
|
} // {
|
||||||
|
identity_providers.oidc = {
|
||||||
|
claims_policies = {
|
||||||
|
# This default claim should go away at some point.
|
||||||
|
# https://www.authelia.com/integration/openid-connect/openid-connect-1.0-claims/#restore-functionality-prior-to-claims-parameter
|
||||||
|
default.id_token = [ "email" "preferred_username" "name" "groups" ];
|
||||||
|
} // cfg.extraOidcClaimsPolicies;
|
||||||
|
scopes = cfg.extraOidcScopes;
|
||||||
|
};
|
||||||
|
} // lib.optionalAttrs (cfg.extraDefinitions != {}) {
|
||||||
|
definitions = cfg.extraDefinitions;
|
||||||
};
|
};
|
||||||
|
|
||||||
settingsFiles = [ "/var/lib/authelia-${fqdn}/oidc_clients.yaml" ];
|
settingsFiles = [ "/var/lib/authelia-${fqdn}/oidc_clients.yaml" ];
|
||||||
|
|
|
||||||
|
|
@ -414,7 +414,6 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
userGroup = lib.mkOption {
|
userGroup = lib.mkOption {
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
description = "Group users must belong to to be able to login to Nextcloud.";
|
description = "Group users must belong to to be able to login to Nextcloud.";
|
||||||
|
|
@ -424,8 +423,8 @@ in
|
||||||
configID = lib.mkOption {
|
configID = lib.mkOption {
|
||||||
type = lib.types.int;
|
type = lib.types.int;
|
||||||
description = ''
|
description = ''
|
||||||
Multiple LDAP configs can co-exist with only one active at a time.This option
|
Multiple LDAP configs can co-exist with only one active at a time.
|
||||||
sets the config ID used by Self Host Blocks.
|
This option sets the config ID used by Self Host Blocks.
|
||||||
'';
|
'';
|
||||||
default = 50;
|
default = 50;
|
||||||
};
|
};
|
||||||
|
|
@ -475,6 +474,12 @@ in
|
||||||
default = "one_factor";
|
default = "one_factor";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
adminGroup = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Group admins must belong to to be able to login to Nextcloud.";
|
||||||
|
default = "nextcloud_admin";
|
||||||
|
};
|
||||||
|
|
||||||
secret = lib.mkOption {
|
secret = lib.mkOption {
|
||||||
description = "OIDC shared secret.";
|
description = "OIDC shared secret.";
|
||||||
type = lib.types.submodule {
|
type = lib.types.submodule {
|
||||||
|
|
@ -1022,7 +1027,7 @@ in
|
||||||
${occ} ldap:set-config "${cID}" 'ldapLoginFilterAttributes' \
|
${occ} ldap:set-config "${cID}" 'ldapLoginFilterAttributes' \
|
||||||
'mail;objectclass'
|
'mail;objectclass'
|
||||||
${occ} ldap:set-config "${cID}" 'ldapUserDisplayName' \
|
${occ} ldap:set-config "${cID}" 'ldapUserDisplayName' \
|
||||||
'displayname'
|
'givenname'
|
||||||
${occ} ldap:set-config "${cID}" 'ldapUserFilter' \
|
${occ} ldap:set-config "${cID}" 'ldapUserFilter' \
|
||||||
'(&(objectclass=person)(memberOf=cn=${cfg'.userGroup},ou=groups,${cfg'.dcdomain}))'
|
'(&(objectclass=person)(memberOf=cn=${cfg'.userGroup},ou=groups,${cfg'.dcdomain}))'
|
||||||
${occ} ldap:set-config "${cID}" 'ldapUserFilterMode' \
|
${occ} ldap:set-config "${cID}" 'ldapUserFilterMode' \
|
||||||
|
|
@ -1033,7 +1038,7 @@ in
|
||||||
# Nextcloud is compatible with the one returned by a (possibly added in the future) SSO
|
# Nextcloud is compatible with the one returned by a (possibly added in the future) SSO
|
||||||
# provider.
|
# provider.
|
||||||
${occ} ldap:set-config "${cID}" 'ldapExpertUsernameAttr' \
|
${occ} ldap:set-config "${cID}" 'ldapExpertUsernameAttr' \
|
||||||
'user_id'
|
'uid'
|
||||||
|
|
||||||
${occ} ldap:test-config -- "${cID}"
|
${occ} ldap:test-config -- "${cID}"
|
||||||
|
|
||||||
|
|
@ -1057,6 +1062,7 @@ in
|
||||||
"profile"
|
"profile"
|
||||||
"email"
|
"email"
|
||||||
"groups"
|
"groups"
|
||||||
|
"nextcloud_userinfo"
|
||||||
];
|
];
|
||||||
in lib.mkIf (cfg.enable && cfg.apps.sso.enable) {
|
in lib.mkIf (cfg.enable && cfg.apps.sso.enable) {
|
||||||
assertions = [
|
assertions = [
|
||||||
|
|
@ -1070,11 +1076,9 @@ in
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
systemd.services.nextcloud-setup.script =
|
services.nextcloud.extraApps = {
|
||||||
''
|
inherit (nextcloudApps) oidc_login;
|
||||||
${occ} app:install oidc_login || :
|
};
|
||||||
${occ} app:enable oidc_login
|
|
||||||
'';
|
|
||||||
|
|
||||||
systemd.services.nextcloud-setup-pre = {
|
systemd.services.nextcloud-setup-pre = {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
@ -1096,6 +1100,12 @@ in
|
||||||
secretFile = "${cfg.dataDir}/config/secretFile";
|
secretFile = "${cfg.dataDir}/config/secretFile";
|
||||||
|
|
||||||
# See all options at https://github.com/pulsejet/nextcloud-oidc-login
|
# See all options at https://github.com/pulsejet/nextcloud-oidc-login
|
||||||
|
# Other important url/links are:
|
||||||
|
# ${fqdn}/.well-known/openid-configuration
|
||||||
|
# https://www.authelia.com/reference/guides/attributes/#custom-attributes
|
||||||
|
# https://github.com/lldap/lldap/blob/main/example_configs/nextcloud_oidc_authelia.md
|
||||||
|
# https://www.authelia.com/integration/openid-connect/nextcloud/#authelia
|
||||||
|
# https://www.openidconnect.net/
|
||||||
settings = {
|
settings = {
|
||||||
allow_user_to_change_display_name = false;
|
allow_user_to_change_display_name = false;
|
||||||
lost_password_link = "disabled";
|
lost_password_link = "disabled";
|
||||||
|
|
@ -1110,12 +1120,14 @@ in
|
||||||
oidc_login_logout_url = ssoFqdnWithPort;
|
oidc_login_logout_url = ssoFqdnWithPort;
|
||||||
oidc_login_button_text = "Log in with ${cfg.apps.sso.provider}";
|
oidc_login_button_text = "Log in with ${cfg.apps.sso.provider}";
|
||||||
oidc_login_hide_password_form = false;
|
oidc_login_hide_password_form = false;
|
||||||
oidc_login_use_id_token = true;
|
# Now, Authelia provides the info using the UserInfo request.
|
||||||
|
oidc_login_use_id_token = false;
|
||||||
oidc_login_attributes = {
|
oidc_login_attributes = {
|
||||||
id = "preferred_username";
|
id = "preferred_username";
|
||||||
name = "name";
|
name = "name";
|
||||||
mail = "email";
|
mail = "email";
|
||||||
groups = "groups";
|
groups = "groups";
|
||||||
|
is_admin = "is_nextcloud_admin";
|
||||||
};
|
};
|
||||||
oidc_login_default_group = "oidc";
|
oidc_login_default_group = "oidc";
|
||||||
oidc_login_use_external_storage = false;
|
oidc_login_use_external_storage = false;
|
||||||
|
|
@ -1136,8 +1148,7 @@ in
|
||||||
# they are not already existing, Default is `false`. This creates groups for all groups
|
# they are not already existing, Default is `false`. This creates groups for all groups
|
||||||
# the user is associated with in LDAP. It's too much.
|
# the user is associated with in LDAP. It's too much.
|
||||||
oidc_create_groups = false;
|
oidc_create_groups = false;
|
||||||
# Enable use of WebDAV via OIDC bearer token.
|
oidc_login_webdav_enabled = false;
|
||||||
oidc_login_webdav_enabled = true;
|
|
||||||
oidc_login_password_authentication = false;
|
oidc_login_password_authentication = false;
|
||||||
oidc_login_public_key_caching_time = 86400;
|
oidc_login_public_key_caching_time = 86400;
|
||||||
oidc_login_min_time_between_jwks_requests = 10;
|
oidc_login_min_time_between_jwks_requests = 10;
|
||||||
|
|
@ -1145,19 +1156,39 @@ in
|
||||||
# If true, nextcloud will download user avatars on login. This may lead to security issues
|
# If true, nextcloud will download user avatars on login. This may lead to security issues
|
||||||
# as the server does not control which URLs will be requested. Use with care.
|
# as the server does not control which URLs will be requested. Use with care.
|
||||||
oidc_login_update_avatar = false;
|
oidc_login_update_avatar = false;
|
||||||
|
oidc_login_code_challenge_method = "S256";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
shb.authelia.extraDefinitions = {
|
||||||
|
user_attributes."is_nextcloud_admin".expression = ''type(groups) == list && "${cfg.apps.sso.adminGroup}" in groups'';
|
||||||
|
};
|
||||||
|
shb.authelia.extraOidcClaimsPolicies."nextcloud_userinfo" = {
|
||||||
|
custom_claims = {
|
||||||
|
is_nextcloud_admin = {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
shb.authelia.extraOidcScopes."nextcloud_userinfo" = {
|
||||||
|
claims = [ "is_nextcloud_admin" ];
|
||||||
|
};
|
||||||
|
|
||||||
shb.authelia.oidcClients = lib.mkIf (cfg.apps.sso.provider == "Authelia") [
|
shb.authelia.oidcClients = lib.mkIf (cfg.apps.sso.provider == "Authelia") [
|
||||||
{
|
{
|
||||||
client_id = cfg.apps.sso.clientID;
|
client_id = cfg.apps.sso.clientID;
|
||||||
client_name = "Nextcloud";
|
client_name = "Nextcloud";
|
||||||
client_secret.source = cfg.apps.sso.secretForAuthelia.result.path;
|
client_secret.source = cfg.apps.sso.secretForAuthelia.result.path;
|
||||||
|
claims_policy = "nextcloud_userinfo";
|
||||||
public = false;
|
public = false;
|
||||||
authorization_policy = cfg.apps.sso.authorization_policy;
|
authorization_policy = cfg.apps.sso.authorization_policy;
|
||||||
|
require_pkce = "true";
|
||||||
|
pkce_challenge_method = "S256";
|
||||||
redirect_uris = [ "${protocol}://${fqdnWithPort}/apps/oidc_login/oidc" ];
|
redirect_uris = [ "${protocol}://${fqdnWithPort}/apps/oidc_login/oidc" ];
|
||||||
inherit scopes;
|
inherit scopes;
|
||||||
userinfo_signing_algorithm = "none";
|
response_types = [ "code" ];
|
||||||
|
grant_types = [ "authorization_code" ];
|
||||||
|
access_token_signed_response_alg = "none";
|
||||||
|
userinfo_signed_response_alg = "none";
|
||||||
|
token_endpoint_auth_method = "client_secret_basic";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -179,10 +179,9 @@ to do that with SOPS we use the `key` option so that both
|
||||||
and `sops.secrets."nextcloud/ldapUserPassword"`
|
and `sops.secrets."nextcloud/ldapUserPassword"`
|
||||||
secrets have the same content.
|
secrets have the same content.
|
||||||
|
|
||||||
Creating LDAP users and groups is not declarative yet,
|
The LDAP [user group](#services-nextcloudserver-options-shb.nextcloud.apps.ldap.userGroup) is created automatically.
|
||||||
so go to the LDAP server at `http://ldap.example.com`,
|
Add your user to it by going to `http://ldap.example.com`,
|
||||||
create the `nextcloud_user` group,
|
create a user if needed and add it to the group.
|
||||||
create a user and add it to the group.
|
|
||||||
When that's done, go back to the Nextcloud server at
|
When that's done, go back to the Nextcloud server at
|
||||||
`https://nextcloud.example.com` and login with that user.
|
`https://nextcloud.example.com` and login with that user.
|
||||||
|
|
||||||
|
|
@ -190,6 +189,7 @@ Note that we cannot create an admin user from the LDAP server,
|
||||||
so you need to create a normal user like above,
|
so you need to create a normal user like above,
|
||||||
login with it once so it is known to Nextcloud, then logout,
|
login with it once so it is known to Nextcloud, then logout,
|
||||||
login with the admin Nextcloud user and promote that new user to admin level.
|
login with the admin Nextcloud user and promote that new user to admin level.
|
||||||
|
This limitation does not exist with the [SSO integration](#services-nextcloudserver-usage-oidc).
|
||||||
|
|
||||||
### With SSO Support {#services-nextcloudserver-usage-oidc}
|
### With SSO Support {#services-nextcloudserver-usage-oidc}
|
||||||
|
|
||||||
|
|
@ -231,6 +231,12 @@ to do that with SOPS we use the `key` option so that both
|
||||||
and `sops.secrets."nextcloud/sso/secretForAuthelia"`
|
and `sops.secrets."nextcloud/sso/secretForAuthelia"`
|
||||||
secrets have the same content.
|
secrets have the same content.
|
||||||
|
|
||||||
|
The LDAP [user group](#services-nextcloudserver-options-shb.nextcloud.apps.ldap.userGroup) and [admin group](#services-nextcloudserver-options-shb.nextcloud.apps.sso.adminGroup) are created automatically.
|
||||||
|
Add your user to one or both by going to `http://ldap.example.com`,
|
||||||
|
create a user if needed and add it to the groups.
|
||||||
|
When that's done, go back to the Nextcloud server at
|
||||||
|
`https://nextcloud.example.com` and login with that user.
|
||||||
|
|
||||||
Setting the `fallbackDefaultAuth` to `false` means the only way to login is through Authelia.
|
Setting the `fallbackDefaultAuth` to `false` means the only way to login is through Authelia.
|
||||||
If this does not work for any reason, you can let users login through Nextcloud directly by setting this option to `true`.
|
If this does not work for any reason, you can let users login through Nextcloud directly by setting this option to `true`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -198,6 +198,10 @@ in
|
||||||
# HTTP(s) server port.
|
# HTTP(s) server port.
|
||||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||||
shb.nginx.accessLog = true;
|
shb.nginx.accessLog = true;
|
||||||
|
|
||||||
|
networking.hosts = {
|
||||||
|
"192.168.1.2" = [ config.test.fqdn ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -415,6 +419,11 @@ in
|
||||||
groups = [ "user_group" "admin_group" ];
|
groups = [ "user_group" "admin_group" ];
|
||||||
password.result.path = pkgs.writeText "bobPassword" "BobPassword";
|
password.result.path = pkgs.writeText "bobPassword" "BobPassword";
|
||||||
};
|
};
|
||||||
|
# charlie = {
|
||||||
|
# email = "charlie@example.com";
|
||||||
|
# groups = [ ];
|
||||||
|
# password.result.path = pkgs.writeText "charliePassword" "CharliePassword";
|
||||||
|
# };
|
||||||
};
|
};
|
||||||
|
|
||||||
ensureGroups = {
|
ensureGroups = {
|
||||||
|
|
@ -430,7 +439,7 @@ in
|
||||||
];
|
];
|
||||||
|
|
||||||
networking.hosts = {
|
networking.hosts = {
|
||||||
"127.0.0.1" = [ "auth.${config.test.domain}" ];
|
"127.0.0.1" = [ "${config.shb.authelia.subdomain}.${config.shb.authelia.domain}" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
shb.authelia = {
|
shb.authelia = {
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,91 @@ let
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
clientLdapLogin = { config, ... }: {
|
||||||
|
imports = [
|
||||||
|
testLib.baseModule
|
||||||
|
testLib.clientLoginModule
|
||||||
|
];
|
||||||
|
virtualisation.memorySize = 4096;
|
||||||
|
|
||||||
|
test = {
|
||||||
|
subdomain = "n";
|
||||||
|
};
|
||||||
|
|
||||||
|
test.login = {
|
||||||
|
startUrl = "http://${config.test.fqdn}";
|
||||||
|
usernameFieldLabelRegex = "Account name";
|
||||||
|
passwordFieldLabelRegex = "^ *[Pp]assword";
|
||||||
|
loginButtonNameRegex = "[Ll]og [Ii]n";
|
||||||
|
testLoginWith = [
|
||||||
|
{ username = "alice"; password = "AlicePassword"; nextPageExpect = [
|
||||||
|
"expect(page.get_by_text('Wrong login or password')).not_to_be_visible()"
|
||||||
|
"expect(page.get_by_role('button', name=re.compile('[Ll]og [Ii]n'))).not_to_be_visible()"
|
||||||
|
"expect(page).to_have_title(re.compile('Dashboard'))"
|
||||||
|
]; }
|
||||||
|
{ username = "alice"; password = "NotAlicePassword"; nextPageExpect = [
|
||||||
|
"expect(page.get_by_text('Wrong login or password')).to_be_visible()"
|
||||||
|
]; }
|
||||||
|
{ username = "bob"; password = "BobPassword"; nextPageExpect = [
|
||||||
|
"expect(page.get_by_text('Wrong login or password')).not_to_be_visible()"
|
||||||
|
"expect(page.get_by_role('button', name=re.compile('[Ll]og [Ii]n'))).not_to_be_visible()"
|
||||||
|
"expect(page).to_have_title(re.compile('Dashboard'))"
|
||||||
|
]; }
|
||||||
|
{ username = "bob"; password = "NotBobPassword"; nextPageExpect = [
|
||||||
|
"expect(page.get_by_text('Wrong login or password')).to_be_visible()"
|
||||||
|
]; }
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
clientSsoLogin = { config, ... }: {
|
||||||
|
imports = [
|
||||||
|
testLib.baseModule
|
||||||
|
testLib.clientLoginModule
|
||||||
|
];
|
||||||
|
virtualisation.memorySize = 4096;
|
||||||
|
|
||||||
|
test = {
|
||||||
|
subdomain = "n";
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.hosts = {
|
||||||
|
"192.168.1.2" = [ "auth.example.com" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
test.login = {
|
||||||
|
startUrl = "http://${config.test.fqdn}";
|
||||||
|
usernameFieldLabelRegex = "Username";
|
||||||
|
passwordFieldSelector = "get_by_label(\"Password *\")";
|
||||||
|
loginButtonNameRegex = "[sS]ign [iI]n";
|
||||||
|
testLoginWith = [
|
||||||
|
{ username = "alice"; password = "AlicePassword"; nextPageExpect = [
|
||||||
|
"page.get_by_role('button', name=re.compile('Accept')).click()"
|
||||||
|
"expect(page).to_have_title(re.compile('Dashboard'))"
|
||||||
|
"page.goto('https://${config.test.fqdn}/settings/admin')"
|
||||||
|
"expect(page.get_by_text('Access forbidden')).to_be_visible()"
|
||||||
|
]; }
|
||||||
|
{ username = "alice"; password = "NotAlicePassword"; nextPageExpect = [
|
||||||
|
"expect(page.get_by_text('Incorrect username or password')).to_be_visible()"
|
||||||
|
]; }
|
||||||
|
{ username = "bob"; password = "BobPassword"; nextPageExpect = [
|
||||||
|
"page.get_by_role('button', name=re.compile('Accept')).click()"
|
||||||
|
"expect(page).to_have_title(re.compile('Dashboard'))"
|
||||||
|
"page.goto('https://${config.test.fqdn}/settings/admin')"
|
||||||
|
"expect(page.get_by_text('Access forbidden')).not_to_be_visible()"
|
||||||
|
]; }
|
||||||
|
{ username = "bob"; password = "NotBobPassword"; nextPageExpect = [
|
||||||
|
"expect(page.get_by_text('Incorrect username or password')).to_be_visible()"
|
||||||
|
]; }
|
||||||
|
# TODO: charlie has no groups, which makes lldap return a 'null' value instead of an empty array and Authelia does not like that.
|
||||||
|
# { username = "charlie"; password = "CharliePassword"; nextPageExpect = [
|
||||||
|
# "page.get_by_role('button', name=re.compile('Accept')).click()"
|
||||||
|
# "expect(page).to_have_title(re.compile('Dashboard'))"
|
||||||
|
# ]; }
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
https = { config, ...}: {
|
https = { config, ...}: {
|
||||||
shb.nextcloud = {
|
shb.nextcloud = {
|
||||||
ssl = config.shb.certs.certs.selfsigned.n;
|
ssl = config.shb.certs.certs.selfsigned.n;
|
||||||
|
|
@ -168,7 +253,7 @@ let
|
||||||
dcdomain = config.shb.lldap.dcdomain;
|
dcdomain = config.shb.lldap.dcdomain;
|
||||||
adminName = "admin";
|
adminName = "admin";
|
||||||
adminPassword.result = config.shb.hardcodedsecret.nextcloudLdapUserPassword.result;
|
adminPassword.result = config.shb.hardcodedsecret.nextcloudLdapUserPassword.result;
|
||||||
userGroup = "nextcloud_user";
|
userGroup = "user_group";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
shb.hardcodedsecret.nextcloudLdapUserPassword = {
|
shb.hardcodedsecret.nextcloudLdapUserPassword = {
|
||||||
|
|
@ -184,7 +269,7 @@ let
|
||||||
enable = true;
|
enable = true;
|
||||||
endpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}";
|
endpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}";
|
||||||
clientID = "nextcloud";
|
clientID = "nextcloud";
|
||||||
# adminUserGroup = "nextcloud_admin";
|
adminGroup = "admin_group";
|
||||||
|
|
||||||
secret.result = config.shb.hardcodedsecret.oidcSecret.result;
|
secret.result = config.shb.hardcodedsecret.oidcSecret.result;
|
||||||
secretForAuthelia.result = config.shb.hardcodedsecret.oidcAutheliaSecret.result;
|
secretForAuthelia.result = config.shb.hardcodedsecret.oidcAutheliaSecret.result;
|
||||||
|
|
@ -192,6 +277,10 @@ let
|
||||||
fallbackDefaultAuth = false;
|
fallbackDefaultAuth = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
# Needed because OIDC somehow does not like self-signed certificates
|
||||||
|
# which we do use in tests.
|
||||||
|
# See https://github.com/pulsejet/nextcloud-oidc-login/issues/267
|
||||||
|
services.nextcloud.settings.oidc_login_tls_verify = lib.mkForce false;
|
||||||
|
|
||||||
shb.hardcodedsecret.oidcSecret = {
|
shb.hardcodedsecret.oidcSecret = {
|
||||||
request = config.shb.nextcloud.apps.sso.secret.request;
|
request = config.shb.nextcloud.apps.sso.secret.request;
|
||||||
|
|
@ -436,13 +525,19 @@ in
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
nodes.client = {};
|
nodes.client = {
|
||||||
|
imports = [
|
||||||
|
clientLdapLogin
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
testScript = commonTestScript.access;
|
testScript = commonTestScript.access;
|
||||||
};
|
};
|
||||||
|
|
||||||
sso = pkgs.testers.runNixOSTest {
|
sso = pkgs.testers.runNixOSTest {
|
||||||
name = "nextcloud_sso";
|
name = "nextcloud_sso";
|
||||||
|
|
||||||
|
interactive.sshBackdoor.enable = true;
|
||||||
|
|
||||||
nodes.server = { config, ... }: {
|
nodes.server = { config, ... }: {
|
||||||
imports = [
|
imports = [
|
||||||
|
|
@ -453,10 +548,24 @@ in
|
||||||
ldap
|
ldap
|
||||||
(testLib.sso config.shb.certs.certs.selfsigned.n)
|
(testLib.sso config.shb.certs.certs.selfsigned.n)
|
||||||
sso
|
sso
|
||||||
|
({ config, ... }: {
|
||||||
|
networking.hosts = {
|
||||||
|
"127.0.0.1" = [ config.test.fqdn ];
|
||||||
|
};
|
||||||
|
})
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
nodes.client = {};
|
nodes.client = {
|
||||||
|
imports = [
|
||||||
|
clientSsoLogin
|
||||||
|
({ config, ... }: {
|
||||||
|
networking.hosts = {
|
||||||
|
"192.168.1.2" = [ config.test.fqdn ];
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
testScript = commonTestScript.access;
|
testScript = commonTestScript.access;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue