1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.pumpio;
7 dataDir = "/var/lib/pump.io";
8 user = "pumpio";
9
10 configOptions = {
11 driver = if cfg.driver == "disk" then null else cfg.driver;
12 params = ({ } //
13 (if cfg.driver == "disk" then {
14 dir = dataDir;
15 } else { }) //
16 (if cfg.driver == "mongodb" || cfg.driver == "redis" then {
17 host = cfg.dbHost;
18 port = cfg.dbPort;
19 dbname = cfg.dbName;
20 dbuser = cfg.dbUser;
21 dbpass = cfg.dbPassword;
22 } else { }) //
23 (if cfg.driver == "memcached" then {
24 host = cfg.dbHost;
25 port = cfg.dbPort;
26 } else { }) //
27 cfg.driverParams);
28
29 secret = cfg.secret;
30
31 address = cfg.address;
32 port = cfg.port;
33
34 noweb = false;
35 urlPort = cfg.urlPort;
36 hostname = cfg.hostname;
37 favicon = cfg.favicon;
38
39 site = cfg.site;
40 owner = cfg.owner;
41 ownerURL = cfg.ownerURL;
42
43 key = cfg.sslKey;
44 cert = cfg.sslCert;
45 bounce = false;
46
47 spamhost = cfg.spamHost;
48 spamclientid = cfg.spamClientId;
49 spamclientsecret = cfg.spamClientSecret;
50
51 requireEmail = cfg.requireEmail;
52 smtpserver = cfg.smtpHost;
53 smtpport = cfg.smtpPort;
54 smtpuser = cfg.smtpUser;
55 smtppass = cfg.smtpPassword;
56 smtpusessl = cfg.smtpUseSSL;
57 smtpfrom = cfg.smtpFrom;
58
59 nologger = false;
60 uploaddir = "${dataDir}/uploads";
61 debugClient = false;
62 firehose = cfg.firehose;
63 disableRegistration = cfg.disableRegistration;
64 } //
65 (if cfg.port < 1024 then {
66 serverUser = user; # have pump.io listen then drop privileges
67 } else { }) //
68 cfg.extraConfig;
69
70in
71
72{
73 options = {
74
75 services.pumpio = {
76
77 enable = mkEnableOption "Pump.io social streams server";
78
79 secret = mkOption {
80 type = types.str;
81 example = "my dog has fleas";
82 description = ''
83 A session-generating secret, server-wide password. Warning:
84 this is stored in cleartext in the Nix store!
85 '';
86 };
87
88 site = mkOption {
89 type = types.str;
90 example = "Awesome Sauce";
91 description = "Name of the server";
92 };
93
94 owner = mkOption {
95 type = types.str;
96 default = "";
97 example = "Awesome Inc.";
98 description = "Name of owning entity, if you want to link to it.";
99 };
100
101 ownerURL = mkOption {
102 type = types.str;
103 default = "";
104 example = "https://pump.io";
105 description = "URL of owning entity, if you want to link to it.";
106 };
107
108 address = mkOption {
109 type = types.str;
110 default = "localhost";
111 description = ''
112 Web server listen address.
113 '';
114 };
115
116 port = mkOption {
117 type = types.int;
118 default = 31337;
119 description = ''
120 Port to listen on. Defaults to 31337, which is suitable for
121 running behind a reverse proxy. For a standalone server,
122 use 443.
123 '';
124 };
125
126 hostname = mkOption {
127 type = types.nullOr types.str;
128 default = null;
129 description = ''
130 The hostname of the server, used for generating
131 URLs. Defaults to "localhost" which doesn't do much for you.
132 '';
133 };
134
135 urlPort = mkOption {
136 type = types.int;
137 default = 443;
138 description = ''
139 Port to use for generating URLs. This basically has to be
140 either 80 or 443 because the host-meta and Webfinger
141 protocols don't make any provision for HTTP/HTTPS servers
142 running on other ports.
143 '';
144 };
145
146 favicon = mkOption {
147 type = types.nullOr types.path;
148 default = null;
149 description = ''
150 Local filesystem path to the favicon.ico file to use. This
151 will be served as "/favicon.ico" by the server.
152 '';
153 };
154
155 sslKey = mkOption {
156 type = types.path;
157 example = "${dataDir}/myserver.key";
158 default = "";
159 description = ''
160 The path to the server certificate private key. The
161 certificate is required, but it can be self-signed.
162 '';
163 };
164
165 sslCert = mkOption {
166 type = types.path;
167 example = "${dataDir}/myserver.crt";
168 default = "";
169 description = ''
170 The path to the server certificate. The certificate is
171 required, but it can be self-signed.
172 '';
173 };
174
175 firehose = mkOption {
176 type = types.str;
177 default = "ofirehose.com";
178 description = ''
179 Firehose host running the ofirehose software. Defaults to
180 "ofirehose.com". Public notices will be ping this firehose
181 server and from there go out to search engines and the
182 world. If you want to disconnect from the public web, set
183 this to something falsy.
184 '';
185 };
186
187 disableRegistration = mkOption {
188 type = types.bool;
189 default = false;
190 description = ''
191 Disables registering new users on the site through the Web
192 or the API.
193 '';
194 };
195
196 requireEmail = mkOption {
197 type = types.bool;
198 default = false;
199 description = "Require an e-mail address to register.";
200 };
201
202 extraConfig = mkOption {
203 default = { };
204 description = ''
205 Extra configuration options which are serialized to json and added
206 to the pump.io.json config file.
207 '';
208 };
209
210 driver = mkOption {
211 type = types.enum [ "mongodb" "disk" "lrucache" "memcached" "redis" ];
212 default = "mongodb";
213 description = "Type of database. Corresponds to a nodejs databank driver.";
214 };
215
216 driverParams = mkOption {
217 default = { };
218 description = "Extra parameters for the driver.";
219 };
220
221 dbHost = mkOption {
222 type = types.str;
223 default = "localhost";
224 description = "The database host to connect to.";
225 };
226
227 dbPort = mkOption {
228 type = types.int;
229 default = 27017;
230 description = "The port that the database is listening on.";
231 };
232
233 dbName = mkOption {
234 type = types.str;
235 default = "pumpio";
236 description = "The name of the database to use.";
237 };
238
239 dbUser = mkOption {
240 type = types.nullOr types.str;
241 default = null;
242 description = ''
243 The username. Defaults to null, meaning no authentication.
244 '';
245 };
246
247 dbPassword = mkOption {
248 type = types.nullOr types.str;
249 default = null;
250 description = ''
251 The password corresponding to dbUser. Warning: this is
252 stored in cleartext in the Nix store!
253 '';
254 };
255
256 smtpHost = mkOption {
257 type = types.nullOr types.str;
258 default = null;
259 example = "localhost";
260 description = ''
261 Server to use for sending transactional email. If it's not
262 set up, no email is sent and features like password recovery
263 and email notification won't work.
264 '';
265 };
266
267 smtpPort = mkOption {
268 type = types.int;
269 default = 25;
270 description = ''
271 Port to connect to on SMTP server.
272 '';
273 };
274
275 smtpUser = mkOption {
276 type = types.nullOr types.str;
277 default = null;
278 description = ''
279 Username to use to connect to SMTP server. Might not be
280 necessary for some servers.
281 '';
282 };
283
284 smtpPassword = mkOption {
285 type = types.nullOr types.str;
286 default = null;
287 description = ''
288 Password to use to connect to SMTP server. Might not be
289 necessary for some servers. Warning: this is stored in
290 cleartext in the Nix store!
291 '';
292 };
293
294 smtpUseSSL = mkOption {
295 type = types.bool;
296 default = false;
297 description = ''
298 Only use SSL with the SMTP server. By default, a SSL
299 connection is negotiated using TLS. You may need to change
300 the smtpPort value if you set this.
301 '';
302 };
303
304 smtpFrom = mkOption {
305 type = types.nullOr types.str;
306 default = null;
307 description = ''
308 Email address to use in the "From:" header of outgoing
309 notifications. Defaults to 'no-reply@' plus the site
310 hostname.
311 '';
312 };
313
314 spamHost = mkOption {
315 type = types.nullOr types.str;
316 default = null;
317 description = ''
318 Host running activityspam software to use to test updates
319 for spam.
320 '';
321 };
322 spamClientId = mkOption {
323 type = types.nullOr types.str;
324 default = null;
325 description = "OAuth pair for spam server.";
326 };
327 spamClientSecret = mkOption {
328 type = types.nullOr types.str;
329 default = null;
330 description = ''
331 OAuth pair for spam server. Warning: this is
332 stored in cleartext in the Nix store!
333 '';
334 };
335 };
336
337 };
338
339 config = mkIf cfg.enable {
340 systemd.services."pump.io" =
341 { description = "pump.io social network stream server";
342 after = [ "network.target" ];
343 wantedBy = [ "multi-user.target" ];
344 serviceConfig.ExecStart = "${pkgs.pumpio}/bin/pump -c /etc/pump.io.json";
345 serviceConfig.User = if cfg.port < 1024 then "root" else user;
346 serviceConfig.Group = user;
347 };
348
349 environment.etc."pump.io.json" = {
350 mode = "0440";
351 gid = config.ids.gids.pumpio;
352 text = builtins.toJSON configOptions;
353 };
354
355 users.extraGroups.pumpio.gid = config.ids.gids.pumpio;
356 users.extraUsers.pumpio = {
357 group = "pumpio";
358 uid = config.ids.uids.pumpio;
359 description = "Pump.io user";
360 home = dataDir;
361 createHome = true;
362 };
363 };
364}