Skip to content

Commit c49c60c

Browse files
authored
Merge branch 'main' into phorcys420/fix-template-api-docs
2 parents 856d4b5 + 155c7bb commit c49c60c

Some content is hidden

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

60 files changed

+2296
-404
lines changed

cli/server.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import (
5555

5656
"cdr.dev/slog"
5757
"cdr.dev/slog/sloggers/sloghuman"
58+
"github.com/coder/coder/v2/coderd/pproflabel"
5859
"github.com/coder/pretty"
5960
"github.com/coder/quartz"
6061
"github.com/coder/retry"
@@ -1459,14 +1460,14 @@ func newProvisionerDaemon(
14591460
tracer := coderAPI.TracerProvider.Tracer(tracing.TracerName)
14601461
terraformClient, terraformServer := drpcsdk.MemTransportPipe()
14611462
wg.Add(1)
1462-
go func() {
1463+
pproflabel.Go(ctx, pproflabel.Service(pproflabel.ServiceTerraformProvisioner), func(ctx context.Context) {
14631464
defer wg.Done()
14641465
<-ctx.Done()
14651466
_ = terraformClient.Close()
14661467
_ = terraformServer.Close()
1467-
}()
1468+
})
14681469
wg.Add(1)
1469-
go func() {
1470+
pproflabel.Go(ctx, pproflabel.Service(pproflabel.ServiceTerraformProvisioner), func(ctx context.Context) {
14701471
defer wg.Done()
14711472
defer cancel()
14721473

@@ -1485,7 +1486,7 @@ func newProvisionerDaemon(
14851486
default:
14861487
}
14871488
}
1488-
}()
1489+
})
14891490

14901491
connector[string(database.ProvisionerTypeTerraform)] = sdkproto.NewDRPCProvisionerClient(terraformClient)
14911492
default:

coderd/apidoc/docs.go

Lines changed: 2 additions & 0 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: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/autobuild/lifecycle_executor.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020

2121
"cdr.dev/slog"
2222
"github.com/coder/coder/v2/coderd/files"
23+
"github.com/coder/coder/v2/coderd/pproflabel"
2324

2425
"github.com/coder/coder/v2/coderd/audit"
2526
"github.com/coder/coder/v2/coderd/database"
@@ -107,10 +108,10 @@ func (e *Executor) WithStatsChannel(ch chan<- Stats) *Executor {
107108
// tick from its channel. It will stop when its context is Done, or when
108109
// its channel is closed.
109110
func (e *Executor) Run() {
110-
go func() {
111+
pproflabel.Go(e.ctx, pproflabel.Service(pproflabel.ServiceLifecycles), func(ctx context.Context) {
111112
for {
112113
select {
113-
case <-e.ctx.Done():
114+
case <-ctx.Done():
114115
return
115116
case t, ok := <-e.tick:
116117
if !ok {
@@ -120,15 +121,15 @@ func (e *Executor) Run() {
120121
e.metrics.autobuildExecutionDuration.Observe(stats.Elapsed.Seconds())
121122
if e.statsCh != nil {
122123
select {
123-
case <-e.ctx.Done():
124+
case <-ctx.Done():
124125
return
125126
case e.statsCh <- stats:
126127
}
127128
}
128-
e.log.Debug(e.ctx, "run stats", slog.F("elapsed", stats.Elapsed), slog.F("transitions", stats.Transitions))
129+
e.log.Debug(ctx, "run stats", slog.F("elapsed", stats.Elapsed), slog.F("transitions", stats.Transitions))
129130
}
130131
}
131-
}()
132+
})
132133
}
133134

134135
func (e *Executor) runOnce(t time.Time) Stats {

coderd/coderd.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ import (
1414
"net/url"
1515
"path/filepath"
1616
"regexp"
17+
"runtime/pprof"
1718
"strings"
1819
"sync"
1920
"sync/atomic"
2021
"time"
2122

2223
"github.com/coder/coder/v2/coderd/oauth2provider"
24+
"github.com/coder/coder/v2/coderd/pproflabel"
2325
"github.com/coder/coder/v2/coderd/prebuilds"
2426
"github.com/coder/coder/v2/coderd/wsbuilder"
2527

@@ -852,6 +854,7 @@ func New(options *Options) *API {
852854

853855
r.Use(
854856
httpmw.Recover(api.Logger),
857+
httpmw.WithProfilingLabels,
855858
tracing.StatusWriterMiddleware,
856859
tracing.Middleware(api.TracerProvider),
857860
httpmw.AttachRequestID,
@@ -1339,7 +1342,13 @@ func New(options *Options) *API {
13391342
).Get("/connection", api.workspaceAgentConnectionGeneric)
13401343
r.Route("/me", func(r chi.Router) {
13411344
r.Use(workspaceAgentInfo)
1342-
r.Get("/rpc", api.workspaceAgentRPC)
1345+
r.Group(func(r chi.Router) {
1346+
r.Use(
1347+
// Override the request_type for agent rpc traffic.
1348+
httpmw.WithStaticProfilingLabels(pprof.Labels(pproflabel.RequestTypeTag, "agent-rpc")),
1349+
)
1350+
r.Get("/rpc", api.workspaceAgentRPC)
1351+
})
13431352
r.Patch("/logs", api.patchWorkspaceAgentLogs)
13441353
r.Patch("/app-status", api.patchWorkspaceAgentAppStatus)
13451354
// Deprecated: Required to support legacy agents
@@ -1415,7 +1424,8 @@ func New(options *Options) *API {
14151424
r.Get("/timings", api.workspaceTimings)
14161425
r.Route("/acl", func(r chi.Router) {
14171426
r.Use(
1418-
httpmw.RequireExperiment(api.Experiments, codersdk.ExperimentWorkspaceSharing))
1427+
httpmw.RequireExperiment(api.Experiments, codersdk.ExperimentWorkspaceSharing),
1428+
)
14191429

14201430
r.Patch("/", api.patchWorkspaceACL)
14211431
})

coderd/database/dbauthz/dbauthz.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,6 +1387,14 @@ func (q *querier) CountUnreadInboxNotificationsByUserID(ctx context.Context, use
13871387
return q.db.CountUnreadInboxNotificationsByUserID(ctx, userID)
13881388
}
13891389

1390+
func (q *querier) CreateUserSecret(ctx context.Context, arg database.CreateUserSecretParams) (database.UserSecret, error) {
1391+
obj := rbac.ResourceUserSecret.WithOwner(arg.UserID.String())
1392+
if err := q.authorizeContext(ctx, policy.ActionCreate, obj); err != nil {
1393+
return database.UserSecret{}, err
1394+
}
1395+
return q.db.CreateUserSecret(ctx, arg)
1396+
}
1397+
13901398
// TODO: Handle org scoped lookups
13911399
func (q *querier) CustomRoles(ctx context.Context, arg database.CustomRolesParams) ([]database.CustomRole, error) {
13921400
roleObject := rbac.ResourceAssignRole
@@ -1657,6 +1665,19 @@ func (q *querier) DeleteTailnetTunnel(ctx context.Context, arg database.DeleteTa
16571665
return q.db.DeleteTailnetTunnel(ctx, arg)
16581666
}
16591667

1668+
func (q *querier) DeleteUserSecret(ctx context.Context, id uuid.UUID) error {
1669+
// First get the secret to check ownership
1670+
secret, err := q.GetUserSecret(ctx, id)
1671+
if err != nil {
1672+
return err
1673+
}
1674+
1675+
if err := q.authorizeContext(ctx, policy.ActionDelete, secret); err != nil {
1676+
return err
1677+
}
1678+
return q.db.DeleteUserSecret(ctx, id)
1679+
}
1680+
16601681
func (q *querier) DeleteWebpushSubscriptionByUserIDAndEndpoint(ctx context.Context, arg database.DeleteWebpushSubscriptionByUserIDAndEndpointParams) error {
16611682
if err := q.authorizeContext(ctx, policy.ActionDelete, rbac.ResourceWebpushSubscription.WithOwner(arg.UserID.String())); err != nil {
16621683
return err
@@ -3075,6 +3096,28 @@ func (q *querier) GetUserNotificationPreferences(ctx context.Context, userID uui
30753096
return q.db.GetUserNotificationPreferences(ctx, userID)
30763097
}
30773098

3099+
func (q *querier) GetUserSecret(ctx context.Context, id uuid.UUID) (database.UserSecret, error) {
3100+
// First get the secret to check ownership
3101+
secret, err := q.db.GetUserSecret(ctx, id)
3102+
if err != nil {
3103+
return database.UserSecret{}, err
3104+
}
3105+
3106+
if err := q.authorizeContext(ctx, policy.ActionRead, secret); err != nil {
3107+
return database.UserSecret{}, err
3108+
}
3109+
return secret, nil
3110+
}
3111+
3112+
func (q *querier) GetUserSecretByUserIDAndName(ctx context.Context, arg database.GetUserSecretByUserIDAndNameParams) (database.UserSecret, error) {
3113+
obj := rbac.ResourceUserSecret.WithOwner(arg.UserID.String())
3114+
if err := q.authorizeContext(ctx, policy.ActionRead, obj); err != nil {
3115+
return database.UserSecret{}, err
3116+
}
3117+
3118+
return q.db.GetUserSecretByUserIDAndName(ctx, arg)
3119+
}
3120+
30783121
func (q *querier) GetUserStatusCounts(ctx context.Context, arg database.GetUserStatusCountsParams) ([]database.GetUserStatusCountsRow, error) {
30793122
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceUser); err != nil {
30803123
return nil, err
@@ -4153,6 +4196,14 @@ func (q *querier) ListProvisionerKeysByOrganizationExcludeReserved(ctx context.C
41534196
return fetchWithPostFilter(q.auth, policy.ActionRead, q.db.ListProvisionerKeysByOrganizationExcludeReserved)(ctx, organizationID)
41544197
}
41554198

4199+
func (q *querier) ListUserSecrets(ctx context.Context, userID uuid.UUID) ([]database.UserSecret, error) {
4200+
obj := rbac.ResourceUserSecret.WithOwner(userID.String())
4201+
if err := q.authorizeContext(ctx, policy.ActionRead, obj); err != nil {
4202+
return nil, err
4203+
}
4204+
return q.db.ListUserSecrets(ctx, userID)
4205+
}
4206+
41564207
func (q *querier) ListWorkspaceAgentPortShares(ctx context.Context, workspaceID uuid.UUID) ([]database.WorkspaceAgentPortShare, error) {
41574208
workspace, err := q.db.GetWorkspaceByID(ctx, workspaceID)
41584209
if err != nil {
@@ -4866,6 +4917,19 @@ func (q *querier) UpdateUserRoles(ctx context.Context, arg database.UpdateUserRo
48664917
return q.db.UpdateUserRoles(ctx, arg)
48674918
}
48684919

4920+
func (q *querier) UpdateUserSecret(ctx context.Context, arg database.UpdateUserSecretParams) (database.UserSecret, error) {
4921+
// First get the secret to check ownership
4922+
secret, err := q.db.GetUserSecret(ctx, arg.ID)
4923+
if err != nil {
4924+
return database.UserSecret{}, err
4925+
}
4926+
4927+
if err := q.authorizeContext(ctx, policy.ActionUpdate, secret); err != nil {
4928+
return database.UserSecret{}, err
4929+
}
4930+
return q.db.UpdateUserSecret(ctx, arg)
4931+
}
4932+
48694933
func (q *querier) UpdateUserStatus(ctx context.Context, arg database.UpdateUserStatusParams) (database.User, error) {
48704934
fetch := func(ctx context.Context, arg database.UpdateUserStatusParams) (database.User, error) {
48714935
return q.db.GetUserByID(ctx, arg.ID)
@@ -5376,6 +5440,26 @@ func (q *querier) UpsertWorkspaceAppAuditSession(ctx context.Context, arg databa
53765440
return q.db.UpsertWorkspaceAppAuditSession(ctx, arg)
53775441
}
53785442

5443+
func (q *querier) ValidateGroupIDs(ctx context.Context, groupIDs []uuid.UUID) (database.ValidateGroupIDsRow, error) {
5444+
// This check is probably overly restrictive, but the "correct" check isn't
5445+
// necessarily obvious. It's only used as a verification check for ACLs right
5446+
// now, which are performed as system.
5447+
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceSystem); err != nil {
5448+
return database.ValidateGroupIDsRow{}, err
5449+
}
5450+
return q.db.ValidateGroupIDs(ctx, groupIDs)
5451+
}
5452+
5453+
func (q *querier) ValidateUserIDs(ctx context.Context, userIDs []uuid.UUID) (database.ValidateUserIDsRow, error) {
5454+
// This check is probably overly restrictive, but the "correct" check isn't
5455+
// necessarily obvious. It's only used as a verification check for ACLs right
5456+
// now, which are performed as system.
5457+
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceSystem); err != nil {
5458+
return database.ValidateUserIDsRow{}, err
5459+
}
5460+
return q.db.ValidateUserIDs(ctx, userIDs)
5461+
}
5462+
53795463
func (q *querier) GetAuthorizedTemplates(ctx context.Context, arg database.GetTemplatesWithFilterParams, _ rbac.PreparedAuthorized) ([]database.Template, error) {
53805464
// TODO Delete this function, all GetTemplates should be authorized. For now just call getTemplates on the authz querier.
53815465
return q.GetTemplatesWithFilter(ctx, arg)

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,11 @@ func (s *MethodTestSuite) TestGroup() {
623623
ID: g.ID,
624624
}).Asserts(g, policy.ActionUpdate)
625625
}))
626+
s.Run("ValidateGroupIDs", s.Subtest(func(db database.Store, check *expects) {
627+
o := dbgen.Organization(s.T(), db, database.Organization{})
628+
g := dbgen.Group(s.T(), db, database.Group{OrganizationID: o.ID})
629+
check.Args([]uuid.UUID{g.ID}).Asserts(rbac.ResourceSystem, policy.ActionRead)
630+
}))
626631
}
627632

628633
func (s *MethodTestSuite) TestProvisionerJob() {
@@ -2077,6 +2082,10 @@ func (s *MethodTestSuite) TestUser() {
20772082
Interval: int32((time.Hour * 24).Seconds()),
20782083
}).Asserts(rbac.ResourceUser, policy.ActionRead)
20792084
}))
2085+
s.Run("ValidateUserIDs", s.Subtest(func(db database.Store, check *expects) {
2086+
u := dbgen.User(s.T(), db, database.User{})
2087+
check.Args([]uuid.UUID{u.ID}).Asserts(rbac.ResourceSystem, policy.ActionRead)
2088+
}))
20802089
}
20812090

20822091
func (s *MethodTestSuite) TestWorkspace() {
@@ -5874,3 +5883,64 @@ func (s *MethodTestSuite) TestAuthorizePrebuiltWorkspace() {
58745883
}).Asserts(w, policy.ActionUpdate, w.AsPrebuild(), policy.ActionUpdate)
58755884
}))
58765885
}
5886+
5887+
func (s *MethodTestSuite) TestUserSecrets() {
5888+
s.Run("GetUserSecretByUserIDAndName", s.Subtest(func(db database.Store, check *expects) {
5889+
user := dbgen.User(s.T(), db, database.User{})
5890+
userSecret := dbgen.UserSecret(s.T(), db, database.UserSecret{
5891+
UserID: user.ID,
5892+
})
5893+
arg := database.GetUserSecretByUserIDAndNameParams{
5894+
UserID: user.ID,
5895+
Name: userSecret.Name,
5896+
}
5897+
check.Args(arg).
5898+
Asserts(rbac.ResourceUserSecret.WithOwner(arg.UserID.String()), policy.ActionRead).
5899+
Returns(userSecret)
5900+
}))
5901+
s.Run("GetUserSecret", s.Subtest(func(db database.Store, check *expects) {
5902+
user := dbgen.User(s.T(), db, database.User{})
5903+
userSecret := dbgen.UserSecret(s.T(), db, database.UserSecret{
5904+
UserID: user.ID,
5905+
})
5906+
check.Args(userSecret.ID).
5907+
Asserts(userSecret, policy.ActionRead).
5908+
Returns(userSecret)
5909+
}))
5910+
s.Run("ListUserSecrets", s.Subtest(func(db database.Store, check *expects) {
5911+
user := dbgen.User(s.T(), db, database.User{})
5912+
userSecret := dbgen.UserSecret(s.T(), db, database.UserSecret{
5913+
UserID: user.ID,
5914+
})
5915+
check.Args(user.ID).
5916+
Asserts(rbac.ResourceUserSecret.WithOwner(user.ID.String()), policy.ActionRead).
5917+
Returns([]database.UserSecret{userSecret})
5918+
}))
5919+
s.Run("CreateUserSecret", s.Subtest(func(db database.Store, check *expects) {
5920+
user := dbgen.User(s.T(), db, database.User{})
5921+
arg := database.CreateUserSecretParams{
5922+
UserID: user.ID,
5923+
}
5924+
check.Args(arg).
5925+
Asserts(rbac.ResourceUserSecret.WithOwner(arg.UserID.String()), policy.ActionCreate)
5926+
}))
5927+
s.Run("UpdateUserSecret", s.Subtest(func(db database.Store, check *expects) {
5928+
user := dbgen.User(s.T(), db, database.User{})
5929+
userSecret := dbgen.UserSecret(s.T(), db, database.UserSecret{
5930+
UserID: user.ID,
5931+
})
5932+
arg := database.UpdateUserSecretParams{
5933+
ID: userSecret.ID,
5934+
}
5935+
check.Args(arg).
5936+
Asserts(userSecret, policy.ActionUpdate)
5937+
}))
5938+
s.Run("DeleteUserSecret", s.Subtest(func(db database.Store, check *expects) {
5939+
user := dbgen.User(s.T(), db, database.User{})
5940+
userSecret := dbgen.UserSecret(s.T(), db, database.UserSecret{
5941+
UserID: user.ID,
5942+
})
5943+
check.Args(userSecret.ID).
5944+
Asserts(userSecret, policy.ActionRead, userSecret, policy.ActionDelete)
5945+
}))
5946+
}

coderd/database/dbgen/dbgen.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,6 +1422,20 @@ func PresetParameter(t testing.TB, db database.Store, seed database.InsertPreset
14221422
return parameters
14231423
}
14241424

1425+
func UserSecret(t testing.TB, db database.Store, seed database.UserSecret) database.UserSecret {
1426+
userSecret, err := db.CreateUserSecret(genCtx, database.CreateUserSecretParams{
1427+
ID: takeFirst(seed.ID, uuid.New()),
1428+
UserID: takeFirst(seed.UserID, uuid.New()),
1429+
Name: takeFirst(seed.Name, "secret-name"),
1430+
Description: takeFirst(seed.Description, "secret description"),
1431+
Value: takeFirst(seed.Value, "secret value"),
1432+
EnvName: takeFirst(seed.EnvName, "SECRET_ENV_NAME"),
1433+
FilePath: takeFirst(seed.FilePath, "~/secret/file/path"),
1434+
})
1435+
require.NoError(t, err, "failed to insert user secret")
1436+
return userSecret
1437+
}
1438+
14251439
func ClaimPrebuild(t testing.TB, db database.Store, newUserID uuid.UUID, newName string, presetID uuid.UUID) database.ClaimPrebuiltWorkspaceRow {
14261440
claimedWorkspace, err := db.ClaimPrebuiltWorkspace(genCtx, database.ClaimPrebuiltWorkspaceParams{
14271441
NewUserID: newUserID,

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