← back to Cli Printing Press
fix(cli): generate usable oauth auth config (#617)
5b489da7bc09991d53251be1e847a348b408b016 · 2026-05-05 11:43:05 -0500 · Cathryn Lavery
Files touched
M internal/generator/auth_env_precedence_test.goM internal/generator/templates/auth.go.tmplM internal/generator/templates/config.go.tmpl
Diff
commit 5b489da7bc09991d53251be1e847a348b408b016
Author: Cathryn Lavery <50469282+cathrynlavery@users.noreply.github.com>
Date: Tue May 5 11:43:05 2026 -0500
fix(cli): generate usable oauth auth config (#617)
---
internal/generator/auth_env_precedence_test.go | 56 ++++++++++++++++++++++++++
internal/generator/templates/auth.go.tmpl | 4 +-
internal/generator/templates/config.go.tmpl | 2 +-
3 files changed, 59 insertions(+), 3 deletions(-)
diff --git a/internal/generator/auth_env_precedence_test.go b/internal/generator/auth_env_precedence_test.go
index 18650b0d..381fba78 100644
--- a/internal/generator/auth_env_precedence_test.go
+++ b/internal/generator/auth_env_precedence_test.go
@@ -48,6 +48,62 @@ func TestAuthHeader_ClientCredentialsAccessTokenWinsOverEnv(t *testing.T) {
"AccessToken check must appear BEFORE env-var fallback under OAuth2 client_credentials")
}
+func TestAuthHeader_OAuth2AuthorizationCodeUsesToken(t *testing.T) {
+ t.Parallel()
+
+ apiSpec := minimalSpec("oauth-precedence")
+ apiSpec.Auth = spec.AuthConfig{
+ Type: "oauth2",
+ Header: "Authorization",
+ Format: "Bearer {token}",
+ EnvVars: []string{"OAUTH_AUTH_TEST_TOKEN"},
+ AuthorizationURL: "https://example.com/auth",
+ TokenURL: "https://example.com/token",
+ }
+
+ outputDir := filepath.Join(t.TempDir(), "oauth-precedence-pp-cli")
+ require.NoError(t, New(apiSpec, outputDir).Generate())
+
+ cfgSrc, err := os.ReadFile(filepath.Join(outputDir, "internal", "config", "config.go"))
+ require.NoError(t, err)
+ content := string(cfgSrc)
+
+ envCheck := "if c." + resolveEnvVarField("OAUTH_AUTH_TEST_TOKEN") + ` != ""`
+ tokenCheck := `if c.AccessToken != ""`
+
+ require.Contains(t, content, envCheck)
+ require.Contains(t, content, tokenCheck)
+
+ body := authHeaderBody(t, content)
+ envIdx := strings.Index(body, envCheck)
+ tokenIdx := strings.Index(body, tokenCheck)
+ assert.Less(t, envIdx, tokenIdx,
+ "env-var bearer fallback should win over file token for OAuth2 authorization_code")
+}
+
+func TestAuthLoginEnvVarsUseShellSafePrefix(t *testing.T) {
+ t.Parallel()
+
+ apiSpec := minimalSpec("hyphen-api")
+ apiSpec.Auth = spec.AuthConfig{
+ Type: "oauth2",
+ Header: "Authorization",
+ AuthorizationURL: "https://example.com/auth",
+ TokenURL: "https://example.com/token",
+ }
+
+ outputDir := filepath.Join(t.TempDir(), "hyphen-api-pp-cli")
+ require.NoError(t, New(apiSpec, outputDir).Generate())
+
+ authSrc, err := os.ReadFile(filepath.Join(outputDir, "internal", "cli", "auth.go"))
+ require.NoError(t, err)
+ content := string(authSrc)
+
+ require.Contains(t, content, `os.Getenv("HYPHEN_API_CLIENT_ID")`)
+ require.Contains(t, content, `os.Getenv("HYPHEN_API_CLIENT_SECRET")`)
+ require.NotContains(t, content, `HYPHEN-API_CLIENT_ID`)
+}
+
// TestAuthHeader_EnvVarWinsOverFileToken pins env-first precedence for
// the non-client_credentials cases — plain bearer_token (PAT-style),
// cookie, and composed all follow the env > config convention so a
diff --git a/internal/generator/templates/auth.go.tmpl b/internal/generator/templates/auth.go.tmpl
index bf4ec25b..aee7d8ed 100644
--- a/internal/generator/templates/auth.go.tmpl
+++ b/internal/generator/templates/auth.go.tmpl
@@ -182,8 +182,8 @@ func newAuthLoginCmd(flags *rootFlags) *cobra.Command {
},
}
- cmd.Flags().StringVar(&clientID, "client-id", os.Getenv("{{upper .Name}}_CLIENT_ID"), "OAuth2 client ID")
- cmd.Flags().StringVar(&clientSecret, "client-secret", os.Getenv("{{upper .Name}}_CLIENT_SECRET"), "OAuth2 client secret")
+ cmd.Flags().StringVar(&clientID, "client-id", os.Getenv("{{envName .Name}}_CLIENT_ID"), "OAuth2 client ID")
+ cmd.Flags().StringVar(&clientSecret, "client-secret", os.Getenv("{{envName .Name}}_CLIENT_SECRET"), "OAuth2 client secret")
cmd.Flags().IntVar(&port, "port", 8085, "Local callback server port")
return cmd
diff --git a/internal/generator/templates/config.go.tmpl b/internal/generator/templates/config.go.tmpl
index dd55f37d..d1a0d50e 100644
--- a/internal/generator/templates/config.go.tmpl
+++ b/internal/generator/templates/config.go.tmpl
@@ -154,7 +154,7 @@ func (c *Config) AuthHeader() string {
{{- else}}
return ""
{{- end}}
-{{- else if eq .Auth.Type "bearer_token"}}
+{{- else if or (eq .Auth.Type "bearer_token") (eq .Auth.Type "oauth2")}}
{{- if eq .Auth.EffectiveOAuth2Grant "client_credentials"}}
// Under OAuth2 client_credentials the env var is the Client ID, not a
// usable bearer; the minted AccessToken must win.
← c5e7a801 chore(main): release 3.9.1 (#607)
·
back to Cli Printing Press
·
docs(cli): codify lookup-priority discipline in layout contr e08c268b →