-
-
Notifications
You must be signed in to change notification settings - Fork 17.8k
nixos/nextcloud: Add services.nextcloud.settings.mail_* options #460529
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -120,7 +120,8 @@ let | |
| ++ (lib.optional ( | ||
| cfg.config.objectstore.s3.sseCKeyFile != null | ||
| ) "s3_sse_c_key:${cfg.config.objectstore.s3.sseCKeyFile}") | ||
| ++ (lib.optional (cfg.secretFile != null) "secret_file:${cfg.secretFile}"); | ||
| ++ (lib.optional (cfg.secretFile != null) "secret_file:${cfg.secretFile}") | ||
| ++ (lib.mapAttrsToList (credential: file: "${credential}:${file}") cfg.secrets); | ||
|
|
||
| requiresRuntimeSystemdCredentials = (lib.length runtimeSystemdCredentials) != 0; | ||
|
|
||
|
|
@@ -296,6 +297,9 @@ let | |
| ) "'dbtableprefix' => '${toString c.dbtableprefix}',"} | ||
| ${lib.optionalString (c.dbpassFile != null) "'dbpassword' => nix_read_secret('dbpass'),"} | ||
| 'dbtype' => '${c.dbtype}', | ||
| ${lib.concatStringsSep "\n" ( | ||
| lib.mapAttrsToList (name: credential: "'${name}' => nix_read_secret('${name}'),") cfg.secrets | ||
| )} | ||
| ${objectstoreConfig} | ||
| ]; | ||
|
|
||
|
|
@@ -390,6 +394,24 @@ in | |
| ''; | ||
| example = "/mnt/nextcloud-file"; | ||
| }; | ||
| secrets = lib.mkOption { | ||
| type = lib.types.attrsOf ( | ||
| lib.types.pathWith { | ||
| inStore = false; | ||
| absolute = true; | ||
| } | ||
| ); | ||
| default = { }; | ||
| description = '' | ||
| Secret files to read into entries in `config.php`. | ||
| This uses `nix_read_secret` and LoadCredential to read the contents of the file into the entry in `config.php`. | ||
| ''; | ||
| example = lib.literalExpression '' | ||
| { | ||
| oidc_login_client_secret = "/run/secrets/nextcloud_oidc_secret"; | ||
| } | ||
| ''; | ||
| }; | ||
| extraApps = lib.mkOption { | ||
| type = lib.types.attrsOf lib.types.package; | ||
| default = { }; | ||
|
|
@@ -975,6 +997,126 @@ in | |
| The preview providers that should be explicitly enabled. | ||
| ''; | ||
| }; | ||
| mail_domain = lib.mkOption { | ||
| type = lib.types.nullOr lib.types.str; | ||
| default = null; | ||
| description = '' | ||
| The return address that you want to appear on emails sent by the Nextcloud server, for example `[email protected]`, substituting your own domain, of course. | ||
| ''; | ||
| }; | ||
| mail_from_address = lib.mkOption { | ||
| type = lib.types.nullOr lib.types.str; | ||
| default = null; | ||
| description = '' | ||
| FROM address that overrides the built-in `sharing-noreply` and `lostpassword-noreply` FROM addresses. | ||
| Defaults to different FROM addresses depending on the feature. | ||
| ''; | ||
| }; | ||
| mail_smtpdebug = lib.mkOption { | ||
| type = lib.types.bool; | ||
| default = false; | ||
| description = '' | ||
| Enable SMTP class debugging. | ||
| `loglevel` will likely need to be adjusted too. | ||
| [See docs](https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/email_configuration.html#enabling-debug-mode). | ||
| ''; | ||
| }; | ||
| mail_smtpmode = lib.mkOption { | ||
| type = lib.types.enum [ | ||
| "sendmail" | ||
| "smtp" | ||
| "qmail" | ||
| "null" # Yes, this is really a string null and not null. | ||
| ]; | ||
| default = "smtp"; | ||
| description = '' | ||
| Which mode to use for sending mail. | ||
| If you are using local or remote SMTP, set this to `smtp`. | ||
| For the `sendmail` option, you need an installed and working email system on the server, with your local `sendmail` installation. | ||
| For `qmail`, the binary is /var/qmail/bin/sendmail, and it must be installed on your Unix system. | ||
| Use the string null to send no mails (disable mail delivery). This can be useful if mails should be sent via APIs and rendering messages is not necessary. | ||
| ''; | ||
| }; | ||
| mail_smtphost = lib.mkOption { | ||
| type = lib.types.str; | ||
| default = "127.0.0.1"; | ||
| description = '' | ||
| This depends on `mail_smtpmode`. Specify the IP address of your mail server host. This may contain multiple hosts separated by a semicolon. If you need to specify the port number, append it to the IP address separated by a colon, like this: `127.0.0.1:24`. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Uhm, what will happen if you specify both
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TBH I have no idea, this is just copied from the sample config docs. I suppose the mail_smtpport would act as a default and with the colon it would be possible to override it for each server.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK I see. We don't have much of a choice anyways. |
||
| ''; | ||
| }; | ||
| mail_smtpport = lib.mkOption { | ||
| type = lib.types.port; | ||
| default = 25; | ||
| description = '' | ||
| This depends on `mail_smtpmode`. Specify the port for sending mail. | ||
| ''; | ||
| }; | ||
| mail_smtptimeout = lib.mkOption { | ||
| type = lib.types.int; | ||
| default = 10; | ||
| description = '' | ||
| This depends on `mail_smtpmode`. This sets the SMTP server timeout, in seconds. You may need to increase this if you are running an anti-malware or spam scanner. | ||
| ''; | ||
| }; | ||
| mail_smtpsecure = lib.mkOption { | ||
| type = lib.types.enum [ | ||
| "" | ||
| "ssl" | ||
| ]; | ||
| default = ""; | ||
| description = '' | ||
| This depends on `mail_smtpmode`. Specify `ssl` when you are using SSL/TLS. Any other value will be ignored. | ||
| If the server advertises STARTTLS capabilities, they might be used, but they cannot be enforced by this config option. | ||
| ''; | ||
| }; | ||
| mail_smtpauth = lib.mkOption { | ||
| type = lib.types.bool; | ||
| default = false; | ||
| description = '' | ||
| This depends on `mail_smtpmode`. Change this to `true` if your mail server requires authentication. | ||
| ''; | ||
| }; | ||
| mail_smtpname = lib.mkOption { | ||
| type = lib.types.str; | ||
| default = ""; | ||
| description = '' | ||
| This depends on `mail_smtpauth`. Specify the username for authenticating to the SMTP server. | ||
| ''; | ||
| }; | ||
| # mail_smtppassword is skipped as it must be set through services.nextcloud.secrets | ||
| mail_template_class = lib.mkOption { | ||
| type = lib.types.str; | ||
| default = "\\OC\\Mail\\EMailTemplate"; | ||
| description = '' | ||
| Replaces the default mail template layout. This can be utilized if the options to modify the mail texts with the theming app are not enough. | ||
| The class must extend `\OC\Mail\EMailTemplate` | ||
| ''; | ||
| }; | ||
| mail_send_plaintext_only = lib.mkOption { | ||
| type = lib.types.bool; | ||
| default = false; | ||
| description = '' | ||
| Email will be sent by default with an HTML and a plain text body. This option allows sending only plain text emails. | ||
| ''; | ||
| }; | ||
| mail_smtpstreamoptions = lib.mkOption { | ||
| type = lib.types.listOf lib.types.str; | ||
| default = [ ]; | ||
| description = '' | ||
| This depends on `mail_smtpmode`. Array of additional streams options that will be passed to underlying Swift mailer implementation. | ||
| ''; | ||
| }; | ||
| mail_sendmailmode = lib.mkOption { | ||
| type = lib.types.enum [ | ||
| "smtp" | ||
| "pipe" | ||
| ]; | ||
| default = "smtp"; | ||
| description = '' | ||
| For `smtp`, the sendmail binary is started with the parameter `-bs`: Use the SMTP protocol on standard input and output. | ||
| For `pipe`, the binary is started with the parameters `-t`: Read message from STDIN and extract recipients. | ||
| ''; | ||
| }; | ||
| }; | ||
| }; | ||
| default = { }; | ||
|
|
@@ -1165,6 +1307,13 @@ in | |
| If `services.nextcloud.config.adminpassFile` is null, `services.nextcloud.config.adminuser` must be null as well in order to disable initial admin user creation. | ||
| ''; | ||
| } | ||
| { | ||
| assertion = !(cfg.settings ? mail_smtppassword); | ||
| message = '' | ||
| The option `services.nextcloud.settings.mail_smtppassword` must not be used, as it puts the password into the world-readable nix store. | ||
| Use `services.nextcloud.secrets.mail_smtppassword` instead and set it to a file containing the password. | ||
| ''; | ||
| } | ||
| ]; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| { | ||
| name, | ||
| pkgs, | ||
| testBase, | ||
| system, | ||
| ... | ||
| }: | ||
| with import ../../lib/testing-python.nix { inherit system pkgs; }; | ||
| runTest ( | ||
| { config, lib, ... }: | ||
| let | ||
| certs = import ../common/acme/server/snakeoil-certs.nix; | ||
| domain = certs.domain; | ||
| in | ||
| { | ||
| inherit name; | ||
|
|
||
| meta.maintainers = lib.teams.nextcloud.members; | ||
|
|
||
| imports = [ testBase ]; | ||
|
|
||
| nodes = { | ||
| nextcloud = | ||
| { | ||
| config, | ||
| pkgs, | ||
| nodes, | ||
| ... | ||
| }: | ||
| { | ||
| security.pki.certificateFiles = [ certs.ca.cert ]; | ||
|
|
||
| networking.extraHosts = '' | ||
| ${nodes.stalwart.networking.primaryIPAddress} ${domain} | ||
| ''; | ||
|
|
||
| environment.etc."nextcloud/mail_smtppassword".text = "foobar"; | ||
|
|
||
| services.nextcloud = { | ||
| config.dbtype = "sqlite"; | ||
|
|
||
| settings = { | ||
| mail_from_address = "alice"; | ||
| mail_domain = domain; | ||
| mail_smtpmode = "smtp"; | ||
| mail_smtphost = domain; | ||
| mail_smtpport = 587; | ||
| mail_smtpauth = true; | ||
| mail_smtpname = "alice"; | ||
| mail_send_plaintext_only = true; | ||
| }; | ||
|
|
||
| secrets.mail_smtppassword = "/etc/nextcloud/mail_smtppassword"; | ||
| }; | ||
| }; | ||
|
|
||
| stalwart = | ||
| { pkgs, ... }: | ||
| { | ||
| imports = [ ../stalwart/stalwart-mail-config.nix ]; | ||
|
|
||
| networking.firewall.allowedTCPPorts = [ 587 ]; | ||
|
|
||
| environment.systemPackages = [ | ||
| (pkgs.writers.writePython3Bin "test-imap-read" { } '' | ||
| from imaplib import IMAP4 | ||
|
|
||
| with IMAP4('localhost') as imap: | ||
| imap.starttls() | ||
| status, [caps] = imap.login('bob', 'foobar') | ||
| assert status == 'OK' | ||
| imap.select() | ||
| status, [ref] = imap.search(None, 'ALL') | ||
| assert status == 'OK' | ||
| [msgId] = ref.split() | ||
| status, msg = imap.fetch(msgId, 'BODY[TEXT]') | ||
| assert status == 'OK' | ||
| assert (msg[0][1].strip() | ||
| == (b'Well done, ${config.adminuser}!\r\n\r\n' | ||
| b'If you received this email, the email configuration ' | ||
| b's=\r\neems to be correct.\r\n\r\n\r\n--=20\r\n' | ||
| b'Nextcloud - a safe home for all your data=\r\n\r\n' | ||
| b'This is an automatically sent email, please do not reply.')) | ||
| '') | ||
| ]; | ||
| }; | ||
| }; | ||
|
|
||
| test-helpers.init = '' | ||
| stalwart.wait_for_unit("multi-user.target") | ||
| stalwart.wait_until_succeeds("nc -vzw 2 localhost 587") | ||
|
|
||
| nextcloud.succeed("nc -vzw 2 ${domain} 587") | ||
| nextcloud.succeed("curl -sS --fail-with-body -u ${config.adminuser}:${config.adminpass} -H 'OCS-APIRequest: true' -X PUT http://nextcloud/ocs/v2.php/cloud/users/${config.adminuser} -H 'Content-Type: application/json' --data-raw '{\"key\":\"email\",\"value\":\"bob@${domain}\"}'") | ||
| nextcloud.succeed("curl -sS --fail-with-body -u ${config.adminuser}:${config.adminpass} -H 'OCS-APIRequest: true' -X POST http://nextcloud/settings/admin/mailtest") | ||
|
|
||
| stalwart.succeed("test-imap-read") | ||
| ''; | ||
| } | ||
| ) |
Uh oh!
There was an error while loading. Please reload this page.