vuls: init at 0.27.0 (#348530)
[NixPkgs.git] / nixos / modules / services / web-apps / wakapi.nix
bloba38df9c8878a2626f4b22daea13566a524b8cd13
2   lib,
3   pkgs,
4   config,
5   ...
6 }:
7 let
8   cfg = config.services.wakapi;
10   settingsFormat = pkgs.formats.yaml { };
11   settingsFile = settingsFormat.generate "wakapi-settings" cfg.settings;
13   inherit (lib)
14     getExe
15     mkOption
16     mkEnableOption
17     mkPackageOption
18     types
19     mkIf
20     optional
21     mkMerge
22     singleton
23     ;
26   options.services.wakapi = {
27     enable = mkEnableOption "Wakapi";
28     package = mkPackageOption pkgs "wakapi" { };
30     settings = mkOption {
31       inherit (settingsFormat) type;
32       default = { };
33       description = ''
34         Settings for Wakapi.
36         See [config.default.yml](https://github.com/muety/wakapi/blob/master/config.default.yml) for a list of all possible options.
37       '';
38     };
40     passwordSalt = mkOption {
41       type = types.nullOr types.str;
42       default = null;
43       description = ''
44         The password salt to use for Wakapi.
45       '';
46     };
47     passwordSaltFile = mkOption {
48       type = types.nullOr types.path;
49       default = null;
50       description = ''
51         The path to a file containing the password salt to use for Wakapi.
52       '';
53     };
55     smtpPassword = mkOption {
56       type = types.nullOr types.str;
57       default = null;
58       description = ''
59         The password used for the smtp mailed to used by Wakapi.
60       '';
61     };
62     smtpPasswordFile = mkOption {
63       type = types.nullOr types.path;
64       default = null;
65       description = ''
66         The path to a file containing the password for the smtp mailer used by Wakapi.
67       '';
68     };
69   };
71   config = mkIf cfg.enable {
72     systemd.services.wakapi = {
73       description = "Wakapi (self-hosted WakaTime-compatible backend)";
74       wants = [
75         "network-online.target"
76       ] ++ optional (cfg.settings.db.dialect == "postgres") "postgresql.service";
77       after = [
78         "network-online.target"
79       ] ++ optional (cfg.settings.db.dialect == "postgres") "postgresql.service";
80       wantedBy = [ "multi-user.target" ];
82       script = ''
83         exec ${getExe cfg.package} -config ${settingsFile}
84       '';
86       serviceConfig = {
87         Environment = mkMerge [
88           (mkIf (cfg.passwordSalt != null) "WAKAPI_PASSWORD_SALT=${cfg.passwordSalt}")
89           (mkIf (cfg.smtpPassword != null) "WAKAPI_MAIL_SMTP_PASS=${cfg.smtpPassword}")
90         ];
91         EnvironmentFile = [
92           (optional (cfg.passwordSaltFile != null) cfg.passwordSaltFile)
93           (optional (cfg.smtpPasswordFile != null) cfg.smtpPasswordFile)
94         ];
96         User = config.users.users.wakapi.name;
97         Group = config.users.users.wakapi.group;
99         DynamicUser = true;
100         ProtectHome = true;
101         ProtectHostname = true;
102         ProtectKernelLogs = true;
103         ProtectKernelModules = true;
104         ProtectKernelTunables = true;
105         ProtectProc = "invisible";
106         ProtectSystem = "strict";
107         RestrictAddressFamilies = [
108           "AF_INET"
109           "AF_INET6"
110           "AF_UNIX"
111         ];
112         RestrictNamespaces = true;
113         RestrictRealtime = true;
114         RestrictSUIDSGID = true;
115         StateDirectory = "wakapi";
116         StateDirectoryMode = "0700";
117         Restart = "always";
118       };
119     };
121     services.wakapi.settings = {
122       env = lib.mkDefault "production";
123     };
125     assertions = [
126       {
127         assertion = cfg.passwordSalt != null || cfg.passwordSaltFile != null;
128         message = "Either `services.wakapi.passwordSalt` or `services.wakapi.passwordSaltFile` must be set.";
129       }
130       {
131         assertion = cfg.passwordSalt != null -> cfg.passwordSaltFile != null;
132         message = "Both `services.wakapi.passwordSalt` `services.wakapi.passwordSaltFile` should not be set at the same time.";
133       }
134       {
135         assertion = cfg.smtpPassword != null -> cfg.smtpPasswordFile != null;
136         message = "Both `services.wakapi.smtpPassword` `services.wakapi.smtpPasswordFile` should not be set at the same time.";
137       }
138     ];
140     users = {
141       users.wakapi = {
142         group = "wakapi";
143         createHome = false;
144         isSystemUser = true;
145       };
146       groups.wakapi = { };
147     };
149     services.postgresql = mkIf (cfg.settings.db.dialect == "postgres") {
150       enable = true;
152       ensureDatabases = singleton cfg.settings.db.name;
153       ensureUsers = singleton {
154         name = cfg.settings.db.user;
155         ensureDBOwnership = true;
156       };
158       authentication = ''
159         host ${cfg.settings.db.name} ${cfg.settings.db.user} 127.0.0.1/32 trust
160       '';
161     };
162   };
164   meta.maintainers = with lib.maintainers; [ isabelroses ];