{ config, globals, nodes, pkgs, lib, ... }: { age.secrets.resticpasswd = { generator.script = "alnum"; }; age.secrets.forgejoHetznerSsh = { generator.script = "ssh-ed25519"; }; services.restic.backups = { main = { user = "root"; timerConfig = { OnCalendar = "06:00"; Persistent = true; RandomizedDelaySec = "3h"; }; initialize = true; passwordFile = config.age.secrets.resticpasswd.path; hetznerStorageBox = { enable = true; inherit (globals.hetzner) mainUser; inherit (globals.hetzner.users.forgejo) subUid path; sshAgeSecret = "forgejoHetznerSsh"; }; paths = [ config.services.forgejo.stateDir ]; #pruneOpts = [ # "--keep-daily 10" # "--keep-weekly 7" # "--keep-monthly 12" # "--keep-yearly 75" #]; }; }; # Recommended by forgejo: https://forgejo.org/docs/latest/admin/recommendations/#git-over-ssh services.openssh.settings.AcceptEnv = "GIT_PROTOCOL"; users.groups.git = { }; users.users.git = { isSystemUser = true; useDefaultShell = true; group = "git"; home = config.services.forgejo.stateDir; }; wireguard.services = { client.via = "nucnix"; firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [ config.services.forgejo.settings.server.HTTP_PORT ]; }; networking.firewall.allowedTCPPorts = [ config.services.forgejo.settings.server.SSH_PORT ]; environment.persistence."/panzer".directories = [ { directory = config.services.forgejo.stateDir; user = "git"; group = "git"; mode = "0700"; } ]; age.secrets.mailnix-passwd = { generator.script = "alnum"; group = "git"; }; age.secrets.mailnix-passwd-hash = { generator.dependencies = [ config.age.secrets.mailnix-passwd ]; generator.script = "argon2id"; mode = "440"; intermediary = true; }; nodes.mailnix = { age.secrets.idmail-forgejo-passwd-hash = { inherit (config.age.secrets.mailnix-passwd-hash) rekeyFile; group = "stalwart-mail"; mode = "440"; }; services.idmail.provision.mailboxes."forge@${globals.domains.mail_public}" = { password_hash = "%{file:${nodes.mailnix.config.age.secrets.idmail-forgejo-passwd-hash.path}}%"; owner = "admin"; }; }; services.forgejo = { enable = true; # TODO db backups # dump.enable = true; user = "git"; group = "git"; lfs.enable = true; secrets.mailer.PASSWD = config.age.secrets.mailnix-passwd.path; settings = { DEFAULT.APP_NAME = "Patricks tolles git"; actions = { ENABLED = true; DEFAULT_ACTIONS_URL = "github"; }; database = { SQLITE_JOURNAL_MODE = "WAL"; LOG_SQL = false; # Leaks secrets }; indexer = { REPO_INDEXER_ENABLED = true; }; # federation.ENABLED = true; mailer = { ENABLED = true; SMTP_ADDR = "smtp.${globals.domains.mail_public}"; FROM = "forge@${globals.domains.mail_public}"; USER = "forge@${globals.domains.mail_public}"; SEND_AS_PLAIN_TEXT = true; }; oauth2_client = { ACCOUNT_LINKING = "login"; ENABLE_AUTO_REGISTRATION = false; REGISTER_EMAIL_CONFIRM = false; UPDATE_AVATAR = true; USERNAME = "nickname"; }; # packages.ENABLED = true; repository = { DEFAULT_PRIVATE = "private"; ENABLE_PUSH_CREATE_USER = true; ENABLE_PUSH_CREATE_ORG = true; }; server = { HTTP_ADDR = "0.0.0.0"; HTTP_PORT = 3000; DOMAIN = globals.services.forgejo.domain; ROOT_URL = "https://${globals.services.forgejo.domain}/"; LANDING_PAGE = "login"; SSH_PORT = 9922; }; service = { DISABLE_REGISTRATION = false; ALLOW_ONLY_EXTERNAL_REGISTRATION = true; SHOW_REGISTRATION_BUTTON = false; REGISTER_EMAIL_CONFIRM = false; ENABLE_NOTIFY_MAIL = true; DEFAULT_KEEP_EMAIL_PRIVATE = true; }; session.COOKIE_SECURE = true; ui.DEFAULT_THEME = "forgejo-dark"; "ui.meta" = { AUTHOR = "Patrick"; DESCRIPTION = "Tollstes Forgejo EU-West"; }; }; }; # XXX: PKCE is currently not supported by gitea/forgejo, # see https://github.com/go-gitea/gitea/issues/21376. systemd.services.forgejo = { serviceConfig.RestartSec = "60"; # Retry every minute preStart = let exe = lib.getExe config.services.forgejo.package; providerName = "kanidm"; clientId = "forgejo"; args = lib.escapeShellArgs [ "--name" providerName "--provider" "openidConnect" "--key" clientId "--auto-discover-url" "https://auth.${globals.domains.web}/oauth2/openid/${clientId}/.well-known/openid-configuration" "--scopes" "email" "--scopes" "profile" "--group-claim-name" "groups" "--admin-group" "admin" "--skip-local-2fa" ]; in lib.mkAfter '' provider_id=$(${exe} admin auth list | ${pkgs.gnugrep}/bin/grep -w '${providerName}' | cut -f1) SECRET="$(< ${config.age.secrets.openid-secret.path})" if [[ -z "$provider_id" ]]; then ${exe} admin auth add-oauth ${args} --secret "$SECRET" else ${exe} admin auth update-oauth --id "$provider_id" ${args} --secret "$SECRET" fi ''; }; age.secrets.openid-secret = { inherit (nodes.elisabeth-kanidm.config.age.secrets.oauth2-forgejo) rekeyFile; mode = "440"; inherit (config.services.forgejo) group; }; }