diff --git a/build-images.sh b/build-images.sh index 48df5f6..351094f 100644 --- a/build-images.sh +++ b/build-images.sh @@ -53,7 +53,7 @@ buildah add "${container}" ui/dist /ui buildah config --entrypoint=/ \ --label="org.nethserver.tcp-ports-demand=1" \ --label="org.nethserver.rootfull=0" \ - --label="org.nethserver.authorizations=traefik@any:routeadm" \ + --label="org.nethserver.authorizations=traefik@any:routeadm cluster:accountconsumer" \ --label="org.nethserver.images=docker.io/bitnami/dokuwiki:20240206-debian-12" \ "${container}" # Commit everything diff --git a/imageroot/actions/configure-module/20configure b/imageroot/actions/configure-module/20configure index b0ea21f..dc49495 100755 --- a/imageroot/actions/configure-module/20configure +++ b/imageroot/actions/configure-module/20configure @@ -40,6 +40,13 @@ username = data.get("username","admin") password = data.get("password","admin") email = data.get("email", "admin@example.org") full_name = data.get("user_full_name","Administrator") +ldap_domain = data.get("ldap_domain", "") +# bind user to the domain +if ldap_domain: + agent.bind_user_domains([ldap_domain]) +else: + agent.bind_user_domains([]) + # Talk with agent using file descriptor. # Setup configuration from user input. @@ -53,6 +60,9 @@ agent.set_env("DOKUWIKI_FULL_NAME", full_name) agent.set_env("PHP_ENABLE_OPCACHE", "1") agent.set_env("PHP_MEMORY_LIMIT", "512M") +# Setup LDAP domain +agent.set_env("LDAP_DOMAIN", ldap_domain) + # Make sure everything is saved inside the environment file # just before starting systemd unit agent.dump_env() diff --git a/imageroot/actions/configure-module/validate-input.json b/imageroot/actions/configure-module/validate-input.json index 28ec857..fd3db3e 100644 --- a/imageroot/actions/configure-module/validate-input.json +++ b/imageroot/actions/configure-module/validate-input.json @@ -23,7 +23,8 @@ "email", "host", "http2https", - "lets_encrypt" + "lets_encrypt", + "ldap_domain" ], "properties": { "wiki_name": { @@ -61,6 +62,10 @@ "type": "boolean", "title": "HTTP to HTTPS redirection", "description": "Redirect all the HTTP requests to HTTPS" + }, + "ldap_domain": { + "type": "string", + "description": "LDAP domain name" } } } diff --git a/imageroot/actions/get-configuration/20read b/imageroot/actions/get-configuration/20read index 12d017b..390cb00 100755 --- a/imageroot/actions/get-configuration/20read +++ b/imageroot/actions/get-configuration/20read @@ -28,6 +28,7 @@ import os import sys import json import agent +from agent.ldapproxy import Ldapproxy # Prepare return variable config = {} @@ -43,6 +44,17 @@ config["user_full_name"] = rdb.hget(env, "DOKUWIKI_FULL_NAME"); config["host"] = rdb.hget(env, "TRAEFIK_HOST"); config["http2https"] = rdb.hget(env, "TRAEFIK_HTTP2HTTPS") == "True"; config["lets_encrypt"] = rdb.hget(env, "TRAEFIK_LETS_ENCRYPT") == "True"; +# retrieve LDAP domains list +lp = Ldapproxy() +domains = [] +for key in lp.get_domains_list(): + domains.append({ + "name": key, + "label": key, + "value": key, + }) +config['ldap_domain_list'] = domains +config['ldap_domain'] = os.environ.get("LDAP_DOMAIN",'') # Dump the configuratio to stdou json.dump(config, fp=sys.stdout) diff --git a/imageroot/actions/get-configuration/validate-output.json b/imageroot/actions/get-configuration/validate-output.json index 6c5dfab..c398f99 100644 --- a/imageroot/actions/get-configuration/validate-output.json +++ b/imageroot/actions/get-configuration/validate-output.json @@ -23,7 +23,8 @@ "email", "host", "http2https", - "lets_encrypt" + "lets_encrypt", + "ldap_domain" ], "properties": { "wiki_name": { @@ -59,6 +60,10 @@ "type": "boolean", "title": "HTTP to HTTPS redirection", "description": "Redirect all the HTTP requests to HTTPS" + }, + "ldap_domain": { + "type": "string", + "description": "The LDAP domain name" } } } diff --git a/imageroot/bin/discover-ldap b/imageroot/bin/discover-ldap new file mode 100755 index 0000000..9a1c011 --- /dev/null +++ b/imageroot/bin/discover-ldap @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 + +# +# Copyright (C) 2024 Nethesis S.r.l. +# SPDX-License-Identifier: GPL-3.0-or-later +# + +# +# Find settings for LDAP service +# + +import os +import agent +from agent.ldapproxy import Ldapproxy + +udomname = os.environ.get('LDAP_DOMAIN','') + +try: + odom = Ldapproxy().get_domain(udomname) + 'host' in odom # Throw exception if odom is None +except: + # During restore the domain could be unavailable. Use a fallback + # configuration, pointing to nowhere, just to set the variables. + # Once the domain becomes available, the event will fix them. + odom = { + 'host': '127.0.0.1', + 'port': 20000, + 'schema': 'rfc2307', + 'location': 'internal', + 'base_dn': 'dc=dokuwiki,dc=invalid', + 'bind_dn': 'cn=example,dc=dokuwiki,dc=invalid', + 'bind_password': 'invalid', + } + +tmpfile = "discover.env." + str(os.getpid()) + +with open(tmpfile, "w") as denv: + print('LDAP_PORT=' + str(odom['port']), file=denv) + print('LDAP_USER=' + odom['bind_dn'], file=denv) + print('LDAP_HOST=' + odom['host'], file=denv) + print('LDAP_PASS=' + odom['bind_password'], file=denv) + print('LDAP_SCHEMA=' + odom['schema'], file=denv) + print('LDAP_BASE=' + odom['base_dn'], file=denv) + +os.replace(tmpfile, "discovery_ldap.env") diff --git a/imageroot/bin/wait-after-boot b/imageroot/bin/wait-after-boot new file mode 100755 index 0000000..172e763 --- /dev/null +++ b/imageroot/bin/wait-after-boot @@ -0,0 +1,22 @@ +#!/bin/bash + +# +# Copyright (C) 2024 Nethesis S.r.l. +# SPDX-License-Identifier: GPL-3.0-or-later +# + +# specific to dokuwiki, it creates its own configuration file after a long time boot + +count=0 +while [[ $count -lt 60 ]]; do + if podman exec -ti dokuwiki ls /bitnami/dokuwiki/conf/local.php.dist >/dev/null 2>&1; then + echo "First Configuration done. We push custom configuration files." + exit 0 + fi + ((count++)) + echo "Waiting for dokuwiki container to be ready..." + sleep 1 +done + +echo "Dokuwiki container is not ready after 60s. Exiting..." +exit 1 diff --git a/imageroot/bin/write-ldap-conf b/imageroot/bin/write-ldap-conf new file mode 100755 index 0000000..d83c776 --- /dev/null +++ b/imageroot/bin/write-ldap-conf @@ -0,0 +1,78 @@ +#!/bin/bash + +# +# Copyright (C) 2024 Nethesis S.r.l. +# SPDX-License-Identifier: GPL-3.0-or-later +# + +# Retrieving environment variables +LDAP_DOMAIN=${LDAP_DOMAIN} +LDAP_PORT=${LDAP_PORT} +LDAP_USER=${LDAP_USER} +LDAP_HOST=${LDAP_HOST} +LDAP_PASS=${LDAP_PASS} +LDAP_SCHEMA=${LDAP_SCHEMA} +LDAP_BASE=${LDAP_BASE} + +mkdir -vp dokuwiki-config +cat < dokuwiki-config/local.protected.php +> dokuwiki-config/local.protected.php +\$conf['authtype'] = 'authplain'; +EOF + +elif [[ "$LDAP_DOMAIN" != "" ]]; then + if [[ "$LDAP_SCHEMA" == "rfc2307" ]]; then + cat <> dokuwiki-config/local.protected.php +\$conf['authtype'] = 'authldap'; +\$conf['plugin'][\$conf['authtype']]['server'] = "ldap://accountprovider:${LDAP_PORT}"; +\$conf['plugin'][\$conf['authtype']]['version'] = '3'; +\$conf['plugin'][\$conf['authtype']]['usertree'] = "ou=People,${LDAP_BASE}"; +\$conf['plugin'][\$conf['authtype']]['grouptree'] = "ou=Groups,${LDAP_BASE}"; +\$conf['plugin'][\$conf['authtype']]['userfilter'] = '(|(uid=%{user})(mail=%{user}))'; +\$conf['plugin']['authldap']['groupfilter'] = '(memberUid=%{uid})'; +\$conf['plugin'][\$conf['authtype']]['groupkey'] = 'cn'; +\$conf['plugin']['authldap']['binddn'] = "${LDAP_USER}"; +\$conf['plugin']['authldap']['bindpw'] = "${LDAP_PASS}"; +\$conf['plugin']['authldap']['starttls'] = 0; +\$conf['plugin']['authldap']['modPass'] = 0; +EOF + elif [[ "$LDAP_SCHEMA" == "ad" ]]; then + cat <> dokuwiki-config/local.protected.php +\$conf['authtype'] = 'authad'; +\$conf['plugin']['authad']['account_suffix'] = '@${LDAP_DOMAIN}'; +\$conf['plugin']['authad']['base_dn'] = '${LDAP_BASE}'; +\$conf['plugin']['authad']['domain_controllers'] = 'ldap://accountprovider:${LDAP_PORT}'; //multiple can be given +\$conf['plugin']['authad']['use_tls'] = 0; +EOF + + fi +fi +cat <> dokuwiki-config/local.protected.php +\$conf['useacl'] = 1; +\$conf['superuser'] = 'admin,admin@${LDAP_DOMAIN},administrator,administrator@${LDAP_DOMAIN}'; +EOF + +echo "Configuration written to dokuwiki-config/local.protected.php" + +cat < dokuwiki-config/plugins.local.php +
- + + - - - - - - - - + + + + { + this.ldap_domain = config.ldap_domain; + if (this.ldap_domain == "") { + this.ldap_domain = "-"; + } + }); + // for NSComboBox we need to create a temporary variable + let ldap_domain_list_tmp = config.ldap_domain_list; + ldap_domain_list_tmp.unshift({ + name: "no_user_domain", + label: this.$t("settings.internal_authentication"), + value: "-", + }); + this.ldap_domain_list = ldap_domain_list_tmp; // set already_set to true if the configuration is not empty if ( this.wikiName && @@ -274,8 +334,9 @@ export default { ) { this.already_set = true; } + this.loading.getConfiguration = false; - this.focusElement("wikiName"); + this.focusElement("host"); }, validateConfigureModule() { this.clearErrors(this); @@ -404,6 +465,7 @@ export default { host: this.host, lets_encrypt: this.isLetsEncryptEnabled, http2https: this.isHttpToHttpsEnabled, + ldap_domain: this.ldap_domain == "-" ? "" : this.ldap_domain, }, extra: { title: this.$t("settings.instance_configuration", { diff --git a/ui/yarn.lock b/ui/yarn.lock index 0561939..315d93b 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -1012,10 +1012,10 @@ call-me-maybe "^1.0.1" glob-to-regexp "^0.3.0" -"@nethserver/ns8-ui-lib@^0.0.91": - version "0.0.91" - resolved "https://registry.yarnpkg.com/@nethserver/ns8-ui-lib/-/ns8-ui-lib-0.0.91.tgz#9685e12233958007f2d10b48236f42bfd59d7c46" - integrity sha512-nfc31uumTaHfujuksPkiKgNKdG81ccpj80jD1/tcQcwvW9rLsIlJaT3XGwTeNPJ9d04WQ5SAIsCcn0gdQ0yPMw== +"@nethserver/ns8-ui-lib@^0.1.32": + version "0.1.32" + resolved "https://registry.npmmirror.com/@nethserver/ns8-ui-lib/-/ns8-ui-lib-0.1.32.tgz#7556dd5c7f96ff166597552c9b20e02599d86ba6" + integrity sha512-CqW+Qr65uFiKYe/cG0qahRD+3ojXhDxMJ8Mf8M9CXDHY0WSWygyGYAftLxF8rtQkOdGHlaYv7cSK7TctHggHGA== dependencies: "@rollup/plugin-json" "^4.1.0" core-js "^3.15.2"