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