Skip to content

Commit 439d3bc

Browse files
committed
Add overriding VS Code configuration
1 parent 7237d9b commit 439d3bc

File tree

5 files changed

+144
-0
lines changed

5 files changed

+144
-0
lines changed

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"cSpell.words": [
3+
"afero",
34
"apps",
45
"ASKPASS",
56
"awsidentity",

coderd/gitauth/vscode.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package gitauth
2+
3+
import (
4+
"encoding/json"
5+
"errors"
6+
"os"
7+
"path/filepath"
8+
9+
"github.com/adrg/xdg"
10+
"github.com/spf13/afero"
11+
"golang.org/x/xerrors"
12+
)
13+
14+
// OverrideVSCodeConfigs overwrites a few properties to consume
15+
// GIT_ASKPASS from the host instead of VS Code-specific authentication.
16+
func OverrideVSCodeConfigs(fs afero.Fs) error {
17+
home, err := os.UserHomeDir()
18+
if err != nil {
19+
return err
20+
}
21+
mutate := func(m map[string]interface{}) {
22+
// This prevents VS Code from overriding GIT_ASKPASS, which
23+
// we use to automatically authenticate Git providers.
24+
m["git.useIntegratedAskPass"] = false
25+
// This prevents VS Code from using it's own GitHub authentication
26+
// which would circumvent cloning with Coder-configured providers.
27+
m["github.gitAuthentication"] = false
28+
}
29+
30+
for _, configPath := range []string{
31+
// code-server's default configuration path.
32+
filepath.Join(xdg.DataHome, "code-server", "Machine", "settings.json"),
33+
// vscode-remote's default configuration path.
34+
filepath.Join(home, ".vscode-server", "data", "Machine", "settings.json"),
35+
} {
36+
_, err := fs.Stat(configPath)
37+
if err != nil {
38+
if !errors.Is(err, os.ErrNotExist) {
39+
return xerrors.Errorf("stat %q: %w", configPath, err)
40+
}
41+
42+
m := map[string]interface{}{}
43+
mutate(m)
44+
data, err := json.MarshalIndent(m, "", "\t")
45+
if err != nil {
46+
return xerrors.Errorf("marshal: %w", err)
47+
}
48+
49+
err = afero.WriteFile(fs, configPath, data, 0600)
50+
if err != nil {
51+
return xerrors.Errorf("write %q: %w", configPath, err)
52+
}
53+
continue
54+
}
55+
56+
data, err := afero.ReadFile(fs, configPath)
57+
if err != nil {
58+
return xerrors.Errorf("read %q: %w", configPath, err)
59+
}
60+
mapping := map[string]interface{}{}
61+
err = json.Unmarshal(data, &mapping)
62+
if err != nil {
63+
return xerrors.Errorf("unmarshal %q: %w", configPath, err)
64+
}
65+
mutate(mapping)
66+
data, err = json.MarshalIndent(mapping, "", "\t")
67+
if err != nil {
68+
return xerrors.Errorf("marshal %q: %w", configPath, err)
69+
}
70+
err = afero.WriteFile(fs, configPath, data, 0600)
71+
if err != nil {
72+
return xerrors.Errorf("write %q: %w", configPath, err)
73+
}
74+
}
75+
return nil
76+
}

coderd/gitauth/vscode_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package gitauth_test
2+
3+
import (
4+
"encoding/json"
5+
"os"
6+
"path/filepath"
7+
"testing"
8+
9+
"github.com/adrg/xdg"
10+
"github.com/spf13/afero"
11+
"github.com/stretchr/testify/require"
12+
13+
"github.com/coder/coder/coderd/gitauth"
14+
)
15+
16+
func TestOverrideVSCodeConfigs(t *testing.T) {
17+
t.Parallel()
18+
home, err := os.UserHomeDir()
19+
require.NoError(t, err)
20+
configPaths := []string{
21+
filepath.Join(xdg.DataHome, "code-server", "Machine", "settings.json"),
22+
filepath.Join(home, ".vscode-server", "data", "Machine", "settings.json"),
23+
}
24+
t.Run("Create", func(t *testing.T) {
25+
t.Parallel()
26+
fs := afero.NewMemMapFs()
27+
err := gitauth.OverrideVSCodeConfigs(fs)
28+
require.NoError(t, err)
29+
for _, configPath := range configPaths {
30+
data, err := afero.ReadFile(fs, configPath)
31+
require.NoError(t, err)
32+
mapping := map[string]interface{}{}
33+
err = json.Unmarshal(data, &mapping)
34+
require.NoError(t, err)
35+
require.Equal(t, false, mapping["git.useIntegratedAskPass"])
36+
require.Equal(t, false, mapping["github.gitAuthentication"])
37+
}
38+
})
39+
t.Run("Append", func(t *testing.T) {
40+
t.Parallel()
41+
fs := afero.NewMemMapFs()
42+
mapping := map[string]interface{}{
43+
"hotdogs": "something",
44+
}
45+
data, err := json.Marshal(mapping)
46+
require.NoError(t, err)
47+
for _, configPath := range configPaths {
48+
err = afero.WriteFile(fs, configPath, data, 0600)
49+
require.NoError(t, err)
50+
}
51+
err = gitauth.OverrideVSCodeConfigs(fs)
52+
require.NoError(t, err)
53+
for _, configPath := range configPaths {
54+
data, err := afero.ReadFile(fs, configPath)
55+
require.NoError(t, err)
56+
mapping := map[string]interface{}{}
57+
err = json.Unmarshal(data, &mapping)
58+
require.NoError(t, err)
59+
require.Equal(t, false, mapping["git.useIntegratedAskPass"])
60+
require.Equal(t, false, mapping["github.gitAuthentication"])
61+
require.Equal(t, "something", mapping["hotdogs"])
62+
}
63+
})
64+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ require (
170170
)
171171

172172
require (
173+
github.com/adrg/xdg v0.4.0 // indirect
173174
github.com/fsnotify/fsnotify v1.5.4 // indirect
174175
github.com/magiconair/properties v1.8.6 // indirect
175176
github.com/pelletier/go-toml v1.9.5 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdko
159159
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
160160
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
161161
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
162+
github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls=
163+
github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E=
162164
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
163165
github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
164166
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=

0 commit comments

Comments
 (0)