diff --git a/nixos/modules/services/web-apps/pump.io-configure.js b/nixos/modules/services/web-apps/pump.io-configure.js new file mode 100644 index 000000000000..1fbf346a34c4 --- /dev/null +++ b/nixos/modules/services/web-apps/pump.io-configure.js @@ -0,0 +1,23 @@ +var fs = require('fs'); + +var opts = JSON.parse(fs.readFileSync("/dev/stdin").toString()); +var config = opts.config; + +var readSecret = function(filename) { + return fs.readFileSync(filename).toString().trim(); +}; + +if (opts.secretFile) { + config.secret = readSecret(opts.secretFile); +} +if (opts.dbPasswordFile) { + config.params.dbpass = readSecret(opts.dbPasswordFile); +} +if (opts.smtpPasswordFile) { + config.smtppass = readSecret(opts.smtpPasswordFile); +} +if (opts.spamClientSecretFile) { + config.spamclientsecret = readSecret(opts.opts.spamClientSecretFile); +} + +fs.writeFileSync(opts.outputFile, JSON.stringify(config)); diff --git a/nixos/modules/services/web-apps/pump.io.nix b/nixos/modules/services/web-apps/pump.io.nix index b946aa28477f..27ae68516367 100644 --- a/nixos/modules/services/web-apps/pump.io.nix +++ b/nixos/modules/services/web-apps/pump.io.nix @@ -5,72 +5,74 @@ with lib; let cfg = config.services.pumpio; dataDir = "/var/lib/pump.io"; + runDir = "/run/pump.io"; user = "pumpio"; + optionalSet = condition: value: if condition then value else {}; + + configScript = ./pump.io-configure.js; configOptions = { - driver = if cfg.driver == "disk" then null else cfg.driver; - params = ({ } // - (if cfg.driver == "disk" then { - dir = dataDir; - } else { }) // - (if cfg.driver == "mongodb" || cfg.driver == "redis" then { - host = cfg.dbHost; - port = cfg.dbPort; - dbname = cfg.dbName; - dbuser = cfg.dbUser; - dbpass = cfg.dbPassword; - } else { }) // - (if cfg.driver == "memcached" then { - host = cfg.dbHost; - port = cfg.dbPort; - } else { }) // - cfg.driverParams); + outputFile = "${runDir}/config.json"; + config = + (optionalSet (cfg.driver != "disk") { + driver = cfg.driver; + }) // + { + params = (optionalSet (cfg.driver == "disk") { dir = dataDir; }) // + (optionalSet (cfg.driver == "mongodb" || cfg.driver == "redis") { + host = cfg.dbHost; + port = cfg.dbPort; + dbname = cfg.dbName; + dbuser = cfg.dbUser; + dbpass = cfg.dbPassword; + }) // + (optionalSet (cfg.driver == "memcached") { + host = cfg.dbHost; + port = cfg.dbPort; + }) // cfg.driverParams; + secret = cfg.secret; - secret = cfg.secret; + address = cfg.address; + port = cfg.port; - address = cfg.address; - port = cfg.port; + noweb = false; + urlPort = cfg.urlPort; + hostname = cfg.hostname; + favicon = cfg.favicon; - noweb = false; - urlPort = cfg.urlPort; - hostname = cfg.hostname; - favicon = cfg.favicon; + site = cfg.site; + owner = cfg.owner; + ownerURL = cfg.ownerURL; - site = cfg.site; - owner = cfg.owner; - ownerURL = cfg.ownerURL; + key = cfg.sslKey; + cert = cfg.sslCert; + bounce = false; - key = cfg.sslKey; - cert = cfg.sslCert; - bounce = false; + spamhost = cfg.spamHost; + spamclientid = cfg.spamClientId; + spamclientsecret = cfg.spamClientSecret; - spamhost = cfg.spamHost; - spamclientid = cfg.spamClientId; - spamclientsecret = cfg.spamClientSecret; + requireEmail = cfg.requireEmail; + smtpserver = cfg.smtpHost; + smtpport = cfg.smtpPort; + smtpuser = cfg.smtpUser; + smtppass = cfg.smtpPassword; + smtpusessl = cfg.smtpUseSSL; + smtpfrom = cfg.smtpFrom; - requireEmail = cfg.requireEmail; - smtpserver = cfg.smtpHost; - smtpport = cfg.smtpPort; - smtpuser = cfg.smtpUser; - smtppass = cfg.smtpPassword; - smtpusessl = cfg.smtpUseSSL; - smtpfrom = cfg.smtpFrom; + nologger = false; + enableUploads = cfg.enableUploads; + datadir = dataDir; + debugClient = false; + firehose = cfg.firehose; + disableRegistration = cfg.disableRegistration; - nologger = false; - enableUploads = cfg.enableUploads; - datadir = dataDir; - debugClient = false; - firehose = cfg.firehose; - disableRegistration = cfg.disableRegistration; - } // - (if cfg.port < 1024 then { - serverUser = user; # have pump.io listen then drop privileges - } else { }) // - cfg.extraConfig; - -in - -{ + inherit (cfg) secretFile dbPasswordFile smtpPasswordFile spamClientSecretFile; + } // + (optionalSet (cfg.port < 1024) { + serverUser = user; # have pump.io listen then drop privileges + }) // cfg.extraConfig; +}; in { options = { services.pumpio = { @@ -78,7 +80,8 @@ in enable = mkEnableOption "Pump.io social streams server"; secret = mkOption { - type = types.str; + type = types.nullOr types.str; + default = null; example = "my dog has fleas"; description = '' A session-generating secret, server-wide password. Warning: @@ -86,6 +89,16 @@ in ''; }; + secretFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/keys/pump.io-secret"; + description = '' + A file containing the session-generating secret, + server-wide password. + ''; + }; + site = mkOption { type = types.str; example = "Awesome Sauce"; @@ -126,7 +139,7 @@ in hostname = mkOption { type = types.nullOr types.str; - default = null; + default = "localhost"; description = '' The hostname of the server, used for generating URLs. Defaults to "localhost" which doesn't do much for you. @@ -263,6 +276,15 @@ in ''; }; + dbPasswordFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/keys/pump.io-dbpassword"; + description = '' + A file containing the password corresponding to dbUser. + ''; + }; + smtpHost = mkOption { type = types.nullOr types.str; default = null; @@ -301,6 +323,17 @@ in ''; }; + smtpPasswordFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/keys/pump.io-smtppassword"; + description = '' + A file containing the password used to connect to SMTP + server. Might not be necessary for some servers. + ''; + }; + + smtpUseSSL = mkOption { type = types.bool; default = false; @@ -342,32 +375,55 @@ in stored in cleartext in the Nix store! ''; }; + spamClientSecretFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/keys/pump.io-spamclientsecret"; + description = '' + A file containing the OAuth key for the spam server. + ''; + }; }; }; config = mkIf cfg.enable { + warnings = let warn = k: optional (cfg.${k} != null) + "config.services.pumpio.${k} is insecure. Use ${k}File instead."; + in concatMap warn [ "secret" "dbPassword" "smtpPassword" "spamClientSecret" ]; + + assertions = [ + { assertion = !(isNull cfg.secret && isNull cfg.secretFile); + message = "pump.io needs a secretFile configured"; + } + ]; + systemd.services."pump.io" = - { description = "pump.io social network stream server"; + { description = "Pump.io - stream server that does most of what people really want from a social network"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; preStart = '' mkdir -p ${dataDir}/uploads - chown pumpio:pumpio ${dataDir}/uploads - chmod 770 ${dataDir}/uploads + mkdir -p ${runDir} + chown pumpio:pumpio ${dataDir}/uploads ${runDir} + chmod 770 ${dataDir}/uploads ${runDir} + + ${pkgs.nodejs}/bin/node ${configScript} <