diff --git a/services/fediversity/default.nix b/services/fediversity/default.nix index d935499a..4f793c03 100644 --- a/services/fediversity/default.nix +++ b/services/fediversity/default.nix @@ -34,6 +34,30 @@ in description = "number of cores; should be obtained from NixOps4"; type = types.int; }; + + ## NOTE: In practice, we will want to plug our services to a central + ## authentication service, eg. LDAP. In the meantime, for the demo + ## effect (and for testing, tbh), we need a way to inject an initial + ## user into our services. + initialUser = { + username = mkOption { + type = types.str; + description = "Username of the initial user"; + }; + displayName = mkOption { + type = types.str; + description = "Name of the initial user, for humans"; + default = config.fediversity.temp.initialUser.name; + }; + email = mkOption { + type = types.str; + description = "Email of the initial user"; + }; + passwordFile = mkOption { + type = types.path; + description = "Path to a file containing the initial user's password"; + }; + }; }; }; }; diff --git a/services/fediversity/pixelfed/default.nix b/services/fediversity/pixelfed/default.nix index 7df53527..d6328e3b 100644 --- a/services/fediversity/pixelfed/default.nix +++ b/services/fediversity/pixelfed/default.nix @@ -6,7 +6,12 @@ }: let - inherit (lib) mkIf mkMerge readFile; + inherit (lib) + mkIf + mkMerge + readFile + escapeShellArg + ; in { @@ -108,6 +113,60 @@ in 80 443 ]; + + systemd.services.inject-initial-pixelfed-user = { + ## Make this service start after pixelfed has started successfully + after = [ "phpfpm-pixelfed.service" ]; + requires = [ "phpfpm-pixelfed.service" ]; + + serviceConfig = { + Type = "simple"; + Restart = "on-failure"; + RestartSec = "10s"; + ExecStart = pkgs.writeShellScript "inject-initial-pixelfed-user.sh" '' + #!/bin/sh + set -euC + + ## NOTE: The packaging for Pixelfed provides a 'pixelfed-manage' + ## command that is added to the environment but isn't easily + ## grabable otherwise, so we go the ugly route and extract it from + ## the Horizon service that runs 'pixelfed-manage horizon'. + + pixelfed-manage () { + local f=${escapeShellArg config.systemd.services.pixelfed-horizon.serviceConfig.ExecStart} + "''${f% horizon}" "$@" + } + + ## NOTE: The 'user:table' command prints headers: + ## + ## +----+----------+------+------------+ + ## | ID | Username | Name | Registered | + ## +----+----------+------+------------+ + ## + ## so we check whether that is all we got to know if there are any + ## users yet. + + users_table=$(pixelfed-manage user:table) + if [ "$(echo "$users_table" | wc -l)" -ne 3 ]; then + printf 'There are already users; nothing to do:\n\n%s' "$users_table" + exit 0 + fi + + ## No user so far; let's go! + + pixelfed-manage user:create \ + --name=${escapeShellArg config.fediversity.temp.initialUser.displayName} \ + --username=${escapeShellArg config.fediversity.temp.initialUser.username} \ + --email=${escapeShellArg config.fediversity.temp.initialUser.email} \ + --password="$(cat ${escapeShellArg config.fediversity.temp.initialUser.passwordFile})" \ + --confirm_email=1 + ''; + }; + + # Set the service to automatically start + wantedBy = [ "multi-user.target" ]; + }; + }) ]; }