···
1
+
{ config, pkgs, lib, ... }:
4
+
cfg = config.services.anuko-time-tracker;
6
+
smtpPassword = if cfg.settings.email.smtpPasswordFile == null
8
+
else "trim(file_get_contents('${cfg.settings.email.smtpPasswordFile}'))";
10
+
in pkgs.writeText "config.php" ''
12
+
// Set include path for PEAR and its modules, which we include in the distribution.
13
+
// Updated for the correct location in the nix store.
14
+
set_include_path('${cfg.package}/WEB-INF/lib/pear' . PATH_SEPARATOR . get_include_path());
15
+
define('DSN', 'mysqli://${cfg.database.user}@${cfg.database.host}/${cfg.database.name}?charset=utf8mb4');
16
+
define('MULTIORG_MODE', ${lib.boolToString cfg.settings.multiorgMode});
17
+
define('EMAIL_REQUIRED', ${lib.boolToString cfg.settings.emailRequired});
18
+
define('WEEKEND_START_DAY', ${toString cfg.settings.weekendStartDay});
19
+
define('FORUM_LINK', '${cfg.settings.forumLink}');
20
+
define('HELP_LINK', '${cfg.settings.helpLink}');
21
+
define('SENDER', '${cfg.settings.email.sender}');
22
+
define('MAIL_MODE', '${cfg.settings.email.mode}');
23
+
define('MAIL_SMTP_HOST', '${toString cfg.settings.email.smtpHost}');
24
+
define('MAIL_SMTP_PORT', '${toString cfg.settings.email.smtpPort}');
25
+
define('MAIL_SMTP_USER', '${cfg.settings.email.smtpUser}');
26
+
define('MAIL_SMTP_PASSWORD', ${smtpPassword});
27
+
define('MAIL_SMTP_AUTH', ${lib.boolToString cfg.settings.email.smtpAuth});
28
+
define('MAIL_SMTP_DEBUG', ${lib.boolToString cfg.settings.email.smtpDebug});
29
+
define('DEFAULT_CSS', 'default.css');
30
+
define('RTL_CSS', 'rtl.css'); // For right to left languages.
31
+
define('LANG_DEFAULT', '${cfg.settings.defaultLanguage}');
32
+
define('CURRENCY_DEFAULT', '${cfg.settings.defaultCurrency}');
33
+
define('EXPORT_DECIMAL_DURATION', ${lib.boolToString cfg.settings.exportDecimalDuration});
34
+
define('REPORT_FOOTER', ${lib.boolToString cfg.settings.reportFooter});
35
+
define('AUTH_MODULE', 'db');
37
+
package = pkgs.stdenv.mkDerivation rec {
38
+
pname = "anuko-time-tracker";
39
+
inherit (src) version;
45
+
ln -s ${configFile} $out/WEB-INF/config.php
47
+
# Link writable templates_c directory
48
+
rm -rf $out/WEB-INF/templates_c
49
+
ln -s ${cfg.dataDir}/templates_c $out/WEB-INF/templates_c
51
+
# ln -fs ${cfg.dataDir}/templates_c $out/WEB-INF/templates_c
56
+
options.services.anuko-time-tracker = {
57
+
enable = lib.mkEnableOption (lib.mdDoc "Anuko Time Tracker");
59
+
package = lib.mkPackageOptionMD pkgs "anuko-time-tracker" {};
62
+
createLocally = lib.mkOption {
63
+
type = lib.types.bool;
65
+
description = lib.mdDoc "Create the database and database user locally.";
68
+
host = lib.mkOption {
69
+
type = lib.types.str;
70
+
description = lib.mdDoc "Database host.";
71
+
default = "localhost";
74
+
name = lib.mkOption {
75
+
type = lib.types.str;
76
+
description = lib.mdDoc "Database name.";
77
+
default = "anuko_time_tracker";
80
+
user = lib.mkOption {
81
+
type = lib.types.str;
82
+
description = lib.mdDoc "Database username.";
83
+
default = "anuko_time_tracker";
86
+
passwordFile = lib.mkOption {
87
+
type = lib.types.nullOr lib.types.str;
88
+
description = lib.mdDoc "Database user password file.";
93
+
poolConfig = lib.mkOption {
94
+
type = lib.types.attrsOf (lib.types.oneOf [ lib.types.str lib.types.int lib.types.bool ]);
97
+
"pm.max_children" = 32;
98
+
"pm.start_servers" = 2;
99
+
"pm.min_spare_servers" = 2;
100
+
"pm.max_spare_servers" = 4;
101
+
"pm.max_requests" = 500;
103
+
description = lib.mdDoc ''
104
+
Options for Anuko Time Tracker's PHP-FPM pool.
108
+
dataDir = lib.mkOption {
109
+
type = lib.types.str;
110
+
default = "/var/lib/anuko-time-tracker";
111
+
description = lib.mdDoc "Default data folder for Anuko Time Tracker.";
112
+
example = "/mnt/anuko-time-tracker";
115
+
user = lib.mkOption {
116
+
type = lib.types.str;
117
+
default = "anuko_time_tracker";
118
+
description = lib.mdDoc "User under which Anuko Time Tracker runs.";
121
+
virtualHost = lib.mkOption {
122
+
type = lib.types.nullOr lib.types.str;
123
+
default = "localhost";
124
+
description = lib.mdDoc ''
125
+
Name of the nginx virtualhost to use and setup. If null, do not setup
131
+
multiorgMode = lib.mkOption {
132
+
type = lib.types.bool;
134
+
description = lib.mdDoc ''
135
+
Defines whether users see the Register option in the menu of Time Tracker that allows them
136
+
to self-register and create new organizations (top groups).
140
+
emailRequired = lib.mkOption {
141
+
type = lib.types.bool;
143
+
description = lib.mdDoc "Defines whether an email is required for new registrations.";
146
+
weekendStartDay = lib.mkOption {
147
+
type = lib.types.int;
149
+
description = lib.mdDoc ''
150
+
This option defines which days are highlighted with weekend color.
151
+
6 means Saturday. For Saudi Arabia, etc. set it to 4 for Thursday and Friday to be
156
+
forumLink = lib.mkOption {
157
+
type = lib.types.str;
158
+
description = lib.mdDoc "Forum link from the main menu.";
159
+
default = "https://www.anuko.com/forum/viewforum.php?f=4";
162
+
helpLink = lib.mkOption {
163
+
type = lib.types.str;
164
+
description = lib.mdDoc "Help link from the main menu.";
165
+
default = "https://www.anuko.com/time-tracker/user-guide/index.htm";
169
+
sender = lib.mkOption {
170
+
type = lib.types.str;
171
+
description = lib.mdDoc "Default sender for mail.";
172
+
default = "Anuko Time Tracker <bounces@example.com>";
175
+
mode = lib.mkOption {
176
+
type = lib.types.str;
177
+
description = lib.mdDoc "Mail sending mode. Can be 'mail' or 'smtp'.";
181
+
smtpHost = lib.mkOption {
182
+
type = lib.types.str;
183
+
description = lib.mdDoc "MTA hostname.";
184
+
default = "localhost";
187
+
smtpPort = lib.mkOption {
188
+
type = lib.types.int;
189
+
description = lib.mdDoc "MTA port.";
193
+
smtpUser = lib.mkOption {
194
+
type = lib.types.str;
195
+
description = lib.mdDoc "MTA authentication username.";
199
+
smtpAuth = lib.mkOption {
200
+
type = lib.types.bool;
202
+
description = lib.mdDoc "MTA requires authentication.";
205
+
smtpPasswordFile = lib.mkOption {
206
+
type = lib.types.nullOr lib.types.path;
208
+
example = "/var/lib/anuko-time-tracker/secrets/smtp-password";
209
+
description = lib.mdDoc ''
210
+
Path to file containing the MTA authentication password.
214
+
smtpDebug = lib.mkOption {
215
+
type = lib.types.bool;
217
+
description = lib.mdDoc "Debug mail sending.";
221
+
defaultLanguage = lib.mkOption {
222
+
type = lib.types.str;
223
+
description = lib.mdDoc ''
224
+
Defines Anuko Time Tracker default language. It is used on Time Tracker login page.
225
+
After login, a language set for user group is used.
226
+
Empty string means the language is defined by user browser.
232
+
defaultCurrency = lib.mkOption {
233
+
type = lib.types.str;
234
+
description = lib.mdDoc ''
235
+
Defines a default currency symbol for new groups.
236
+
Use €, £, a more specific dollar like US$, CAD, etc.
242
+
exportDecimalDuration = lib.mkOption {
243
+
type = lib.types.bool;
245
+
description = lib.mdDoc ''
246
+
Defines whether time duration values are decimal in CSV and XML data
247
+
exports (1.25 vs 1:15).
251
+
reportFooter = lib.mkOption {
252
+
type = lib.types.bool;
254
+
description = lib.mdDoc "Defines whether to use a footer on reports.";
259
+
config = lib.mkIf cfg.enable {
263
+
assertion = cfg.database.createLocally -> cfg.database.passwordFile == null;
265
+
<option>services.anuko-time-tracker.database.passwordFile</option> cannot be specified if
266
+
<option>services.anuko-time-tracker.database.createLocally</option> is set to true.
270
+
assertion = cfg.settings.email.smtpAuth -> (cfg.settings.email.smtpPasswordFile != null);
272
+
<option>services.anuko-time-tracker.settings.email.smtpPasswordFile</option> needs to be set if
273
+
<option>services.anuko-time-tracker.settings.email.smtpAuth</option> is enabled.
278
+
services.phpfpm = {
279
+
pools.anuko-time-tracker = {
280
+
inherit (cfg) user;
281
+
group = config.services.nginx.group;
283
+
"listen.owner" = config.services.nginx.user;
284
+
"listen.group" = config.services.nginx.group;
285
+
} // cfg.poolConfig;
289
+
services.nginx = lib.mkIf (cfg.virtualHost != null) {
292
+
"${cfg.virtualHost}" = {
293
+
root = lib.mkForce "${package}";
294
+
locations."/".index = "index.php";
295
+
locations."~ [^/]\\.php(/|$)" = {
297
+
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
298
+
fastcgi_pass unix:${config.services.phpfpm.pools.anuko-time-tracker.socket};
305
+
services.mysql = lib.mkIf cfg.database.createLocally {
306
+
enable = lib.mkDefault true;
307
+
package = lib.mkDefault pkgs.mariadb;
308
+
ensureDatabases = [ cfg.database.name ];
310
+
name = cfg.database.user;
311
+
ensurePermissions = {
312
+
"${cfg.database.name}.*" = "ALL PRIVILEGES";
319
+
anuko-time-tracker-setup-database = lib.mkIf cfg.database.createLocally {
320
+
description = "Set up Anuko Time Tracker database";
323
+
RemainAfterExit = true;
325
+
wantedBy = [ "phpfpm-anuko-time-tracker.service" ];
326
+
after = [ "mysql.service" ];
329
+
mysql = "${config.services.mysql.package}/bin/mysql";
332
+
if [ ! -f ${cfg.dataDir}/.dbexists ]; then
333
+
# Load database schema provided with package
334
+
${mysql} ${cfg.database.name} < ${cfg.package}/mysql.sql
336
+
touch ${cfg.dataDir}/.dbexists
342
+
"d ${cfg.dataDir} 0750 ${cfg.user} ${config.services.nginx.group} -"
343
+
"d ${cfg.dataDir}/templates_c 0750 ${cfg.user} ${config.services.nginx.group} -"
347
+
users.users."${cfg.user}" = {
348
+
isSystemUser = true;
349
+
group = config.services.nginx.group;
353
+
meta.maintainers = with lib.maintainers; [ michaelshmitty ];