Skip to content

Commit 122387f

Browse files
feat: add list-user-secrets db query
1 parent b5c904a commit 122387f

File tree

8 files changed

+127
-40
lines changed

8 files changed

+127
-40
lines changed

coderd/database/dbauthz/dbauthz.go

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -590,9 +590,9 @@ func As(ctx context.Context, actor rbac.Subject) context.Context {
590590
// running the insertFunc. The insertFunc is expected to return the object that
591591
// was inserted.
592592
func insert[
593-
ObjectType any,
594-
ArgumentType any,
595-
Insert func(ctx context.Context, arg ArgumentType) (ObjectType, error),
593+
ObjectType any,
594+
ArgumentType any,
595+
Insert func(ctx context.Context, arg ArgumentType) (ObjectType, error),
596596
](
597597
logger slog.Logger,
598598
authorizer rbac.Authorizer,
@@ -603,9 +603,9 @@ Insert func(ctx context.Context, arg ArgumentType) (ObjectType, error),
603603
}
604604

605605
func insertWithAction[
606-
ObjectType any,
607-
ArgumentType any,
608-
Insert func(ctx context.Context, arg ArgumentType) (ObjectType, error),
606+
ObjectType any,
607+
ArgumentType any,
608+
Insert func(ctx context.Context, arg ArgumentType) (ObjectType, error),
609609
](
610610
logger slog.Logger,
611611
authorizer rbac.Authorizer,
@@ -632,10 +632,10 @@ Insert func(ctx context.Context, arg ArgumentType) (ObjectType, error),
632632
}
633633

634634
func deleteQ[
635-
ObjectType rbac.Objecter,
636-
ArgumentType any,
637-
Fetch func(ctx context.Context, arg ArgumentType) (ObjectType, error),
638-
Delete func(ctx context.Context, arg ArgumentType) error,
635+
ObjectType rbac.Objecter,
636+
ArgumentType any,
637+
Fetch func(ctx context.Context, arg ArgumentType) (ObjectType, error),
638+
Delete func(ctx context.Context, arg ArgumentType) error,
639639
](
640640
logger slog.Logger,
641641
authorizer rbac.Authorizer,
@@ -647,10 +647,10 @@ Delete func(ctx context.Context, arg ArgumentType) error,
647647
}
648648

649649
func updateWithReturn[
650-
ObjectType rbac.Objecter,
651-
ArgumentType any,
652-
Fetch func(ctx context.Context, arg ArgumentType) (ObjectType, error),
653-
UpdateQuery func(ctx context.Context, arg ArgumentType) (ObjectType, error),
650+
ObjectType rbac.Objecter,
651+
ArgumentType any,
652+
Fetch func(ctx context.Context, arg ArgumentType) (ObjectType, error),
653+
UpdateQuery func(ctx context.Context, arg ArgumentType) (ObjectType, error),
654654
](
655655
logger slog.Logger,
656656
authorizer rbac.Authorizer,
@@ -661,10 +661,10 @@ UpdateQuery func(ctx context.Context, arg ArgumentType) (ObjectType, error),
661661
}
662662

663663
func update[
664-
ObjectType rbac.Objecter,
665-
ArgumentType any,
666-
Fetch func(ctx context.Context, arg ArgumentType) (ObjectType, error),
667-
Exec func(ctx context.Context, arg ArgumentType) error,
664+
ObjectType rbac.Objecter,
665+
ArgumentType any,
666+
Fetch func(ctx context.Context, arg ArgumentType) (ObjectType, error),
667+
Exec func(ctx context.Context, arg ArgumentType) error,
668668
](
669669
logger slog.Logger,
670670
authorizer rbac.Authorizer,
@@ -682,9 +682,9 @@ Exec func(ctx context.Context, arg ArgumentType) error,
682682
// user cannot read the resource. This is because the resource details are
683683
// required to run a proper authorization check.
684684
func fetchWithAction[
685-
ArgumentType any,
686-
ObjectType rbac.Objecter,
687-
DatabaseFunc func(ctx context.Context, arg ArgumentType) (ObjectType, error),
685+
ArgumentType any,
686+
ObjectType rbac.Objecter,
687+
DatabaseFunc func(ctx context.Context, arg ArgumentType) (ObjectType, error),
688688
](
689689
logger slog.Logger,
690690
authorizer rbac.Authorizer,
@@ -715,9 +715,9 @@ DatabaseFunc func(ctx context.Context, arg ArgumentType) (ObjectType, error),
715715
}
716716

717717
func fetch[
718-
ArgumentType any,
719-
ObjectType rbac.Objecter,
720-
DatabaseFunc func(ctx context.Context, arg ArgumentType) (ObjectType, error),
718+
ArgumentType any,
719+
ObjectType rbac.Objecter,
720+
DatabaseFunc func(ctx context.Context, arg ArgumentType) (ObjectType, error),
721721
](
722722
logger slog.Logger,
723723
authorizer rbac.Authorizer,
@@ -730,10 +730,10 @@ DatabaseFunc func(ctx context.Context, arg ArgumentType) (ObjectType, error),
730730
// from SQL 'exec' functions which only return an error.
731731
// See fetchAndQuery for more information.
732732
func fetchAndExec[
733-
ObjectType rbac.Objecter,
734-
ArgumentType any,
735-
Fetch func(ctx context.Context, arg ArgumentType) (ObjectType, error),
736-
Exec func(ctx context.Context, arg ArgumentType) error,
733+
ObjectType rbac.Objecter,
734+
ArgumentType any,
735+
Fetch func(ctx context.Context, arg ArgumentType) (ObjectType, error),
736+
Exec func(ctx context.Context, arg ArgumentType) error,
737737
](
738738
logger slog.Logger,
739739
authorizer rbac.Authorizer,
@@ -756,10 +756,10 @@ Exec func(ctx context.Context, arg ArgumentType) error,
756756
// **before** the query runs. The returns from the fetch are only used to
757757
// assert rbac. The final return of this function comes from the Query function.
758758
func fetchAndQuery[
759-
ObjectType rbac.Objecter,
760-
ArgumentType any,
761-
Fetch func(ctx context.Context, arg ArgumentType) (ObjectType, error),
762-
Query func(ctx context.Context, arg ArgumentType) (ObjectType, error),
759+
ObjectType rbac.Objecter,
760+
ArgumentType any,
761+
Fetch func(ctx context.Context, arg ArgumentType) (ObjectType, error),
762+
Query func(ctx context.Context, arg ArgumentType) (ObjectType, error),
763763
](
764764
logger slog.Logger,
765765
authorizer rbac.Authorizer,
@@ -793,9 +793,9 @@ Query func(ctx context.Context, arg ArgumentType) (ObjectType, error),
793793
// fetchWithPostFilter is like fetch, but works with lists of objects.
794794
// SQL filters are much more optimal.
795795
func fetchWithPostFilter[
796-
ArgumentType any,
797-
ObjectType rbac.Objecter,
798-
DatabaseFunc func(ctx context.Context, arg ArgumentType) ([]ObjectType, error),
796+
ArgumentType any,
797+
ObjectType rbac.Objecter,
798+
DatabaseFunc func(ctx context.Context, arg ArgumentType) ([]ObjectType, error),
799799
](
800800
authorizer rbac.Authorizer,
801801
action policy.Action,
@@ -4110,6 +4110,15 @@ func (q *querier) ListProvisionerKeysByOrganizationExcludeReserved(ctx context.C
41104110
return fetchWithPostFilter(q.auth, policy.ActionRead, q.db.ListProvisionerKeysByOrganizationExcludeReserved)(ctx, organizationID)
41114111
}
41124112

4113+
func (q *querier) ListUserSecrets(ctx context.Context, userID uuid.UUID) ([]database.UserSecret, error) {
4114+
obj := rbac.ResourceUserSecret.WithOwner(userID.String())
4115+
if err := q.authorizeContext(ctx, policy.ActionRead, obj); err != nil {
4116+
return nil, err
4117+
}
4118+
4119+
return q.db.ListUserSecrets(ctx, userID)
4120+
}
4121+
41134122
func (q *querier) ListWorkspaceAgentPortShares(ctx context.Context, workspaceID uuid.UUID) ([]database.WorkspaceAgentPortShare, error) {
41144123
workspace, err := q.db.GetWorkspaceByID(ctx, workspaceID)
41154124
if err != nil {

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,7 +1845,7 @@ func (s *MethodTestSuite) TestUser() {
18451845
check.Args(database.DeleteCustomRoleParams{
18461846
Name: customRole.Name,
18471847
}).Asserts(
1848-
// fails immediately, missing organization id
1848+
// fails immediately, missing organization id
18491849
).Errors(dbauthz.NotAuthorizedError{Err: xerrors.New("custom roles must belong to an organization")})
18501850
}))
18511851
s.Run("Blank/UpdateCustomRole", s.Subtest(func(db database.Store, check *expects) {
@@ -1876,7 +1876,7 @@ func (s *MethodTestSuite) TestUser() {
18761876
codersdk.ResourceWorkspace: {codersdk.ActionRead},
18771877
}), convertSDKPerm),
18781878
}).Asserts(
1879-
// fails immediately, missing organization id
1879+
// fails immediately, missing organization id
18801880
).Errors(dbauthz.NotAuthorizedError{Err: xerrors.New("custom roles must belong to an organization")})
18811881
}))
18821882
s.Run("OrgPermissions/UpdateCustomRole", s.Subtest(func(db database.Store, check *expects) {
@@ -1929,7 +1929,7 @@ func (s *MethodTestSuite) TestUser() {
19291929
codersdk.ResourceWorkspace: {codersdk.ActionRead},
19301930
}), convertSDKPerm),
19311931
}).Asserts(
1932-
// fails immediately, missing organization id
1932+
// fails immediately, missing organization id
19331933
).Errors(dbauthz.NotAuthorizedError{Err: xerrors.New("custom roles must belong to an organization")})
19341934
}))
19351935
s.Run("OrgPermissions/InsertCustomRole", s.Subtest(func(db database.Store, check *expects) {
@@ -4262,13 +4262,13 @@ func (s *MethodTestSuite) TestSystemFunctions() {
42624262
StorageMethod: database.ProvisionerStorageMethodFile,
42634263
Type: database.ProvisionerJobTypeWorkspaceBuild,
42644264
Input: json.RawMessage("{}"),
4265-
}).Asserts( /* rbac.ResourceProvisionerJobs, policy.ActionCreate */ )
4265+
}).Asserts( /* rbac.ResourceProvisionerJobs, policy.ActionCreate */)
42664266
}))
42674267
s.Run("InsertProvisionerJobLogs", s.Subtest(func(db database.Store, check *expects) {
42684268
j := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{})
42694269
check.Args(database.InsertProvisionerJobLogsParams{
42704270
JobID: j.ID,
4271-
}).Asserts( /* rbac.ResourceProvisionerJobs, policy.ActionUpdate */ )
4271+
}).Asserts( /* rbac.ResourceProvisionerJobs, policy.ActionUpdate */)
42724272
}))
42734273
s.Run("InsertProvisionerJobTimings", s.Subtest(func(db database.Store, check *expects) {
42744274
j := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{})
@@ -5794,4 +5794,14 @@ func (s *MethodTestSuite) TestUserSecrets() {
57945794
ErrorsWithInMemDB(dbmem.ErrUnimplemented).
57955795
Returns(userSecret)
57965796
}))
5797+
s.Run("ListUserSecrets", s.Subtest(func(db database.Store, check *expects) {
5798+
user := dbgen.User(s.T(), db, database.User{})
5799+
userSecret := dbgen.UserSecret(s.T(), db, database.InsertUserSecretParams{
5800+
UserID: user.ID,
5801+
})
5802+
check.Args(user.ID).
5803+
Asserts(rbac.ResourceUserSecret.WithOwner(user.ID.String()), policy.ActionRead).
5804+
ErrorsWithInMemDB(dbmem.ErrUnimplemented).
5805+
Returns([]database.UserSecret{userSecret})
5806+
}))
57975807
}

coderd/database/dbmem/dbmem.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10285,6 +10285,10 @@ func (q *FakeQuerier) ListProvisionerKeysByOrganizationExcludeReserved(_ context
1028510285
return keys, nil
1028610286
}
1028710287

10288+
func (q *FakeQuerier) ListUserSecrets(ctx context.Context, userID uuid.UUID) ([]database.UserSecret, error) {
10289+
panic("not implemented")
10290+
}
10291+
1028810292
func (q *FakeQuerier) ListWorkspaceAgentPortShares(_ context.Context, workspaceID uuid.UUID) ([]database.WorkspaceAgentPortShare, error) {
1028910293
q.mutex.Lock()
1029010294
defer q.mutex.Unlock()

coderd/database/dbmetrics/querymetrics.go

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

coderd/database/dbmock/dbmock.go

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

coderd/database/querier.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.

coderd/database/queries.sql.go

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

coderd/database/queries/user_secrets.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
SELECT * FROM user_secrets
1111
WHERE user_id = @user_id AND name = @name;
1212

13+
-- name: ListUserSecrets :many
14+
SELECT * FROM user_secrets
15+
WHERE user_id = @user_id;
16+
1317
-- name: InsertUserSecret :one
1418
INSERT INTO user_secrets (
1519
id,

0 commit comments

Comments
 (0)