summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--nixos/modules/services/web-apps/alps.nix52
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/alps.nix104
-rw-r--r--pkgs/servers/alps/default.nix20
4 files changed, 163 insertions, 14 deletions
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";