{ config, lib, pkgs, ... }: with lib; let cfg = config.fudo.services.jabber; domain-name = config.instance.local-domain; domain = config.fudo.domains.${domain-name}; zone-name = domain.zone; hostname = config.instance.hostname; host-secrets = config.fudo.secrets.host-secrets.${hostname}; xmpp-server = elem hostname domain.xmpp-servers; in { options.fudo.services.jabber = with types; { user = mkOption { type = str; description = "User as which to run the ejabberd server."; default = "ejabberd"; }; group = mkOption { type = str; description = "Group as which to run the ejabberd server."; default = "ejabberd"; }; # hostname = mkOption { # type = str; # description = "Hostname of the user jabber server."; # default = "jabber.${domain-name}"; # }; enable-pubsub = mkEnableOption "Enable PubSub module."; domain = mkOption { type = str; description = "Jabber domain."; }; ldap = { user = mkOption { type = str; description = "System user as which to connect to the LDAP server to authenticate users."; default = "ejabberd-auth"; }; servers = mkOption { type = listOf str; description = "List of LDAP servers to use while authenticating users."; }; }; state-directory = mkOption { type = str; description = "Directory at which to store Jabber state. Should be persistent."; default = "/var/lib/ejabberd"; }; }; config.fudo = let ejabberd-ldap-auth-passwd-file = pkgs.lib.passwd.stablerandom-passwd-file "ejabberd-auth-passwd-file" "ejabberd-auth-passwd-file-${config.instance.build-seed}"; hostname-map = listToAttrs (imap0 (i: hostname: nameValuePair hostname "xmpp-${toString i}") domain.xmpp-servers); in { system-users.${cfg.ldap.user} = { description = "ejabberd authentication user."; ldap-hashed-password = pkgs.lib.passwd.hash-ldap-passwd "ejabberd-ldap-auth-passwd" ejabberd-ldap-auth-passwd-file; }; zones.${zone-name} = { srv-records.tcp = let to-fqdn = server: "${hostname-map.${server}}.${domain-name}"; in { xmpp-server = map (host: { host = to-fqdn host; port = 5269; }) domain.xmpp-servers; xmpp-client = map (host: { host = to-fqdn host; port = 5222; }) domain.xmpp-servers; }; aliases = mapAttrs' (host: alias: nameValuePair alias host) hostname-map; }; jabber = mkIf xmpp-server { enable = true; state-directory = cfg.state-directory; secret-files = { "__LDAP_PASSWORD__" = ejabberd-ldap-auth-passwd-file; }; sites = { ${cfg.domain} = { hostname = "${hostname-map.${hostname}}.${domain-name}"; site-config = { auth_method = "ldap"; ldap_servers = cfg.ldap.servers; ldap_port = 389; ldap_rootdn = "cn=${cfg.ldap.user},dc=fudo,dc=org"; ldap_password = "__LDAP_PASSWORD__"; ldap_base = "ou=members,dc=fudo,dc=org"; ldap_filter = "(objectClass=posixAccount)"; ldap_uids = { uid = "%u"; }; ldap_tls_cacertfile = "${pkgs.letsencrypt-ca}"; ldap_tls_verify = "false"; modules = { mod_adhoc = {}; mod_announce = {}; mod_avatar = {}; mod_blocking = {}; mod_caps = {}; mod_carboncopy = {}; mod_client_state = {}; mod_configure = {}; mod_disco = {}; mod_fail2ban = {}; mod_last = {}; mod_offline = { access_max_user_messages = 5000; }; mod_ping = {}; mod_privacy = {}; mod_private = {}; mod_pubsub = { access_createnode = "pubsub_createnode"; ignore_pep_from_offline = true; last_item_cache = false; plugins = [ "flat" "pep" ]; }; mod_roster = {}; mod_stream_mgmt = {}; mod_time = {}; mod_vcard = { search = false; }; mod_vcard_xupdate = {}; mod_version = {}; }; }; }; }; }; }; }