Skip to content

Commit adbb025

Browse files
authored
feat: add user-level parameter autofill (#11731)
This PR solves #10478 by auto-filling previously used template values in create and update workspace flows. I decided against explicit user values in settings for these reasons: * Autofill is far easier to implement * Users benefit from autofill _by default_ — we don't need to teach them new concepts * If we decide that autofill creates more harm than good, we can remove it without breaking compatibility
1 parent aeb4112 commit adbb025

Some content is hidden

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

44 files changed

+861
-136
lines changed

coderd/apidoc/docs.go

+57
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

+53
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/coderd.go

+1
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,7 @@ func New(options *Options) *API {
821821
r.Post("/convert-login", api.postConvertLoginType)
822822
r.Delete("/", api.deleteUser)
823823
r.Get("/", api.userByName)
824+
r.Get("/autofill-parameters", api.userAutofillParameters)
824825
r.Get("/login-type", api.userLoginType)
825826
r.Put("/profile", api.putUserProfile)
826827
r.Route("/status", func(r chi.Router) {

coderd/database/dbauthz/dbauthz.go

+11
Original file line numberDiff line numberDiff line change
@@ -1768,6 +1768,17 @@ func (q *querier) GetUserLinksByUserID(ctx context.Context, userID uuid.UUID) ([
17681768
return q.db.GetUserLinksByUserID(ctx, userID)
17691769
}
17701770

1771+
func (q *querier) GetUserWorkspaceBuildParameters(ctx context.Context, params database.GetUserWorkspaceBuildParametersParams) ([]database.GetUserWorkspaceBuildParametersRow, error) {
1772+
u, err := q.db.GetUserByID(ctx, params.OwnerID)
1773+
if err != nil {
1774+
return nil, err
1775+
}
1776+
if err := q.authorizeContext(ctx, rbac.ActionRead, u.UserWorkspaceBuildParametersObject()); err != nil {
1777+
return nil, err
1778+
}
1779+
return q.db.GetUserWorkspaceBuildParameters(ctx, params)
1780+
}
1781+
17711782
func (q *querier) GetUsers(ctx context.Context, arg database.GetUsersParams) ([]database.GetUsersRow, error) {
17721783
// This does the filtering in SQL.
17731784
prep, err := prepareSQLFilter(ctx, q.auth, rbac.ActionRead, rbac.ResourceUser.Type)

coderd/database/dbauthz/dbauthz_test.go

+11
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,17 @@ func (s *MethodTestSuite) TestUser() {
10521052
UpdatedAt: u.UpdatedAt,
10531053
}).Asserts(u.UserDataRBACObject(), rbac.ActionUpdate).Returns(u)
10541054
}))
1055+
s.Run("GetUserWorkspaceBuildParameters", s.Subtest(func(db database.Store, check *expects) {
1056+
u := dbgen.User(s.T(), db, database.User{})
1057+
check.Args(
1058+
database.GetUserWorkspaceBuildParametersParams{
1059+
OwnerID: u.ID,
1060+
TemplateID: uuid.UUID{},
1061+
},
1062+
).Asserts(u.UserWorkspaceBuildParametersObject(), rbac.ActionRead).Returns(
1063+
[]database.GetUserWorkspaceBuildParametersRow{},
1064+
)
1065+
}))
10551066
s.Run("UpdateUserAppearanceSettings", s.Subtest(func(db database.Store, check *expects) {
10561067
u := dbgen.User(s.T(), db, database.User{})
10571068
check.Args(database.UpdateUserAppearanceSettingsParams{

coderd/database/dbmem/dbmem.go

+59
Original file line numberDiff line numberDiff line change
@@ -3797,6 +3797,65 @@ func (q *FakeQuerier) GetUserLinksByUserID(_ context.Context, userID uuid.UUID)
37973797
return uls, nil
37983798
}
37993799

3800+
func (q *FakeQuerier) GetUserWorkspaceBuildParameters(_ context.Context, params database.GetUserWorkspaceBuildParametersParams) ([]database.GetUserWorkspaceBuildParametersRow, error) {
3801+
q.mutex.RLock()
3802+
defer q.mutex.RUnlock()
3803+
3804+
userWorkspaceIDs := make(map[uuid.UUID]struct{})
3805+
for _, ws := range q.workspaces {
3806+
if ws.OwnerID != params.OwnerID {
3807+
continue
3808+
}
3809+
if ws.TemplateID != params.TemplateID {
3810+
continue
3811+
}
3812+
userWorkspaceIDs[ws.ID] = struct{}{}
3813+
}
3814+
3815+
userWorkspaceBuilds := make(map[uuid.UUID]struct{})
3816+
for _, wb := range q.workspaceBuilds {
3817+
if _, ok := userWorkspaceIDs[wb.WorkspaceID]; !ok {
3818+
continue
3819+
}
3820+
userWorkspaceBuilds[wb.ID] = struct{}{}
3821+
}
3822+
3823+
templateVersions := make(map[uuid.UUID]struct{})
3824+
for _, tv := range q.templateVersions {
3825+
if tv.TemplateID.UUID != params.TemplateID {
3826+
continue
3827+
}
3828+
templateVersions[tv.ID] = struct{}{}
3829+
}
3830+
3831+
tvps := make(map[string]struct{})
3832+
for _, tvp := range q.templateVersionParameters {
3833+
if _, ok := templateVersions[tvp.TemplateVersionID]; !ok {
3834+
continue
3835+
}
3836+
3837+
if _, ok := tvps[tvp.Name]; !ok && !tvp.Ephemeral {
3838+
tvps[tvp.Name] = struct{}{}
3839+
}
3840+
}
3841+
3842+
userWorkspaceBuildParameters := make(map[string]database.GetUserWorkspaceBuildParametersRow)
3843+
for _, wbp := range q.workspaceBuildParameters {
3844+
if _, ok := userWorkspaceBuilds[wbp.WorkspaceBuildID]; !ok {
3845+
continue
3846+
}
3847+
if _, ok := tvps[wbp.Name]; !ok {
3848+
continue
3849+
}
3850+
userWorkspaceBuildParameters[wbp.Name] = database.GetUserWorkspaceBuildParametersRow{
3851+
Name: wbp.Name,
3852+
Value: wbp.Value,
3853+
}
3854+
}
3855+
3856+
return maps.Values(userWorkspaceBuildParameters), nil
3857+
}
3858+
38003859
func (q *FakeQuerier) GetUsers(_ context.Context, params database.GetUsersParams) ([]database.GetUsersRow, error) {
38013860
if err := validateDatabaseType(params); err != nil {
38023861
return nil, err

coderd/database/dbmetrics/dbmetrics.go

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbmock/dbmock.go

+15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/modelmethods.go

+4
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,10 @@ func (u User) UserDataRBACObject() rbac.Object {
256256
return rbac.ResourceUserData.WithID(u.ID).WithOwner(u.ID.String())
257257
}
258258

259+
func (u User) UserWorkspaceBuildParametersObject() rbac.Object {
260+
return rbac.ResourceUserWorkspaceBuildParameters.WithID(u.ID).WithOwner(u.ID.String())
261+
}
262+
259263
func (u GetUsersRow) RBACObject() rbac.Object {
260264
return rbac.ResourceUserObject(u.ID)
261265
}

coderd/database/querier.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

+56
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)