{ config, pkgs, lib, ... }: { age.secrets.kanidm-oauth2-gitea = lib.mkSecret "kanidm"; services.kanidm.provision = { groups."gitea.access" = {}; groups."gitea.admins" = {}; systems.oauth2.gitea = { displayName = "gitea"; originUrl = "https://tea.nothing.run/user/oauth2/kanidm/callback"; originLanding = "https://tea.nothing.run/"; basicSecretFile = config.age.secrets.kanidm-oauth2-gitea.path; scopeMaps."gitea.access" = [ "openid" "email" "profile" ]; allowInsecureClientDisablePkce = true; preferShortUsername = true; claimMaps.groups = { joinType = "array"; valuesByGroup."gitea.admins" = [ "admins" ]; }; }; }; containers.gitea = let host-config = config; in { autoStart = true; bindMounts = { "/var/lib/gitea" = { hostPath = "/nix/persist/services/gitea"; isReadOnly = false; }; # "${config.age.secretsDir}" = { hostPath = config.age.secretsDir; isReadOnly = true; }; "/run/agenix" = { hostPath = "/run/agenix"; isReadOnly = false; }; }; # tmpfs = [ "/" ]; hostAddress = "192.168.102.10"; localAddress = "192.168.102.11"; # forwardPorts = [ # { # containerPort = 22; # hostPort = 9922; # protocol = "tcp"; # } # ]; privateNetwork = true; config = { lib, config, ... }: { imports = [ ../../modules/global/dnscrypt-proxy.nix ]; users.groups.kanidm = {}; users.groups.git = { }; users.users.git = { isSystemUser = true; useDefaultShell = true; group = "git"; extraGroups = [ "kanidm" ]; home = config.services.gitea.stateDir; openssh.authorizedKeys.keys = lib.mkForce host-config.users.users.root.openssh.authorizedKeys.keys; }; services.openssh = { enable = true; # settings = { # PasswordAuthentication = false; # KbdInteractiveAuthentication = false; # PermitRootLogin = "prohibit-password"; # }; # openFirewall = true; # ports = [ 22 ]; # settings.AcceptEnv = "GIT_PROTOCOL"; }; services.gitea = { enable = true; package = pkgs.gitea; user = "git"; group = "git"; settings = { DEFAULT.APP_NAME = "Hollow Tea"; mailer.ENABLED = false; metrics.ENABLED = false; oauth2_client = { ACCOUNT_LINKING = "login"; USERNAME = "nickname"; ENABLE_AUTO_REGISTRATION = false; REGISTER_EMAIL_CONFIRM = false; UPDATE_AVATAR = 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 = "tea.nothing.run"; ROOT_URL = "https://tea.nothing.run"; LANDING_PAGE = "login"; SSH_PORT = 9922; SSH_USER = "git"; }; service = { DISABLE_REGISTRATION = false; ALLOW_ONLY_INTERNAL_REGISTRATION = false; ALLOW_ONLY_EXTERNAL_REGISTRATION = true; SHOW_REGISTRATION_BUTTON = false; REGISTER_EMAIL_CONFIRM = false; ENABLE_NOTIFY_MAIL = false; }; "service.explore" = { REQUIRE_SIGNIN_VIEW = true; DISABLE_USERS_PAGE = false; DISABLE_ORGANIZATIONS_PAGE = true; DISABLE_CODE_PAGE = true; }; admin.DISABLE_REGULAR_ORG_CREATION = true; # Prohibit creation of organizations by non-admin users session.COOKIE_SECURE = true; }; }; systemd.services.gitea = { enable = true; wantedBy = [ "multi-user.target" ]; serviceConfig.RestartSec = "60"; # Retry every minute preStart = let exe = lib.getExe config.services.gitea.package; providerName = "kanidm"; clientId = "gitea"; args = lib.escapeShellArgs ( lib.concatLists [ [ "--name" providerName ] [ "--provider" "openidConnect" ] [ "--key" clientId ] [ "--auto-discover-url" "https://idm.nothing.run/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="$(< ${host-config.age.secrets.kanidm-oauth2-gitea.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 ''; }; networking.firewall = { enable = true; allowedTCPPorts = [ 3000 22 ]; }; system.stateVersion = "25.05"; }; }; networking.firewall.allowedTCPPorts = [ 9922 ]; services.caddy.virtualHosts = { "tea.nothing.run".extraConfig = '' reverse_proxy http://192.168.102.11:3000 ''; }; }