This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

superconfig / configs / services / matrix / bridges / matrix-zulip-bridge.nix
5.2 kB 164 lines
1{ pkgs, lib, ... }: 2let 3 pkg = pkgs.matrix-zulip-bridge; 4 bin = lib.getExe pkg; 5 6 address = "127.0.0.1"; 7 port = 28464; 8 homeserver = "http://[::1]:8008"; 9 owner = "@lassulus:lassul.us"; 10 11 registrationFile = "/var/lib/matrix-zulip-bridge/registration.yml"; 12 13 # JSON is a proper subset of YAML. We render our desired registration and 14 # merge in the tokens from the bridge-generated file in preStart, mirroring 15 # the upstream heisenbridge module (this bridge shares its architecture). 16 bridgeConfig = builtins.toFile "matrix-zulip-bridge-registration.yml" ( 17 builtins.toJSON { 18 id = "zulipbridge"; 19 url = "http://${address}:${toString port}"; 20 rate_limited = false; 21 sender_localpart = "zulipbridge"; 22 namespaces = { 23 users = [ 24 { 25 regex = "@zulip_.*:lassul\\.us"; 26 exclusive = true; 27 } 28 { 29 regex = "@zulipbridge:lassul\\.us"; 30 exclusive = true; 31 } 32 ]; 33 aliases = [ ]; 34 rooms = [ ]; 35 }; 36 } 37 ); 38in 39{ 40 # Upstream zulip-emoji-mapping (a bridge dependency) is a Poetry project 41 # (version lives in [tool.poetry]) with no [build-system] table, but nixpkgs 42 # builds it with setuptools. Setuptools can't read the poetry version, so the 43 # wheel metadata gets 0.0.0 while the derivation declares 1.0.1, tripping 44 # pythonMetadataCheckPhase. Build with poetry-core and add the missing 45 # [build-system] table so the version is picked up correctly. 46 nixpkgs.overlays = [ 47 (_final: prev: { 48 pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [ 49 (pyfinal: pyprev: { 50 zulip-emoji-mapping = pyprev.zulip-emoji-mapping.overridePythonAttrs (old: { 51 build-system = [ pyfinal.poetry-core ]; 52 postPatch = (old.postPatch or "") + '' 53 cat >> pyproject.toml <<'EOF' 54 55 [build-system] 56 requires = ["poetry-core"] 57 build-backend = "poetry.core.masonry.api" 58 EOF 59 ''; 60 }); 61 }) 62 ]; 63 }) 64 ]; 65 66 systemd.services.matrix-zulip-bridge = { 67 description = "Matrix<->Zulip bridge"; 68 before = [ "matrix-synapse.service" ]; # So the registration file can be used by Synapse 69 wantedBy = [ "multi-user.target" ]; 70 71 preStart = '' 72 umask 077 73 set -e -u -o pipefail 74 75 if ! [ -f "${registrationFile}" ]; then 76 # Generate registration file if not present (we only care about the tokens in it) 77 ${bin} --generate --config ${registrationFile} 78 fi 79 80 # Overwrite the registration file with our generated one (the config may have 81 # changed since then), but keep the tokens. Two step procedure to be failure safe. 82 ${pkgs.yq}/bin/yq --slurp \ 83 '.[0] + (.[1] | {as_token, hs_token})' \ 84 ${bridgeConfig} \ 85 ${registrationFile} \ 86 > ${registrationFile}.new 87 mv -f ${registrationFile}.new ${registrationFile} 88 89 # Grant Synapse access to the registration 90 if ${pkgs.getent}/bin/getent group matrix-synapse > /dev/null; then 91 chgrp -v matrix-synapse ${registrationFile} 92 chmod -v g+r ${registrationFile} 93 fi 94 ''; 95 96 serviceConfig = { 97 Type = "simple"; 98 ExecStart = lib.concatStringsSep " " [ 99 bin 100 "-v" 101 "--config" 102 registrationFile 103 "--listen-address" 104 (lib.escapeShellArg address) 105 "--listen-port" 106 (toString port) 107 "--owner" 108 (lib.escapeShellArg owner) 109 (lib.escapeShellArg homeserver) 110 ]; 111 112 # Hardening options (mirrors upstream heisenbridge module) 113 User = "matrix-zulip-bridge"; 114 Group = "matrix-zulip-bridge"; 115 RuntimeDirectory = "matrix-zulip-bridge"; 116 RuntimeDirectoryMode = "0700"; 117 StateDirectory = "matrix-zulip-bridge"; 118 StateDirectoryMode = "0755"; 119 120 ProtectSystem = "strict"; 121 ProtectHome = true; 122 PrivateTmp = true; 123 PrivateDevices = true; 124 ProtectKernelTunables = true; 125 ProtectControlGroups = true; 126 RestrictSUIDSGID = true; 127 PrivateMounts = true; 128 ProtectKernelModules = true; 129 ProtectKernelLogs = true; 130 ProtectHostname = true; 131 ProtectClock = true; 132 ProtectProc = "invisible"; 133 ProcSubset = "pid"; 134 RestrictNamespaces = true; 135 RemoveIPC = true; 136 UMask = "0077"; 137 138 CapabilityBoundingSet = [ "CAP_CHOWN" ]; 139 AmbientCapabilities = [ "CAP_CHOWN" ]; 140 NoNewPrivileges = true; 141 LockPersonality = true; 142 RestrictRealtime = true; 143 SystemCallFilter = [ 144 "@system-service" 145 "~@privileged" 146 "@chown" 147 ]; 148 SystemCallArchitectures = "native"; 149 RestrictAddressFamilies = "AF_INET AF_INET6"; 150 }; 151 }; 152 153 # Wire the registration into Synapse (merges with the other bridges' lists). 154 services.matrix-synapse.settings.app_service_config_files = [ 155 registrationFile 156 ]; 157 158 users.groups.matrix-zulip-bridge = { }; 159 users.users.matrix-zulip-bridge = { 160 description = "Service user for the Matrix Zulip bridge"; 161 group = "matrix-zulip-bridge"; 162 isSystemUser = true; 163 }; 164}