fix(auth): harden unified diagnostic execution
This commit is contained in:
@@ -98,7 +98,7 @@ func RunWithProbe(ctx context.Context, installation config.Installation, runner
|
||||
if probe == nil {
|
||||
return Report{}, errors.New("doctor requires an HTTP probe")
|
||||
}
|
||||
secretValues := secretValues(installation)
|
||||
secretValues, secretErr := secretValues(installation)
|
||||
report := Report{Checks: make([]Check, 0, 12)}
|
||||
add := func(name, status, detail string) {
|
||||
report.Checks = append(report.Checks, Check{Name: name, Status: status, Detail: output.SanitizeDetail(detail, secretValues)})
|
||||
@@ -109,11 +109,28 @@ func RunWithProbe(ctx context.Context, installation config.Installation, runner
|
||||
} else {
|
||||
add("descriptor", StatusPassed, "installation descriptor is loaded")
|
||||
}
|
||||
if err := filePermissions(installation); err != nil {
|
||||
add("files", StatusFailed, err.Error())
|
||||
if err := filePermissions(installation); err != nil || secretErr != nil {
|
||||
if secretErr != nil {
|
||||
add("files", StatusFailed, "declared secret files could not be read")
|
||||
} else {
|
||||
add("files", StatusFailed, err.Error())
|
||||
}
|
||||
} else {
|
||||
add("files", StatusPassed, "declared host files have safe permissions")
|
||||
}
|
||||
if secretErr != nil {
|
||||
add("docker", StatusSkipped, "declared secret files are unavailable")
|
||||
add("compose", StatusSkipped, "declared secret files are unavailable")
|
||||
add("configuration", StatusSkipped, "declared secret files are unavailable")
|
||||
add("authentication", StatusSkipped, "declared secret files are unavailable")
|
||||
add("services", StatusSkipped, "declared secret files are unavailable")
|
||||
add("core-http", StatusSkipped, "declared secret files are unavailable")
|
||||
add("frontend-http", StatusSkipped, "declared secret files are unavailable")
|
||||
add("workspace-registry", StatusSkipped, "declared secret files are unavailable")
|
||||
add("workflow", StatusSkipped, "declared secret files are unavailable")
|
||||
add("pi", StatusSkipped, "declared secret files are unavailable")
|
||||
return finalize(report), nil
|
||||
}
|
||||
|
||||
if !commandCheck(ctx, runner, []string{"version", "--format", "{{.Client.Version}}"}, secretValues, add, "docker", "Docker Engine") {
|
||||
add("compose", StatusSkipped, "Docker Engine is unavailable")
|
||||
@@ -307,16 +324,16 @@ func validateInstallation(installation config.Installation) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func secretValues(installation config.Installation) []string {
|
||||
func secretValues(installation config.Installation) ([]string, error) {
|
||||
files, err := installation.SecretFiles()
|
||||
if err != nil {
|
||||
return nil
|
||||
return nil, errors.New("declared secret files could not be read")
|
||||
}
|
||||
values, err := output.SecretValuesFromFiles(files)
|
||||
if err != nil {
|
||||
return nil
|
||||
return nil, errors.New("declared secret files could not be read")
|
||||
}
|
||||
return values
|
||||
return values, nil
|
||||
}
|
||||
|
||||
func filePermissions(installation config.Installation) error {
|
||||
|
||||
@@ -181,6 +181,28 @@ func TestRunRedactsWorkflowDiagnosticFailures(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunFailsBeforeDockerWhenDeclaredSecretCorpusIsIncomplete(t *testing.T) {
|
||||
installation := doctorInstallation(t, "")
|
||||
missing := filepath.Join(filepath.Dir(installation.EnvFile), "missing-pi-auth.json")
|
||||
if err := os.WriteFile(installation.EnvFile, []byte("PI_AUTH_FILE="+missing+"\n"), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
runner := &doctorRunner{services: healthyServices}
|
||||
|
||||
report, err := Run(context.Background(), installation, runner)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if report.OK || checkStatus(report, "files") != StatusFailed || len(runner.calls) != 0 {
|
||||
t.Fatalf("incomplete corpus was not refused before Docker: report=%#v calls=%v", report, runner.calls)
|
||||
}
|
||||
if strings.Contains(reportText(report), missing) {
|
||||
t.Fatalf("incomplete corpus report exposed a secret path: %#v", report)
|
||||
}
|
||||
assertChecklist(t, report, []string{"descriptor", "files", "docker", "compose", "configuration", "authentication", "services", "core-http", "frontend-http", "workspace-registry", "workflow", "pi"})
|
||||
}
|
||||
|
||||
func doctorInstallation(t *testing.T, _ string) config.Installation {
|
||||
t.Helper()
|
||||
base, err := filepath.EvalSymlinks(os.TempDir())
|
||||
|
||||
Reference in New Issue
Block a user