Skip to content

Commit 388a58b

Browse files
committed
feat(password): apply backend logic to all password set fields
1 parent 309d839 commit 388a58b

File tree

179 files changed

+5478
-1322
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

179 files changed

+5478
-1322
lines changed

.github/workflows/ci.yaml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ jobs:
466466
api-key: ${{ secrets.DATADOG_API_KEY }}
467467

468468
test-go-race:
469-
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-8' || 'ubuntu-latest' }}
469+
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-16' || 'ubuntu-latest' }}
470470
needs: changes
471471
if: needs.changes.outputs.go == 'true' || needs.changes.outputs.ci == 'true' || github.ref == 'refs/heads/main'
472472
timeout-minutes: 25
@@ -487,9 +487,13 @@ jobs:
487487
- name: Setup Terraform
488488
uses: ./.github/actions/setup-tf
489489

490+
# We run race tests with reduced parallelism because they use more CPU and we were finding
491+
# instances where tests appear to hang for multiple seconds, resulting in flaky tests when
492+
# short timeouts are used.
493+
# c.f. discussion on https://github.com/coder/coder/pull/15106
490494
- name: Run Tests
491495
run: |
492-
gotestsum --junitfile="gotests.xml" -- -race ./...
496+
gotestsum --junitfile="gotests.xml" -- -race -parallel 4 -p 4 ./...
493497
494498
- name: Upload test stats to Datadog
495499
timeout-minutes: 1
@@ -966,7 +970,7 @@ jobs:
966970
uses: google-github-actions/setup-gcloud@f0990588f1e5b5af6827153b93673613abdc6ec7 # v2.1.1
967971

968972
- name: Set up Flux CLI
969-
uses: fluxcd/flux2/action@9b3958825a314eb79495c6993ef397ddbf87f32f # v2.2.1
973+
uses: fluxcd/flux2/action@5350425cdcd5fa015337e09fa502153c0275bd4b # v2.4.0
970974
with:
971975
# Keep this and the github action up to date with the version of flux installed in dogfood cluster
972976
version: "2.2.1"

.github/workflows/scorecard.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,6 @@ jobs:
4747

4848
# Upload the results to GitHub's code scanning dashboard.
4949
- name: "Upload to code-scanning"
50-
uses: github/codeql-action/upload-sarif@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
50+
uses: github/codeql-action/upload-sarif@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13
5151
with:
5252
sarif_file: results.sarif

.github/workflows/security.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
uses: ./.github/actions/setup-go
3838

3939
- name: Initialize CodeQL
40-
uses: github/codeql-action/init@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
40+
uses: github/codeql-action/init@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13
4141
with:
4242
languages: go, javascript
4343

@@ -47,7 +47,7 @@ jobs:
4747
rm Makefile
4848
4949
- name: Perform CodeQL Analysis
50-
uses: github/codeql-action/analyze@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
50+
uses: github/codeql-action/analyze@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13
5151

5252
- name: Send Slack notification on failure
5353
if: ${{ failure() }}
@@ -124,15 +124,15 @@ jobs:
124124
echo "image=$(cat "$image_job")" >> $GITHUB_OUTPUT
125125
126126
- name: Run Trivy vulnerability scanner
127-
uses: aquasecurity/trivy-action@5681af892cd0f4997658e2bacc62bd0a894cf564
127+
uses: aquasecurity/trivy-action@915b19bbe73b92a6cf82a1bc12b087c9a19a5fe2
128128
with:
129129
image-ref: ${{ steps.build.outputs.image }}
130130
format: sarif
131131
output: trivy-results.sarif
132132
severity: "CRITICAL,HIGH"
133133

134134
- name: Upload Trivy scan results to GitHub Security tab
135-
uses: github/codeql-action/upload-sarif@c36620d31ac7c881962c3d9dd939c40ec9434f2b # v3.26.12
135+
uses: github/codeql-action/upload-sarif@f779452ac5af1c261dce0346a8f964149f49322b # v3.26.13
136136
with:
137137
sarif_file: trivy-results.sarif
138138
category: "Trivy"
@@ -147,7 +147,7 @@ jobs:
147147
# Prisma cloud scan runs last because it fails the entire job if it
148148
# detects vulnerabilities. :|
149149
- name: Run Prisma Cloud image scan
150-
uses: PaloAltoNetworks/prisma-cloud-scan@1f38c94d789ff9b01a4e80070b442294ebd3e362 # v1.4.0
150+
uses: PaloAltoNetworks/prisma-cloud-scan@124b48d8325c23f58a35da0f1b4d9a6b54301d05 # v1.6.7
151151
with:
152152
pcc_console_url: ${{ secrets.PRISMA_CLOUD_URL }}
153153
pcc_user: ${{ secrets.PRISMA_CLOUD_ACCESS_KEY }}

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,7 @@ test-postgres-docker:
817817

818818
# Make sure to keep this in sync with test-go-race from .github/workflows/ci.yaml.
819819
test-race:
820-
$(GIT_FLAGS) gotestsum --junitfile="gotests.xml" -- -race -count=1 ./...
820+
$(GIT_FLAGS) gotestsum --junitfile="gotests.xml" -- -race -count=1 -parallel 4 -p 4 ./...
821821
.PHONY: test-race
822822

823823
test-tailnet-integration:

agent/agent.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,11 +1134,19 @@ func (a *agent) trackGoroutine(fn func()) error {
11341134
}
11351135

11361136
func (a *agent) createTailnet(ctx context.Context, agentID uuid.UUID, derpMap *tailcfg.DERPMap, derpForceWebSockets, disableDirectConnections bool) (_ *tailnet.Conn, err error) {
1137+
// Inject `CODER_AGENT_HEADER` into the DERP header.
1138+
var header http.Header
1139+
if client, ok := a.client.(*agentsdk.Client); ok {
1140+
if headerTransport, ok := client.SDK.HTTPClient.Transport.(*codersdk.HeaderTransport); ok {
1141+
header = headerTransport.Header
1142+
}
1143+
}
11371144
network, err := tailnet.NewConn(&tailnet.Options{
11381145
ID: agentID,
11391146
Addresses: a.wireguardAddresses(agentID),
11401147
DERPMap: derpMap,
11411148
DERPForceWebSockets: derpForceWebSockets,
1149+
DERPHeader: &header,
11421150
Logger: a.logger.Named("net.tailnet"),
11431151
ListenPort: a.tailnetListenPort,
11441152
BlockEndpoints: disableDirectConnections,

cli/agent_test.go

Lines changed: 76 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"fmt"
66
"net/http"
7-
"net/http/httptest"
87
"os"
98
"path/filepath"
109
"runtime"
@@ -18,6 +17,7 @@ import (
1817

1918
"github.com/coder/coder/v2/agent"
2019
"github.com/coder/coder/v2/cli/clitest"
20+
"github.com/coder/coder/v2/coderd"
2121
"github.com/coder/coder/v2/coderd/coderdtest"
2222
"github.com/coder/coder/v2/coderd/database"
2323
"github.com/coder/coder/v2/coderd/database/dbfake"
@@ -35,7 +35,7 @@ func TestWorkspaceAgent(t *testing.T) {
3535

3636
client, db := coderdtest.NewWithDatabase(t, nil)
3737
user := coderdtest.CreateFirstUser(t, client)
38-
r := dbfake.WorkspaceBuild(t, db, database.Workspace{
38+
r := dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
3939
OrganizationID: user.OrganizationID,
4040
OwnerID: user.UserID,
4141
}).
@@ -71,7 +71,7 @@ func TestWorkspaceAgent(t *testing.T) {
7171
AzureCertificates: certificates,
7272
})
7373
user := coderdtest.CreateFirstUser(t, client)
74-
r := dbfake.WorkspaceBuild(t, db, database.Workspace{
74+
r := dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
7575
OrganizationID: user.OrganizationID,
7676
OwnerID: user.UserID,
7777
}).WithAgent(func(agents []*proto.Agent) []*proto.Agent {
@@ -110,7 +110,7 @@ func TestWorkspaceAgent(t *testing.T) {
110110
AWSCertificates: certificates,
111111
})
112112
user := coderdtest.CreateFirstUser(t, client)
113-
r := dbfake.WorkspaceBuild(t, db, database.Workspace{
113+
r := dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
114114
OrganizationID: user.OrganizationID,
115115
OwnerID: user.UserID,
116116
}).WithAgent(func(agents []*proto.Agent) []*proto.Agent {
@@ -151,7 +151,7 @@ func TestWorkspaceAgent(t *testing.T) {
151151
})
152152
owner := coderdtest.CreateFirstUser(t, client)
153153
member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
154-
r := dbfake.WorkspaceBuild(t, db, database.Workspace{
154+
r := dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
155155
OrganizationID: owner.OrganizationID,
156156
OwnerID: memberUser.ID,
157157
}).WithAgent(func(agents []*proto.Agent) []*proto.Agent {
@@ -205,7 +205,7 @@ func TestWorkspaceAgent(t *testing.T) {
205205

206206
client, db := coderdtest.NewWithDatabase(t, nil)
207207
user := coderdtest.CreateFirstUser(t, client)
208-
r := dbfake.WorkspaceBuild(t, db, database.Workspace{
208+
r := dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
209209
OrganizationID: user.OrganizationID,
210210
OwnerID: user.UserID,
211211
}).WithAgent().Do()
@@ -232,42 +232,92 @@ func TestWorkspaceAgent(t *testing.T) {
232232
require.Equal(t, codersdk.AgentSubsystemEnvbox, resources[0].Agents[0].Subsystems[0])
233233
require.Equal(t, codersdk.AgentSubsystemExectrace, resources[0].Agents[0].Subsystems[1])
234234
})
235-
t.Run("Header", func(t *testing.T) {
235+
t.Run("Headers&DERPHeaders", func(t *testing.T) {
236236
t.Parallel()
237237

238-
var url string
239-
var called int64
240-
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
241-
assert.Equal(t, "wow", r.Header.Get("X-Testing"))
242-
assert.Equal(t, "Ethan was Here!", r.Header.Get("Cool-Header"))
243-
assert.Equal(t, "very-wow-"+url, r.Header.Get("X-Process-Testing"))
244-
assert.Equal(t, "more-wow", r.Header.Get("X-Process-Testing2"))
245-
atomic.AddInt64(&called, 1)
246-
w.WriteHeader(http.StatusGone)
238+
// Create a coderd API instance the hard way since we need to change the
239+
// handler to inject our custom /derp handler.
240+
dv := coderdtest.DeploymentValues(t)
241+
dv.DERP.Config.BlockDirect = true
242+
setHandler, cancelFunc, serverURL, newOptions := coderdtest.NewOptions(t, &coderdtest.Options{
243+
DeploymentValues: dv,
244+
})
245+
246+
// We set the handler after server creation for the access URL.
247+
coderAPI := coderd.New(newOptions)
248+
setHandler(coderAPI.RootHandler)
249+
provisionerCloser := coderdtest.NewProvisionerDaemon(t, coderAPI)
250+
t.Cleanup(func() {
251+
_ = provisionerCloser.Close()
252+
})
253+
client := codersdk.New(serverURL)
254+
t.Cleanup(func() {
255+
cancelFunc()
256+
_ = provisionerCloser.Close()
257+
_ = coderAPI.Close()
258+
client.HTTPClient.CloseIdleConnections()
259+
})
260+
261+
var (
262+
admin = coderdtest.CreateFirstUser(t, client)
263+
member, memberUser = coderdtest.CreateAnotherUser(t, client, admin.OrganizationID)
264+
called int64
265+
derpCalled int64
266+
)
267+
268+
setHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
269+
// Ignore client requests
270+
if r.Header.Get("X-Testing") == "agent" {
271+
assert.Equal(t, "Ethan was Here!", r.Header.Get("Cool-Header"))
272+
assert.Equal(t, "very-wow-"+client.URL.String(), r.Header.Get("X-Process-Testing"))
273+
assert.Equal(t, "more-wow", r.Header.Get("X-Process-Testing2"))
274+
if strings.HasPrefix(r.URL.Path, "/derp") {
275+
atomic.AddInt64(&derpCalled, 1)
276+
} else {
277+
atomic.AddInt64(&called, 1)
278+
}
279+
}
280+
coderAPI.RootHandler.ServeHTTP(w, r)
247281
}))
248-
defer srv.Close()
249-
url = srv.URL
282+
r := dbfake.WorkspaceBuild(t, coderAPI.Database, database.WorkspaceTable{
283+
OrganizationID: memberUser.OrganizationIDs[0],
284+
OwnerID: memberUser.ID,
285+
}).WithAgent().Do()
286+
250287
coderURLEnv := "$CODER_URL"
251288
if runtime.GOOS == "windows" {
252289
coderURLEnv = "%CODER_URL%"
253290
}
254291

255292
logDir := t.TempDir()
256-
inv, _ := clitest.New(t,
293+
agentInv, _ := clitest.New(t,
257294
"agent",
258295
"--auth", "token",
259-
"--agent-token", "fake-token",
260-
"--agent-url", srv.URL,
296+
"--agent-token", r.AgentToken,
297+
"--agent-url", client.URL.String(),
261298
"--log-dir", logDir,
262-
"--agent-header", "X-Testing=wow",
299+
"--agent-header", "X-Testing=agent",
263300
"--agent-header", "Cool-Header=Ethan was Here!",
264301
"--agent-header-command", "printf X-Process-Testing=very-wow-"+coderURLEnv+"'\\r\\n'X-Process-Testing2=more-wow",
265302
)
303+
clitest.Start(t, agentInv)
304+
coderdtest.NewWorkspaceAgentWaiter(t, client, r.Workspace.ID).
305+
MatchResources(matchAgentWithVersion).Wait()
306+
307+
ctx := testutil.Context(t, testutil.WaitLong)
308+
clientInv, root := clitest.New(t,
309+
"-v",
310+
"--no-feature-warning",
311+
"--no-version-warning",
312+
"ping", r.Workspace.Name,
313+
"-n", "1",
314+
)
315+
clitest.SetupConfig(t, member, root)
316+
err := clientInv.WithContext(ctx).Run()
317+
require.NoError(t, err)
266318

267-
clitest.Start(t, inv)
268-
require.Eventually(t, func() bool {
269-
return atomic.LoadInt64(&called) > 0
270-
}, testutil.WaitShort, testutil.IntervalFast)
319+
require.Greater(t, atomic.LoadInt64(&called), int64(0), "expected coderd to be reached with custom headers")
320+
require.Greater(t, atomic.LoadInt64(&derpCalled), int64(0), "expected /derp to be called with custom headers")
271321
})
272322
}
273323

cli/clistat/container.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
const (
1313
procMounts = "/proc/mounts"
1414
procOneCgroup = "/proc/1/cgroup"
15+
sysCgroupType = "/sys/fs/cgroup/cgroup.type"
1516
kubernetesDefaultServiceAccountToken = "/var/run/secrets/kubernetes.io/serviceaccount/token" //nolint:gosec
1617
)
1718

@@ -65,6 +66,17 @@ func IsContainerized(fs afero.Fs) (ok bool, err error) {
6566
}
6667
}
6768

69+
// Adapted from https://github.com/systemd/systemd/blob/88bbf187a9b2ebe0732caa1e886616ae5f8186da/src/basic/virt.c#L603-L605
70+
// The file `/sys/fs/cgroup/cgroup.type` does not exist on the root cgroup.
71+
// If this file exists we can be sure we're in a container.
72+
cgTypeExists, err := afero.Exists(fs, sysCgroupType)
73+
if err != nil {
74+
return false, xerrors.Errorf("check file exists %s: %w", sysCgroupType, err)
75+
}
76+
if cgTypeExists {
77+
return true, nil
78+
}
79+
6880
// If we get here, we are _probably_ not running in a container.
6981
return false, nil
7082
}

cli/clistat/stat_internal_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,12 @@ func TestIsContainerized(t *testing.T) {
309309
Expected: true,
310310
Error: "",
311311
},
312+
{
313+
Name: "Docker (Cgroupns=private)",
314+
FS: fsContainerCgroupV2PrivateCgroupns,
315+
Expected: true,
316+
Error: "",
317+
},
312318
} {
313319
tt := tt
314320
t.Run(tt.Name, func(t *testing.T) {
@@ -374,6 +380,12 @@ proc /proc/sys proc ro,nosuid,nodev,noexec,relatime 0 0`,
374380
cgroupV2MemoryUsageBytes: "536870912",
375381
cgroupV2MemoryStat: "inactive_file 268435456",
376382
}
383+
fsContainerCgroupV2PrivateCgroupns = map[string]string{
384+
procOneCgroup: "0::/",
385+
procMounts: `overlay / overlay rw,relatime,lowerdir=/some/path:/some/path,upperdir=/some/path:/some/path,workdir=/some/path:/some/path 0 0
386+
proc /proc/sys proc ro,nosuid,nodev,noexec,relatime 0 0`,
387+
sysCgroupType: "domain",
388+
}
377389
fsContainerCgroupV1 = map[string]string{
378390
procOneCgroup: "0::/docker/aa86ac98959eeedeae0ecb6e0c9ddd8ae8b97a9d0fdccccf7ea7a474f4e0bb1f",
379391
procMounts: `overlay / overlay rw,relatime,lowerdir=/some/path:/some/path,upperdir=/some/path:/some/path,workdir=/some/path:/some/path 0 0

cli/configssh_test.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"os"
1111
"os/exec"
1212
"path/filepath"
13+
"runtime"
1314
"strconv"
1415
"strings"
1516
"sync"
@@ -63,6 +64,10 @@ func sshConfigFileRead(t *testing.T, name string) string {
6364
func TestConfigSSH(t *testing.T) {
6465
t.Parallel()
6566

67+
if runtime.GOOS == "windows" {
68+
t.Skip("See coder/internal#117")
69+
}
70+
6671
const hostname = "test-coder."
6772
const expectedKey = "ConnectionAttempts"
6873
const removeKey = "ConnectTimeout"
@@ -78,7 +83,7 @@ func TestConfigSSH(t *testing.T) {
7883
})
7984
owner := coderdtest.CreateFirstUser(t, client)
8085
member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
81-
r := dbfake.WorkspaceBuild(t, db, database.Workspace{
86+
r := dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
8287
OrganizationID: owner.OrganizationID,
8388
OwnerID: memberUser.ID,
8489
}).WithAgent().Do()
@@ -642,7 +647,7 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) {
642647
client, db := coderdtest.NewWithDatabase(t, nil)
643648
user := coderdtest.CreateFirstUser(t, client)
644649
if tt.hasAgent {
645-
_ = dbfake.WorkspaceBuild(t, db, database.Workspace{
650+
_ = dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
646651
OrganizationID: user.OrganizationID,
647652
OwnerID: user.UserID,
648653
}).WithAgent().Do()
@@ -762,7 +767,7 @@ func TestConfigSSH_Hostnames(t *testing.T) {
762767
owner := coderdtest.CreateFirstUser(t, client)
763768
member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
764769

765-
r := dbfake.WorkspaceBuild(t, db, database.Workspace{
770+
r := dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{
766771
OrganizationID: owner.OrganizationID,
767772
OwnerID: memberUser.ID,
768773
}).Resource(resources...).Do()

cli/favorite_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func TestFavoriteUnfavorite(t *testing.T) {
1919
client, db = coderdtest.NewWithDatabase(t, nil)
2020
owner = coderdtest.CreateFirstUser(t, client)
2121
memberClient, member = coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
22-
ws = dbfake.WorkspaceBuild(t, db, database.Workspace{OwnerID: member.ID, OrganizationID: owner.OrganizationID}).Do()
22+
ws = dbfake.WorkspaceBuild(t, db, database.WorkspaceTable{OwnerID: member.ID, OrganizationID: owner.OrganizationID}).Do()
2323
)
2424

2525
inv, root := clitest.New(t, "favorite", ws.Workspace.Name)

0 commit comments

Comments
 (0)