1{ config, lib, pkgs, serverInfo, php, ... }:
2
3with lib;
4
5let
6
7 httpd = serverInfo.serverConfig.package;
8
9 version24 = !versionOlder httpd.version "2.4";
10
11 allGranted = if version24 then ''
12 Require all granted
13 '' else ''
14 Order allow,deny
15 Allow from all
16 '';
17
18 owncloudConfig = pkgs.writeText "config.php"
19 ''
20 <?php
21
22 /* Only enable this for local development and not in productive environments */
23 /* This will disable the minifier and outputs some additional debug informations */
24 define("DEBUG", false);
25
26 $CONFIG = array(
27 /* Flag to indicate ownCloud is successfully installed (true = installed) */
28 "installed" => true,
29
30 /* Type of database, can be sqlite, mysql or pgsql */
31 "dbtype" => "${config.dbType}",
32
33 /* Name of the ownCloud database */
34 "dbname" => "${config.dbName}",
35
36 /* User to access the ownCloud database */
37 "dbuser" => "${config.dbUser}",
38
39 /* Password to access the ownCloud database */
40 "dbpassword" => "${config.dbPassword}",
41
42 /* Host running the ownCloud database. To specify a port use "HOSTNAME:####"; to specify a unix sockets use "localhost:/path/to/socket". */
43 "dbhost" => "${config.dbServer}",
44
45 /* Prefix for the ownCloud tables in the database */
46 "dbtableprefix" => "",
47
48 /* Force use of HTTPS connection (true = use HTTPS) */
49 "forcessl" => ${config.forceSSL},
50
51 /* Blacklist a specific file and disallow the upload of files with this name - WARNING: USE THIS ONLY IF YOU KNOW WHAT YOU ARE DOING. */
52 "blacklisted_files" => array('.htaccess'),
53
54 /* The automatic hostname detection of ownCloud can fail in certain reverse proxy and CLI/cron situations. This option allows to manually override the automatic detection. You can also add a port. For example "www.example.com:88" */
55 "overwritehost" => "${config.overwriteHost}",
56
57 /* The automatic protocol detection of ownCloud can fail in certain reverse proxy and CLI/cron situations. This option allows to manually override the protocol detection. For example "https" */
58 "overwriteprotocol" => "${config.overwriteProtocol}",
59
60 /* The automatic webroot detection of ownCloud can fail in certain reverse proxy and CLI/cron situations. This option allows to manually override the automatic detection. For example "/domain.tld/ownCloud". The value "/" can be used to remove the root. */
61 "overwritewebroot" => "${config.overwriteWebRoot}",
62
63 /* The automatic detection of ownCloud can fail in certain reverse proxy and CLI/cron situations. This option allows to define a manually override condition as regular expression for the remote ip address. For example "^10\.0\.0\.[1-3]$" */
64 "overwritecondaddr" => "",
65
66 /* A proxy to use to connect to the internet. For example "myproxy.org:88" */
67 "proxy" => "",
68
69 /* The optional authentication for the proxy to use to connect to the internet. The format is: [username]:[password] */
70 "proxyuserpwd" => "",
71
72 /* List of trusted domains, to prevent host header poisoning ownCloud is only using these Host headers */
73 ${if config.trustedDomain != "" then "'trusted_domains' => array('${config.trustedDomain}')," else ""}
74
75 /* Theme to use for ownCloud */
76 "theme" => "",
77
78 /* Optional ownCloud default language - overrides automatic language detection on public pages like login or shared items. This has no effect on the user's language preference configured under "personal -> language" once they have logged in */
79 "default_language" => "${config.defaultLang}",
80
81 /* Path to the parent directory of the 3rdparty directory */
82 "3rdpartyroot" => "",
83
84 /* URL to the parent directory of the 3rdparty directory, as seen by the browser */
85 "3rdpartyurl" => "",
86
87 /* Default app to open on login.
88 * This can be a comma-separated list of app ids.
89 * If the first app is not enabled for the current user,
90 * it will try with the second one and so on. If no enabled app could be found,
91 * the "files" app will be displayed instead. */
92 "defaultapp" => "${config.defaultApp}",
93
94 /* Enable the help menu item in the settings */
95 "knowledgebaseenabled" => true,
96
97 /* Enable installing apps from the appstore */
98 "appstoreenabled" => ${config.appStoreEnable},
99
100 /* URL of the appstore to use, server should understand OCS */
101 "appstoreurl" => "https://api.owncloud.com/v1",
102
103 /* Domain name used by ownCloud for the sender mail address, e.g. no-reply@example.com */
104 "mail_domain" => "${config.mailFromDomain}",
105
106 /* FROM address used by ownCloud for the sender mail address, e.g. owncloud@example.com
107 This setting overwrites the built in 'sharing-noreply' and 'lostpassword-noreply'
108 FROM addresses, that ownCloud uses
109 */
110 "mail_from_address" => "${config.mailFrom}",
111
112 /* Enable SMTP class debugging */
113 "mail_smtpdebug" => false,
114
115 /* Mode to use for sending mail, can be sendmail, smtp, qmail or php, see PHPMailer docs */
116 "mail_smtpmode" => "${config.SMTPMode}",
117
118 /* Host to use for sending mail, depends on mail_smtpmode if this is used */
119 "mail_smtphost" => "${config.SMTPHost}",
120
121 /* Port to use for sending mail, depends on mail_smtpmode if this is used */
122 "mail_smtpport" => ${config.SMTPPort},
123
124 /* SMTP server timeout in seconds for sending mail, depends on mail_smtpmode if this is used */
125 "mail_smtptimeout" => ${config.SMTPTimeout},
126
127 /* SMTP connection prefix or sending mail, depends on mail_smtpmode if this is used.
128 Can be "", ssl or tls */
129 "mail_smtpsecure" => "${config.SMTPSecure}",
130
131 /* authentication needed to send mail, depends on mail_smtpmode if this is used
132 * (false = disable authentication)
133 */
134 "mail_smtpauth" => ${config.SMTPAuth},
135
136 /* authentication type needed to send mail, depends on mail_smtpmode if this is used
137 * Can be LOGIN (default), PLAIN or NTLM */
138 "mail_smtpauthtype" => "${config.SMTPAuthType}",
139
140 /* Username to use for sendmail mail, depends on mail_smtpauth if this is used */
141 "mail_smtpname" => "${config.SMTPUser}",
142
143 /* Password to use for sendmail mail, depends on mail_smtpauth if this is used */
144 "mail_smtppassword" => "${config.SMTPPass}",
145
146 /* memcached servers (Only used when xCache, APC and APCu are absent.) */
147 "memcached_servers" => array(
148 // hostname, port and optional weight. Also see:
149 // http://www.php.net/manual/en/memcached.addservers.php
150 // http://www.php.net/manual/en/memcached.addserver.php
151 //array('localhost', 11211),
152 //array('other.host.local', 11211),
153 ),
154
155 /* How long should ownCloud keep deleted files in the trash bin, default value: 30 days */
156 'trashbin_retention_obligation' => 30,
157
158 /* Disable/Enable auto expire for the trash bin, by default auto expire is enabled */
159 'trashbin_auto_expire' => true,
160
161 /* allow user to change his display name, if it is supported by the back-end */
162 'allow_user_to_change_display_name' => true,
163
164 /* Check 3rdparty apps for malicious code fragments */
165 "appcodechecker" => true,
166
167 /* Check if ownCloud is up to date */
168 "updatechecker" => true,
169
170 /* Are we connected to the internet or are we running in a closed network? */
171 "has_internet_connection" => true,
172
173 /* Check if the ownCloud WebDAV server is working correctly. Can be disabled if not needed in special situations*/
174 "check_for_working_webdav" => true,
175
176 /* Check if .htaccess protection of data is working correctly. Can be disabled if not needed in special situations*/
177 "check_for_working_htaccess" => true,
178
179 /* Place to log to, can be owncloud and syslog (owncloud is log menu item in admin menu) */
180 "log_type" => "owncloud",
181
182 /* File for the owncloud logger to log to, (default is ownloud.log in the data dir) */
183 "logfile" => "${config.dataDir}/owncloud.log",
184
185 /* Loglevel to start logging at. 0=DEBUG, 1=INFO, 2=WARN, 3=ERROR (default is WARN) */
186 "loglevel" => "2",
187
188 /* date format to be used while writing to the owncloud logfile */
189 'logdateformat' => 'F d, Y H:i:s',
190
191 ${tzSetting}
192
193 /* Append all database queries and parameters to the log file.
194 (watch out, this option can increase the size of your log file)*/
195 "log_query" => false,
196
197 /* Whether ownCloud should log the last successfull cron exec */
198 "cron_log" => true,
199
200 /*
201 * Configure the size in bytes log rotation should happen, 0 or false disables the rotation.
202 * This rotates the current owncloud logfile to a new name, this way the total log usage
203 * will stay limited and older entries are available for a while longer. The
204 * total disk usage is twice the configured size.
205 * WARNING: When you use this, the log entries will eventually be lost.
206 */
207 'log_rotate_size' => "104857600", // 104857600, // 100 MiB
208
209 /* Lifetime of the remember login cookie, default is 15 days */
210 "remember_login_cookie_lifetime" => 1296000,
211
212 /* Life time of a session after inactivity */
213 "session_lifetime" => 86400,
214
215 /*
216 * Enable/disable session keep alive when a user is logged in in the Web UI.
217 * This is achieved by sending a "heartbeat" to the server to prevent
218 * the session timing out.
219 */
220 "session_keepalive" => true,
221
222 /* Custom CSP policy, changing this will overwrite the standard policy */
223 "custom_csp_policy" => "default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src *; img-src *; font-src 'self' data:; media-src *",
224
225 /* Enable/disable X-Frame-Restriction */
226 /* HIGH SECURITY RISK IF DISABLED*/
227 "xframe_restriction" => true,
228
229 /* The directory where the user data is stored, default to data in the owncloud
230 * directory. The sqlite database is also stored here, when sqlite is used.
231 */
232 "datadirectory" => "${config.dataDir}/storage",
233
234 /* The directory where the skeleton files are located. These files will be copied to the data
235 * directory of new users. Leave empty to not copy any skeleton files.
236 */
237 // "skeletondirectory" => "",
238
239 /* Enable maintenance mode to disable ownCloud
240 If you want to prevent users to login to ownCloud before you start doing some maintenance work,
241 you need to set the value of the maintenance parameter to true.
242 Please keep in mind that users who are already logged-in are kicked out of ownCloud instantly.
243 */
244 "maintenance" => false,
245
246 "apps_paths" => array(
247
248 /* Set an array of path for your apps directories
249 key 'path' is for the fs path and the key 'url' is for the http path to your
250 applications paths. 'writable' indicates whether the user can install apps in this folder.
251 You must have at least 1 app folder writable or you must set the parameter 'appstoreenabled' to false
252 */
253 array(
254 'path'=> '${config.dataDir}/apps',
255 'url' => '/apps',
256 'writable' => true,
257 ),
258 ),
259 'user_backends'=>array(
260 /*
261 array(
262 'class'=>'OC_User_IMAP',
263 'arguments'=>array('{imap.gmail.com:993/imap/ssl}INBOX')
264 )
265 */
266 ),
267 //links to custom clients
268 'customclient_desktop' => ''', //http://owncloud.org/sync-clients/
269 'customclient_android' => ''', //https://play.google.com/store/apps/details?id=com.owncloud.android
270 'customclient_ios' => ''', //https://itunes.apple.com/us/app/owncloud/id543672169?mt=8
271
272 // PREVIEW
273 'enable_previews' => true,
274 /* the max width of a generated preview, if value is null, there is no limit */
275 'preview_max_x' => null,
276 /* the max height of a generated preview, if value is null, there is no limit */
277 'preview_max_y' => null,
278 /* the max factor to scale a preview, default is set to 10 */
279 'preview_max_scale_factor' => 10,
280 /* custom path for libreoffice / openoffice binary */
281 'preview_libreoffice_path' => '${config.libreofficePath}',
282 /* cl parameters for libreoffice / openoffice */
283 'preview_office_cl_parameters' => ''',
284
285 /* whether avatars should be enabled */
286 'enable_avatars' => true,
287
288 // Extra SSL options to be used for configuration
289 'openssl' => array(
290 'config' => '/etc/ssl/openssl.cnf',
291 ),
292
293 // default cipher used for file encryption, currently we support AES-128-CFB and AES-256-CFB
294 'cipher' => 'AES-256-CFB',
295
296 /* whether usage of the instance should be restricted to admin users only */
297 'singleuser' => false,
298
299 /* all css and js files will be served by the web server statically in one js file and ons css file*/
300 'asset-pipeline.enabled' => false,
301
302 /* where mount.json file should be stored, defaults to data/mount.json */
303 'mount_file' => ''',
304
305 /*
306 * Location of the cache folder, defaults to "data/$user/cache" where "$user" is the current user.
307 *
308 * When specified, the format will change to "$cache_path/$user" where "$cache_path" is the configured
309 * cache directory and "$user" is the user.
310 *
311 */
312 'cache_path' => ''',
313
314 /* EXPERIMENTAL: option whether to include external storage in quota calculation, defaults to false */
315 'quota_include_external_storage' => false,
316
317 /*
318 * specifies how often the filesystem is checked for changes made outside owncloud
319 * 0 -> never check the filesystem for outside changes, provides a performance increase when it's certain that no changes are made directly to the filesystem
320 * 1 -> check each file or folder at most once per request, recomended for general use if outside changes might happen
321 * 2 -> check every time the filesystem is used, causes a performance hit when using external storages, not recomended for regular use
322 */
323 'filesystem_check_changes' => 1,
324
325 /* If true, prevent owncloud from changing the cache due to changes in the filesystem for all storage */
326 'filesystem_cache_readonly' => false,
327
328 /**
329 * define default folder for shared files and folders
330 */
331 'share_folder' => '/',
332
333 'version' => '${config.package.version}',
334
335 'openssl' => '${pkgs.openssl.bin}/bin/openssl'
336
337 );
338
339 '';
340
341 tzSetting = let tz = serverInfo.fullConfig.time.timeZone; in optionalString (!isNull tz) ''
342 /* timezone used while writing to the owncloud logfile (default: UTC) */
343 'logtimezone' => '${tz}',
344 '';
345
346 postgresql = serverInfo.fullConfig.services.postgresql.package;
347
348 setupDb = pkgs.writeScript "setup-owncloud-db" ''
349 #!${pkgs.stdenv.shell}
350 PATH="${postgresql}/bin"
351 createuser --no-superuser --no-createdb --no-createrole "${config.dbUser}" || true
352 createdb "${config.dbName}" -O "${config.dbUser}" || true
353 psql -U postgres -d postgres -c "alter user ${config.dbUser} with password '${config.dbPassword}';" || true
354
355 QUERY="CREATE TABLE appconfig
356 ( appid VARCHAR( 255 ) NOT NULL
357 , configkey VARCHAR( 255 ) NOT NULL
358 , configvalue VARCHAR( 255 ) NOT NULL
359 );
360 GRANT ALL ON appconfig TO ${config.dbUser};
361 ALTER TABLE appconfig OWNER TO ${config.dbUser};"
362
363 psql -h "/tmp" -U postgres -d ${config.dbName} -Atw -c "$QUERY" || true
364 '';
365
366in
367
368rec {
369
370 extraConfig =
371 ''
372 ${if config.urlPrefix != "" then "Alias ${config.urlPrefix} ${config.package}" else ''
373
374 RewriteEngine On
375 RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
376 RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
377 ''}
378
379 <Directory ${config.package}>
380 Include ${config.package}/.htaccess
381 </Directory>
382 '';
383
384 globalEnvVars = [
385 { name = "OC_CONFIG_PATH"; value = "${config.dataDir}/config/"; }
386 ];
387
388 documentRoot = if config.urlPrefix == "" then config.package else null;
389
390 enablePHP = true;
391
392 options = {
393
394 package = mkOption {
395 type = types.package;
396 default = pkgs.owncloud70;
397 defaultText = "pkgs.owncloud70";
398 example = literalExample "pkgs.owncloud70";
399 description = ''
400 ownCloud package to use.
401 '';
402 };
403
404 urlPrefix = mkOption {
405 default = "";
406 example = "/owncloud";
407 description = ''
408 The URL prefix under which the owncloud service appears.
409 '';
410 };
411
412 id = mkOption {
413 default = "main";
414 description = ''
415 A unique identifier necessary to keep multiple owncloud server
416 instances on the same machine apart. This is used to
417 disambiguate the administrative scripts, which get names like
418 mediawiki-$id-change-password.
419 '';
420 };
421
422 adminUser = mkOption {
423 default = "owncloud";
424 description = "The admin user name for accessing owncloud.";
425 };
426
427 adminPassword = mkOption {
428 description = "The admin password for accessing owncloud.";
429 };
430
431 dbType = mkOption {
432 default = "pgsql";
433 description = "Type of database, in NixOS, for now, only pgsql.";
434 };
435
436 dbName = mkOption {
437 default = "owncloud";
438 description = "Name of the database that holds the owncloud data.";
439 };
440
441 dbServer = mkOption {
442 default = "localhost:5432";
443 description = ''
444 The location of the database server.
445 '';
446 };
447
448 dbUser = mkOption {
449 default = "owncloud";
450 description = "The user name for accessing the database.";
451 };
452
453 dbPassword = mkOption {
454 example = "foobar";
455 description = ''
456 The password of the database user. Warning: this is stored in
457 cleartext in the Nix store!
458 '';
459 };
460
461 forceSSL = mkOption {
462 default = "false";
463 description = "Force use of HTTPS connection.";
464 };
465
466 adminAddr = mkOption {
467 default = serverInfo.serverConfig.adminAddr;
468 example = "admin@example.com";
469 description = ''
470 Emergency contact e-mail address. Defaults to the Apache
471 admin address.
472 '';
473 };
474
475 siteName = mkOption {
476 default = "owncloud";
477 example = "Foobar owncloud";
478 description = "Name of the owncloud";
479 };
480
481 trustedDomain = mkOption {
482 default = "";
483 description = "Trusted domain";
484 };
485
486 defaultLang = mkOption {
487 default = "";
488 description = "Default language";
489 };
490
491 defaultApp = mkOption {
492 default = "";
493 description = "Default application";
494 };
495
496 appStoreEnable = mkOption {
497 default = "true";
498 description = "Enable app store";
499 };
500
501 mailFrom = mkOption {
502 default = "no-reply";
503 description = "Mail from";
504 };
505
506 mailFromDomain = mkOption {
507 default = "example.xyz";
508 description = "Mail from domain";
509 };
510
511 SMTPMode = mkOption {
512 default = "smtp";
513 description = "Which mode to use for sending mail: sendmail, smtp, qmail or php.";
514 };
515
516 SMTPHost = mkOption {
517 default = "";
518 description = "SMTP host";
519 };
520
521 SMTPPort = mkOption {
522 default = "25";
523 description = "SMTP port";
524 };
525
526 SMTPTimeout = mkOption {
527 default = "10";
528 description = "SMTP mode";
529 };
530
531 SMTPSecure = mkOption {
532 default = "ssl";
533 description = "SMTP secure";
534 };
535
536 SMTPAuth = mkOption {
537 default = "true";
538 description = "SMTP auth";
539 };
540
541 SMTPAuthType = mkOption {
542 default = "LOGIN";
543 description = "SMTP auth type";
544 };
545
546 SMTPUser = mkOption {
547 default = "";
548 description = "SMTP user";
549 };
550
551 SMTPPass = mkOption {
552 default = "";
553 description = "SMTP pass";
554 };
555
556 dataDir = mkOption {
557 default = "/var/lib/owncloud";
558 description = "Data dir";
559 };
560
561 libreofficePath = mkOption {
562 default = "/usr/bin/libreoffice";
563 description = "Path for LibreOffice/OpenOffice binary.";
564 };
565
566 overwriteHost = mkOption {
567 default = "";
568 description = "The automatic hostname detection of ownCloud can fail in
569 certain reverse proxy and CLI/cron situations. This option allows to
570 manually override the automatic detection. You can also add a port.";
571 };
572
573 overwriteProtocol = mkOption {
574 default = "";
575 description = "The automatic protocol detection of ownCloud can fail in
576 certain reverse proxy and CLI/cron situations. This option allows to
577 manually override the protocol detection.";
578 };
579
580 overwriteWebRoot = mkOption {
581 default = "";
582 description = "The automatic webroot detection of ownCloud can fail in
583 certain reverse proxy and CLI/cron situations. This option allows to
584 manually override the automatic detection.";
585 };
586
587 };
588
589 startupScript = pkgs.writeScript "owncloud_startup.sh" ''
590
591 if [ ! -d ${config.dataDir}/config ]; then
592 mkdir -p ${config.dataDir}/config
593 cp ${owncloudConfig} ${config.dataDir}/config/config.php
594 mkdir -p ${config.dataDir}/storage
595 mkdir -p ${config.dataDir}/apps
596 cp -r ${config.package}/apps/* ${config.dataDir}/apps/
597 chmod -R ug+rw ${config.dataDir}
598 chmod -R o-rwx ${config.dataDir}
599 chown -R wwwrun:wwwrun ${config.dataDir}
600
601 ${pkgs.sudo}/bin/sudo -u postgres ${setupDb}
602 fi
603
604 if [ -e ${config.package}/config/ca-bundle.crt ]; then
605 cp -f ${config.package}/config/ca-bundle.crt ${config.dataDir}/config/
606 fi
607
608 ${php}/bin/php ${config.package}/occ upgrade >> ${config.dataDir}/upgrade.log || true
609
610 chown wwwrun:wwwrun ${config.dataDir}/owncloud.log || true
611
612 QUERY="INSERT INTO groups (gid) values('admin');
613 INSERT INTO users (uid,password)
614 values('${config.adminUser}','${builtins.hashString "sha1" config.adminPassword}');
615 INSERT INTO group_user (gid,uid)
616 values('admin','${config.adminUser}');"
617 ${pkgs.sudo}/bin/sudo -u postgres ${postgresql}/bin/psql -h "/tmp" -U postgres -d ${config.dbName} -Atw -c "$QUERY" || true
618 '';
619}