From a84ad8a3fa1449b16de6b03f6382061ff294c6dc Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Tue, 16 Jun 2026 15:50:22 +0200 Subject: [PATCH] nixos/rustical: fix unix domain socket support While the config supported UNIX domain sockets, the runtime environment did not. For this to work we need to relax the UMask, which is not great and will be fixed once Rustical gains socket activation. --- nixos/modules/services/web-apps/rustical.nix | 5 ++- nixos/tests/web-apps/rustical.nix | 32 +++++++++++--------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/nixos/modules/services/web-apps/rustical.nix b/nixos/modules/services/web-apps/rustical.nix index a92daf8c07b4..56661c9c24d6 100644 --- a/nixos/modules/services/web-apps/rustical.nix +++ b/nixos/modules/services/web-apps/rustical.nix @@ -149,6 +149,8 @@ in EnvironmentFile = cfg.environmentFiles; Restart = "on-failure"; StateDirectory = "rustical"; + RuntimeDirectory = "rustical"; + RuntimeDirectoryMode = "0750"; CapabilityBoundingSet = ""; DevicePolicy = "closed"; @@ -172,6 +174,7 @@ in RestrictAddressFamilies = [ "AF_INET" "AF_INET6" + "AF_UNIX" ]; RestrictNamespaces = true; RestrictRealtime = true; @@ -181,7 +184,7 @@ in "~@privileged @resources" ]; SystemCallErrorNumber = "EPERM"; - UMask = "0077"; + UMask = "0007"; }; }; }; diff --git a/nixos/tests/web-apps/rustical.nix b/nixos/tests/web-apps/rustical.nix index 15a718e87702..3213cfd61f09 100644 --- a/nixos/tests/web-apps/rustical.nix +++ b/nixos/tests/web-apps/rustical.nix @@ -4,10 +4,6 @@ ... }: -let - port = "4000"; -in - { name = "rustical"; @@ -15,14 +11,21 @@ in containers.machine = { + config, pkgs, ... }: { - services.rustical = { + services.rustical.enable = true; + services.nginx = { enable = true; - settings.http.bind = "[::]:${port}"; + virtualHosts."localhost" = { + locations."/" = { + proxyPass = "http://${config.services.rustical.settings.http.bind}"; + }; + }; }; + systemd.services.nginx.serviceConfig.SupplementaryGroups = [ "rustical" ]; environment.systemPackages = with pkgs; [ calendar-cli ]; }; @@ -32,8 +35,6 @@ in ... }: let - url = "http://localhost:${toString port}"; - createPrincipalScript = pkgs.writeScript "rustical-create-principal" '' #!${lib.getExe pkgs.expect} spawn rustical principals create alice --password @@ -45,30 +46,31 @@ in calendarCliConfig = (pkgs.formats.json { }).generate "rustical-test-calendar-cli.json" { default = { caldav_user = "alice"; - caldav_url = "${url}/caldav/"; - calendar_url = "${url}/caldav/principal/alice"; + caldav_url = "http://localhost/caldav/"; + calendar_url = "http://localhost/caldav/principal/alice"; }; testcal = { inherits = "default"; - calendar_url = "${url}/caldav/principal/alice/testcal"; + calendar_url = "http://localhost/caldav/principal/alice/testcal"; }; }; in # python '' machine.wait_for_unit("rustical.service") - machine.wait_for_open_port(${port}) + machine.wait_for_file("${lib.removePrefix "unix:" containers.machine.services.rustical.settings.http.bind}") + machine.wait_for_open_port(80) with subtest("Smoketest"): - machine.succeed("curl --fail ${url}") + machine.succeed("curl --fail http://localhost") with subtest("Create principal"): machine.succeed("${createPrincipalScript}") machine.succeed("rustical principals list | grep alice") with subtest("Generate token for principal"): - machine.succeed("curl -f -c cookies.txt -d 'username=alice&password=foobar' ${url}/frontend/login") - machine.succeed("curl -f -b cookies.txt -d 'name=mytoken' ${url}/frontend/user/alice/app_token > token.txt") + machine.succeed("curl -f -c cookies.txt -d 'username=alice&password=foobar' http://localhost/frontend/login") + machine.succeed("curl -f -b cookies.txt -d 'name=mytoken' http://localhost/frontend/user/alice/app_token > token.txt") with subtest("Interact with caldav"): machine.succeed('calendar-cli --config-file ${calendarCliConfig} --caldav-pass "$(cat token.txt)" calendar create testcal')