Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 96cfa71

Browse files
committedAug 8, 2023
Merge branch 'main' of https://github.com/coder/coder into bq/add-datepicker-range
2 parents 224bbb9 + 4a987e9 commit 96cfa71

File tree

35 files changed

+1123
-206
lines changed

35 files changed

+1123
-206
lines changed
 

‎.github/actions/setup-go/action.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: |
44
inputs:
55
version:
66
description: "The Go version to use."
7-
default: "1.20.6"
7+
default: "1.20.7"
88
runs:
99
using: "composite"
1010
steps:

‎.github/workflows/ci.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ jobs:
224224
with:
225225
# This doesn't need caching. It's super fast anyways!
226226
cache: false
227-
go-version: 1.20.6
227+
go-version: 1.20.7
228228

229229
- name: Install shfmt
230230
run: go install mvdan.cc/sh/v3/cmd/shfmt@v3.5.0
@@ -668,6 +668,7 @@ jobs:
668668
- test-go-pg
669669
- test-go-race
670670
- test-js
671+
- test-e2e
671672
- offlinedocs
672673
# Allow this job to run even if the needed jobs fail, are skipped or
673674
# cancelled.

‎.github/workflows/release.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@ env:
2828
# https://github.blog/changelog/2022-06-10-github-actions-inputs-unified-across-manual-and-reusable-workflows/
2929
CODER_RELEASE: ${{ !inputs.dry_run }}
3030
CODER_DRY_RUN: ${{ inputs.dry_run }}
31-
# For some reason, setup-go won't actually pick up a new patch version if
32-
# it has an old one cached. We need to manually specify the versions so we
33-
# can get the latest release. Never use "~1.xx" here!
34-
CODER_GO_VERSION: "1.20.6"
3531

3632
jobs:
3733
release:

‎.github/workflows/security.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@ concurrency:
2121
group: ${{ github.workflow }}-${{ github.ref }}-security
2222
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
2323

24-
env:
25-
CODER_GO_VERSION: "1.20.6"
26-
2724
jobs:
2825
codeql:
2926
runs-on: ${{ github.repository_owner == 'coder' && 'buildjet-8vcpu-ubuntu-2204' || 'ubuntu-latest' }}

‎cli/root_internal_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package cli
22

33
import (
4+
"os"
5+
"runtime"
46
"testing"
57

68
"github.com/stretchr/testify/require"
@@ -67,6 +69,11 @@ func Test_formatExamples(t *testing.T) {
6769
}
6870

6971
func TestMain(m *testing.M) {
72+
if runtime.GOOS == "windows" {
73+
// Don't run goleak on windows tests, they're super flaky right now.
74+
// See: https://github.com/coder/coder/issues/8954
75+
os.Exit(m.Run())
76+
}
7077
goleak.VerifyTestMain(m,
7178
// The lumberjack library is used by by agent and seems to leave
7279
// goroutines after Close(), fails TestGitSSH tests.

‎cli/stat.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ func (*RootCmd) statDisk(s *clistat.Statter) *clibase.Cmd {
240240
ds, err := s.Disk(pfx, pathArg)
241241
if err != nil {
242242
if os.IsNotExist(err) {
243-
// fmt.Errorf produces a more concise error.
243+
//nolint:gocritic // fmt.Errorf produces a more concise error.
244244
return fmt.Errorf("not found: %q", pathArg)
245245
}
246246
return err

‎coderd/apidoc/docs.go

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎coderd/apidoc/swagger.json

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎coderd/batchstats/batcher.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313

1414
"cdr.dev/slog"
1515
"cdr.dev/slog/sloggers/sloghuman"
16-
1716
"github.com/coder/coder/coderd/database"
1817
"github.com/coder/coder/coderd/database/dbauthz"
1918
"github.com/coder/coder/codersdk/agentsdk"
@@ -126,6 +125,7 @@ func New(ctx context.Context, opts ...Option) (*Batcher, func(), error) {
126125

127126
// Add adds a stat to the batcher for the given workspace and agent.
128127
func (b *Batcher) Add(
128+
now time.Time,
129129
agentID uuid.UUID,
130130
templateID uuid.UUID,
131131
userID uuid.UUID,
@@ -135,7 +135,7 @@ func (b *Batcher) Add(
135135
b.mu.Lock()
136136
defer b.mu.Unlock()
137137

138-
now := database.Now()
138+
now = database.Time(now)
139139

140140
b.buf.ID = append(b.buf.ID, uuid.New())
141141
b.buf.CreatedAt = append(b.buf.CreatedAt, now)
@@ -199,15 +199,6 @@ func (b *Batcher) flush(ctx context.Context, forced bool, reason string) {
199199
defer func() {
200200
b.flushForced.Store(false)
201201
b.mu.Unlock()
202-
// Notify that a flush has completed. This only happens in tests.
203-
if b.flushed != nil {
204-
select {
205-
case <-ctx.Done():
206-
close(b.flushed)
207-
default:
208-
b.flushed <- count
209-
}
210-
}
211202
if count > 0 {
212203
elapsed := time.Since(start)
213204
b.log.Debug(ctx, "flush complete",
@@ -217,6 +208,15 @@ func (b *Batcher) flush(ctx context.Context, forced bool, reason string) {
217208
slog.F("reason", reason),
218209
)
219210
}
211+
// Notify that a flush has completed. This only happens in tests.
212+
if b.flushed != nil {
213+
select {
214+
case <-ctx.Done():
215+
close(b.flushed)
216+
default:
217+
b.flushed <- count
218+
}
219+
}
220220
}()
221221

222222
if len(b.buf.ID) == 0 {

‎coderd/batchstats/batcher_internal_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func TestBatchStats(t *testing.T) {
4646

4747
// Given: no data points are added for workspace
4848
// When: it becomes time to report stats
49-
t1 := time.Now()
49+
t1 := database.Now()
5050
// Signal a tick and wait for a flush to complete.
5151
tick <- t1
5252
f := <-flushed
@@ -59,9 +59,9 @@ func TestBatchStats(t *testing.T) {
5959
require.Empty(t, stats, "should have no stats for workspace")
6060

6161
// Given: a single data point is added for workspace
62-
t2 := time.Now()
62+
t2 := t1.Add(time.Second)
6363
t.Logf("inserting 1 stat")
64-
require.NoError(t, b.Add(deps1.Agent.ID, deps1.User.ID, deps1.Template.ID, deps1.Workspace.ID, randAgentSDKStats(t)))
64+
require.NoError(t, b.Add(t2.Add(time.Millisecond), deps1.Agent.ID, deps1.User.ID, deps1.Template.ID, deps1.Workspace.ID, randAgentSDKStats(t)))
6565

6666
// When: it becomes time to report stats
6767
// Signal a tick and wait for a flush to complete.
@@ -77,17 +77,17 @@ func TestBatchStats(t *testing.T) {
7777

7878
// Given: a lot of data points are added for both workspaces
7979
// (equal to batch size)
80-
t3 := time.Now()
80+
t3 := t2.Add(time.Second)
8181
done := make(chan struct{})
8282

8383
go func() {
8484
defer close(done)
8585
t.Logf("inserting %d stats", defaultBufferSize)
8686
for i := 0; i < defaultBufferSize; i++ {
8787
if i%2 == 0 {
88-
require.NoError(t, b.Add(deps1.Agent.ID, deps1.User.ID, deps1.Template.ID, deps1.Workspace.ID, randAgentSDKStats(t)))
88+
require.NoError(t, b.Add(t3.Add(time.Millisecond), deps1.Agent.ID, deps1.User.ID, deps1.Template.ID, deps1.Workspace.ID, randAgentSDKStats(t)))
8989
} else {
90-
require.NoError(t, b.Add(deps2.Agent.ID, deps2.User.ID, deps2.Template.ID, deps2.Workspace.ID, randAgentSDKStats(t)))
90+
require.NoError(t, b.Add(t3.Add(time.Millisecond), deps2.Agent.ID, deps2.User.ID, deps2.Template.ID, deps2.Workspace.ID, randAgentSDKStats(t)))
9191
}
9292
}
9393
}()
@@ -105,15 +105,15 @@ func TestBatchStats(t *testing.T) {
105105
require.Len(t, stats, 2, "should have stats for both workspaces")
106106

107107
// Ensures that a subsequent flush pushes all the remaining data
108-
t4 := time.Now()
108+
t4 := t3.Add(time.Second)
109109
tick <- t4
110110
f2 := <-flushed
111111
t.Logf("flush 4 completed")
112112
expectedCount := defaultBufferSize - f
113113
require.Equal(t, expectedCount, f2, "did not flush expected remaining rows")
114114

115115
// Ensure that a subsequent flush does not push stale data.
116-
t5 := time.Now()
116+
t5 := t4.Add(time.Second)
117117
tick <- t5
118118
f = <-flushed
119119
require.Zero(t, f, "expected zero stats to have been flushed")

‎coderd/coderd.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -693,15 +693,13 @@ func New(options *Options) *API {
693693
r.Route("/github", func(r chi.Router) {
694694
r.Use(
695695
httpmw.ExtractOAuth2(options.GithubOAuth2Config, options.HTTPClient, nil),
696-
apiKeyMiddlewareOptional,
697696
)
698697
r.Get("/callback", api.userOAuth2Github)
699698
})
700699
})
701700
r.Route("/oidc/callback", func(r chi.Router) {
702701
r.Use(
703702
httpmw.ExtractOAuth2(options.OIDCConfig, options.HTTPClient, oidcAuthURLParams),
704-
apiKeyMiddlewareOptional,
705703
)
706704
r.Get("/", api.userOIDC)
707705
})

‎coderd/coderdtest/coderdtest.go

Lines changed: 63 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,9 +1022,31 @@ func NewAWSInstanceIdentity(t *testing.T, instanceID string) (awsidentity.Certif
10221022
type OIDCConfig struct {
10231023
key *rsa.PrivateKey
10241024
issuer string
1025+
// These are optional
1026+
refreshToken string
1027+
oidcTokenExpires func() time.Time
1028+
tokenSource func() (*oauth2.Token, error)
10251029
}
10261030

1027-
func NewOIDCConfig(t *testing.T, issuer string) *OIDCConfig {
1031+
func WithRefreshToken(token string) func(cfg *OIDCConfig) {
1032+
return func(cfg *OIDCConfig) {
1033+
cfg.refreshToken = token
1034+
}
1035+
}
1036+
1037+
func WithTokenExpires(expFunc func() time.Time) func(cfg *OIDCConfig) {
1038+
return func(cfg *OIDCConfig) {
1039+
cfg.oidcTokenExpires = expFunc
1040+
}
1041+
}
1042+
1043+
func WithTokenSource(src func() (*oauth2.Token, error)) func(cfg *OIDCConfig) {
1044+
return func(cfg *OIDCConfig) {
1045+
cfg.tokenSource = src
1046+
}
1047+
}
1048+
1049+
func NewOIDCConfig(t *testing.T, issuer string, opts ...func(cfg *OIDCConfig)) *OIDCConfig {
10281050
t.Helper()
10291051

10301052
block, _ := pem.Decode([]byte(testRSAPrivateKey))
@@ -1035,54 +1057,79 @@ func NewOIDCConfig(t *testing.T, issuer string) *OIDCConfig {
10351057
issuer = "https://coder.com"
10361058
}
10371059

1038-
return &OIDCConfig{
1060+
cfg := &OIDCConfig{
10391061
key: pkey,
10401062
issuer: issuer,
10411063
}
1064+
for _, opt := range opts {
1065+
opt(cfg)
1066+
}
1067+
return cfg
10421068
}
10431069

10441070
func (*OIDCConfig) AuthCodeURL(state string, _ ...oauth2.AuthCodeOption) string {
10451071
return "/?state=" + url.QueryEscape(state)
10461072
}
10471073

1048-
func (*OIDCConfig) TokenSource(context.Context, *oauth2.Token) oauth2.TokenSource {
1049-
return nil
1074+
type tokenSource struct {
1075+
src func() (*oauth2.Token, error)
1076+
}
1077+
1078+
func (s tokenSource) Token() (*oauth2.Token, error) {
1079+
return s.src()
1080+
}
1081+
1082+
func (cfg *OIDCConfig) TokenSource(context.Context, *oauth2.Token) oauth2.TokenSource {
1083+
if cfg.tokenSource == nil {
1084+
return nil
1085+
}
1086+
return tokenSource{
1087+
src: cfg.tokenSource,
1088+
}
10501089
}
10511090

1052-
func (*OIDCConfig) Exchange(_ context.Context, code string, _ ...oauth2.AuthCodeOption) (*oauth2.Token, error) {
1091+
func (cfg *OIDCConfig) Exchange(_ context.Context, code string, _ ...oauth2.AuthCodeOption) (*oauth2.Token, error) {
10531092
token, err := base64.StdEncoding.DecodeString(code)
10541093
if err != nil {
10551094
return nil, xerrors.Errorf("decode code: %w", err)
10561095
}
1096+
1097+
var exp time.Time
1098+
if cfg.oidcTokenExpires != nil {
1099+
exp = cfg.oidcTokenExpires()
1100+
}
1101+
10571102
return (&oauth2.Token{
1058-
AccessToken: "token",
1103+
AccessToken: "token",
1104+
RefreshToken: cfg.refreshToken,
1105+
Expiry: exp,
10591106
}).WithExtra(map[string]interface{}{
10601107
"id_token": string(token),
10611108
}), nil
10621109
}
10631110

1064-
func (o *OIDCConfig) EncodeClaims(t *testing.T, claims jwt.MapClaims) string {
1111+
func (cfg *OIDCConfig) EncodeClaims(t *testing.T, claims jwt.MapClaims) string {
10651112
t.Helper()
10661113

10671114
if _, ok := claims["exp"]; !ok {
10681115
claims["exp"] = time.Now().Add(time.Hour).UnixMilli()
10691116
}
10701117

10711118
if _, ok := claims["iss"]; !ok {
1072-
claims["iss"] = o.issuer
1119+
claims["iss"] = cfg.issuer
10731120
}
10741121

10751122
if _, ok := claims["sub"]; !ok {
10761123
claims["sub"] = "testme"
10771124
}
10781125

1079-
signed, err := jwt.NewWithClaims(jwt.SigningMethodRS256, claims).SignedString(o.key)
1126+
signed, err := jwt.NewWithClaims(jwt.SigningMethodRS256, claims).SignedString(cfg.key)
10801127
require.NoError(t, err)
10811128

10821129
return base64.StdEncoding.EncodeToString([]byte(signed))
10831130
}
10841131

1085-
func (o *OIDCConfig) OIDCConfig(t *testing.T, userInfoClaims jwt.MapClaims, opts ...func(cfg *coderd.OIDCConfig)) *coderd.OIDCConfig {
1132+
func (cfg *OIDCConfig) OIDCConfig(t *testing.T, userInfoClaims jwt.MapClaims, opts ...func(cfg *coderd.OIDCConfig)) *coderd.OIDCConfig {
10861133
// By default, the provider can be empty.
10871134
// This means it won't support any endpoints!
10881135
provider := &oidc.Provider{}
@@ -1099,10 +1146,10 @@ func (o *OIDCConfig) OIDCConfig(t *testing.T, userInfoClaims jwt.MapClaims, opts
10991146
}
11001147
provider = cfg.NewProvider(context.Background())
11011148
}
1102-
cfg := &coderd.OIDCConfig{
1103-
OAuth2Config: o,
1104-
Verifier: oidc.NewVerifier(o.issuer, &oidc.StaticKeySet{
1105-
PublicKeys: []crypto.PublicKey{o.key.Public()},
1149+
newCFG := &coderd.OIDCConfig{
1150+
OAuth2Config: cfg,
1151+
Verifier: oidc.NewVerifier(cfg.issuer, &oidc.StaticKeySet{
1152+
PublicKeys: []crypto.PublicKey{cfg.key.Public()},
11061153
}, &oidc.Config{
11071154
SkipClientIDCheck: true,
11081155
}),
@@ -1113,9 +1160,9 @@ func (o *OIDCConfig) OIDCConfig(t *testing.T, userInfoClaims jwt.MapClaims, opts
11131160
GroupField: "groups",
11141161
}
11151162
for _, opt := range opts {
1116-
opt(cfg)
1163+
opt(newCFG)
11171164
}
1118-
return cfg
1165+
return newCFG
11191166
}
11201167

11211168
// NewAzureInstanceIdentity returns a metadata client and ID token validator for faking
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.