diff --git a/hosts/homex/configuration.nix b/hosts/homex/configuration.nix index 27e5d21..68ce0a1 100644 --- a/hosts/homex/configuration.nix +++ b/hosts/homex/configuration.nix @@ -20,6 +20,10 @@ forgejo = { enable = true; + settings.users."test-declarative" = { + email = "testdeclarative@example.com"; + password = "teste"; + }; }; }; diff --git a/modules/nixos/homelab/forgejo.nix b/modules/nixos/homelab/forgejo.nix index ece1492..8b46467 100644 --- a/modules/nixos/homelab/forgejo.nix +++ b/modules/nixos/homelab/forgejo.nix @@ -2,6 +2,14 @@ let cfg = config.homelab.forgejo; + users = (builtins.attrValues (builtins.mapAttrs + (username: info: { + name = username; + email = info.email; + password = info.password; + admin = info.admin; + }) + cfg.settings.users)); in { imports = [ ]; @@ -25,7 +33,28 @@ in default = config.homelab.storage + /forgejo; }; }; + handleUndeclaredUsers = mkOption { + type = bool; + default = true; + }; settings = { + users = mkOption { + type = attrsOf (submodule ({ config, lib, ... }: { + options = { + password = mkOption { + type = either str path; + }; + email = mkOption { + type = either str path; + }; + admin = mkOption { + type = bool; + default = false; + }; + }; + })); + default = { }; + }; name = mkOption { type = str; default = "Forgejo: Beyond coding. We forge"; @@ -174,8 +203,99 @@ in }; }; }; + systemd.services."homelab-forgejo-setup" = with builtins; { + script = '' + gum="${pkgs.gum}/bin/gum" + forgejo="${cfg.package}/bin/gitea --work-path ${cfg.data.root}" + user="$forgejo admin user" + awk="${pkgs.gawk}/bin/awk" + + declaredUsers=(${toString (map (user: "${user.name}") users)}); + + $gum log --structured --time timeonly --level info "HANDLING UNDECLARED USERS" + + $user list | $awk '{print $2}' | tail -n +2 | while read username; do + if printf '%s\0' "''${declaredUsers[@]}" | grep -Fxqz -- "$username"; then + $gum log --structured \ + --time timeonly \ + --level warn "Declared user already exists, ignoring" \ + username $username \ + / + else + if [[ "$($user list | grep "$username" | $awk '{print $4}')" == "true" ]]; then + $gum log --structured \ + --time timeonly \ + --level warn "Undeclared user is a ADMIN, ignoring" \ + username $username \ + / + else + ${if cfg.handleUndeclaredUsers then '' + $gum log --structured \ + --time timeonly \ + --level warn "DELETING undeclared user" \ + username $username \ + / + + $user delete -u "$username"; + '' else '' + $gum log --structured \ + --time timeonly \ + --level warn "UNDECLARED user, please declare it in the config so it's reproducible" \ + username "$username" \ + / + ''} + fi + fi + done + + ${toString (map (user: '' + username="${if isPath user.name then "\"$(cat ${toString user.name})\"" else user.name}"; + email="${if isPath user.email then "\"$(cat ${toString user.email})\"" else user.email}"; + password="${if isPath user.password then "\"$(cat ${toString user.password})\"" else user.password}"; + + if [[ "$($user list | grep "$username" | $awk '{print $2}')" ]]; then + $gum log --structured \ + --time timeonly \ + --level warn "User with username already exists" \ + username $username \ + / + elif [[ "$($user list | grep "$email" | $awk '{print $3}')" ]]; then + $gum log --structured \ + --time timeonly \ + --level warn "User with email already exists" \ + email $email \ + / + else + $gum log --structured \ + --time timeonly \ + --level info ${if user.admin then "Creating ADMIN user" else "Creating user"} \ + username $username \ + email $email \ + password $password \ + / + $user create --username $username \ + --email $email \ + --password $password \ + ${if user.admin then "--admin \\" else ""} + / + fi + '') users)} + ''; + wantedBy = [ "multi-user.target" ]; + after = [ "forgejo.service" ]; + serviceConfig = { + Type = "oneshot"; + User = cfg.user; + Group = cfg.user; + }; + }; }; } + + + + +