Skip to content

Commit 59a70b4

Browse files
committed
Address HTTP scheme review feedback
1 parent 355e498 commit 59a70b4

6 files changed

Lines changed: 64 additions & 8 deletions

File tree

internal/cli/auth.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ func authLoginCmd() *cobra.Command {
7070
}
7171
}
7272

73+
scheme = strings.ToLower(scheme)
7374
if scheme != "" && scheme != "http" && scheme != "https" {
7475
return fmt.Errorf("invalid --scheme %q: must be http or https", scheme)
7576
}

internal/cli/auth_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,33 @@ func TestAuthLoginNonInteractive(t *testing.T) {
113113
}
114114
}
115115

116+
func TestAuthLoginNormalizesScheme(t *testing.T) {
117+
resetCmd(rootCmd)
118+
dir := t.TempDir()
119+
t.Setenv("XDG_CONFIG_HOME", dir)
120+
config.ResetCache()
121+
defer config.ResetCache()
122+
123+
rootCmd.SetArgs([]string{
124+
"auth", "login",
125+
"--domain", "forgejo.example.com",
126+
"--token", "test_token_123",
127+
"--scheme", "HTTP",
128+
})
129+
130+
if err := rootCmd.Execute(); err != nil {
131+
t.Fatalf("auth login: %v", err)
132+
}
133+
134+
data, err := os.ReadFile(filepath.Join(dir, "forge", "config"))
135+
if err != nil {
136+
t.Fatalf("reading config: %v", err)
137+
}
138+
if !strings.Contains(string(data), "scheme = http") {
139+
t.Errorf("expected normalized scheme, got:\n%s", data)
140+
}
141+
}
142+
116143
func TestAuthLoginTokenCmd(t *testing.T) {
117144
resetCmd(rootCmd)
118145
dir := t.TempDir()

internal/config/config.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,14 @@ func findProjectConfig(dir string) string {
339339
// Creates the config directory if needed. Sets file permissions to 0600
340340
// since the file may contain tokens.
341341
func SetDomain(domain, token, tokenCmd, forgeType, scheme string) error {
342+
if scheme != "" {
343+
normalizedScheme, err := parseScheme(scheme)
344+
if err != nil {
345+
return err
346+
}
347+
scheme = normalizedScheme
348+
}
349+
342350
path := UserConfigPath()
343351
if path == "" {
344352
return fmt.Errorf("cannot determine config path")

internal/config/config_test.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ func TestSetDomainScheme(t *testing.T) {
498498
dir := t.TempDir()
499499
t.Setenv("XDG_CONFIG_HOME", dir)
500500

501-
if err := SetDomain("forgejo.local:3000", "tok", "", "forgejo", "http"); err != nil {
501+
if err := SetDomain("forgejo.local:3000", "tok", "", "forgejo", "HTTP"); err != nil {
502502
t.Fatalf("SetDomain: %v", err)
503503
}
504504

@@ -518,6 +518,22 @@ func TestSetDomainScheme(t *testing.T) {
518518
}
519519
}
520520

521+
func TestSetDomainRejectsInvalidScheme(t *testing.T) {
522+
dir := t.TempDir()
523+
t.Setenv("XDG_CONFIG_HOME", dir)
524+
525+
err := SetDomain("forgejo.local", "tok", "", "forgejo", "ftp")
526+
if err == nil {
527+
t.Fatal("expected invalid scheme error")
528+
}
529+
if !strings.Contains(err.Error(), "invalid scheme") {
530+
t.Errorf("expected scheme error, got %v", err)
531+
}
532+
if _, statErr := os.Stat(filepath.Join(dir, "forge", "config")); !os.IsNotExist(statErr) {
533+
t.Errorf("config should not be written for an invalid scheme, stat error: %v", statErr)
534+
}
535+
}
536+
521537
func TestLoadFileInvalidScheme(t *testing.T) {
522538
dir := t.TempDir()
523539
path := filepath.Join(dir, "config")

internal/resolve/resolve.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,17 @@ func SetHost(host string) {
6464
// splitScheme splits a leading http:// or https:// off s and returns
6565
// (scheme, host). If s has no scheme, scheme is "".
6666
func splitScheme(s string) (scheme, host string) {
67-
if h, ok := strings.CutPrefix(s, "http://"); ok {
68-
return "http", strings.TrimRight(h, "/")
69-
}
70-
if h, ok := strings.CutPrefix(s, "https://"); ok {
71-
return "https", strings.TrimRight(h, "/")
67+
s = strings.TrimRight(s, "/")
68+
u, err := url.Parse(s)
69+
if err == nil && u.Host != "" {
70+
switch strings.ToLower(u.Scheme) {
71+
case "http":
72+
return "http", u.Host
73+
case "https":
74+
return "https", u.Host
75+
}
7276
}
73-
return "", strings.TrimRight(s, "/")
77+
return "", s
7478
}
7579

7680
// SetForgeType forces the API client implementation for the resolved domain,

internal/resolve/resolve_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ func TestSetHostWithScheme(t *testing.T) {
403403
oldH, oldS := hostOverride, schemeOverride
404404
defer func() { hostOverride, schemeOverride = oldH, oldS }()
405405

406-
SetHost("http://172.30.0.10:3000")
406+
SetHost("HTTP://172.30.0.10:3000/forge/")
407407
if hostOverride != "172.30.0.10:3000" {
408408
t.Errorf("SetHost with URL should store bare host, got %q", hostOverride)
409409
}

0 commit comments

Comments
 (0)