Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitabf7633

Browse files
committed
Merge branch 'main' into webterm
2 parents229c7e4 +82364d1 commitabf7633

File tree

53 files changed

+2216
-547
lines changed

Some content is hidden

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

53 files changed

+2216
-547
lines changed

‎.goreleaser.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ builds:
2929
-id:coder-slim
3030
dir:cmd/coder
3131
ldflags:
32-
["-s -w -X github.com/coder/coder/cli/buildinfo.tag={{ .Version }}"]
32+
["-s -w -X github.com/coder/coder/buildinfo.tag={{ .Version }}"]
3333
env:[CGO_ENABLED=0]
3434
goos:[darwin, linux, windows]
3535
goarch:[amd64]
@@ -42,7 +42,7 @@ builds:
4242
dir:cmd/coder
4343
flags:[-tags=embed]
4444
ldflags:
45-
["-s -w -X github.com/coder/coder/cli/buildinfo.tag={{ .Version }}"]
45+
["-s -w -X github.com/coder/coder/buildinfo.tag={{ .Version }}"]
4646
env:[CGO_ENABLED=0]
4747
goos:[linux]
4848
goarch:[amd64, arm64]
@@ -51,7 +51,7 @@ builds:
5151
dir:cmd/coder
5252
flags:[-tags=embed]
5353
ldflags:
54-
["-s -w -X github.com/coder/coder/cli/buildinfo.tag={{ .Version }}"]
54+
["-s -w -X github.com/coder/coder/buildinfo.tag={{ .Version }}"]
5555
env:[CGO_ENABLED=0]
5656
goos:[windows]
5757
goarch:[amd64, arm64]
@@ -60,7 +60,7 @@ builds:
6060
dir:cmd/coder
6161
flags:[-tags=embed]
6262
ldflags:
63-
["-s -w -X github.com/coder/coder/cli/buildinfo.tag={{ .Version }}"]
63+
["-s -w -X github.com/coder/coder/buildinfo.tag={{ .Version }}"]
6464
env:[CGO_ENABLED=0]
6565
goos:[darwin]
6666
goarch:[amd64, arm64]

‎cli/server.go

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import (
4141
"github.com/coder/coder/coderd/gitsshkey"
4242
"github.com/coder/coder/coderd/turnconn"
4343
"github.com/coder/coder/codersdk"
44+
"github.com/coder/coder/cryptorand"
4445
"github.com/coder/coder/provisioner/terraform"
4546
"github.com/coder/coder/provisionerd"
4647
"github.com/coder/coder/provisionersdk"
@@ -50,11 +51,13 @@ import (
5051
// nolint:gocyclo
5152
funcserver()*cobra.Command {
5253
var (
53-
accessURLstring
54-
addressstring
55-
cacheDirstring
56-
devbool
57-
postgresURLstring
54+
accessURLstring
55+
addressstring
56+
cacheDirstring
57+
devbool
58+
devUserEmailstring
59+
devUserPasswordstring
60+
postgresURLstring
5861
// provisionerDaemonCount is a uint8 to ensure a number > 0.
5962
provisionerDaemonCountuint8
6063
oauth2GithubClientIDstring
@@ -271,10 +274,19 @@ func server() *cobra.Command {
271274
config:=createConfig(cmd)
272275

273276
ifdev {
274-
err=createFirstUser(cmd,client,config)
277+
ifdevUserPassword=="" {
278+
devUserPassword,err=cryptorand.String(10)
279+
iferr!=nil {
280+
returnxerrors.Errorf("generate random admin password for dev: %w",err)
281+
}
282+
}
283+
err=createFirstUser(cmd,client,config,devUserEmail,devUserPassword)
275284
iferr!=nil {
276285
returnxerrors.Errorf("create first user: %w",err)
277286
}
287+
_,_=fmt.Fprintf(cmd.ErrOrStderr(),"email: %s\n",devUserEmail)
288+
_,_=fmt.Fprintf(cmd.ErrOrStderr(),"password: %s\n",devUserPassword)
289+
_,_=fmt.Fprintln(cmd.ErrOrStderr())
278290

279291
_,_=fmt.Fprintf(cmd.ErrOrStderr(),cliui.Styles.Wrap.Render(`Started in dev mode. All data is in-memory! `+cliui.Styles.Bold.Render("Do not use in production")+`. Press `+
280292
cliui.Styles.Field.Render("ctrl+c")+` to clean up provisioned infrastructure.`)+"\n\n")
@@ -399,6 +411,8 @@ func server() *cobra.Command {
399411
// systemd uses the CACHE_DIRECTORY environment variable!
400412
cliflag.StringVarP(root.Flags(),&cacheDir,"cache-dir","","CACHE_DIRECTORY",filepath.Join(os.TempDir(),"coder-cache"),"Specifies a directory to cache binaries for provision operations.")
401413
cliflag.BoolVarP(root.Flags(),&dev,"dev","","CODER_DEV_MODE",false,"Serve Coder in dev mode for tinkering")
414+
cliflag.StringVarP(root.Flags(),&devUserEmail,"dev-admin-email","","CODER_DEV_ADMIN_EMAIL","admin@coder.com","Specifies the admin email to be used in dev mode (--dev)")
415+
cliflag.StringVarP(root.Flags(),&devUserPassword,"dev-admin-password","","CODER_DEV_ADMIN_PASSWORD","","Specifies the admin password to be used in dev mode (--dev) instead of a randomly generated one")
402416
cliflag.StringVarP(root.Flags(),&postgresURL,"postgres-url","","CODER_PG_CONNECTION_URL","","URL of a PostgreSQL database to connect to")
403417
cliflag.Uint8VarP(root.Flags(),&provisionerDaemonCount,"provisioner-daemons","","CODER_PROVISIONER_DAEMONS",3,"The amount of provisioner daemons to create on start.")
404418
cliflag.StringVarP(root.Flags(),&oauth2GithubClientID,"oauth2-github-client-id","","CODER_OAUTH2_GITHUB_CLIENT_ID","",
@@ -440,19 +454,25 @@ func server() *cobra.Command {
440454
returnroot
441455
}
442456

443-
funccreateFirstUser(cmd*cobra.Command,client*codersdk.Client,cfg config.Root)error {
457+
funccreateFirstUser(cmd*cobra.Command,client*codersdk.Client,cfg config.Root,email,passwordstring)error {
458+
ifemail=="" {
459+
returnxerrors.New("email is empty")
460+
}
461+
ifpassword=="" {
462+
returnxerrors.New("password is empty")
463+
}
444464
_,err:=client.CreateFirstUser(cmd.Context(), codersdk.CreateFirstUserRequest{
445-
Email:"admin@coder.com",
465+
Email:email,
446466
Username:"developer",
447-
Password:"password",
467+
Password:password,
448468
OrganizationName:"acme-corp",
449469
})
450470
iferr!=nil {
451471
returnxerrors.Errorf("create first user: %w",err)
452472
}
453473
token,err:=client.LoginWithPassword(cmd.Context(), codersdk.LoginWithPasswordRequest{
454-
Email:"admin@coder.com",
455-
Password:"password",
474+
Email:email,
475+
Password:password,
456476
})
457477
iferr!=nil {
458478
returnxerrors.Errorf("login with first user: %w",err)

‎cli/server_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,19 @@ import (
99
"crypto/x509"
1010
"crypto/x509/pkix"
1111
"encoding/pem"
12+
"fmt"
1213
"math/big"
1314
"net"
1415
"net/http"
1516
"net/url"
1617
"os"
1718
"runtime"
19+
"strings"
20+
"sync"
1821
"testing"
1922
"time"
2023

24+
"github.com/stretchr/testify/assert"
2125
"github.com/stretchr/testify/require"
2226
"go.uber.org/goleak"
2327

@@ -72,10 +76,30 @@ func TestServer(t *testing.T) {
7276
t.Parallel()
7377
ctx,cancelFunc:=context.WithCancel(context.Background())
7478
defercancelFunc()
79+
80+
wantEmail:="admin@coder.com"
81+
7582
root,cfg:=clitest.New(t,"server","--dev","--skip-tunnel","--address",":0")
83+
varbuf strings.Builder
84+
root.SetOutput(&buf)
85+
varwg sync.WaitGroup
86+
wg.Add(1)
7687
gofunc() {
88+
deferwg.Done()
89+
7790
err:=root.ExecuteContext(ctx)
7891
require.ErrorIs(t,err,context.Canceled)
92+
93+
// Verify that credentials were output to the terminal.
94+
assert.Contains(t,buf.String(),fmt.Sprintf("email: %s",wantEmail),"expected output %q; got no match",wantEmail)
95+
// Check that the password line is output and that it's non-empty.
96+
if_,after,found:=strings.Cut(buf.String(),"password: ");found {
97+
before,_,_:=strings.Cut(after,"\n")
98+
before=strings.Trim(before,"\r")// Ensure no control character is left.
99+
assert.NotEmpty(t,before,"expected non-empty password; got empty")
100+
}else {
101+
t.Error("expected password line output; got no match")
102+
}
79103
}()
80104
vartokenstring
81105
require.Eventually(t,func()bool {
@@ -92,6 +116,55 @@ func TestServer(t *testing.T) {
92116
client.SessionToken=token
93117
_,err=client.User(ctx,codersdk.Me)
94118
require.NoError(t,err)
119+
120+
cancelFunc()
121+
wg.Wait()
122+
})
123+
// Duplicated test from "Development" above to test setting email/password via env.
124+
// Cannot run parallel due to os.Setenv.
125+
//nolint:paralleltest
126+
t.Run("Development with email and password from env",func(t*testing.T) {
127+
ctx,cancelFunc:=context.WithCancel(context.Background())
128+
defercancelFunc()
129+
130+
wantEmail:="myadmin@coder.com"
131+
wantPassword:="testpass42"
132+
t.Setenv("CODER_DEV_ADMIN_EMAIL",wantEmail)
133+
t.Setenv("CODER_DEV_ADMIN_PASSWORD",wantPassword)
134+
135+
root,cfg:=clitest.New(t,"server","--dev","--skip-tunnel","--address",":0")
136+
varbuf strings.Builder
137+
root.SetOutput(&buf)
138+
varwg sync.WaitGroup
139+
wg.Add(1)
140+
gofunc() {
141+
deferwg.Done()
142+
143+
err:=root.ExecuteContext(ctx)
144+
require.ErrorIs(t,err,context.Canceled)
145+
146+
// Verify that credentials were output to the terminal.
147+
assert.Contains(t,buf.String(),fmt.Sprintf("email: %s",wantEmail),"expected output %q; got no match",wantEmail)
148+
assert.Contains(t,buf.String(),fmt.Sprintf("password: %s",wantPassword),"expected output %q; got no match",wantPassword)
149+
}()
150+
vartokenstring
151+
require.Eventually(t,func()bool {
152+
varerrerror
153+
token,err=cfg.Session().Read()
154+
returnerr==nil
155+
},15*time.Second,25*time.Millisecond)
156+
// Verify that authentication was properly set in dev-mode.
157+
accessURL,err:=cfg.URL().Read()
158+
require.NoError(t,err)
159+
parsed,err:=url.Parse(accessURL)
160+
require.NoError(t,err)
161+
client:=codersdk.New(parsed)
162+
client.SessionToken=token
163+
_,err=client.User(ctx,codersdk.Me)
164+
require.NoError(t,err)
165+
166+
cancelFunc()
167+
wg.Wait()
95168
})
96169
t.Run("TLSBadVersion",func(t*testing.T) {
97170
t.Parallel()

‎coderd/database/databasefake/databasefake.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,29 @@ func (q *fakeQuerier) GetOrganizationMemberByUserID(_ context.Context, arg datab
709709
return database.OrganizationMember{},sql.ErrNoRows
710710
}
711711

712+
func (q*fakeQuerier)GetOrganizationIDsByMemberIDs(_ context.Context,ids []uuid.UUID) ([]database.GetOrganizationIDsByMemberIDsRow,error) {
713+
q.mutex.RLock()
714+
deferq.mutex.RUnlock()
715+
716+
getOrganizationIDsByMemberIDRows:=make([]database.GetOrganizationIDsByMemberIDsRow,0,len(ids))
717+
for_,userID:=rangeids {
718+
userOrganizationIDs:=make([]uuid.UUID,0)
719+
for_,membership:=rangeq.organizationMembers {
720+
ifmembership.UserID==userID {
721+
userOrganizationIDs=append(userOrganizationIDs,membership.OrganizationID)
722+
}
723+
}
724+
getOrganizationIDsByMemberIDRows=append(getOrganizationIDsByMemberIDRows, database.GetOrganizationIDsByMemberIDsRow{
725+
UserID:userID,
726+
OrganizationIDs:userOrganizationIDs,
727+
})
728+
}
729+
iflen(getOrganizationIDsByMemberIDRows)==0 {
730+
returnnil,sql.ErrNoRows
731+
}
732+
returngetOrganizationIDsByMemberIDRows,nil
733+
}
734+
712735
func (q*fakeQuerier)GetProvisionerDaemons(_ context.Context) ([]database.ProvisionerDaemon,error) {
713736
q.mutex.RLock()
714737
deferq.mutex.RUnlock()

‎coderd/database/querier.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/queries.sql.go

Lines changed: 39 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/queries/organizationmembers.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,13 @@ INSERT INTO
2020
)
2121
VALUES
2222
($1, $2, $3, $4, $5) RETURNING*;
23+
24+
-- name: GetOrganizationIDsByMemberIDs :many
25+
SELECT
26+
user_id, array_agg(organization_id) :: uuid [ ]AS"organization_IDs"
27+
FROM
28+
organization_members
29+
WHERE
30+
user_id= ANY(@ids :: uuid [ ])
31+
GROUP BY
32+
user_id;
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package userpassword_test
2+
3+
import (
4+
"crypto/sha256"
5+
"testing"
6+
7+
"github.com/coder/coder/cryptorand"
8+
"golang.org/x/crypto/bcrypt"
9+
"golang.org/x/crypto/pbkdf2"
10+
)
11+
12+
var (
13+
salt= []byte(must(cryptorand.String(16)))
14+
secret= []byte(must(cryptorand.String(24)))
15+
16+
resBcrypt []byte
17+
resPbkdf2 []byte
18+
)
19+
20+
funcBenchmarkBcryptMinCost(b*testing.B) {
21+
varr []byte
22+
b.ReportAllocs()
23+
24+
fori:=0;i<b.N;i++ {
25+
r,_=bcrypt.GenerateFromPassword(secret,bcrypt.MinCost)
26+
}
27+
28+
resBcrypt=r
29+
}
30+
31+
funcBenchmarkPbkdf2MinCost(b*testing.B) {
32+
varr []byte
33+
b.ReportAllocs()
34+
35+
fori:=0;i<b.N;i++ {
36+
r=pbkdf2.Key(secret,salt,1024,64,sha256.New)
37+
}
38+
39+
resPbkdf2=r
40+
}
41+
42+
funcBenchmarkBcryptDefaultCost(b*testing.B) {
43+
varr []byte
44+
b.ReportAllocs()
45+
46+
fori:=0;i<b.N;i++ {
47+
r,_=bcrypt.GenerateFromPassword(secret,bcrypt.DefaultCost)
48+
}
49+
50+
resBcrypt=r
51+
}
52+
53+
funcBenchmarkPbkdf2(b*testing.B) {
54+
varr []byte
55+
b.ReportAllocs()
56+
57+
fori:=0;i<b.N;i++ {
58+
r=pbkdf2.Key(secret,salt,65536,64,sha256.New)
59+
}
60+
61+
resPbkdf2=r
62+
}
63+
64+
funcmust(sstring,errerror)string {
65+
iferr!=nil {
66+
panic(err)
67+
}
68+
69+
returns
70+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp