fix(audit): ensure template creation errors are audited (#7315)

This commit is contained in:
Colin Adler 2023-04-27 18:55:34 -05:00 committed by GitHub
parent 77d9937dc4
commit 59efa4a528
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 18 deletions

View File

@ -21,6 +21,7 @@ import (
"github.com/coder/coder/coderd/rbac"
"github.com/coder/coder/coderd/schedule"
"github.com/coder/coder/coderd/telemetry"
"github.com/coder/coder/coderd/util/ptr"
"github.com/coder/coder/codersdk"
"github.com/coder/coder/examples"
)
@ -149,6 +150,19 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
if !httpapi.Read(ctx, rw, r, &createTemplate) {
return
}
// Make a temporary struct to represent the template. This is used for
// auditing if any of the following checks fail. It will be overwritten when
// the template is inserted into the db.
templateAudit.New = database.Template{
OrganizationID: organization.ID,
Name: createTemplate.Name,
Description: createTemplate.Description,
CreatedBy: apiKey.UserID,
Icon: createTemplate.Icon,
DisplayName: createTemplate.DisplayName,
}
_, err := api.Database.GetTemplateByOrganizationAndName(ctx, database.GetTemplateByOrganizationAndNameParams{
OrganizationID: organization.ID,
Name: createTemplate.Name,
@ -170,6 +184,7 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
})
return
}
templateVersion, err := api.Database.GetTemplateVersionByID(ctx, createTemplate.VersionID)
if errors.Is(err, sql.ErrNoRows) {
httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{
@ -228,22 +243,14 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
}
var (
allowUserCancelWorkspaceJobs bool
allowUserAutostart = true
allowUserAutostop = true
)
if createTemplate.AllowUserCancelWorkspaceJobs != nil {
allowUserCancelWorkspaceJobs = *createTemplate.AllowUserCancelWorkspaceJobs
}
if createTemplate.AllowUserAutostart != nil {
allowUserAutostart = *createTemplate.AllowUserAutostart
}
if createTemplate.AllowUserAutostop != nil {
allowUserAutostop = *createTemplate.AllowUserAutostop
}
dbTemplate database.Template
template codersdk.Template
allowUserCancelWorkspaceJobs = ptr.NilToDefault(createTemplate.AllowUserCancelWorkspaceJobs, false)
allowUserAutostart = ptr.NilToDefault(createTemplate.AllowUserAutostart, true)
allowUserAutostop = ptr.NilToDefault(createTemplate.AllowUserAutostop, true)
)
var dbTemplate database.Template
var template codersdk.Template
err = api.Database.InTx(func(tx database.Store) error {
now := database.Now()
dbTemplate, err = tx.InsertTemplate(ctx, database.InsertTemplateParams{

View File

@ -17,10 +17,19 @@ func NilOrEmpty(s *string) bool {
return s == nil || *s == ""
}
// NilToEmpty coalesces a nil str to the empty string.
func NilToEmpty(s *string) string {
// NilToEmpty coalesces a nil value to the empty value.
func NilToEmpty[T any](s *T) T {
var def T
if s == nil {
return ""
return def
}
return *s
}
// NilToDefault coalesces a nil value to the provided default value.
func NilToDefault[T any](s *T, def T) T {
if s == nil {
return def
}
return *s
}

View File

@ -52,6 +52,28 @@ func Test_NilOrEmpty(t *testing.T) {
assert.False(t, ptr.NilOrEmpty(&nonEmptyString))
}
func Test_NilToEmpty(t *testing.T) {
t.Parallel()
assert.False(t, ptr.NilToEmpty((*bool)(nil)))
assert.Empty(t, ptr.NilToEmpty((*int64)(nil)))
assert.Empty(t, ptr.NilToEmpty((*string)(nil)))
assert.Equal(t, true, ptr.NilToEmpty(ptr.Ref(true)))
}
func Test_NilToDefault(t *testing.T) {
t.Parallel()
assert.True(t, ptr.NilToDefault(ptr.Ref(true), false))
assert.True(t, ptr.NilToDefault((*bool)(nil), true))
assert.Equal(t, int64(4), ptr.NilToDefault(ptr.Ref[int64](4), 5))
assert.Equal(t, int64(5), ptr.NilToDefault((*int64)(nil), 5))
assert.Equal(t, "hi", ptr.NilToDefault((*string)(nil), "hi"))
assert.Equal(t, "hello", ptr.NilToDefault(ptr.Ref("hello"), "hi"))
}
func Test_NilOrZero(t *testing.T) {
t.Parallel()