Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Then launch `configure-module`, by setting the following parameters:
- fully qualified domain name for Nextcloud
- let's encrypt option
- LDAP domain (optional)
- use internal Nextcloud mail sending settings or the cluster smarthost

Example:
```
Expand All @@ -35,7 +36,8 @@ api-cli run module/nextcloud1/configure-module --data - <<EOF
"host": "nextcloud.nethserver.org",
"lets_encrypt": true,
"domain": "ad.nethserver.org",
"password": "Nethesis,1234"
"password": "Nethesis,1234",
"internal_smarthost": false
}
EOF
```
Expand Down
3 changes: 3 additions & 0 deletions imageroot/actions/get-configuration/20read
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,8 @@ config["is_collabora"] = True if array_collabora else False
if "tls_verify_collabora" not in config:
config["tls_verify_collabora"] = False

if "internal_smarthost" not in config:
config["internal_smarthost"] = False

# Dump the configuration to stdout
json.dump(config, fp=sys.stdout)
8 changes: 4 additions & 4 deletions imageroot/bin/discover-smarthost
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@ smtp_settings = agent.get_smarthost_settings(rdb)

envfile = "smarthost.env"

with open('config.json', 'r') as cf:
config = json.loads(cf.read())

# Using .tmp suffix: do not overwrite the target file until the new one is
# saved to disk:
if not smtp_settings['host']:
if not smtp_settings['host'] or config['internal_smarthost'] == True:
f = open(envfile, "w")
f.write("")
f.close
sys.exit(0)

with open('config.json', 'r') as cf:
config = json.loads(cf.read())

domain = config['host'].split('.',1)[1]

with open(envfile + ".tmp", "w") as efp:
Expand Down
30 changes: 27 additions & 3 deletions imageroot/bin/setup-smtp
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,44 @@
#

import agent
import json
import subprocess

def occ(args):
cmd = ['podman', 'exec', '--user', 'www-data', 'nextcloud-app', 'php', './occ']
p = subprocess.run(cmd + args, capture_output=True)
return (p.returncode, p.stdout)

def occget(args):
cmd = ['podman', 'exec', '--user', 'www-data', 'nextcloud-app', 'php', './occ']
p = subprocess.run(cmd + args, capture_output=True)
return (p.stdout.decode()[:-1])

smarthost= agent.read_envfile("smarthost.env")
smtphost= occget(["config:system:get","mail_smtphost"])

with open('config.json', 'r') as cf:
config = json.loads(cf.read())

# Remove mail configuration when smarthost is disabled
if 'SMTP_HOST' not in smarthost and config['internal_smarthost'] == False and smtphost:
occ(["config:system:delete","mail_from_address"])
occ(["config:system:delete","mail_smtpmode"])
occ(["config:system:delete","mail_sendmailmode"])
occ(["config:system:delete","mail_domain"])
occ(["config:system:delete","mail_smtphost"])
occ(["config:system:delete","mail_smtpauth"])
occ(["config:system:delete","mail_smtpport"])
occ(["config:system:delete","mail_smtpname"])
occ(["config:system:delete","mail_smtppassword"])
occ(["config:system:delete","mail_smtpsecure"])
occ(["config:system:delete","mail_smtpauthtype"])
occ(["config:system:delete","mail_smtpstreamoptions"])

# smarthost is configured
if 'SMTP_HOST' in smarthost:
if 'SMTP_HOST' in smarthost and config['internal_smarthost'] == False:
# verify if smarthost verify tls certificate
if smarthost.get('SMTP_SECURE') == 'none' or smarthost.get('SMTP_TLS_VERIFY') == 'False':
occ(["config:system:set","mail_smtpstreamoptions","ssl","allow_self_signed","--value=true", "--type=boolean"])
occ(["config:system:set","mail_smtpstreamoptions","ssl","verify_peer","--value=false","--type=boolean"])
occ(["config:system:set","mail_smtpstreamoptions","ssl","verify_peer_name","--value=false","--type=boolean"])
else:
occ(["config:system:delete","mail_smtpstreamoptions","ssl"])
44 changes: 44 additions & 0 deletions imageroot/update-module.d/17smarthost_switch
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env python3

#
# Copyright (C) 2026 Nethesis S.r.l.
# SPDX-License-Identifier: GPL-3.0-or-later
#

import agent
import json
import subprocess
import sys

def occget(args):
cmd = ['podman', 'exec', '--user', 'www-data', 'nextcloud-app', 'php', './occ']
p = subprocess.run(cmd + args, capture_output=True)
return (p.stdout.decode()[:-1])

smarthost = agent.read_envfile("smarthost.env")

with open('config.json', 'r') as cf:
config = json.loads(cf.read())

# Exit if internal smarthost is already set
if "internal_smarthost" in config:
sys.exit(0)

# Get the smtphost via occ
smtphost = occget(["config:system:get","mail_smtphost"])

# Get the smarthost
if 'SMTP_HOST' in smarthost:
smtpsmarthost=smarthost['SMTP_HOST']
else:
smtpsmarthost=""

# Compare occ with smarthost settings and set the internal_smarthost variable accordingly
if smtphost == smtpsmarthost:
config["internal_smarthost"] = False
else:
config["internal_smarthost"] = True

# Write config.json
with open('config.json', 'w') as cfp:
cfp.write(json.dumps(config))
2 changes: 1 addition & 1 deletion tests/nextcloud.robot
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Check if nextcloud is installed correctly
Set Suite Variable ${module_id} ${output.module_id}

Check if nextcloud can be configured
${out} ${err} ${rc} = Execute Command api-cli run module/${module_id}/configure-module --data '{"host": "nextcloud.dom.test", "lets_encrypt": false, "domain": "", "password": "Nethesis,1234"}'
${out} ${err} ${rc} = Execute Command api-cli run module/${module_id}/configure-module --data '{"host": "nextcloud.dom.test", "lets_encrypt": false, "domain": "", "password": "Nethesis,1234", "internal_smarthost": false}'
... return_rc=True return_stdout=True return_stderr=True
Should Be Equal As Integers ${rc} 0

Expand Down
3 changes: 2 additions & 1 deletion ui/public/i18n/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
"host_placeholder": "E.g. mynextcloud.example.org",
"admin_password_tooltip": "The user 'admin' is the internal administrator of Nextcloud. This password is used to authenticate the 'admin' user in the Nextcloud web interface.",
"host_pattern": "Must be a valid fully qualified domain name",
"host_format": "Must be a valid fully qualified domain name"
"host_format": "Must be a valid fully qualified domain name",
"internal_smarthost": "Manage email sending from Nextcloud admin panel"
},
"about": {
"title": "About"
Expand Down
17 changes: 17 additions & 0 deletions ui/src/views/Settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,20 @@
ref="domain"
>
</NsComboBox>
<NsToggle
value="internalSmarthost"
:label="$t('settings.internal_smarthost')"
v-model="internalSmarthost"
:disabled="loadingUi"
class="mg-bottom"
>
<template slot="text-left">{{
$t("settings.disabled")
}}</template>
<template slot="text-right">{{
$t("settings.enabled")
}}</template>
</NsToggle>
<template v-if="is_collabora && installed">
<NsComboBox
v-model.trim="collabora_host"
Expand Down Expand Up @@ -241,6 +255,7 @@ export default {
host: "",
isLetsEncryptEnabled: false,
isLetsEncryptCurrentlyEnabled: false,
internalSmarthost: false,
collabora_host: "",
domain: "",
password: "Nethesis,1234",
Expand Down Expand Up @@ -490,6 +505,7 @@ export default {
host: this.host,
lets_encrypt: this.isLetsEncryptEnabled,
domain: this.domain === "-" ? "" : this.domain,
internal_smarthost: this.internalSmarthost,
is_collabora: this.is_collabora,
collabora_host: this.collabora_host,
tls_verify_collabora: this.tls_verify_collabora,
Expand Down Expand Up @@ -521,6 +537,7 @@ export default {
this.host = config.host;
this.isLetsEncryptEnabled = config.lets_encrypt;
this.isLetsEncryptCurrentlyEnabled = config.lets_encrypt;
this.internalSmarthost = config.internal_smarthost;
this.running = config.running;
this.installed = config.installed;
this.is_collabora = config.is_collabora;
Expand Down
Loading