diff --git a/sp-modules/gitea/module.nix b/sp-modules/gitea/module.nix index 41381fb..3c888df 100644 --- a/sp-modules/gitea/module.nix +++ b/sp-modules/gitea/module.nix @@ -1,4 +1,4 @@ -{ config, lib, options, pkgs, ... }: +{ config, lib, pkgs, ... }: let sp = config.selfprivacy; stateDir = @@ -309,152 +309,149 @@ in }; } # the following part is active only when "auth" module is enabled - (lib.attrsets.optionalAttrs - (options.selfprivacy.modules ? "auth") - (lib.mkIf is-auth-enabled { - services.forgejo.settings = { - auth.DISABLE_LOGIN_FORM = true; - service = { - DISABLE_REGISTRATION = cfg.disableRegistration; - REQUIRE_SIGNIN_VIEW = cfg.requireSigninView; - ALLOW_ONLY_EXTERNAL_REGISTRATION = true; - SHOW_REGISTRATION_BUTTON = false; - ENABLE_BASIC_AUTHENTICATION = false; - }; - - # disallow explore page and access to private repositories, but allow public - "service.explore".REQUIRE_SIGNIN_VIEW = true; - - # TODO control via selfprivacy parameter - # "service.explore".DISABLE_USERS_PAGE = true; - - oauth2_client = { - REDIRECT_URI = redirect-uri; - ACCOUNT_LINKING = "auto"; - ENABLE_AUTO_REGISTRATION = true; - OPENID_CONNECT_SCOPES = "email openid profile"; - }; - # doesn't work if LDAP auth source is not active! - "cron.sync_external_users" = { - ENABLED = true; - RUN_AT_START = true; - NOTICE_ON_SUCCESS = true; - }; + (lib.mkIf is-auth-enabled { + services.forgejo.settings = { + auth.DISABLE_LOGIN_FORM = true; + service = { + DISABLE_REGISTRATION = cfg.disableRegistration; + REQUIRE_SIGNIN_VIEW = cfg.requireSigninView; + ALLOW_ONLY_EXTERNAL_REGISTRATION = true; + SHOW_REGISTRATION_BUTTON = false; + ENABLE_BASIC_AUTHENTICATION = false; }; - systemd.services.forgejo = { - preStart = - let - exe = lib.getExe config.services.forgejo.package; - # FIXME skip-tls-verify, bind-password - ldapConfigArgs = '' - --name LDAP \ - --active \ - --security-protocol LDAPS \ - --skip-tls-verify \ - --host '${auth-passthru.ldap-host}' \ - --port '${toString auth-passthru.ldap-port}' \ - --user-search-base '${auth-passthru.ldap-base-dn}' \ - --user-filter '(&(class=person)(memberof=${users-group})(name=%s))' \ - --admin-filter '(&(class=person)(memberof=${admins-group}))' \ - --username-attribute name \ - --firstname-attribute name \ - --surname-attribute displayname \ - --email-attribute mail \ - --public-ssh-key-attribute sshPublicKey \ - --bind-dn 'dn=token' \ - --bind-password "$(cat ${kanidm-service-account-token-fp})" \ - --synchronize-users - ''; - oauthConfigArgs = '' - --name "${oauth2-provider-name}" \ - --provider openidConnect \ - --key forgejo \ - --secret "$(<${kanidm-oauth-client-secret-fp})" \ - --group-claim-name groups \ - --admin-group admins \ - --auto-discover-url '${auth-passthru.oauth2-discovery-url oauth-client-id}' - ''; - in - lib.mkAfter '' - set -o xtrace - # Check if LDAP is already configured - ldap_line="$(${exe} admin auth list | grep LDAP | head -n 1)" + # disallow explore page and access to private repositories, but allow public + "service.explore".REQUIRE_SIGNIN_VIEW = true; - if [[ -n "$ldap_line" ]]; then - # update ldap config - id="$(echo "$ldap_line" | ${pkgs.gawk}/bin/awk '{print $1}')" - ${exe} admin auth update-ldap --id "$id" ${ldapConfigArgs} - else - # initially configure ldap - ${exe} admin auth add-ldap ${ldapConfigArgs} - fi + # TODO control via selfprivacy parameter + # "service.explore".DISABLE_USERS_PAGE = true; - oauth_line="$(${exe} admin auth list | grep "${oauth2-provider-name}" | head -n 1)" - if [[ -n "$oauth_line" ]]; then - id="$(echo "$oauth_line" | ${pkgs.gawk}/bin/awk '{print $1}')" - ${exe} admin auth update-oauth --id "$id" ${oauthConfigArgs} - else - ${exe} admin auth add-oauth ${oauthConfigArgs} - fi + oauth2_client = { + REDIRECT_URI = redirect-uri; + ACCOUNT_LINKING = "auto"; + ENABLE_AUTO_REGISTRATION = true; + OPENID_CONNECT_SCOPES = "email openid profile"; + }; + # doesn't work if LDAP auth source is not active! + "cron.sync_external_users" = { + ENABLED = true; + RUN_AT_START = true; + NOTICE_ON_SUCCESS = true; + }; + }; + systemd.services.forgejo = { + preStart = + let + exe = lib.getExe config.services.forgejo.package; + # FIXME skip-tls-verify, bind-password + ldapConfigArgs = '' + --name LDAP \ + --active \ + --security-protocol LDAPS \ + --skip-tls-verify \ + --host '${auth-passthru.ldap-host}' \ + --port '${toString auth-passthru.ldap-port}' \ + --user-search-base '${auth-passthru.ldap-base-dn}' \ + --user-filter '(&(class=person)(memberof=${users-group})(name=%s))' \ + --admin-filter '(&(class=person)(memberof=${admins-group})' \ + --username-attribute name \ + --firstname-attribute name \ + --surname-attribute displayname \ + --email-attribute mail \ + --public-ssh-key-attribute sshPublicKey \ + --bind-dn 'dn=token' \ + --bind-password "$(cat ${kanidm-service-account-token-fp})" \ + --synchronize-users ''; - # TODO consider passing oauth consumer service to auth module instead - after = [ auth-passthru.oauth2-systemd-service ]; - requires = [ auth-passthru.oauth2-systemd-service ]; - }; + oauthConfigArgs = '' + --name "${oauth2-provider-name}" \ + --provider openidConnect \ + --key forgejo \ + --secret "$(<${kanidm-oauth-client-secret-fp})" \ + --group-claim-name groups \ + --admin-group admins \ + --auto-discover-url '${auth-passthru.oauth2-discovery-url oauth-client-id}' + ''; + in + lib.mkAfter '' + set -o xtrace - # for ExecStartPost script to have access to /run/keys/* - users.groups.keys.members = [ config.services.forgejo.group ]; + # Check if LDAP is already configured + ldap_line="$(${exe} admin auth list | grep LDAP | head -n 1)" - systemd.services.kanidm.serviceConfig.ExecStartPre = [ - ("-+" + kanidmExecStartPreScriptRoot) - ("-" + kanidmExecStartPreScript) - ]; - systemd.services.kanidm.serviceConfig.ExecStartPost = - lib.mkAfter [ ("-" + kanidmExecStartPostScript) ]; + if [[ -n "$ldap_line" ]]; then + # update ldap config + id="$(echo "$ldap_line" | ${pkgs.gawk}/bin/awk '{print $1}')" + ${exe} admin auth update-ldap --id "$id" ${ldapConfigArgs} + else + # initially configure ldap + ${exe} admin auth add-ldap ${ldapConfigArgs} + fi - services.nginx.virtualHosts."${cfg.subdomain}.${sp.domain}" = { - extraConfig = lib.mkAfter '' - rewrite ^/user/login$ /user/oauth2/${oauth2-provider-name} last; - # FIXME is it needed? - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + oauth_line="$(${exe} admin auth list | grep "${oauth2-provider-name}" | head -n 1)" + if [[ -n "$oauth_line" ]]; then + id="$(echo "$oauth_line" | ${pkgs.gawk}/bin/awk '{print $1}')" + ${exe} admin auth update-oauth --id "$id" ${oauthConfigArgs} + else + ${exe} admin auth add-oauth ${oauthConfigArgs} + fi ''; - }; + # TODO consider passing oauth consumer service to auth module instead + after = [ auth-passthru.oauth2-systemd-service ]; + requires = [ auth-passthru.oauth2-systemd-service ]; + }; - services.kanidm.provision = { - groups = { - "${admins-group}".members = [ auth-passthru.admins-group ]; - "${users-group}".members = - [ admins-group auth-passthru.full-users-group ]; + # for ExecStartPost script to have access to /run/keys/* + users.groups.keys.members = [ config.services.forgejo.group ]; + + systemd.services.kanidm.serviceConfig.ExecStartPre = [ + ("-+" + kanidmExecStartPreScriptRoot) + ("-" + kanidmExecStartPreScript) + ]; + systemd.services.kanidm.serviceConfig.ExecStartPost = + lib.mkAfter [ ("-" + kanidmExecStartPostScript) ]; + + services.nginx.virtualHosts."${cfg.subdomain}.${sp.domain}" = { + extraConfig = lib.mkAfter '' + rewrite ^/user/login$ /user/oauth2/${oauth2-provider-name} last; + # FIXME is it needed? + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + ''; + }; + + services.kanidm.provision = { + groups = { + "${admins-group}".members = [ auth-passthru.admins-group ]; + "${users-group}".members = + [ admins-group auth-passthru.full-users-group ]; + }; + systems.oauth2.forgejo = { + displayName = "Forgejo"; + originUrl = redirect-uri; + originLanding = "https://${cfg.subdomain}.${sp.domain}/"; + basicSecretFile = kanidm-oauth-client-secret-fp; + # when true, name is passed to a service instead of name@domain + preferShortUsername = true; + allowInsecureClientDisablePkce = true; # FIXME is it needed? + scopeMaps = { + "${users-group}" = [ + "email" + "openid" + "profile" + ]; }; - systems.oauth2.forgejo = { - displayName = "Forgejo"; - originUrl = redirect-uri; - originLanding = "https://${cfg.subdomain}.${sp.domain}/"; - basicSecretFile = kanidm-oauth-client-secret-fp; - # when true, name is passed to a service instead of name@domain - preferShortUsername = true; - allowInsecureClientDisablePkce = true; # FIXME is it needed? - scopeMaps = { - "${users-group}" = [ - "email" - "openid" - "profile" - ]; - }; - removeOrphanedClaimMaps = true; - # NOTE https://github.com/oddlama/kanidm-provision/issues/15 - # add more scopes when a user is a member of specific group - # currently not possible due to https://github.com/kanidm/kanidm/issues/2882#issuecomment-2564490144 - # supplementaryScopeMaps."${admins-group}" = - # [ "read:admin" "write:admin" ]; - claimMaps.groups = { - joinType = "array"; - valuesByGroup.${admins-group} = [ "admins" ]; - }; + removeOrphanedClaimMaps = true; + # NOTE https://github.com/oddlama/kanidm-provision/issues/15 + # add more scopes when a user is a member of specific group + # currently not possible due to https://github.com/kanidm/kanidm/issues/2882#issuecomment-2564490144 + # supplementaryScopeMaps."${admins-group}" = + # [ "read:admin" "write:admin" ]; + claimMaps.groups = { + joinType = "array"; + valuesByGroup.${admins-group} = [ "admins" ]; }; }; - }) - ) + }; + }) ]); } diff --git a/sp-modules/nextcloud/module.nix b/sp-modules/nextcloud/module.nix index 70a856b..17719f3 100644 --- a/sp-modules/nextcloud/module.nix +++ b/sp-modules/nextcloud/module.nix @@ -1,4 +1,4 @@ -{ config, lib, options, pkgs, ... }: +{ config, lib, pkgs, ... }: let inherit (import ./common.nix config) admin-pass-filepath @@ -276,133 +276,131 @@ in }; } # the following part is active only when "auth" module is enabled - (lib.attrsets.optionalAttrs - (options.selfprivacy.modules ? "auth") - (lib.mkIf is-auth-enabled { - systemd.services.nextcloud-setup = { - path = [ pkgs.jq ]; - script = '' - set -o errexit - set -o nounset - ${lib.strings.optionalString cfg.debug "set -o xtrace"} + (lib.mkIf is-auth-enabled { + systemd.services.nextcloud-setup = { + path = [ pkgs.jq ]; + script = '' + set -o errexit + set -o nounset + ${lib.strings.optionalString cfg.debug "set -o xtrace"} - ${occ} app:install user_ldap || : - ${occ} app:enable user_ldap + ${occ} app:install user_ldap || : + ${occ} app:enable user_ldap - # The following code tries to match an existing config or creates a new one. - # The criteria for matching is the ldapHost value. + # The following code tries to match an existing config or creates a new one. + # The criteria for matching is the ldapHost value. - # remove broken link after previous nextcloud (un)installation - [[ ! -f "${override-config-fp}" && -L "${override-config-fp}" ]] && \ - rm -v "${override-config-fp}" + # remove broken link after previous nextcloud (un)installation + [[ ! -f "${override-config-fp}" && -L "${override-config-fp}" ]] && \ + rm -v "${override-config-fp}" - ALL_CONFIG="$(${occ} ldap:show-config --output=json)" + ALL_CONFIG="$(${occ} ldap:show-config --output=json)" - MATCHING_CONFIG_IDs="$(jq '[to_entries[] | select(.value.ldapHost=="${ldap_scheme_and_host}") | .key]' <<<"$ALL_CONFIG")" - if [[ $(jq 'length' <<<"$MATCHING_CONFIG_IDs") > 0 ]]; then - CONFIG_ID="$(jq --raw-output '.[0]' <<<"$MATCHING_CONFIG_IDs")" - else - CONFIG_ID="$(${occ} ldap:create-empty-config --only-print-prefix)" - fi + MATCHING_CONFIG_IDs="$(jq '[to_entries[] | select(.value.ldapHost=="${ldap_scheme_and_host}") | .key]' <<<"$ALL_CONFIG")" + if [[ $(jq 'length' <<<"$MATCHING_CONFIG_IDs") > 0 ]]; then + CONFIG_ID="$(jq --raw-output '.[0]' <<<"$MATCHING_CONFIG_IDs")" + else + CONFIG_ID="$(${occ} ldap:create-empty-config --only-print-prefix)" + fi - echo "Using configId $CONFIG_ID" + echo "Using configId $CONFIG_ID" - # The following CLI commands follow - # https://github.com/lldap/lldap/blob/main/example_configs/nextcloud.md#nextcloud-config--the-cli-way + # The following CLI commands follow + # https://github.com/lldap/lldap/blob/main/example_configs/nextcloud.md#nextcloud-config--the-cli-way - # StartTLS is not supported in Kanidm due to security risks, whereas - # user_ldap doesn't support SASL. Importing certificate doesn't - # help: - # ${occ} security:certificates:import "${config.security.acme.certs.${domain}.directory}/cert.pem" - ${occ} ldap:set-config "$CONFIG_ID" 'turnOffCertCheck' '1' + # StartTLS is not supported in Kanidm due to security risks, whereas + # user_ldap doesn't support SASL. Importing certificate doesn't + # help: + # ${occ} security:certificates:import "${config.security.acme.certs.${domain}.directory}/cert.pem" + ${occ} ldap:set-config "$CONFIG_ID" 'turnOffCertCheck' '1' - ${occ} ldap:set-config "$CONFIG_ID" 'ldapHost' '${ldap_scheme_and_host}' - ${occ} ldap:set-config "$CONFIG_ID" 'ldapPort' '${toString auth-passthru.ldap-port}' - ${occ} ldap:set-config "$CONFIG_ID" 'ldapAgentName' 'dn=token' - ${occ} ldap:set-config "$CONFIG_ID" 'ldapAgentPassword' "$(<${kanidm-service-account-token-fp})" - ${occ} ldap:set-config "$CONFIG_ID" 'ldapBase' '${auth-passthru.ldap-base-dn}' - ${occ} ldap:set-config "$CONFIG_ID" 'ldapBaseGroups' '${auth-passthru.ldap-base-dn}' - ${occ} ldap:set-config "$CONFIG_ID" 'ldapBaseUsers' '${auth-passthru.ldap-base-dn}' - ${occ} ldap:set-config "$CONFIG_ID" 'ldapEmailAttribute' 'mail' - ${occ} ldap:set-config "$CONFIG_ID" 'ldapGroupFilter' \ - '(&(class=group)(${wildcard-group}))' - ${occ} ldap:set-config "$CONFIG_ID" 'ldapGroupFilterGroups' \ - '(&(class=group)(${wildcard-group}))' - # ${occ} ldap:set-config "$CONFIG_ID" 'ldapGroupFilterObjectclass' \ - # 'groupOfUniqueNames' - # ${occ} ldap:set-config "$CONFIG_ID" 'ldapGroupMemberAssocAttr' \ - # 'uniqueMember' - ${occ} ldap:set-config "$CONFIG_ID" 'ldapLoginFilter' \ - '(&(class=person)(memberof=${users-group})(uid=%uid))' - ${occ} ldap:set-config "$CONFIG_ID" 'ldapLoginFilterAttributes' \ - 'uid' - ${occ} ldap:set-config "$CONFIG_ID" 'ldapUserDisplayName' \ - 'displayname' - ${occ} ldap:set-config "$CONFIG_ID" 'ldapUserFilter' \ - '(&(class=person)(memberof=${users-group})(name=%s))' - ${occ} ldap:set-config "$CONFIG_ID" 'ldapUserFilterMode' \ - '1' - ${occ} ldap:set-config "$CONFIG_ID" 'ldapUserFilterObjectclass' \ - 'person' + ${occ} ldap:set-config "$CONFIG_ID" 'ldapHost' '${ldap_scheme_and_host}' + ${occ} ldap:set-config "$CONFIG_ID" 'ldapPort' '${toString auth-passthru.ldap-port}' + ${occ} ldap:set-config "$CONFIG_ID" 'ldapAgentName' 'dn=token' + ${occ} ldap:set-config "$CONFIG_ID" 'ldapAgentPassword' "$(<${kanidm-service-account-token-fp})" + ${occ} ldap:set-config "$CONFIG_ID" 'ldapBase' '${auth-passthru.ldap-base-dn}' + ${occ} ldap:set-config "$CONFIG_ID" 'ldapBaseGroups' '${auth-passthru.ldap-base-dn}' + ${occ} ldap:set-config "$CONFIG_ID" 'ldapBaseUsers' '${auth-passthru.ldap-base-dn}' + ${occ} ldap:set-config "$CONFIG_ID" 'ldapEmailAttribute' 'mail' + ${occ} ldap:set-config "$CONFIG_ID" 'ldapGroupFilter' \ + '(&(class=group)(${wildcard-group})' + ${occ} ldap:set-config "$CONFIG_ID" 'ldapGroupFilterGroups' \ + '(&(class=group)(${wildcard-group}))' + # ${occ} ldap:set-config "$CONFIG_ID" 'ldapGroupFilterObjectclass' \ + # 'groupOfUniqueNames' + # ${occ} ldap:set-config "$CONFIG_ID" 'ldapGroupMemberAssocAttr' \ + # 'uniqueMember' + ${occ} ldap:set-config "$CONFIG_ID" 'ldapLoginFilter' \ + '(&(class=person)(memberof=${users-group})(uid=%uid))' + ${occ} ldap:set-config "$CONFIG_ID" 'ldapLoginFilterAttributes' \ + 'uid' + ${occ} ldap:set-config "$CONFIG_ID" 'ldapUserDisplayName' \ + 'displayname' + ${occ} ldap:set-config "$CONFIG_ID" 'ldapUserFilter' \ + '(&(class=person)(memberof=${users-group})(name=%s))' + ${occ} ldap:set-config "$CONFIG_ID" 'ldapUserFilterMode' \ + '1' + ${occ} ldap:set-config "$CONFIG_ID" 'ldapUserFilterObjectclass' \ + 'person' - ${occ} ldap:test-config -- "$CONFIG_ID" + ${occ} ldap:test-config -- "$CONFIG_ID" - # delete all configs except "$CONFIG_ID" - for configid in $(jq --raw-output "keys[] | select(. != \"$CONFIG_ID\")" <<<"$ALL_CONFIG"); do - echo "Deactivating $configid" - ${occ} ldap:set-config "$configid" 'ldapConfigurationActive' '0' - echo "Deactivated $configid" - echo "Deleting $configid" - ${occ} ldap:delete-config "$configid" - echo "Deleted $configid" - done + # delete all configs except "$CONFIG_ID" + for configid in $(jq --raw-output "keys[] | select(. != \"$CONFIG_ID\")" <<<"$ALL_CONFIG"); do + echo "Deactivating $configid" + ${occ} ldap:set-config "$configid" 'ldapConfigurationActive' '0' + echo "Deactivated $configid" + echo "Deleting $configid" + ${occ} ldap:delete-config "$configid" + echo "Deleted $configid" + done - ${occ} ldap:set-config "$CONFIG_ID" 'ldapConfigurationActive' '1' + ${occ} ldap:set-config "$CONFIG_ID" 'ldapConfigurationActive' '1' - ############################################################################ - # OIDC app - ############################################################################ - ${occ} app:install user_oidc || : - ${occ} app:enable user_oidc + ############################################################################ + # OIDC app + ############################################################################ + ${occ} app:install user_oidc || : + ${occ} app:enable user_oidc - ${occ} user_oidc:provider ${auth-passthru.oauth2-provider-name} \ - --clientid="${oauth-client-id}" \ - --clientsecret="$(<${kanidm-oauth-client-secret-fp})" \ - --discoveryuri="${auth-passthru.oauth2-discovery-url "nextcloud"}" \ - --unique-uid=0 \ - --scope="email openid profile" \ - --mapping-uid=preferred_username \ - --no-interaction \ - --mapping-groups=groups \ - --group-provisioning=1 \ - -vvv - ''; - # TODO consider passing oauth consumer service to auth module instead - after = [ auth-passthru.oauth2-systemd-service ]; - requires = [ auth-passthru.oauth2-systemd-service ]; + ${occ} user_oidc:provider ${auth-passthru.oauth2-provider-name} \ + --clientid="${oauth-client-id}" \ + --clientsecret="$(<${kanidm-oauth-client-secret-fp})" \ + --discoveryuri="${auth-passthru.oauth2-discovery-url "nextcloud"}" \ + --unique-uid=0 \ + --scope="email openid profile" \ + --mapping-uid=preferred_username \ + --no-interaction \ + --mapping-groups=groups \ + --group-provisioning=1 \ + -vvv + ''; + # TODO consider passing oauth consumer service to auth module instead + after = [ auth-passthru.oauth2-systemd-service ]; + requires = [ auth-passthru.oauth2-systemd-service ]; + }; + services.kanidm.provision = { + groups = { + "${admins-group}".members = [ auth-passthru.admins-group ]; + "${users-group}".members = + [ admins-group auth-passthru.full-users-group ]; }; - services.kanidm.provision = { - groups = { - "${admins-group}".members = [ auth-passthru.admins-group ]; - "${users-group}".members = - [ admins-group auth-passthru.full-users-group ]; - }; - systems.oauth2.${oauth-client-id} = { - displayName = "Nextcloud"; - originUrl = "https://${cfg.subdomain}.${domain}/apps/user_oidc/code"; - originLanding = "https://${cfg.subdomain}.${domain}/"; - basicSecretFile = kanidm-oauth-client-secret-fp; - # when true, name is passed to a service instead of name@domain - preferShortUsername = true; - allowInsecureClientDisablePkce = false; - scopeMaps.${users-group} = [ "email" "openid" "profile" ]; - removeOrphanedClaimMaps = true; - claimMaps.groups = { - joinType = "array"; - valuesByGroup.${admins-group} = [ "admin" ]; - }; + systems.oauth2.${oauth-client-id} = { + displayName = "Nextcloud"; + originUrl = "https://${cfg.subdomain}.${domain}/apps/user_oidc/code"; + originLanding = "https://${cfg.subdomain}.${domain}/"; + basicSecretFile = kanidm-oauth-client-secret-fp; + # when true, name is passed to a service instead of name@domain + preferShortUsername = true; + allowInsecureClientDisablePkce = false; + scopeMaps.${users-group} = [ "email" "openid" "profile" ]; + removeOrphanedClaimMaps = true; + claimMaps.groups = { + joinType = "array"; + valuesByGroup.${admins-group} = [ "admin" ]; }; }; - })) + }; + }) ]); } diff --git a/sp-modules/roundcube/module.nix b/sp-modules/roundcube/module.nix index 92f6df1..68147d8 100644 --- a/sp-modules/roundcube/module.nix +++ b/sp-modules/roundcube/module.nix @@ -1,4 +1,4 @@ -{ config, lib, options, pkgs, ... }: +{ config, lib, pkgs, ... }: let domain = config.selfprivacy.domain; cfg = config.selfprivacy.modules.roundcube; @@ -82,61 +82,58 @@ in systemd.services.roundcube.after = [ "dovecot2.service" ]; } # the following part is active only when "auth" module is enabled - (lib.attrsets.optionalAttrs - (options.selfprivacy.modules ? "auth") - (lib.mkIf is-auth-enabled { - # for phpfpm-roundcube to have access to get through /run/keys directory - users.groups.keys.members = [ user ]; - services.roundcube.extraConfig = lib.mkAfter '' - $config['oauth_provider'] = 'generic'; - $config['oauth_provider_name'] = '${auth-passthru.oauth2-provider-name}'; - $config['oauth_client_id'] = '${oauth-donor.oauth-client-id}'; - $config['oauth_client_secret'] = file_get_contents('${kanidm-oauth-client-secret-fp}'); - $config['oauth_auth_uri'] = 'https://${auth-fqdn}/ui/oauth2'; - $config['oauth_token_uri'] = 'https://${auth-fqdn}/oauth2/token'; - $config['oauth_identity_uri'] = 'https://${auth-fqdn}/oauth2/openid/${oauth-donor.oauth-client-id}/userinfo'; - $config['oauth_scope'] = 'email profile openid'; # FIXME - $config['oauth_auth_parameters'] = []; - $config['oauth_identity_fields'] = ['email']; - $config['oauth_login_redirect'] = true; - $config['auto_create_user'] = true; - $config['oauth_verify_peer'] = false; # FIXME - # $config['oauth_pkce'] = 'S256'; # FIXME - ''; - systemd.services.roundcube = { - after = [ auth-passthru.oauth2-systemd-service ]; - requires = [ auth-passthru.oauth2-systemd-service ]; + (lib.mkIf is-auth-enabled { + # for phpfpm-roundcube to have access to get through /run/keys directory + users.groups.keys.members = [ user ]; + services.roundcube.extraConfig = lib.mkAfter '' + $config['oauth_provider'] = 'generic'; + $config['oauth_provider_name'] = '${auth-passthru.oauth2-provider-name}'; + $config['oauth_client_id'] = '${oauth-donor.oauth-client-id}'; + $config['oauth_client_secret'] = file_get_contents('${kanidm-oauth-client-secret-fp}'); + $config['oauth_auth_uri'] = 'https://${auth-fqdn}/ui/oauth2'; + $config['oauth_token_uri'] = 'https://${auth-fqdn}/oauth2/token'; + $config['oauth_identity_uri'] = 'https://${auth-fqdn}/oauth2/openid/${oauth-donor.oauth-client-id}/userinfo'; + $config['oauth_scope'] = 'email profile openid'; # FIXME + $config['oauth_auth_parameters'] = []; + $config['oauth_identity_fields'] = ['email']; + $config['oauth_login_redirect'] = true; + $config['auto_create_user'] = true; + $config['oauth_verify_peer'] = false; # FIXME + # $config['oauth_pkce'] = 'S256'; # FIXME + ''; + systemd.services.roundcube = { + after = [ auth-passthru.oauth2-systemd-service ]; + requires = [ auth-passthru.oauth2-systemd-service ]; + }; + systemd.services.kanidm = { + serviceConfig.ExecStartPre = lib.mkBefore [ + ("-+" + kanidmExecStartPreScriptRoot) + ]; + }; + services.kanidm.provision = { + groups = { + "sp.roundcube.admins".members = [ auth-passthru.admins-group ]; + "sp.roundcube.users".members = + [ "sp.roundcube.admins" auth-passthru.full-users-group ]; }; - systemd.services.kanidm = { - serviceConfig.ExecStartPre = lib.mkBefore [ - ("-+" + kanidmExecStartPreScriptRoot) - ]; - }; - services.kanidm.provision = { - groups = { - "sp.roundcube.admins".members = [ auth-passthru.admins-group ]; - "sp.roundcube.users".members = - [ "sp.roundcube.admins" auth-passthru.full-users-group ]; - }; - systems.oauth2.${oauth-donor.oauth-client-id} = { - displayName = "Roundcube"; - originUrl = "https://${cfg.subdomain}.${domain}/index.php/login/oauth"; - originLanding = "https://${cfg.subdomain}.${domain}/"; - basicSecretFile = kanidm-oauth-client-secret-fp; - # when true, name is passed to a service instead of name@domain - preferShortUsername = false; - allowInsecureClientDisablePkce = true; # FIXME is it needed? - scopeMaps = { - "sp.roundcube.users" = [ - "email" - "openid" - "profile" - ]; - }; - removeOrphanedClaimMaps = true; + systems.oauth2.${oauth-donor.oauth-client-id} = { + displayName = "Roundcube"; + originUrl = "https://${cfg.subdomain}.${domain}/index.php/login/oauth"; + originLanding = "https://${cfg.subdomain}.${domain}/"; + basicSecretFile = kanidm-oauth-client-secret-fp; + # when true, name is passed to a service instead of name@domain + preferShortUsername = false; + allowInsecureClientDisablePkce = true; # FIXME is it needed? + scopeMaps = { + "sp.roundcube.users" = [ + "email" + "openid" + "profile" + ]; }; + removeOrphanedClaimMaps = true; }; - }) - ) + }; + }) ]); } diff --git a/sp-modules/simple-nixos-mailserver/config.nix b/sp-modules/simple-nixos-mailserver/config.nix index 68cd44c..1d864f6 100644 --- a/sp-modules/simple-nixos-mailserver/config.nix +++ b/sp-modules/simple-nixos-mailserver/config.nix @@ -1,4 +1,4 @@ -{ config, lib, options, pkgs, ... }@nixos-args: +{ config, lib, pkgs, ... }@nixos-args: let sp = config.selfprivacy; @@ -176,42 +176,36 @@ lib.mkIf sp.modules.simple-nixos-mailserver.enable (lib.mkMerge [ }; } # the following parts are active only when "auth" module is enabled - (lib.attrsets.optionalAttrs - (options.selfprivacy.modules ? "auth") - (lib.mkIf is-auth-enabled { - mailserver = { - extraVirtualAliases = lib.mkForce { }; - loginAccounts = lib.mkForce { }; - # LDAP is needed for Postfix to query Kanidm about email address ownership. - # LDAP is needed for Dovecot also. - ldap = { - # false; otherwise, simple-nixos-mailserver enables auth via LDAP - enable = false; + (lib.mkIf is-auth-enabled { + mailserver = { + extraVirtualAliases = lib.mkForce { }; + loginAccounts = lib.mkForce { }; + # LDAP is needed for Postfix to query Kanidm about email address ownership. + # LDAP is needed for Dovecot also. + ldap = { + # false; otherwise, simple-nixos-mailserver enables auth via LDAP + enable = false; - # bind.dn = "uid=mail,ou=persons," + ldap_base_dn; - bind.dn = "dn=token"; - # TODO change in this file should trigger system restart dovecot - bind.passwordFile = mailserver-service-account-token-fp; + # bind.dn = "uid=mail,ou=persons," + ldap_base_dn; + bind.dn = "dn=token"; + # TODO change in this file should trigger system restart dovecot + bind.passwordFile = mailserver-service-account-token-fp; - # searchBase = "ou=persons," + ldap_base_dn; - searchBase = auth-passthru.ldap-base-dn; # TODO refine this + # searchBase = "ou=persons," + ldap_base_dn; + searchBase = auth-passthru.ldap-base-dn; # TODO refine this - # NOTE: 127.0.0.1 instead of localhost doesn't work (maybe because of TLS) - uris = [ "ldaps://localhost:${toString auth-passthru.ldap-port}" ]; - }; + # NOTE: 127.0.0.1 instead of localhost doesn't work (maybe because of TLS) + uris = [ "ldaps://localhost:${toString auth-passthru.ldap-port}" ]; }; - # FIXME set auth module option instead - systemd.services.kanidm.serviceConfig.ExecStartPre = lib.mkBefore [ - ("-+" + kanidmExecStartPreScriptRoot) - ]; - systemd.services.kanidm.serviceConfig.ExecStartPost = lib.mkAfter [ - ("-" + kanidmExecStartPostScript) - ]; - })) - (lib.attrsets.optionalAttrs - (options.selfprivacy.modules ? "auth") - (lib.mkIf is-auth-enabled (import ./auth-dovecot.nix nixos-args))) - (lib.attrsets.optionalAttrs - (options.selfprivacy.modules ? "auth") - (lib.mkIf is-auth-enabled (import ./auth-postfix.nix nixos-args))) + }; + # FIXME set auth module option instead + systemd.services.kanidm.serviceConfig.ExecStartPre = lib.mkBefore [ + ("-+" + kanidmExecStartPreScriptRoot) + ]; + systemd.services.kanidm.serviceConfig.ExecStartPost = lib.mkAfter [ + ("-" + kanidmExecStartPostScript) + ]; + }) + (lib.mkIf is-auth-enabled (import ./auth-dovecot.nix nixos-args)) + (lib.mkIf is-auth-enabled (import ./auth-postfix.nix nixos-args)) ])