Skip to content

Commit 949d353

Browse files
committed
Merge branch 'main' into taildefault
2 parents a922a88 + 57c7fcf commit 949d353

Some content is hidden

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

41 files changed

+748
-113
lines changed

cli/cliflag/cliflag.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,18 @@ func StringVarP(flagset *pflag.FlagSet, p *string, name string, shorthand string
6161
flagset.StringVarP(p, name, shorthand, v, fmtUsage(usage, env))
6262
}
6363

64+
func StringArray(flagset *pflag.FlagSet, name, shorthand, env string, def []string, usage string) {
65+
v, ok := os.LookupEnv(env)
66+
if !ok || v == "" {
67+
if v == "" {
68+
def = []string{}
69+
} else {
70+
def = strings.Split(v, ",")
71+
}
72+
}
73+
flagset.StringArrayP(name, shorthand, def, fmtUsage(usage, env))
74+
}
75+
6476
func StringArrayVarP(flagset *pflag.FlagSet, ptr *[]string, name string, shorthand string, env string, def []string, usage string) {
6577
val, ok := os.LookupEnv(env)
6678
if ok {

cli/login.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,10 @@ func login() *cobra.Command {
6666
serverURL.Scheme = "https"
6767
}
6868

69-
client := codersdk.New(serverURL)
69+
client, err := createUnauthenticatedClient(cmd, serverURL)
70+
if err != nil {
71+
return err
72+
}
7073

7174
// Try to check the version of the server prior to logging in.
7275
// It may be useful to warn the user if they are trying to login

cli/root.go

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"flag"
66
"fmt"
7+
"net/http"
78
"net/url"
89
"os"
910
"strings"
@@ -41,6 +42,7 @@ const (
4142
varAgentToken = "agent-token"
4243
varAgentURL = "agent-url"
4344
varGlobalConfig = "global-config"
45+
varHeader = "header"
4446
varNoOpen = "no-open"
4547
varNoVersionCheck = "no-version-warning"
4648
varNoFeatureWarning = "no-feature-warning"
@@ -174,6 +176,7 @@ func Root(subcommands []*cobra.Command) *cobra.Command {
174176
cliflag.String(cmd.PersistentFlags(), varAgentURL, "", "CODER_AGENT_URL", "", "Specify the URL for an agent to access your deployment.")
175177
_ = cmd.PersistentFlags().MarkHidden(varAgentURL)
176178
cliflag.String(cmd.PersistentFlags(), varGlobalConfig, "", "CODER_CONFIG_DIR", configdir.LocalConfig("coderv2"), "Specify the path to the global `coder` config directory.")
179+
cliflag.StringArray(cmd.PersistentFlags(), varHeader, "", "CODER_HEADER", []string{}, "HTTP headers added to all requests. Provide as \"Key=Value\"")
177180
cmd.PersistentFlags().Bool(varForceTty, false, "Force the `coder` command to run as if connected to a TTY.")
178181
_ = cmd.PersistentFlags().MarkHidden(varForceTty)
179182
cmd.PersistentFlags().Bool(varNoOpen, false, "Block automatically opening URLs in the browser.")
@@ -237,8 +240,32 @@ func CreateClient(cmd *cobra.Command) (*codersdk.Client, error) {
237240
return nil, err
238241
}
239242
}
243+
client, err := createUnauthenticatedClient(cmd, serverURL)
244+
if err != nil {
245+
return nil, err
246+
}
247+
client.SessionToken = token
248+
return client, nil
249+
}
250+
251+
func createUnauthenticatedClient(cmd *cobra.Command, serverURL *url.URL) (*codersdk.Client, error) {
240252
client := codersdk.New(serverURL)
241-
client.SessionToken = strings.TrimSpace(token)
253+
headers, err := cmd.Flags().GetStringArray(varHeader)
254+
if err != nil {
255+
return nil, err
256+
}
257+
transport := &headerTransport{
258+
transport: http.DefaultTransport,
259+
headers: map[string]string{},
260+
}
261+
for _, header := range headers {
262+
parts := strings.SplitN(header, "=", 2)
263+
if len(parts) < 2 {
264+
return nil, xerrors.Errorf("split header %q had less than two parts", header)
265+
}
266+
transport.headers[parts[0]] = parts[1]
267+
}
268+
client.HTTPClient.Transport = transport
242269
return client, nil
243270
}
244271

@@ -530,3 +557,15 @@ func checkWarnings(cmd *cobra.Command, client *codersdk.Client) error {
530557

531558
return nil
532559
}
560+
561+
type headerTransport struct {
562+
transport http.RoundTripper
563+
headers map[string]string
564+
}
565+
566+
func (h *headerTransport) RoundTrip(req *http.Request) (*http.Response, error) {
567+
for k, v := range h.headers {
568+
req.Header.Add(k, v)
569+
}
570+
return h.transport.RoundTrip(req)
571+
}

cli/root_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ package cli_test
22

33
import (
44
"bytes"
5+
"net/http"
6+
"net/http/httptest"
57
"testing"
68

79
"github.com/spf13/cobra"
10+
"github.com/stretchr/testify/assert"
811
"github.com/stretchr/testify/require"
912
"golang.org/x/xerrors"
1013

@@ -129,4 +132,25 @@ func TestRoot(t *testing.T) {
129132
require.Contains(t, output, buildinfo.Version(), "has version")
130133
require.Contains(t, output, buildinfo.ExternalURL(), "has url")
131134
})
135+
136+
t.Run("Header", func(t *testing.T) {
137+
t.Parallel()
138+
139+
done := make(chan struct{})
140+
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
141+
assert.Equal(t, "wow", r.Header.Get("X-Testing"))
142+
w.WriteHeader(http.StatusGone)
143+
select {
144+
case <-done:
145+
close(done)
146+
default:
147+
}
148+
}))
149+
defer srv.Close()
150+
buf := new(bytes.Buffer)
151+
cmd, _ := clitest.New(t, "--header", "X-Testing=wow", "login", srv.URL)
152+
cmd.SetOut(buf)
153+
// This won't succeed, because we're using the login cmd to assert requests.
154+
_ = cmd.Execute()
155+
})
132156
}

coderd/coderd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ func New(options *Options) *API {
352352
})
353353
r.Route("/{user}", func(r chi.Router) {
354354
r.Use(httpmw.ExtractUserParam(options.Database))
355+
r.Delete("/", api.deleteUser)
355356
r.Get("/", api.userByName)
356357
r.Put("/profile", api.putUserProfile)
357358
r.Route("/status", func(r chi.Router) {

coderd/database/databasefake/databasefake.go

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ func (q *fakeQuerier) GetUserByEmailOrUsername(_ context.Context, arg database.G
284284
defer q.mutex.RUnlock()
285285

286286
for _, user := range q.users {
287-
if user.Email == arg.Email || user.Username == arg.Username {
287+
if (user.Email == arg.Email || user.Username == arg.Username) && user.Deleted == arg.Deleted {
288288
return user, nil
289289
}
290290
}
@@ -307,7 +307,13 @@ func (q *fakeQuerier) GetUserCount(_ context.Context) (int64, error) {
307307
q.mutex.RLock()
308308
defer q.mutex.RUnlock()
309309

310-
return int64(len(q.users)), nil
310+
existing := int64(0)
311+
for _, u := range q.users {
312+
if !u.Deleted {
313+
existing++
314+
}
315+
}
316+
return existing, nil
311317
}
312318

313319
func (q *fakeQuerier) GetActiveUserCount(_ context.Context) (int64, error) {
@@ -316,13 +322,27 @@ func (q *fakeQuerier) GetActiveUserCount(_ context.Context) (int64, error) {
316322

317323
active := int64(0)
318324
for _, u := range q.users {
319-
if u.Status == database.UserStatusActive {
325+
if u.Status == database.UserStatusActive && !u.Deleted {
320326
active++
321327
}
322328
}
323329
return active, nil
324330
}
325331

332+
func (q *fakeQuerier) UpdateUserDeletedByID(_ context.Context, params database.UpdateUserDeletedByIDParams) error {
333+
q.mutex.Lock()
334+
defer q.mutex.Unlock()
335+
336+
for i, u := range q.users {
337+
if u.ID == params.ID {
338+
u.Deleted = params.Deleted
339+
q.users[i] = u
340+
return nil
341+
}
342+
}
343+
return sql.ErrNoRows
344+
}
345+
326346
func (q *fakeQuerier) GetUsers(_ context.Context, params database.GetUsersParams) ([]database.User, error) {
327347
q.mutex.RLock()
328348
defer q.mutex.RUnlock()
@@ -341,6 +361,16 @@ func (q *fakeQuerier) GetUsers(_ context.Context, params database.GetUsersParams
341361
return a.CreatedAt.Before(b.CreatedAt)
342362
})
343363

364+
if params.Deleted {
365+
tmp := make([]database.User, 0, len(users))
366+
for _, user := range users {
367+
if user.Deleted {
368+
tmp = append(tmp, user)
369+
}
370+
}
371+
users = tmp
372+
}
373+
344374
if params.AfterID != uuid.Nil {
345375
found := false
346376
for i, v := range users {
@@ -409,16 +439,19 @@ func (q *fakeQuerier) GetUsers(_ context.Context, params database.GetUsersParams
409439
return users, nil
410440
}
411441

412-
func (q *fakeQuerier) GetUsersByIDs(_ context.Context, ids []uuid.UUID) ([]database.User, error) {
442+
func (q *fakeQuerier) GetUsersByIDs(_ context.Context, params database.GetUsersByIDsParams) ([]database.User, error) {
413443
q.mutex.RLock()
414444
defer q.mutex.RUnlock()
415445

416446
users := make([]database.User, 0)
417447
for _, user := range q.users {
418-
for _, id := range ids {
448+
for _, id := range params.IDs {
419449
if user.ID.String() != id.String() {
420450
continue
421451
}
452+
if user.Deleted != params.Deleted {
453+
continue
454+
}
422455
users = append(users, user)
423456
}
424457
}
@@ -879,8 +912,8 @@ func (q *fakeQuerier) ParameterValues(_ context.Context, arg database.ParameterV
879912
}
880913
}
881914

882-
if len(arg.Ids) > 0 {
883-
if !slice.Contains(arg.Ids, parameterValue.ID) {
915+
if len(arg.IDs) > 0 {
916+
if !slice.Contains(arg.IDs, parameterValue.ID) {
884917
continue
885918
}
886919
}
@@ -961,9 +994,9 @@ func (q *fakeQuerier) GetTemplatesWithFilter(_ context.Context, arg database.Get
961994
continue
962995
}
963996

964-
if len(arg.Ids) > 0 {
997+
if len(arg.IDs) > 0 {
965998
match := false
966-
for _, id := range arg.Ids {
999+
for _, id := range arg.IDs {
9671000
if template.ID == id {
9681001
match = true
9691002
break

coderd/database/dump.sql

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ALTER TABLE users
2+
DROP COLUMN deleted;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
ALTER TABLE users
2+
ADD COLUMN deleted boolean DEFAULT false NOT NULL;
3+
4+
DROP INDEX idx_users_email;
5+
DROP INDEX idx_users_username;
6+
DROP INDEX users_username_lower_idx;
7+
CREATE UNIQUE INDEX idx_users_email ON users USING btree (email) WHERE deleted = false;
8+
CREATE UNIQUE INDEX idx_users_username ON users USING btree (username) WHERE deleted = false;
9+
CREATE UNIQUE INDEX users_username_lower_idx ON users USING btree (lower(username)) WHERE deleted = false;

coderd/database/models.go

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

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy