1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.services.infinoted;
7in {
8 options.services.infinoted = {
9 enable = mkEnableOption (lib.mdDoc "infinoted");
10
11 package = mkOption {
12 type = types.package;
13 default = pkgs.libinfinity;
14 defaultText = literalExpression "pkgs.libinfinity";
15 description = lib.mdDoc ''
16 Package providing infinoted
17 '';
18 };
19
20 keyFile = mkOption {
21 type = types.nullOr types.path;
22 default = null;
23 description = lib.mdDoc ''
24 Private key to use for TLS
25 '';
26 };
27
28 certificateFile = mkOption {
29 type = types.nullOr types.path;
30 default = null;
31 description = lib.mdDoc ''
32 Server certificate to use for TLS
33 '';
34 };
35
36 certificateChain = mkOption {
37 type = types.nullOr types.path;
38 default = null;
39 description = lib.mdDoc ''
40 Chain of CA-certificates to which our `certificateFile` is relative.
41 Optional for TLS.
42 '';
43 };
44
45 securityPolicy = mkOption {
46 type = types.enum ["no-tls" "allow-tls" "require-tls"];
47 default = "require-tls";
48 description = lib.mdDoc ''
49 How strictly to enforce clients connection with TLS.
50 '';
51 };
52
53 port = mkOption {
54 type = types.port;
55 default = 6523;
56 description = lib.mdDoc ''
57 Port to listen on
58 '';
59 };
60
61 rootDirectory = mkOption {
62 type = types.path;
63 default = "/var/lib/infinoted/documents/";
64 description = lib.mdDoc ''
65 Root of the directory structure to serve
66 '';
67 };
68
69 plugins = mkOption {
70 type = types.listOf types.str;
71 default = [ "note-text" "note-chat" "logging" "autosave" ];
72 description = lib.mdDoc ''
73 Plugins to enable
74 '';
75 };
76
77 passwordFile = mkOption {
78 type = types.nullOr types.path;
79 default = null;
80 description = lib.mdDoc ''
81 File to read server-wide password from
82 '';
83 };
84
85 extraConfig = mkOption {
86 type = types.lines;
87 default = ''
88 [autosave]
89 interval=10
90 '';
91 description = lib.mdDoc ''
92 Additional configuration to append to infinoted.conf
93 '';
94 };
95
96 user = mkOption {
97 type = types.str;
98 default = "infinoted";
99 description = lib.mdDoc ''
100 What to call the dedicated user under which infinoted is run
101 '';
102 };
103
104 group = mkOption {
105 type = types.str;
106 default = "infinoted";
107 description = lib.mdDoc ''
108 What to call the primary group of the dedicated user under which infinoted is run
109 '';
110 };
111 };
112
113 config = mkIf (cfg.enable) {
114 users.users = optionalAttrs (cfg.user == "infinoted")
115 { infinoted = {
116 description = "Infinoted user";
117 group = cfg.group;
118 isSystemUser = true;
119 };
120 };
121 users.groups = optionalAttrs (cfg.group == "infinoted")
122 { infinoted = { };
123 };
124
125 systemd.services.infinoted =
126 { description = "Gobby Dedicated Server";
127
128 wantedBy = [ "multi-user.target" ];
129 after = [ "network.target" ];
130
131 serviceConfig = {
132 Type = "simple";
133 Restart = "always";
134 ExecStart = "${cfg.package.infinoted} --config-file=/var/lib/infinoted/infinoted.conf";
135 User = cfg.user;
136 Group = cfg.group;
137 PermissionsStartOnly = true;
138 };
139 preStart = ''
140 mkdir -p /var/lib/infinoted
141 install -o ${cfg.user} -g ${cfg.group} -m 0600 /dev/null /var/lib/infinoted/infinoted.conf
142 cat >>/var/lib/infinoted/infinoted.conf <<EOF
143 [infinoted]
144 ${optionalString (cfg.keyFile != null) "key-file=${cfg.keyFile}"}
145 ${optionalString (cfg.certificateFile != null) "certificate-file=${cfg.certificateFile}"}
146 ${optionalString (cfg.certificateChain != null) "certificate-chain=${cfg.certificateChain}"}
147 port=${toString cfg.port}
148 security-policy=${cfg.securityPolicy}
149 root-directory=${cfg.rootDirectory}
150 plugins=${concatStringsSep ";" cfg.plugins}
151 ${optionalString (cfg.passwordFile != null) "password=$(head -n 1 ${cfg.passwordFile})"}
152
153 ${cfg.extraConfig}
154 EOF
155
156 install -o ${cfg.user} -g ${cfg.group} -m 0750 -d ${cfg.rootDirectory}
157 '';
158 };
159 };
160}