1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3package client_test
4
5import (
6 "testing"
7
8 "github.com/stretchr/testify/assert"
9 "github.com/stretchr/testify/require"
10
11 "bnema.dev/ermite/internal/adapters/client"
12)
13
14func env(kv map[string]string) func(string) string {
15 return func(k string) string { return kv[k] }
16}
17
18func TestConfigFromEnv(t *testing.T) {
19 cfg, err := client.ConfigFromEnv(env(map[string]string{
20 client.EnvURL: " HTTPS://Git.Example.com/base/ ", client.EnvToken: " ermite_abc\n",
21 }))
22 require.NoError(t, err)
23 assert.Equal(t, "https://Git.Example.com/base", cfg.URL)
24 assert.Equal(t, "ermite_abc", cfg.Token)
25}
26
27func TestConfigFromEnvRejects(t *testing.T) {
28 tests := []struct {
29 name, url, want string
30 }{
31 {"unset", "", "ERMITE_URL is not set"},
32 {"no scheme", "git.example.com", "not an http(s) URL"},
33 {"ftp", "ftp://git.example.com", "not an http(s) URL"},
34 {"no host", "https://", "has no host"},
35 {"credentials", "https://user:s3cret@git.example.com", "must not contain credentials"},
36 {"query", "https://git.example.com/?a=b", "query or a fragment"},
37 {"fragment", "https://git.example.com/#x", "query or a fragment"},
38 {"garbage", "http://[::1", "not a valid URL"},
39 }
40 for _, tt := range tests {
41 t.Run(tt.name, func(t *testing.T) {
42 _, err := client.ConfigFromEnv(env(map[string]string{client.EnvURL: tt.url}))
43 require.Error(t, err)
44 assert.Contains(t, err.Error(), tt.want)
45 assert.NotContains(t, err.Error(), "s3cret", "credentials must never be echoed")
46 })
47 }
48}
49
50func TestInsecureTokenWarning(t *testing.T) {
51 tests := []struct {
52 url, token string
53 warn bool
54 }{
55 {"http://git.example.com", "t", true},
56 {"http://10.0.0.5:7341", "t", true},
57 {"http://git.example.com", "", false}, // nothing secret to leak
58 {"https://git.example.com", "t", false},
59 {"http://localhost:7341", "t", false},
60 {"http://127.0.0.1:7341", "t", false},
61 {"http://[::1]:7341", "t", false},
62 {"http://dev.localhost", "t", false},
63 }
64 for _, tt := range tests {
65 w := client.Config{URL: tt.url, Token: tt.token}.InsecureTokenWarning()
66 assert.Equal(t, tt.warn, w != "", "%s token=%q: %q", tt.url, tt.token, w)
67 assert.NotContains(t, w, tt.token+"_", "never echo the token")
68 }
69}
70
71func TestParseURLErrorsDoNotEchoInput(t *testing.T) {
72 for _, raw := range []string{"user:s3cret@host", "s3cret.example.com", "http://", "https://h/?k=s3cret", "http://[s3cret"} {
73 _, err := client.ParseURL(raw)
74 require.Error(t, err, raw)
75 assert.NotContains(t, err.Error(), "s3cret", raw)
76 assert.NotContains(t, err.Error(), "user:", raw)
77 }
78}