fix: prepend scheme to access url (#3317)

- Problems can arise spawning workspaces if a schemeless URL is passed
  as the access URL.

  If an access url is detected to not have an "http" or "https" scheme
  then it is prepended with "https". If the hostname is detected
  to be a loopback device then "http" is preferred.
This commit is contained in:
Jon Ayers
2022-07-31 17:49:25 -05:00
committed by GitHub
parent f82df1bd78
commit 8b17bf98ea
2 changed files with 130 additions and 34 deletions

View File

@ -21,7 +21,6 @@ import (
"time"
"github.com/go-chi/chi"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/goleak"
@ -113,7 +112,10 @@ func TestServer(t *testing.T) {
pty.ExpectMatch("psql")
})
t.Run("NoWarningWithRemoteAccessURL", func(t *testing.T) {
// Validate that an http scheme is prepended to a loopback
// access URL and that a warning is printed that it may not be externally
// reachable.
t.Run("NoSchemeLocalAccessURL", func(t *testing.T) {
t.Parallel()
ctx, cancelFunc := context.WithCancel(context.Background())
defer cancelFunc()
@ -122,7 +124,7 @@ func TestServer(t *testing.T) {
"server",
"--in-memory",
"--address", ":0",
"--access-url", "http://1.2.3.4:3000/",
"--access-url", "localhost:3000/",
"--cache-dir", t.TempDir(),
)
buf := newThreadSafeBuffer()
@ -141,8 +143,74 @@ func TestServer(t *testing.T) {
cancelFunc()
require.ErrorIs(t, <-errC, context.Canceled)
require.Contains(t, buf.String(), "this may cause unexpected problems when creating workspaces")
require.Contains(t, buf.String(), "View the Web UI: http://localhost:3000/\n")
})
assert.NotContains(t, buf.String(), "Workspaces must be able to reach Coder from this URL")
// Validate that an https scheme is prepended to a remote access URL
// and that a warning is printed for a host that cannot be resolved.
t.Run("NoSchemeRemoteAccessURL", func(t *testing.T) {
t.Parallel()
ctx, cancelFunc := context.WithCancel(context.Background())
defer cancelFunc()
root, cfg := clitest.New(t,
"server",
"--in-memory",
"--address", ":0",
"--access-url", "foobarbaz.mydomain",
"--cache-dir", t.TempDir(),
)
buf := newThreadSafeBuffer()
root.SetOutput(buf)
errC := make(chan error, 1)
go func() {
errC <- root.ExecuteContext(ctx)
}()
// Just wait for startup
require.Eventually(t, func() bool {
var err error
_, err = cfg.URL().Read()
return err == nil
}, 15*time.Second, 25*time.Millisecond)
cancelFunc()
require.ErrorIs(t, <-errC, context.Canceled)
require.Contains(t, buf.String(), "this may cause unexpected problems when creating workspaces")
require.Contains(t, buf.String(), "View the Web UI: https://foobarbaz.mydomain\n")
})
t.Run("NoWarningWithRemoteAccessURL", func(t *testing.T) {
t.Parallel()
ctx, cancelFunc := context.WithCancel(context.Background())
defer cancelFunc()
root, cfg := clitest.New(t,
"server",
"--in-memory",
"--address", ":0",
"--access-url", "https://google.com",
"--cache-dir", t.TempDir(),
)
buf := newThreadSafeBuffer()
root.SetOutput(buf)
errC := make(chan error, 1)
go func() {
errC <- root.ExecuteContext(ctx)
}()
// Just wait for startup
require.Eventually(t, func() bool {
var err error
_, err = cfg.URL().Read()
return err == nil
}, 15*time.Second, 25*time.Millisecond)
cancelFunc()
require.ErrorIs(t, <-errC, context.Canceled)
require.NotContains(t, buf.String(), "this may cause unexpected problems when creating workspaces")
require.Contains(t, buf.String(), "View the Web UI: https://google.com\n")
})
t.Run("TLSBadVersion", func(t *testing.T) {