diff --git a/nixos/modules/services/web-apps/alps.nix b/nixos/modules/services/web-apps/alps.nix index b73cb82925d9b..4681739af4ab0 100644 --- a/nixos/modules/services/web-apps/alps.nix +++ b/nixos/modules/services/web-apps/alps.nix @@ -70,6 +70,23 @@ in { ''; }; }; + + package = mkOption { + internal = true; + type = types.package; + default = pkgs.alps; + }; + + args = mkOption { + internal = true; + type = types.listOf types.str; + default = [ + "-addr" "${cfg.bindIP}:${toString cfg.port}" + "-theme" "${cfg.theme}" + "imaps://${cfg.imaps.host}:${toString cfg.imaps.port}" + "smpts://${cfg.smtps.host}:${toString cfg.smtps.port}" + ]; + }; }; config = mkIf cfg.enable { @@ -80,16 +97,33 @@ in { after = [ "network.target" "network-online.target" ]; serviceConfig = { - ExecStart = '' - ${pkgs.alps}/bin/alps \ - -addr ${cfg.bindIP}:${toString cfg.port} \ - -theme ${cfg.theme} \ - imaps://${cfg.imaps.host}:${toString cfg.imaps.port} \ - smpts://${cfg.smtps.host}:${toString cfg.smtps.port} - ''; - StateDirectory = "alps"; - WorkingDirectory = "/var/lib/alps"; + ExecStart = "${cfg.package}/bin/alps ${escapeShellArgs cfg.args}"; DynamicUser = true; + ## This is desirable but would restrict bindIP to 127.0.0.1 + #IPAddressAllow = "localhost"; + #IPAddressDeny = "any"; + LockPersonality = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateIPC = true; + PrivateTmp = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + RemoveIPC = true; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ "@system-service @resources" "~@privileged @obsolete" ]; }; }; }; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index bd0fe18c4f8c2..b238c43849512 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -74,6 +74,7 @@ in { agda = handleTest ./agda.nix {}; airsonic = handleTest ./airsonic.nix {}; allTerminfo = handleTest ./all-terminfo.nix {}; + alps = handleTest ./alps.nix {}; amazon-init-shell = handleTest ./amazon-init-shell.nix {}; apfs = handleTest ./apfs.nix {}; apparmor = handleTest ./apparmor.nix {}; diff --git a/nixos/tests/alps.nix b/nixos/tests/alps.nix new file mode 100644 index 0000000000000..8d7814117df1e --- /dev/null +++ b/nixos/tests/alps.nix @@ -0,0 +1,104 @@ +let + certs = import ./common/acme/server/snakeoil-certs.nix; + domain = certs.domain; +in +import ./make-test-python.nix ({ pkgs, ... }: { + name = "alps"; + + nodes = { + server = { + imports = [ ./common/user-account.nix ]; + security.pki.certificateFiles = [ + certs.ca.cert + ]; + networking.extraHosts = '' + 127.0.0.1 ${domain} + ''; + networking.firewall.allowedTCPPorts = [ 25 465 993 ]; + services.postfix = { + enable = true; + enableSubmission = true; + enableSubmissions = true; + tlsTrustedAuthorities = "${certs.ca.cert}"; + sslCert = "${certs.${domain}.cert}"; + sslKey = "${certs.${domain}.key}"; + }; + services.dovecot2 = { + enable = true; + enableImap = true; + sslCACert = "${certs.ca.cert}"; + sslServerCert = "${certs.${domain}.cert}"; + sslServerKey = "${certs.${domain}.key}"; + }; + }; + + client = { nodes, config, ... }: { + security.pki.certificateFiles = [ + certs.ca.cert + ]; + networking.extraHosts = '' + ${nodes.server.config.networking.primaryIPAddress} ${domain} + ''; + services.alps = { + enable = true; + theme = "alps"; + imaps = { + host = domain; + port = 993; + }; + smtps = { + host = domain; + port = 465; + }; + }; + environment.systemPackages = [ + (pkgs.writers.writePython3Bin "test-alps-login" { } '' + from urllib.request import build_opener, HTTPCookieProcessor, Request + from urllib.parse import urlencode, urljoin + from http.cookiejar import CookieJar + + baseurl = "http://localhost:${toString config.services.alps.port}" + username = "alice" + password = "${nodes.server.config.users.users.alice.password}" + cookiejar = CookieJar() + cookieprocessor = HTTPCookieProcessor(cookiejar) + opener = build_opener(cookieprocessor) + + data = urlencode({"username": username, "password": password}).encode() + req = Request(urljoin(baseurl, "login"), data=data, method="POST") + with opener.open(req) as ret: + # Check that the alps_session cookie is set + print(cookiejar) + assert any(cookie.name == "alps_session" for cookie in cookiejar) + + req = Request(baseurl) + with opener.open(req) as ret: + # Check that the alps_session cookie is still there... + print(cookiejar) + assert any(cookie.name == "alps_session" for cookie in cookiejar) + # ...and that we have not been redirected back to the login page + print(ret.url) + assert ret.url == urljoin(baseurl, "mailbox/INBOX") + + req = Request(urljoin(baseurl, "logout")) + with opener.open(req) as ret: + # Check that the alps_session cookie is now gone + print(cookiejar) + assert all(cookie.name != "alps_session" for cookie in cookiejar) + '') + ]; + }; + }; + + testScript = '' + server.start() + server.wait_for_unit("postfix.service") + server.wait_for_unit("dovecot2.service") + server.wait_for_open_port(465) + server.wait_for_open_port(993) + + client.start() + client.wait_for_unit("alps.service") + client.succeed("test-alps-login") + ''; +}) diff --git a/pkgs/servers/alps/default.nix b/pkgs/servers/alps/default.nix index a2f69473fbaa5..6ce373dce2682 100644 --- a/pkgs/servers/alps/default.nix +++ b/pkgs/servers/alps/default.nix @@ -1,17 +1,17 @@ -{ lib, buildGoModule, fetchFromSourcehut }: +{ lib, buildGoModule, fetchFromSourcehut, fetchpatch, nixosTests }: buildGoModule rec { pname = "alps"; - version = "2022-06-03"; + version = "2022-10-18"; src = fetchFromSourcehut { owner = "~migadu"; repo = "alps"; - rev = "9cb23b09975e95f6a5952e3718eaf471c3e3510f"; - hash = "sha256-BUV1/BRIXHEf2FU1rdmNgueo8KSUlMKbIpAg2lFs3hA="; + rev = "f01fbcbc48db5e65d69a0ebd9d7cb0deb378cf13"; + hash = "sha256-RSug3YSiqYLGs05Bee4NoaoCyPvUZ7IqlKWI1hmxbiA="; }; - vendorSha256 = "sha256-cpY+lYM/nAX3nUaFknrRAavxDk8UDzJkoqFjJ1/KWeg="; + vendorSha256 = "sha256-XDm6LU9D/rVQHiko7EFpocv+IktGe6tQhJYRrOJxeSs="; ldflags = [ "-s" @@ -20,6 +20,14 @@ buildGoModule rec { "-X git.sr.ht/~migadu/alps.PluginDir=${placeholder "out"}/share/alps/plugins" ]; + patches = [ + (fetchpatch { + name = "Issue-160-Alps-theme-has-a-enormous-move-to-list-sel"; + url = "https://lists.sr.ht/~migadu/alps-devel/patches/30096/mbox"; + hash = "sha256-Sz/SCkrrXZWrmJzjfPXi+UfCcbwsy6QiA7m34iiEFX0="; + }) + ]; + postPatch = '' substituteInPlace plugin.go --replace "const PluginDir" "var PluginDir" ''; @@ -31,6 +39,8 @@ buildGoModule rec { proxyVendor = true; + passthru.tests = { inherit(nixosTests) alps; }; + meta = with lib; { description = "A simple and extensible webmail."; homepage = "https://git.sr.ht/~migadu/alps";