diff --git a/module.nix b/module.nix index d1447f4..82f6b0f 100644 --- a/module.nix +++ b/module.nix @@ -27,91 +27,114 @@ in namespace = mkStringOption "The prefix to use for the MXIDs/aliases of bridged users/rooms. Should end with a _!" "_ooye_"; discordTokenPath = mkStringOption "The path to the discord token file." "/etc/ooye-discord-token"; socket = mkStringOption "The socket to listen on, can either be a port number or a unix socket path." "6693"; + + enableSynapseIntegration = lib.mkEnableOption "Enable Synapse integration"; }; }; - config = lib.mkIf cfg.enable { - warnings = - lib.optionals ((builtins.substring (lib.stringLength cfg.namespace - 1) 1 cfg.namespace) != "_") [ - "OOYE namespace does not end with an underscore! This is recommended to have better ID formatting. Provided: '${cfg.namespace}'" - ] - ++ lib.optionals ((builtins.substring 0 1 cfg.namespace) != "_") [ - "OOYE namespace does not start with an underscore! This is recommended to avoid conflicts with registered users. Provided: '${cfg.namespace}'" - ]; + config = lib.mkIf cfg.enable ( + let + baseConfig = pkgs.writeText "matrix-ooye-config.json" ( + builtins.toJSON { + id = cfg.appserviceId; + namespaces = { + users = [ + { + exclusive = true; + regex = "@${cfg.namespace}.*:${cfg.homeserverName}"; + } + ]; + aliases = [ + { + exclusive = true; + regex = "#${cfg.namespace}.*:${cfg.homeserverName}"; + } + ]; + }; + protocols = [ "discord" ]; + sender_localpart = "${cfg.namespace}bot"; + rate_limited = false; + socket = cfg.socket; # Can either be a TCP port or a unix socket path + url = if (lib.hasPrefix "/" cfg.socket) then "unix:${cfg.socket}" else "http://localhost:${cfg.socket}"; + ooye = { + server_name = cfg.homeserverName; + namespace_prefix = cfg.namespace; + max_file_size = 5000000; + content_length_workaround = false; + include_user_id_in_mxid = true; + server_origin = cfg.homeserver; + }; + } + ); - systemd.services."matrix-ooye" = - let - baseConfig = pkgs.writeText "matrix-ooye-config.json" ( - builtins.toJSON { - id = cfg.appserviceId; - namespaces = { - users = [ - { - exclusive = true; - regex = "@${cfg.namespace}.*:${cfg.homeserverName}"; - } - ]; - aliases = [ - { - exclusive = true; - regex = "#${cfg.namespace}.*:${cfg.homeserverName}"; - } - ]; - }; - protocols = [ "discord" ]; - sender_localpart = "${cfg.namespace}bot"; - rate_limited = false; - socket = cfg.socket; # Can either be a TCP port or a unix socket path - url = if (lib.hasPrefix "/" cfg.socket) then "unix:${cfg.socket}" else "http://localhost:${cfg.socket}"; - ooye = { - server_name = cfg.homeserverName; - namespace_prefix = cfg.namespace; - max_file_size = 5000000; - content_length_workaround = false; - include_user_id_in_mxid = true; - server_origin = cfg.homeserver; - }; - } - ); +script = pkgs.writeScript "matrix-ooye-pre-start.sh" '' + #!${lib.getExe pkgs.bash} + REGISTRATION_FILE=registration.yaml - script = pkgs.writeScript "matrix-ooye-pre-start.sh" '' - #!${lib.getExe pkgs.bash} - REGISTRATION_FILE=registration.yaml + id + echo "Before if statement" + stat ''${REGISTRATION_FILE} - if [[ ! -f ''${REGISTRATION_FILE} ]]; then - echo "No registration file found at '$REGISTRATION_FILE'" - cp --no-preserve=mode,ownership ${baseConfig} ''${REGISTRATION_FILE} - fi + if [[ ! -f ''${REGISTRATION_FILE} ]]; then + echo "No registration file found at '$REGISTRATION_FILE'" + cp --no-preserve=mode,ownership ${baseConfig} ''${REGISTRATION_FILE} + fi + + echo "After if statement" + stat ''${REGISTRATION_FILE} - AS_TOKEN=$(${lib.getExe pkgs.jq} -r .as_token ''${REGISTRATION_FILE}) - HS_TOKEN=$(${lib.getExe pkgs.jq} -r .hs_token ''${REGISTRATION_FILE}) - DISCORD_TOKEN=$(cat /run/credentials/matrix-ooye.service/discord_token) + AS_TOKEN=$(${lib.getExe pkgs.jq} -r .as_token ''${REGISTRATION_FILE}) + HS_TOKEN=$(${lib.getExe pkgs.jq} -r .hs_token ''${REGISTRATION_FILE}) + DISCORD_TOKEN=$(cat /run/credentials/matrix-ooye-pre-start.service/discord_token) - if [[ -z "$AS_TOKEN" || "$AS_TOKEN" == "null" ]]; then - AS_TOKEN=$(${lib.getExe pkgs.openssl} rand -hex 64) - echo "Generated new AS token: ''${AS_TOKEN}" - fi - if [[ -z "$HS_TOKEN" || "$HS_TOKEN" == "null" ]]; then - HS_TOKEN=$(${lib.getExe pkgs.openssl} rand -hex 64) - echo "Generated new HS token: ''${HS_TOKEN}" - fi - if [[ -z "$DISCORD_TOKEN" ]]; then - echo "No Discord token found at '${cfg.discordTokenPath}'" - exit 1 - fi + if [[ -z "$AS_TOKEN" || "$AS_TOKEN" == "null" ]]; then + AS_TOKEN=$(${lib.getExe pkgs.openssl} rand -hex 64) + echo "Generated new AS token: ''${AS_TOKEN}" + fi + if [[ -z "$HS_TOKEN" || "$HS_TOKEN" == "null" ]]; then + HS_TOKEN=$(${lib.getExe pkgs.openssl} rand -hex 64) + echo "Generated new HS token: ''${HS_TOKEN}" + fi + if [[ -z "$DISCORD_TOKEN" ]]; then + echo "No Discord token found at '${cfg.discordTokenPath}'" + exit 1 + fi - shred -u ''${REGISTRATION_FILE} - cp --no-preserve=mode,ownership ${baseConfig} ''${REGISTRATION_FILE} + shred -u ''${REGISTRATION_FILE} + cp --no-preserve=mode,ownership ${baseConfig} ''${REGISTRATION_FILE} - ${lib.getExe pkgs.jq} '.as_token = "'$AS_TOKEN'" | .hs_token = "'$HS_TOKEN'" | .ooye.discord_token = "'$DISCORD_TOKEN'"' ''${REGISTRATION_FILE} > ''${REGISTRATION_FILE}.tmp + ${lib.getExe pkgs.jq} '.as_token = "'$AS_TOKEN'" | .hs_token = "'$HS_TOKEN'" | .ooye.discord_token = "'$DISCORD_TOKEN'"' ''${REGISTRATION_FILE} > ''${REGISTRATION_FILE}.tmp - shred -u ''${REGISTRATION_FILE} - mv ''${REGISTRATION_FILE}.tmp ''${REGISTRATION_FILE} - ''; + shred -u ''${REGISTRATION_FILE} + mv ''${REGISTRATION_FILE}.tmp ''${REGISTRATION_FILE} +''; - in - { + in + { + warnings = + lib.optionals ((builtins.substring (lib.stringLength cfg.namespace - 1) 1 cfg.namespace) != "_") [ + "OOYE namespace does not end with an underscore! This is recommended to have better ID formatting. Provided: '${cfg.namespace}'" + ] + ++ lib.optionals ((builtins.substring 0 1 cfg.namespace) != "_") [ + "OOYE namespace does not start with an underscore! This is recommended to avoid conflicts with registered users. Provided: '${cfg.namespace}'" + ]; + + systemd.services."matrix-ooye-pre-start" = { enable = true; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + ExecStart = script; + WorkingDirectory = "/var/lib/matrix-ooye"; + StateDirectory = "matrix-ooye"; + DynamicUser = true; + LoadCredential = [ + "discord_token:${cfg.discordTokenPath}" + ]; + }; + }; + + systemd.services."matrix-ooye" = { + enable = true; description = "Out of Your Element - a Discord bridge for Matrix."; wants = [ @@ -120,35 +143,37 @@ in "conduit.service" "dendrite.service" ]; - after = [ "matrix-ooye-pre-start.service" "network-online.target" - "matrix-synapse.service" - "conduit.service" - "dendrite.service" ]; wantedBy = [ "multi-user.target" ]; + requires = [ "matrix-ooye-pre-start.service" ]; serviceConfig = { - ExecStartPre = script; ExecStart = lib.getExe config.services.matrix-ooye.package; - WorkingDirectory = "/var/lib/matrix-ooye"; StateDirectory = "matrix-ooye"; - StateDirectoryMode = "0700"; ProtectSystem = "strict"; ProtectHome = true; PrivateTmp = true; NoNewPrivileges = true; PrivateDevices = true; Restart = "on-failure"; - DynamicUser = true; - LoadCredential = [ - "discord_token:${cfg.discordTokenPath}" - ]; }; }; - }; + + systemd.services."matrix-synapse".serviceConfig = lib.mkIf cfg.enableSynapseIntegration { + LoadCredential = [ + "matrix-ooye-registration:/var/lib/matrix-ooye/registration.yaml" + ]; + ExecStartPre = "cp /run/credentials/matrix-synapse.service/registration.yaml ${config.services.matrix-synapse.dataDir}/ooye-registration.yaml"; + }; + + services.matrix-synapse.settings.app_service_config_files = lib.mkIf cfg.enableSynapseIntegration [ + "${config.services.matrix-synapse.dataDir}/ooye-registration.yaml" + ]; + } + ); }