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

Commitc65996a

Browse files
feat: add user_secrets table (#19162)
Closescoder/internal#780## Summary of changes:- added `user_secrets` table- `user_secrets` table contains `env_name` and `file_path` fields whichare not used at the moment, but will be used in later PRs- `user_secrets` table doesn't contain `value_key_id`, I will add it ina separate migration in a dbcrypt PR- on one hand I don't want to add fields which are not used (becauseit's a risk smth may change in implementation later), on the other handI don't want to add too many migrations for user secrets table- added unique sql indexes- added sql queries for CRUD operations on user-secrets- introduced new `ResourceUserSecret` resource- basic unit-tests for CRUD ops and authorization behavior- Role updates: - owner: - remove `ResourceUserSecret` from site-wide perms - add `ResourceUserSecret` to user-wide perms - orgAdmin- remove `ResourceUserSecret` from org-wide perms; seems it's notstrictly required, because `ResourceUserSecret` is not tied toorganization in dbauthz wrappers? - memberRole- no need to change memberRole because it implicitly has access touser-secrets thanks to the `allPermsExcept` - is it enough changes to roles? Main questions:- [ ] We will have 2 migrations for user-secrets: - initial migration (in current PR) - adding `value_key_id` in dbcrypt PR - is this approach reasonable?- [ ] Are changes to roles's permissions are correct?- [ ] Are changes in roles_test.go are correct?---------Co-authored-by: Steven Masley <Emyrk@users.noreply.github.com>
1 parent34c46c0 commitc65996a

28 files changed

+913
-3
lines changed

‎coderd/apidoc/docs.go‎

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

‎coderd/database/dbauthz/dbauthz.go‎

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,6 +1387,14 @@ func (q *querier) CountUnreadInboxNotificationsByUserID(ctx context.Context, use
13871387
returnq.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+
iferr:=q.authorizeContext(ctx,policy.ActionCreate,obj);err!=nil {
1393+
return database.UserSecret{},err
1394+
}
1395+
returnq.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
returnq.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+
iferr!=nil {
1672+
returnerr
1673+
}
1674+
1675+
iferr:=q.authorizeContext(ctx,policy.ActionDelete,secret);err!=nil {
1676+
returnerr
1677+
}
1678+
returnq.db.DeleteUserSecret(ctx,id)
1679+
}
1680+
16601681
func (q*querier)DeleteWebpushSubscriptionByUserIDAndEndpoint(ctx context.Context,arg database.DeleteWebpushSubscriptionByUserIDAndEndpointParams)error {
16611682
iferr:=q.authorizeContext(ctx,policy.ActionDelete,rbac.ResourceWebpushSubscription.WithOwner(arg.UserID.String()));err!=nil {
16621683
returnerr
@@ -3075,6 +3096,28 @@ func (q *querier) GetUserNotificationPreferences(ctx context.Context, userID uui
30753096
returnq.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+
iferr!=nil {
3103+
return database.UserSecret{},err
3104+
}
3105+
3106+
iferr:=q.authorizeContext(ctx,policy.ActionRead,secret);err!=nil {
3107+
return database.UserSecret{},err
3108+
}
3109+
returnsecret,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+
iferr:=q.authorizeContext(ctx,policy.ActionRead,obj);err!=nil {
3115+
return database.UserSecret{},err
3116+
}
3117+
3118+
returnq.db.GetUserSecretByUserIDAndName(ctx,arg)
3119+
}
3120+
30783121
func (q*querier)GetUserStatusCounts(ctx context.Context,arg database.GetUserStatusCountsParams) ([]database.GetUserStatusCountsRow,error) {
30793122
iferr:=q.authorizeContext(ctx,policy.ActionRead,rbac.ResourceUser);err!=nil {
30803123
returnnil,err
@@ -4153,6 +4196,14 @@ func (q *querier) ListProvisionerKeysByOrganizationExcludeReserved(ctx context.C
41534196
returnfetchWithPostFilter(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+
iferr:=q.authorizeContext(ctx,policy.ActionRead,obj);err!=nil {
4202+
returnnil,err
4203+
}
4204+
returnq.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
iferr!=nil {
@@ -4866,6 +4917,19 @@ func (q *querier) UpdateUserRoles(ctx context.Context, arg database.UpdateUserRo
48664917
returnq.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+
iferr!=nil {
4924+
return database.UserSecret{},err
4925+
}
4926+
4927+
iferr:=q.authorizeContext(ctx,policy.ActionUpdate,secret);err!=nil {
4928+
return database.UserSecret{},err
4929+
}
4930+
returnq.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
returnq.db.GetUserByID(ctx,arg.ID)

‎coderd/database/dbauthz/dbauthz_test.go‎

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5883,3 +5883,64 @@ func (s *MethodTestSuite) TestAuthorizePrebuiltWorkspace() {
58835883
}).Asserts(w,policy.ActionUpdate,w.AsPrebuild(),policy.ActionUpdate)
58845884
}))
58855885
}
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
returnparameters
14231423
}
14241424

1425+
funcUserSecret(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+
returnuserSecret
1437+
}
1438+
14251439
funcClaimPrebuild(t testing.TB,db database.Store,newUserID uuid.UUID,newNamestring,presetID uuid.UUID) database.ClaimPrebuiltWorkspaceRow {
14261440
claimedWorkspace,err:=db.ClaimPrebuiltWorkspace(genCtx, database.ClaimPrebuiltWorkspaceParams{
14271441
NewUserID:newUserID,

‎coderd/database/dbmetrics/querymetrics.go‎

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp