diff --git a/CHANGELOG.md b/CHANGELOG.md index 933ce9e..12afe1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,22 +4,6 @@ Changes yet to be released are documented here. -## v0.3.0 - -- Stop setting `nix.settings.netrc-file` from the Home Manager module -- Document `netrc_path` in `config.toml` as the path operators should wire into their daemon configuration -- Add a module evaluation check to prevent the Home Manager module from reintroducing `nix.settings.netrc-file` - -These changes are made to support both cppnix and detsysnix. The latter has [special requirements][additionalnetrcsources] around the `netrc` files. - -[additionalnetrcsources]: https://docs.determinate.systems/determinate-nix/#additionalnetrcsources - -## v0.2.1 - -- Fix netrc parsing for one-line entries such as `machine ... login ... password ...` -- Always write netrc entries as one line with a non-empty login (`dummy`) -- Add regression tests for one-line netrc parsing and write format - ## v0.2.0 - Improve config discovery for server workflows: diff --git a/README.md b/README.md index 1cde215..e25a567 100644 --- a/README.md +++ b/README.md @@ -58,14 +58,6 @@ netrc_path = "$XDG_CONFIG_HOME/nix/netrc" Path values support environment variable expansion (`$VAR` and `${VAR}`). -`netrc_path` is the path this tool writes tokens to. - -Configure Nix to read that same path. - -This supports both cppnix and detsysnix. The latter has [special -requirements][additionalnetrcsources] around `netrc` files, so set -`additionalNetrcSources` to include the configured `netrc_path`. - ## Usage ```bash @@ -86,15 +78,6 @@ Config path resolution order: The NixOS server module exports `NIX_CACHE_LOGIN_CONFIG` and installs `/etc/nix-cache-login/config.toml` from `services.nix-cache-login-server.configFile`. -## Module Integration - -The Home Manager and NixOS modules in this repo install the package and refresh -services. - -Nix and detsysnix daemon configuration stays outside these modules. - -Set your daemon to read the `netrc_path` configured in `config.toml`. - ## Maintenance This tool is actively maintained by [Guardian Project](https://guardianproject.info). @@ -109,7 +92,6 @@ For security-related issues, please contact us through our [security policy][sec [issues]: https://guardianproject.dev/ops/nix-cache-login/issues [sec]: https://guardianproject.info/contact/ -[additionalnetrcsources]: https://docs.determinate.systems/determinate-nix/#additionalnetrcsources ## License diff --git a/flake.lock b/flake.lock index 523cd23..d37a53a 100644 --- a/flake.lock +++ b/flake.lock @@ -2,12 +2,12 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1775423009, - "narHash": "sha256-vPKLpjhIVWdDrfiUM8atW6YkIggCEKdSAlJPzzhkQlw=", - "rev": "68d8aa3d661f0e6bd5862291b5bb263b2a6595c9", - "revCount": 975402, + "lastModified": 1771848320, + "narHash": "sha256-0MAd+0mun3K/Ns8JATeHT1sX28faLII5hVLq0L3BdZU=", + "rev": "2fc6539b481e1d2569f25f8799236694180c0993", + "revCount": 953160, "type": "tarball", - "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.975402%2Brev-68d8aa3d661f0e6bd5862291b5bb263b2a6595c9/019d657b-b3b7-7288-b3c0-42d420df206b/source.tar.gz" + "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.953160%2Brev-2fc6539b481e1d2569f25f8799236694180c0993/019c8e05-d2f6-7c7e-9ead-612154b18bfb/source.tar.gz" }, "original": { "type": "tarball", diff --git a/flake.nix b/flake.nix index fa1bf83..48fe69d 100644 --- a/flake.nix +++ b/flake.nix @@ -36,7 +36,6 @@ ''; doCheck = true; }); - module-checks = import ./module-checks.nix { inherit self pkgs; }; devShell = self.devShells.${pkgs.stdenv.hostPlatform.system}.default; } // pkgs.lib.optionalAttrs pkgs.stdenv.isLinux { diff --git a/home-module.nix b/home-module.nix index 90e80ab..572366e 100644 --- a/home-module.nix +++ b/home-module.nix @@ -26,6 +26,7 @@ in }; config = lib.mkIf cfg.enable { + nix.settings.netrc-file = "${config.xdg.configHome}/nix/netrc"; home.packages = [ cfg.package ]; systemd.user.services.nix-cache-login = { Unit.Description = "Nix cache login - refresh access token"; diff --git a/internal/netrc/netrc.go b/internal/netrc/netrc.go index 60eb1f5..6eaae73 100644 --- a/internal/netrc/netrc.go +++ b/internal/netrc/netrc.go @@ -93,34 +93,23 @@ func parse(path string) ([]entry, error) { } fields := strings.Fields(line) - for i := 0; i < len(fields); { - switch fields[i] { - case "machine": - if i+1 >= len(fields) { - i++ - continue - } - if current != nil { - entries = append(entries, *current) - } - current = &entry{machine: fields[i+1]} - i += 2 - case "login": - if current != nil && i+1 < len(fields) { - current.login = fields[i+1] - i += 2 - continue - } - i++ - case "password": - if current != nil && i+1 < len(fields) { - current.password = fields[i+1] - i += 2 - continue - } - i++ - default: - i++ + if len(fields) < 2 { + continue + } + + switch fields[0] { + case "machine": + if current != nil { + entries = append(entries, *current) + } + current = &entry{machine: fields[1]} + case "login": + if current != nil { + current.login = fields[1] + } + case "password": + if current != nil { + current.password = fields[1] } } } @@ -141,12 +130,11 @@ func write(path string, entries []entry) error { } var b strings.Builder - for _, e := range entries { - login := e.login - if login == "" { - login = "dummy" + for i, e := range entries { + if i > 0 { + b.WriteString("\n") } - fmt.Fprintf(&b, "machine %s login %s password %s\n", e.machine, login, e.password) + fmt.Fprintf(&b, "machine %s\nlogin %s\npassword %s\n", e.machine, e.login, e.password) } if err := os.WriteFile(path, []byte(b.String()), 0600); err != nil { diff --git a/internal/netrc/netrc_test.go b/internal/netrc/netrc_test.go index ab8ded5..e8a0b51 100644 --- a/internal/netrc/netrc_test.go +++ b/internal/netrc/netrc_test.go @@ -3,7 +3,6 @@ package netrc import ( "os" "path/filepath" - "strings" "testing" ) @@ -56,28 +55,6 @@ func TestUpsertUpdateExisting(t *testing.T) { } } -func TestUpsertUpdateExistingOneLineEntry(t *testing.T) { - dir := t.TempDir() - path := filepath.Join(dir, "netrc") - - initial := "machine other.host login dummy password otherpass\nmachine cache.example.com login dummy password oldtoken\n" - if err := os.WriteFile(path, []byte(initial), 0600); err != nil { - t.Fatal(err) - } - - if err := Upsert(path, "cache.example.com", "newtoken"); err != nil { - t.Fatalf("unexpected error: %v", err) - } - - pw, err := GetPassword(path, "cache.example.com") - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if pw != "newtoken" { - t.Errorf("password = %q, want %q", pw, "newtoken") - } -} - func TestUpsertAppend(t *testing.T) { dir := t.TempDir() path := filepath.Join(dir, "netrc") @@ -220,29 +197,3 @@ func TestFilePermissionsCorrected(t *testing.T) { t.Errorf("file permissions = %o, want 0600", perm) } } - -func TestWriteUsesOneLineFormatAndDummyLoginFallback(t *testing.T) { - dir := t.TempDir() - path := filepath.Join(dir, "netrc") - - // Existing one-line entry with missing login should be normalized. - if err := os.WriteFile(path, []byte("machine cache.example.com password oldtoken\n"), 0600); err != nil { - t.Fatal(err) - } - - if err := Upsert(path, "cache.example.com", "newtoken"); err != nil { - t.Fatalf("unexpected error: %v", err) - } - - content, err := os.ReadFile(path) - if err != nil { - t.Fatalf("read error: %v", err) - } - text := string(content) - if !strings.Contains(text, "machine cache.example.com login dummy password newtoken\n") { - t.Fatalf("unexpected netrc content: %q", text) - } - if strings.Contains(text, "\nlogin ") || strings.Contains(text, "\npassword ") { - t.Fatalf("netrc entry should be written on one line: %q", text) - } -} diff --git a/module-checks.nix b/module-checks.nix deleted file mode 100644 index 1fc13d9..0000000 --- a/module-checks.nix +++ /dev/null @@ -1,65 +0,0 @@ -{ self, pkgs }: -let - lib = pkgs.lib; - fakePackage = pkgs.runCommand "nix-cache-login-fake-package" { } '' - mkdir -p "$out/bin" - touch "$out/bin/nix-cache-login" - chmod +x "$out/bin/nix-cache-login" - ''; - - hmStubModule = - { lib, ... }: - { - options = { - home.packages = lib.mkOption { - type = lib.types.listOf lib.types.package; - default = [ ]; - }; - home.homeDirectory = lib.mkOption { - type = lib.types.str; - default = "/home/tester"; - }; - xdg.configHome = lib.mkOption { - type = lib.types.str; - default = "/home/tester/.config"; - }; - nix.settings = lib.mkOption { - type = lib.types.attrsOf lib.types.anything; - default = { }; - }; - systemd.user.services = lib.mkOption { - type = lib.types.attrsOf lib.types.anything; - default = { }; - }; - systemd.user.timers = lib.mkOption { - type = lib.types.attrsOf lib.types.anything; - default = { }; - }; - launchd.agents = lib.mkOption { - type = lib.types.attrsOf lib.types.anything; - default = { }; - }; - }; - }; - - evalHome = - extraConfig: - lib.evalModules { - modules = [ - hmStubModule - ./home-module.nix - { - services.nix-cache-login.enable = true; - services.nix-cache-login.package = fakePackage; - } - extraConfig - ]; - }; - - homeDefault = evalHome { }; -in -pkgs.runCommand "nix-cache-login-module-checks" { } '' - test ${lib.escapeShellArg (builtins.toJSON (builtins.hasAttr "netrc-file" homeDefault.config.nix.settings))} = ${lib.escapeShellArg "false"} - test ${lib.escapeShellArg homeDefault.config.systemd.user.services.nix-cache-login.Service.ExecStart} = ${lib.escapeShellArg "${fakePackage}/bin/nix-cache-login refresh"} - touch "$out" -'' diff --git a/package.nix b/package.nix index 8b13d54..08c08bd 100644 --- a/package.nix +++ b/package.nix @@ -6,7 +6,7 @@ buildGoModule { pname = "nix-cache-login"; - version = "0.3.0"; + version = "0.2.0"; src = ./.; # src = fetchgit { # url = "https://guardianproject.dev/ops/nix-cache-login.git";