Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 43 additions & 17 deletions nixos/modules/services/web-apps/nextcloud.nix
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,7 @@ in
'';
};
adminuser = lib.mkOption {
type = lib.types.str;
type = lib.types.nullOr lib.types.str;
default = "root";
description = ''
Username for the admin account. The username is only set during the
Expand All @@ -653,7 +653,7 @@ in
'';
};
adminpassFile = lib.mkOption {
type = lib.types.str;
type = lib.types.nullOr lib.types.str;
description = ''
The full path to a file that contains the admin's password. The password is
set only in the initial setup of Nextcloud by the systemd service `nextcloud-setup.service`.
Expand Down Expand Up @@ -1125,6 +1125,26 @@ in
https://docs.nextcloud.com/server/latest/admin_manual/configuration_database/db_conversion.html
'';
}
{
assertion =
lib.versionAtLeast overridePackage.version "32.0.0"
|| (cfg.config.adminuser != null && cfg.config.adminpassFile != null);
message = ''
Disabling initial admin user creation is only available on Nextcloud >= 32.0.0.
'';
}
{
assertion = cfg.config.adminuser == null -> cfg.config.adminpassFile == null;
message = ''
If `services.nextcloud.config.adminuser` is null, `services.nextcloud.config.adminpassFile` must be null as well in order to disable initial admin user creation.
'';
}
{
assertion = cfg.config.adminpassFile == null -> cfg.config.adminuser == null;
message = ''
If `services.nextcloud.config.adminpassFile` is null, `services.nextcloud.config.adminuser` must be null as well in order to disable initial admin user creation.
'';
}
];
}

Expand Down Expand Up @@ -1168,10 +1188,14 @@ in
arg = "DBPASS";
value = if c.dbpassFile != null then ''"$(<"$CREDENTIALS_DIRECTORY/dbpass")"'' else ''""'';
};
adminpass = {
arg = "ADMINPASS";
value = ''"$(<"$CREDENTIALS_DIRECTORY/adminpass")"'';
};
adminpass =
if c.adminpassFile != null then
{
arg = "ADMINPASS";
value = ''"$(<"$CREDENTIALS_DIRECTORY/adminpass")"'';
}
else
null;
installFlags = lib.concatStringsSep " \\\n " (
lib.mapAttrsToList (k: v: "${k} ${toString v}") {
"--database" = ''"${c.dbtype}"'';
Expand All @@ -1182,15 +1206,16 @@ in
${if c.dbhost != null then "--database-host" else null} = ''"${c.dbhost}"'';
${if c.dbuser != null then "--database-user" else null} = ''"${c.dbuser}"'';
"--database-pass" = "\"\$${dbpass.arg}\"";
"--admin-user" = ''"${c.adminuser}"'';
"--admin-pass" = "\"\$${adminpass.arg}\"";
${if c.adminuser != null then "--admin-user" else null} = ''"${c.adminuser}"'';
${if adminpass != null then "--admin-pass" else null} = "\"\$${adminpass.arg}\"";
${if c.adminuser == null && adminpass == null then "--disable-admin-user" else null} = "";
"--data-dir" = ''"${datadir}/data"'';
}
);
in
''
${mkExport dbpass}
${mkExport adminpass}
${lib.optionalString (adminpass != null) (mkExport adminpass)}
${lib.getExe occ} maintenance:install \
${installFlags}
'';
Expand All @@ -1217,10 +1242,12 @@ in
exit 1
fi
''}
if [ -z "$(<"$CREDENTIALS_DIRECTORY/adminpass")" ]; then
echo "adminpassFile ${c.adminpassFile} is empty!"
exit 1
fi
${lib.optionalString (c.adminpassFile != null) ''
if [ -z "$(<"$CREDENTIALS_DIRECTORY/adminpass")" ]; then
echo "adminpassFile ${c.adminpassFile} is empty!"
exit 1
fi
''}

# Check if systemd-tmpfiles setup worked correctly
if [[ ! -O "${datadir}/config" ]]; then
Expand Down Expand Up @@ -1262,10 +1289,9 @@ in
'';
serviceConfig.Type = "oneshot";
serviceConfig.User = "nextcloud";
serviceConfig.LoadCredential = [
"adminpass:${cfg.config.adminpassFile}"
]
++ runtimeSystemdCredentials;
serviceConfig.LoadCredential =
lib.optional (cfg.config.adminpassFile != null) "adminpass:${cfg.config.adminpassFile}"
++ runtimeSystemdCredentials;
# On Nextcloud ≥ 26, it is not necessary to patch the database files to prevent
# an automatic creation of the database user.
environment.NC_setup_create_db_user = "false";
Expand Down
21 changes: 12 additions & 9 deletions nixos/tests/nextcloud/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ let
}
];

adminuser = "root";
adminpass = "hunter2";
adminuser = pkgs.lib.mkDefault "root";
adminpass = pkgs.lib.mkDefault "hunter2";

test-helpers.rclone = "${pkgs.writeShellScript "rclone" ''
set -euo pipefail
Expand Down Expand Up @@ -129,13 +129,16 @@ let
}
);
in
map callNextcloudTest [
./basic.nix
./with-declarative-redis-and-secrets.nix
./with-mysql-and-memcached.nix
./with-postgresql-and-redis.nix
./with-objectstore.nix
];
map callNextcloudTest (
[
./basic.nix
./with-declarative-redis-and-secrets.nix
./with-mysql-and-memcached.nix
./with-postgresql-and-redis.nix
./with-objectstore.nix
]
++ (pkgs.lib.optional (version >= 32) ./without-admin-user.nix)
);
in
listToAttrs (
concatMap genTests [
Expand Down
48 changes: 48 additions & 0 deletions nixos/tests/nextcloud/without-admin-user.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
name,
pkgs,
testBase,
system,
...
}:

with import ../../lib/testing-python.nix { inherit system pkgs; };
runTest (
{
config,
lib,
...
}:
rec {
inherit name;

meta.maintainers = lib.teams.nextcloud.members;

imports = [ testBase ];

nodes = {
nextcloud =
{ config, pkgs, ... }:
{
services.nextcloud = {
config = {
dbtype = "sqlite";
adminuser = null;
adminpassFile = lib.mkForce null;
};
};
};
};

adminuser = "root";
# This needs to be a "secure" password, since the password_policy app is enabled after installation and will forbid "simple" passwords.
adminpass = "+CVpTwaOEktxsFc6";

# Manually create the adminuser to make the default set of tests pass.
# If adminuser was already created during the installation this command would not succeed.
# This user name must always match the default value in services.nextcloud.config.adminuser!
test-helpers.init = ''
nextcloud.succeed("OC_PASS=${adminpass} nextcloud-occ user:add ${adminuser} --password-from-env")
'';
}
)
Loading