{ config, lib, pkgs, ... }: with lib; let cfg = config.services.xandikos; in { options = { services.xandikos = { enable = mkEnableOption "Xandikos CalDAV and CardDAV server"; package = mkOption { type = types.package; default = pkgs.xandikos; defaultText = "pkgs.xandikos"; description = "The Xandikos package to use."; }; address = mkOption { type = types.str; default = "localhost"; description = '' The IP address on which Xandikos will listen. By default listens on localhost. ''; }; port = mkOption { type = types.port; default = 8080; description = "The port of the Xandikos web application"; }; routePrefix = mkOption { type = types.str; default = "/"; description = '' Path to Xandikos. Useful when Xandikos is behind a reverse proxy. ''; }; extraOptions = mkOption { default = []; type = types.listOf types.str; example = literalExample '' [ "--autocreate" "--defaults" "--current-user-principal user" "--dump-dav-xml" ] ''; description = '' Extra command line arguments to pass to xandikos. ''; }; nginx = mkOption { default = {}; description = '' Configuration for nginx reverse proxy. ''; type = types.submodule { options = { enable = mkOption { type = types.bool; default = false; description = '' Configure the nginx reverse proxy settings. ''; }; hostName = mkOption { type = types.str; description = '' The hostname use to setup the virtualhost configuration ''; }; }; }; }; }; }; config = mkIf cfg.enable ( mkMerge [ { meta.maintainers = [ lib.maintainers."0x4A6F" ]; systemd.services.xandikos = { description = "A Simple Calendar and Contact Server"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { User = "xandikos"; Group = "xandikos"; DynamicUser = "yes"; RuntimeDirectory = "xandikos"; StateDirectory = "xandikos"; StateDirectoryMode = "0700"; PrivateDevices = true; # Sandboxing CapabilityBoundingSet = "CAP_NET_RAW CAP_NET_ADMIN"; ProtectSystem = "strict"; ProtectHome = true; PrivateTmp = true; ProtectKernelTunables = true; ProtectKernelModules = true; ProtectControlGroups = true; RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX AF_PACKET AF_NETLINK"; RestrictNamespaces = true; LockPersonality = true; MemoryDenyWriteExecute = true; RestrictRealtime = true; RestrictSUIDSGID = true; ExecStart = '' ${cfg.package}/bin/xandikos \ --directory /var/lib/xandikos \ --listen-address ${cfg.address} \ --port ${toString cfg.port} \ --route-prefix ${cfg.routePrefix} \ ${lib.concatStringsSep " " cfg.extraOptions} ''; }; }; } ( mkIf cfg.nginx.enable { services.nginx = { enable = true; virtualHosts."${cfg.nginx.hostName}" = { locations."/" = { proxyPass = "http://${cfg.address}:${toString cfg.port}/"; }; }; }; } ) ] ); }