about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRobert Schütz <nix@dotlambda.de>2024-03-28 18:51:07 +0000
committerGitHub <noreply@github.com>2024-03-28 18:51:07 +0000
commit7cdbfcbbd2b142800ef6ca2d53ce86b24b1c5f1f (patch)
tree25118b8af0f0ae413c6c9d8190b382f458938bf9
parentb40caf8c8a7e30fa0befedd3e0139c59c3141af1 (diff)
parent078994248a1e52d95de7c32c0a642f00abf881aa (diff)
downloadnixlib-7cdbfcbbd2b142800ef6ca2d53ce86b24b1c5f1f.tar
nixlib-7cdbfcbbd2b142800ef6ca2d53ce86b24b1c5f1f.tar.gz
nixlib-7cdbfcbbd2b142800ef6ca2d53ce86b24b1c5f1f.tar.bz2
nixlib-7cdbfcbbd2b142800ef6ca2d53ce86b24b1c5f1f.tar.lz
nixlib-7cdbfcbbd2b142800ef6ca2d53ce86b24b1c5f1f.tar.xz
nixlib-7cdbfcbbd2b142800ef6ca2d53ce86b24b1c5f1f.tar.zst
nixlib-7cdbfcbbd2b142800ef6ca2d53ce86b24b1c5f1f.zip
Merge pull request #278981 from dotlambda/mollysocket-init
mollysocket: init at 1.3.0, nixos/mollysocket: init
-rw-r--r--nixos/doc/manual/release-notes/rl-2405.section.md2
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/services/misc/mollysocket.nix133
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/mollysocket.nix27
-rw-r--r--pkgs/by-name/mo/mollysocket/package.nix58
6 files changed, 222 insertions, 0 deletions
diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md
index fea452375477..01ba9038fa75 100644
--- a/nixos/doc/manual/release-notes/rl-2405.section.md
+++ b/nixos/doc/manual/release-notes/rl-2405.section.md
@@ -104,6 +104,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m
 
 - [transfer-sh](https://github.com/dutchcoders/transfer.sh), a tool that supports easy and fast file sharing from the command-line. Available as [services.transfer-sh](#opt-services.transfer-sh.enable).
 
+- [MollySocket](https://github.com/mollyim/mollysocket) which allows getting Signal notifications via UnifiedPush.
+
 - [Suwayomi Server](https://github.com/Suwayomi/Suwayomi-Server), a free and open source manga reader server that runs extensions built for [Tachiyomi](https://tachiyomi.org). Available as [services.suwayomi-server](#opt-services.suwayomi-server.enable).
 
 - [ping_exporter](https://github.com/czerwonk/ping_exporter), a Prometheus exporter for ICMP echo requests. Available as [services.prometheus.exporters.ping](#opt-services.prometheus.exporters.ping.enable).
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index d89d294b0469..90b37e878312 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -728,6 +728,7 @@
   ./services/misc/mbpfan.nix
   ./services/misc/mediatomb.nix
   ./services/misc/metabase.nix
+  ./services/misc/mollysocket.nix
   ./services/misc/moonraker.nix
   ./services/misc/mqtt2influxdb.nix
   ./services/misc/n8n.nix
diff --git a/nixos/modules/services/misc/mollysocket.nix b/nixos/modules/services/misc/mollysocket.nix
new file mode 100644
index 000000000000..f40caa4a782e
--- /dev/null
+++ b/nixos/modules/services/misc/mollysocket.nix
@@ -0,0 +1,133 @@
+{ config, lib, pkgs, ... }:
+
+let
+  inherit (lib) getExe mkIf mkOption mkEnableOption optionals types;
+
+  cfg = config.services.mollysocket;
+  configuration = format.generate "mollysocket.conf" cfg.settings;
+  format = pkgs.formats.toml { };
+  package = pkgs.writeShellScriptBin "mollysocket" ''
+    MOLLY_CONF=${configuration} exec ${getExe pkgs.mollysocket} "$@"
+  '';
+in {
+  options.services.mollysocket = {
+    enable = mkEnableOption ''
+      [MollySocket](https://github.com/mollyim/mollysocket) for getting Signal
+      notifications via UnifiedPush
+    '';
+
+    settings = mkOption {
+      default = { };
+      description = ''
+        Configuration for MollySocket. Available options are listed
+        [here](https://github.com/mollyim/mollysocket#configuration).
+      '';
+      type = types.submodule {
+        freeformType = format.type;
+        options = {
+          host = mkOption {
+            default = "127.0.0.1";
+            description = "Listening address of the web server";
+            type = types.str;
+          };
+
+          port = mkOption {
+            default = 8020;
+            description = "Listening port of the web server";
+            type = types.port;
+          };
+
+          allowed_endpoints = mkOption {
+            default = [ "*" ];
+            description = "List of UnifiedPush servers";
+            example = [ "https://ntfy.sh" ];
+            type = with types; listOf str;
+          };
+
+          allowed_uuids = mkOption {
+            default = [ "*" ];
+            description = "UUIDs of Signal accounts that may use this server";
+            example = [ "abcdef-12345-tuxyz-67890" ];
+            type = with types; listOf str;
+          };
+        };
+      };
+    };
+
+    environmentFile = mkOption {
+      default = null;
+      description = ''
+        Environment file (see {manpage}`systemd.exec(5)` "EnvironmentFile="
+        section for the syntax) passed to the service. This option can be
+        used to safely include secrets in the configuration.
+      '';
+      example = "/run/secrets/mollysocket";
+      type = with types; nullOr path;
+    };
+
+    logLevel = mkOption {
+      default = "info";
+      description = "Set the {env}`RUST_LOG` environment variable";
+      example = "debug";
+      type = types.str;
+    };
+  };
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = [
+      package
+    ];
+
+    # see https://github.com/mollyim/mollysocket/blob/main/mollysocket.service
+    systemd.services.mollysocket = {
+      description = "MollySocket";
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network-online.target" ];
+      wants = [ "network-online.target" ];
+      environment.RUST_LOG = cfg.logLevel;
+      serviceConfig = let
+        capabilities = [ "" ] ++ optionals (cfg.settings.port < 1024) [ "CAP_NET_BIND_SERVICE" ];
+      in {
+        EnvironmentFile = cfg.environmentFile;
+        ExecStart = "${getExe package} server";
+        KillSignal = "SIGINT";
+        Restart = "on-failure";
+        StateDirectory = "mollysocket";
+        TimeoutStopSec = 5;
+        WorkingDirectory = "/var/lib/mollysocket";
+
+        # hardening
+        AmbientCapabilities = capabilities;
+        CapabilityBoundingSet = capabilities;
+        DevicePolicy = "closed";
+        DynamicUser = true;
+        LockPersonality = true;
+        MemoryDenyWriteExecute = true;
+        NoNewPrivileges = true;
+        PrivateDevices = true;
+        PrivateTmp = true;
+        PrivateUsers = true;
+        ProcSubset = "pid";
+        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" ];
+        UMask = "0077";
+      };
+    };
+  };
+
+  meta.maintainers = with lib.maintainers; [ dotlambda ];
+}
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index 9cff268ae1d1..f7ad6c16f587 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -543,6 +543,7 @@ in {
   mobilizon = handleTest ./mobilizon.nix {};
   mod_perl = handleTest ./mod_perl.nix {};
   molly-brown = handleTest ./molly-brown.nix {};
+  mollysocket = handleTest ./mollysocket.nix { };
   monado = handleTest ./monado.nix {};
   monetdb = handleTest ./monetdb.nix {};
   monica = handleTest ./web-apps/monica.nix {};
diff --git a/nixos/tests/mollysocket.nix b/nixos/tests/mollysocket.nix
new file mode 100644
index 000000000000..8cbd0c0272e0
--- /dev/null
+++ b/nixos/tests/mollysocket.nix
@@ -0,0 +1,27 @@
+import ./make-test-python.nix ({ pkgs, lib, ... }:
+
+let
+  port = 1234;
+in {
+  name = "mollysocket";
+  meta.maintainers = with lib.maintainers; [ dotlambda ];
+
+  nodes.mollysocket = { ... }: {
+    services.mollysocket = {
+      enable = true;
+      settings = {
+        inherit port;
+      };
+    };
+  };
+
+  testScript = ''
+    import json
+
+    mollysocket.wait_for_unit("mollysocket.service")
+    mollysocket.wait_for_open_port(${toString port})
+
+    out = mollysocket.succeed("curl --fail http://127.0.0.1:${toString port}")
+    assert json.loads(out)["mollysocket"]["version"] == "${toString pkgs.mollysocket.version}"
+  '';
+})
diff --git a/pkgs/by-name/mo/mollysocket/package.nix b/pkgs/by-name/mo/mollysocket/package.nix
new file mode 100644
index 000000000000..025bb34e8dd7
--- /dev/null
+++ b/pkgs/by-name/mo/mollysocket/package.nix
@@ -0,0 +1,58 @@
+{ lib
+, rustPlatform
+, fetchFromGitHub
+, pkg-config
+, openssl
+, sqlite
+, stdenv
+, darwin
+, nixosTests
+}:
+
+rustPlatform.buildRustPackage rec {
+  pname = "mollysocket";
+  version = "1.3.0";
+
+  src = fetchFromGitHub {
+    owner = "mollyim";
+    repo = "mollysocket";
+    rev = version;
+    hash = "sha256-eFvRjGUQ1AU+kXUp6YALm1lqhTMY2DxvFuf+MHCL38c=";
+  };
+
+  cargoHash = "sha256-3UwvnbHH6v1fJyivdU55GmJ2/+RSqXfBKIcOARASWbE=";
+
+  nativeBuildInputs = [
+    pkg-config
+  ];
+
+  buildInputs = [
+    openssl
+    sqlite
+  ] ++ lib.optionals stdenv.isDarwin [
+    darwin.apple_sdk.frameworks.Security
+  ];
+
+  checkFlags = [
+    # tests interact with Signal servers
+    "--skip=config::tests::check_wildcard_endpoint"
+    "--skip=utils::post_allowed::tests::test_allowed"
+    "--skip=utils::post_allowed::tests::test_not_allowed"
+    "--skip=utils::post_allowed::tests::test_post"
+    "--skip=ws::tls::tests::connect_untrusted_server"
+    "--skip=ws::tls::tests::connect_trusted_server"
+  ];
+
+  passthru.tests = {
+    inherit (nixosTests) mollysocket;
+  };
+
+  meta = {
+    changelog = "https://github.com/mollyim/mollysocket/releases/tag/${version}";
+    description = "Get Signal notifications via UnifiedPush";
+    homepage = "https://github.com/mollyim/mollysocket";
+    license = lib.licenses.agpl3Plus;
+    mainProgram = "mollysocket";
+    maintainers = with lib.maintainers; [ dotlambda ];
+  };
+}