grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / web-apps / sogo.nix
blob1102418077664a6c01c25457163795ffcea01e2d
1 { config, pkgs, lib, ... }: with lib; let
2   cfg = config.services.sogo;
4   preStart = pkgs.writeShellScriptBin "sogo-prestart" ''
5     ${if (cfg.configReplaces != {}) then ''
6       # Insert secrets
7       ${concatStringsSep "\n" (mapAttrsToList (k: v: ''export ${k}="$(cat "${v}" | tr -d '\n')"'') cfg.configReplaces)}
9       ${pkgs.perl}/bin/perl -p ${concatStringsSep " " (mapAttrsToList (k: v: '' -e 's/${k}/''${ENV{"${k}"}}/g;' '') cfg.configReplaces)} /etc/sogo/sogo.conf.raw | install -m 640 -o sogo -g sogo /dev/stdin /etc/sogo/sogo.conf
10     '' else ''
11       install -m 640 -o sogo -g sogo /etc/sogo/sogo.conf.raw /etc/sogo/sogo.conf
12     ''}
13   '';
15 in {
16   options.services.sogo = with types; {
17     enable = mkEnableOption "SOGo groupware";
19     vhostName = mkOption {
20       description = "Name of the nginx vhost";
21       type = str;
22       default = "sogo";
23     };
25     timezone = mkOption {
26       description = "Timezone of your SOGo instance";
27       type = str;
28       example = "America/Montreal";
29     };
31     language = mkOption {
32       description = "Language of SOGo";
33       type = str;
34       default = "English";
35     };
37     ealarmsCredFile = mkOption {
38       description = "Optional path to a credentials file for email alarms";
39       type = nullOr str;
40       default = null;
41     };
43     configReplaces = mkOption {
44       description = ''
45         Replacement-filepath mapping for sogo.conf.
46         Every key is replaced with the contents of the file specified as value.
48         In the example, every occurrence of LDAP_BINDPW will be replaced with the text of the
49         specified file.
50       '';
51       type = attrsOf str;
52       default = {};
53       example = {
54         LDAP_BINDPW = "/var/lib/secrets/sogo/ldappw";
55       };
56     };
58     extraConfig = mkOption {
59       description = "Extra sogo.conf configuration lines";
60       type = lines;
61       default = "";
62     };
63   };
65   config = mkIf cfg.enable {
66     environment.systemPackages = [ pkgs.sogo ];
68     environment.etc."sogo/sogo.conf.raw".text = ''
69       {
70         // Mandatory parameters
71         SOGoTimeZone = "${cfg.timezone}";
72         SOGoLanguage = "${cfg.language}";
73         // Paths
74         WOSendMail = "/run/wrappers/bin/sendmail";
75         SOGoMailSpoolPath = "/var/lib/sogo/spool";
76         // Enable CSRF protection
77         SOGoXSRFValidationEnabled = YES;
78         // Remove dates from log (jornald does that)
79         NGLogDefaultLogEventFormatterClass = "NGLogEventFormatter";
80         // Extra config
81         ${cfg.extraConfig}
82       }
83     '';
85     systemd.services.sogo = {
86       description = "SOGo groupware";
87       after = [ "postgresql.service" "mysql.service" "memcached.service" "openldap.service" "dovecot2.service" ];
88       wantedBy = [ "multi-user.target" ];
89       restartTriggers = [ config.environment.etc."sogo/sogo.conf.raw".source ];
91       environment.LDAPTLS_CACERT = "/etc/ssl/certs/ca-certificates.crt";
93       serviceConfig = {
94         Type = "forking";
95         ExecStartPre = "+" + preStart + "/bin/sogo-prestart";
96         ExecStart = "${pkgs.sogo}/bin/sogod -WOLogFile - -WOPidFile /run/sogo/sogo.pid";
98         ProtectSystem = "strict";
99         ProtectHome = true;
100         PrivateTmp = true;
101         PrivateDevices = true;
102         ProtectKernelTunables = true;
103         ProtectKernelModules = true;
104         ProtectControlGroups = true;
105         RuntimeDirectory = "sogo";
106         StateDirectory = "sogo/spool";
108         User = "sogo";
109         Group = "sogo";
111         CapabilityBoundingSet = "";
112         NoNewPrivileges = true;
114         LockPersonality = true;
115         RestrictRealtime = true;
116         PrivateMounts = true;
117         PrivateUsers = true;
118         MemoryDenyWriteExecute = true;
119         SystemCallFilter = "@basic-io @file-system @network-io @system-service @timer";
120         SystemCallArchitectures = "native";
121         RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
122       };
123     };
125     systemd.services.sogo-tmpwatch = {
126       description = "SOGo tmpwatch";
128       startAt = [ "hourly" ];
129       script = ''
130         SOGOSPOOL=/var/lib/sogo/spool
132         find "$SOGOSPOOL" -type f -user sogo -atime +23 -delete > /dev/null
133         find "$SOGOSPOOL" -mindepth 1 -type d -user sogo -empty -delete > /dev/null
134       '';
136       serviceConfig = {
137         Type = "oneshot";
139         ProtectSystem = "strict";
140         ProtectHome = true;
141         PrivateTmp = true;
142         PrivateDevices = true;
143         ProtectKernelTunables = true;
144         ProtectKernelModules = true;
145         ProtectControlGroups = true;
146         StateDirectory = "sogo/spool";
148         User = "sogo";
149         Group = "sogo";
151         CapabilityBoundingSet = "";
152         NoNewPrivileges = true;
154         LockPersonality = true;
155         RestrictRealtime = true;
156         PrivateMounts = true;
157         PrivateUsers = true;
158         PrivateNetwork = true;
159         SystemCallFilter = "@basic-io @file-system @system-service";
160         SystemCallArchitectures = "native";
161         RestrictAddressFamilies = "";
162       };
163     };
165     systemd.services.sogo-ealarms = {
166       description = "SOGo email alarms";
168       after = [ "postgresql.service" "mysqld.service" "memcached.service" "openldap.service" "dovecot2.service" "sogo.service" ];
169       restartTriggers = [ config.environment.etc."sogo/sogo.conf.raw".source ];
171       startAt = [ "minutely" ];
173       serviceConfig = {
174         Type = "oneshot";
175         ExecStart = "${pkgs.sogo}/bin/sogo-ealarms-notify${optionalString (cfg.ealarmsCredFile != null) " -p ${cfg.ealarmsCredFile}"}";
177         ProtectSystem = "strict";
178         ProtectHome = true;
179         PrivateTmp = true;
180         PrivateDevices = true;
181         ProtectKernelTunables = true;
182         ProtectKernelModules = true;
183         ProtectControlGroups = true;
184         StateDirectory = "sogo/spool";
186         User = "sogo";
187         Group = "sogo";
189         CapabilityBoundingSet = "";
190         NoNewPrivileges = true;
192         LockPersonality = true;
193         RestrictRealtime = true;
194         PrivateMounts = true;
195         PrivateUsers = true;
196         MemoryDenyWriteExecute = true;
197         SystemCallFilter = "@basic-io @file-system @network-io @system-service";
198         SystemCallArchitectures = "native";
199         RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6";
200       };
201     };
203     # nginx vhost
204     services.nginx.virtualHosts."${cfg.vhostName}" = {
205       locations."/".extraConfig = ''
206         rewrite ^ https://$server_name/SOGo;
207         allow all;
208       '';
210       # For iOS 7
211       locations."/principals/".extraConfig = ''
212         rewrite ^ https://$server_name/SOGo/dav;
213         allow all;
214       '';
216       locations."^~/SOGo".extraConfig = ''
217         proxy_pass http://127.0.0.1:20000;
218         proxy_redirect http://127.0.0.1:20000 default;
220         proxy_set_header X-Real-IP $remote_addr;
221         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
222         proxy_set_header Host $host;
223         proxy_set_header x-webobjects-server-protocol HTTP/1.0;
224         proxy_set_header x-webobjects-remote-host 127.0.0.1;
225         proxy_set_header x-webobjects-server-port $server_port;
226         proxy_set_header x-webobjects-server-name $server_name;
227         proxy_set_header x-webobjects-server-url $scheme://$host;
228         proxy_connect_timeout 90;
229         proxy_send_timeout 90;
230         proxy_read_timeout 90;
231         proxy_buffer_size 64k;
232         proxy_buffers 8 64k;
233         proxy_busy_buffers_size 64k;
234         proxy_temp_file_write_size 64k;
235         client_max_body_size 50m;
236         client_body_buffer_size 128k;
237         break;
238       '';
240       locations."/SOGo.woa/WebServerResources/".extraConfig = ''
241         alias ${pkgs.sogo}/lib/GNUstep/SOGo/WebServerResources/;
242         allow all;
243       '';
245       locations."/SOGo/WebServerResources/".extraConfig = ''
246         alias ${pkgs.sogo}/lib/GNUstep/SOGo/WebServerResources/;
247         allow all;
248       '';
250       locations."~ ^/SOGo/so/ControlPanel/Products/([^/]*)/Resources/(.*)$".extraConfig = ''
251         alias ${pkgs.sogo}/lib/GNUstep/SOGo/$1.SOGo/Resources/$2;
252       '';
254       locations."~ ^/SOGo/so/ControlPanel/Products/[^/]*UI/Resources/.*\\.(jpg|png|gif|css|js)$".extraConfig = ''
255         alias ${pkgs.sogo}/lib/GNUstep/SOGo/$1.SOGo/Resources/$2;
256       '';
257     };
259     # User and group
260     users.groups.sogo = {};
261     users.users.sogo = {
262       group = "sogo";
263       isSystemUser = true;
264       description = "SOGo service user";
265     };
266   };