From e3f86fc511d64374b652d5a6f2fb851b6d938f86 Mon Sep 17 00:00:00 2001 From: Colin Adler Date: Thu, 8 Sep 2022 21:29:10 -0500 Subject: [PATCH 1/3] feat: add template/template version auditing --- coderd/database/databasefake/databasefake.go | 6 +- coderd/database/querier.go | 2 +- coderd/database/queries.sql.go | 24 +++++- coderd/database/queries/templates.sql | 2 +- coderd/templates.go | 81 +++++++++++++++----- coderd/templates_test.go | 19 ++++- coderd/templateversions.go | 50 +++++++++--- coderd/templateversions_test.go | 14 +++- 8 files changed, 154 insertions(+), 44 deletions(-) diff --git a/coderd/database/databasefake/databasefake.go b/coderd/database/databasefake/databasefake.go index 8ef1be0355e9e..dc4aa7149cf5b 100644 --- a/coderd/database/databasefake/databasefake.go +++ b/coderd/database/databasefake/databasefake.go @@ -920,7 +920,7 @@ func (q *fakeQuerier) GetTemplateByOrganizationAndName(_ context.Context, arg da return database.Template{}, sql.ErrNoRows } -func (q *fakeQuerier) UpdateTemplateMetaByID(_ context.Context, arg database.UpdateTemplateMetaByIDParams) error { +func (q *fakeQuerier) UpdateTemplateMetaByID(_ context.Context, arg database.UpdateTemplateMetaByIDParams) (database.Template, error) { q.mutex.RLock() defer q.mutex.RUnlock() @@ -935,10 +935,10 @@ func (q *fakeQuerier) UpdateTemplateMetaByID(_ context.Context, arg database.Upd tpl.MaxTtl = arg.MaxTtl tpl.MinAutostartInterval = arg.MinAutostartInterval q.templates[idx] = tpl - return nil + return tpl, nil } - return sql.ErrNoRows + return database.Template{}, sql.ErrNoRows } func (q *fakeQuerier) GetTemplatesWithFilter(_ context.Context, arg database.GetTemplatesWithFilterParams) ([]database.Template, error) { diff --git a/coderd/database/querier.go b/coderd/database/querier.go index 490bacdf43a3b..8e270eb73dbe1 100644 --- a/coderd/database/querier.go +++ b/coderd/database/querier.go @@ -134,7 +134,7 @@ type querier interface { UpdateProvisionerJobWithCompleteByID(ctx context.Context, arg UpdateProvisionerJobWithCompleteByIDParams) error UpdateTemplateActiveVersionByID(ctx context.Context, arg UpdateTemplateActiveVersionByIDParams) error UpdateTemplateDeletedByID(ctx context.Context, arg UpdateTemplateDeletedByIDParams) error - UpdateTemplateMetaByID(ctx context.Context, arg UpdateTemplateMetaByIDParams) error + UpdateTemplateMetaByID(ctx context.Context, arg UpdateTemplateMetaByIDParams) (Template, error) UpdateTemplateVersionByID(ctx context.Context, arg UpdateTemplateVersionByIDParams) error UpdateTemplateVersionDescriptionByJobID(ctx context.Context, arg UpdateTemplateVersionDescriptionByJobIDParams) error UpdateUserHashedPassword(ctx context.Context, arg UpdateUserHashedPasswordParams) error diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 5c3c7f5a8276e..d72604b88c35a 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -2361,7 +2361,7 @@ func (q *sqlQuerier) UpdateTemplateDeletedByID(ctx context.Context, arg UpdateTe return err } -const updateTemplateMetaByID = `-- name: UpdateTemplateMetaByID :exec +const updateTemplateMetaByID = `-- name: UpdateTemplateMetaByID :one UPDATE templates SET @@ -2387,8 +2387,8 @@ type UpdateTemplateMetaByIDParams struct { Icon string `db:"icon" json:"icon"` } -func (q *sqlQuerier) UpdateTemplateMetaByID(ctx context.Context, arg UpdateTemplateMetaByIDParams) error { - _, err := q.db.ExecContext(ctx, updateTemplateMetaByID, +func (q *sqlQuerier) UpdateTemplateMetaByID(ctx context.Context, arg UpdateTemplateMetaByIDParams) (Template, error) { + row := q.db.QueryRowContext(ctx, updateTemplateMetaByID, arg.ID, arg.UpdatedAt, arg.Description, @@ -2397,7 +2397,23 @@ func (q *sqlQuerier) UpdateTemplateMetaByID(ctx context.Context, arg UpdateTempl arg.Name, arg.Icon, ) - return err + var i Template + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.OrganizationID, + &i.Deleted, + &i.Name, + &i.Provisioner, + &i.ActiveVersionID, + &i.Description, + &i.MaxTtl, + &i.MinAutostartInterval, + &i.CreatedBy, + &i.Icon, + ) + return i, err } const getTemplateVersionByID = `-- name: GetTemplateVersionByID :one diff --git a/coderd/database/queries/templates.sql b/coderd/database/queries/templates.sql index b6583c9284fdf..4d552443356fe 100644 --- a/coderd/database/queries/templates.sql +++ b/coderd/database/queries/templates.sql @@ -91,7 +91,7 @@ SET WHERE id = $1; --- name: UpdateTemplateMetaByID :exec +-- name: UpdateTemplateMetaByID :one UPDATE templates SET diff --git a/coderd/templates.go b/coderd/templates.go index 64b10ca83f1d2..0a843217b4e59 100644 --- a/coderd/templates.go +++ b/coderd/templates.go @@ -16,6 +16,7 @@ import ( "github.com/moby/moby/pkg/namesgenerator" "golang.org/x/xerrors" + "github.com/coder/coder/coderd/audit" "github.com/coder/coder/coderd/database" "github.com/coder/coder/coderd/httpapi" "github.com/coder/coder/coderd/httpmw" @@ -82,7 +83,18 @@ func (api *API) template(rw http.ResponseWriter, r *http.Request) { } func (api *API) deleteTemplate(rw http.ResponseWriter, r *http.Request) { - template := httpmw.TemplateParam(r) + var ( + template = httpmw.TemplateParam(r) + aReq, commitAudit = audit.InitRequest[database.Template](rw, &audit.RequestParams{ + Features: api.FeaturesService, + Log: api.Logger, + Request: r, + Action: database.AuditActionDelete, + }) + ) + defer commitAudit() + aReq.Old = template + if !api.Authorize(r, rbac.ActionDelete, template) { httpapi.ResourceNotFound(rw) return @@ -91,10 +103,7 @@ func (api *API) deleteTemplate(rw http.ResponseWriter, r *http.Request) { workspaces, err := api.Database.GetWorkspaces(r.Context(), database.GetWorkspacesParams{ TemplateIds: []uuid.UUID{template.ID}, }) - if errors.Is(err, sql.ErrNoRows) { - err = nil - } - if err != nil { + if err != nil && !errors.Is(err, sql.ErrNoRows) { httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{ Message: "Internal error fetching workspaces by template id.", Detail: err.Error(), @@ -126,9 +135,26 @@ func (api *API) deleteTemplate(rw http.ResponseWriter, r *http.Request) { // Create a new template in an organization. func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Request) { - var createTemplate codersdk.CreateTemplateRequest - organization := httpmw.OrganizationParam(r) - apiKey := httpmw.APIKey(r) + var ( + createTemplate codersdk.CreateTemplateRequest + organization = httpmw.OrganizationParam(r) + apiKey = httpmw.APIKey(r) + templateAudit, commitTemplateAudit = audit.InitRequest[database.Template](rw, &audit.RequestParams{ + Features: api.FeaturesService, + Log: api.Logger, + Request: r, + Action: database.AuditActionCreate, + }) + templateVersionAudit, commitTemplateVersionAudit = audit.InitRequest[database.TemplateVersion](rw, &audit.RequestParams{ + Features: api.FeaturesService, + Log: api.Logger, + Request: r, + Action: database.AuditActionWrite, + }) + ) + defer commitTemplateAudit() + defer commitTemplateVersionAudit() + if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceTemplate.InOrg(organization.ID)) { httpapi.ResourceNotFound(rw) return @@ -175,6 +201,8 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque }) return } + templateVersionAudit.Old = templateVersion + importJob, err := api.Database.GetProvisionerJobByID(r.Context(), templateVersion.JobID) if err != nil { httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{ @@ -234,6 +262,8 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque return xerrors.Errorf("insert template: %s", err) } + templateAudit.New = dbTemplate + err = db.UpdateTemplateVersionByID(r.Context(), database.UpdateTemplateVersionByIDParams{ ID: templateVersion.ID, TemplateID: uuid.NullUUID{ @@ -245,6 +275,12 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque if err != nil { return xerrors.Errorf("insert template version: %s", err) } + newTemplateVersion := templateVersion + newTemplateVersion.TemplateID = uuid.NullUUID{ + UUID: dbTemplate.ID, + Valid: true, + } + templateVersionAudit.New = newTemplateVersion for _, parameterValue := range createTemplate.ParameterValues { _, err = db.InsertParameterValue(r.Context(), database.InsertParameterValueParams{ @@ -397,7 +433,18 @@ func (api *API) templateByOrganizationAndName(rw http.ResponseWriter, r *http.Re } func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) { - template := httpmw.TemplateParam(r) + var ( + template = httpmw.TemplateParam(r) + aReq, commitAudit = audit.InitRequest[database.Template](rw, &audit.RequestParams{ + Features: api.FeaturesService, + Log: api.Logger, + Request: r, + Action: database.AuditActionWrite, + }) + ) + defer commitAudit() + aReq.Old = template + if !api.Authorize(r, rbac.ActionUpdate, template) { httpapi.ResourceNotFound(rw) return @@ -474,7 +521,7 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) { minAutostartInterval = time.Duration(template.MinAutostartInterval) } - if err := s.UpdateTemplateMetaByID(r.Context(), database.UpdateTemplateMetaByIDParams{ + updated, err = s.UpdateTemplateMetaByID(r.Context(), database.UpdateTemplateMetaByIDParams{ ID: template.ID, UpdatedAt: database.Now(), Name: name, @@ -482,28 +529,24 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) { Icon: icon, MaxTtl: int64(maxTTL), MinAutostartInterval: int64(minAutostartInterval), - }); err != nil { - return err - } - - updated, err = s.GetTemplateByID(r.Context(), template.ID) + }) if err != nil { return err } + return nil }) if err != nil { - httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{ - Message: "Internal error updating template metadata.", - Detail: err.Error(), - }) + httpapi.InternalServerError(rw, err) return } if updated.UpdatedAt.IsZero() { + aReq.New = template httpapi.Write(rw, http.StatusNotModified, nil) return } + aReq.New = updated createdByNameMap, err := getCreatedByNamesByTemplateIDs(r.Context(), api.Database, []database.Template{updated}) if err != nil { diff --git a/coderd/templates_test.go b/coderd/templates_test.go index 51ab0f386f5c7..6f0d7e8da10c6 100644 --- a/coderd/templates_test.go +++ b/coderd/templates_test.go @@ -13,7 +13,9 @@ import ( "cdr.dev/slog/sloggers/slogtest" "github.com/coder/coder/agent" + "github.com/coder/coder/coderd/audit" "github.com/coder/coder/coderd/coderdtest" + "github.com/coder/coder/coderd/database" "github.com/coder/coder/coderd/rbac" "github.com/coder/coder/coderd/util/ptr" "github.com/coder/coder/codersdk" @@ -78,7 +80,8 @@ func TestPostTemplateByOrganization(t *testing.T) { t.Parallel() t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + auditor := audit.NewMock() + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true, Auditor: auditor}) user := coderdtest.CreateFirstUser(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) @@ -92,6 +95,9 @@ func TestPostTemplateByOrganization(t *testing.T) { assert.Equal(t, expected.Name, got.Name) assert.Equal(t, expected.Description, got.Description) + require.Len(t, auditor.AuditLogs, 2) + assert.Equal(t, database.AuditActionWrite, auditor.AuditLogs[0].Action) + assert.Equal(t, database.AuditActionCreate, auditor.AuditLogs[1].Action) }) t.Run("AlreadyExists", func(t *testing.T) { @@ -291,7 +297,8 @@ func TestPatchTemplateMeta(t *testing.T) { t.Run("Modified", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + auditor := audit.NewMock() + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true, Auditor: auditor}) user := coderdtest.CreateFirstUser(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID, func(ctr *codersdk.CreateTemplateRequest) { @@ -332,6 +339,9 @@ func TestPatchTemplateMeta(t *testing.T) { assert.Equal(t, req.Icon, updated.Icon) assert.Equal(t, req.MaxTTLMillis, updated.MaxTTLMillis) assert.Equal(t, req.MinAutostartIntervalMillis, updated.MinAutostartIntervalMillis) + + require.Len(t, auditor.AuditLogs, 3) + assert.Equal(t, database.AuditActionWrite, auditor.AuditLogs[2].Action) }) t.Run("NoMaxTTL", func(t *testing.T) { @@ -514,7 +524,8 @@ func TestDeleteTemplate(t *testing.T) { t.Run("NoWorkspaces", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + auditor := audit.NewMock() + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true, Auditor: auditor}) user := coderdtest.CreateFirstUser(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) @@ -524,6 +535,8 @@ func TestDeleteTemplate(t *testing.T) { err := client.DeleteTemplate(ctx, template.ID) require.NoError(t, err) + assert.Len(t, auditor.AuditLogs, 1) + assert.Equal(t, database.AuditActionDelete, auditor.AuditLogs[0].Action) }) t.Run("Workspaces", func(t *testing.T) { diff --git a/coderd/templateversions.go b/coderd/templateversions.go index cc10046791b57..20d2e204c2e7f 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -13,6 +13,7 @@ import ( "github.com/moby/moby/pkg/namesgenerator" "golang.org/x/xerrors" + "github.com/coder/coder/coderd/audit" "github.com/coder/coder/coderd/database" "github.com/coder/coder/coderd/httpapi" "github.com/coder/coder/coderd/httpmw" @@ -556,7 +557,18 @@ func (api *API) templateVersionByName(rw http.ResponseWriter, r *http.Request) { } func (api *API) patchActiveTemplateVersion(rw http.ResponseWriter, r *http.Request) { - template := httpmw.TemplateParam(r) + var ( + template = httpmw.TemplateParam(r) + aReq, commitAudit = audit.InitRequest[database.Template](rw, &audit.RequestParams{ + Features: api.FeaturesService, + Log: api.Logger, + Request: r, + Action: database.AuditActionCreate, + }) + ) + defer commitAudit() + aReq.Old = template + if !api.Authorize(r, rbac.ActionUpdate, template) { httpapi.ResourceNotFound(rw) return @@ -581,7 +593,7 @@ func (api *API) patchActiveTemplateVersion(rw http.ResponseWriter, r *http.Reque return } if version.TemplateID.UUID.String() != template.ID.String() { - httpapi.Write(rw, http.StatusUnauthorized, codersdk.Response{ + httpapi.Write(rw, http.StatusBadRequest, codersdk.Response{ Message: "The provided template version doesn't belong to the specified template.", }) return @@ -605,6 +617,10 @@ func (api *API) patchActiveTemplateVersion(rw http.ResponseWriter, r *http.Reque }) return } + newTemplate := template + newTemplate.ActiveVersionID = req.ID + aReq.New = newTemplate + httpapi.Write(rw, http.StatusOK, codersdk.Response{ Message: "Updated the active template version!", }) @@ -612,13 +628,30 @@ func (api *API) patchActiveTemplateVersion(rw http.ResponseWriter, r *http.Reque // Creates a new version of a template. An import job is queued to parse the storage method provided. func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *http.Request) { - apiKey := httpmw.APIKey(r) - organization := httpmw.OrganizationParam(r) - var req codersdk.CreateTemplateVersionRequest + var ( + apiKey = httpmw.APIKey(r) + organization = httpmw.OrganizationParam(r) + aReq, commitAudit = audit.InitRequest[database.TemplateVersion](rw, &audit.RequestParams{ + Features: api.FeaturesService, + Log: api.Logger, + Request: r, + Action: database.AuditActionCreate, + }) + + req codersdk.CreateTemplateVersionRequest + ) + defer commitAudit() + if !httpapi.Read(rw, r, &req) { return } + // Making a new template version is the same permission as creating a new template. + if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceTemplate.InOrg(organization.ID)) { + httpapi.ResourceNotFound(rw) + return + } + if req.TemplateID != uuid.Nil { _, err := api.Database.GetTemplateByID(r.Context(), req.TemplateID) if errors.Is(err, sql.ErrNoRows) { @@ -651,12 +684,6 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht return } - // Making a new template version is the same permission as creating a new template. - if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceTemplate.InOrg(organization.ID)) { - httpapi.ResourceNotFound(rw) - return - } - if !api.Authorize(r, rbac.ActionRead, file) { httpapi.ResourceNotFound(rw) return @@ -778,6 +805,7 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht }) return } + aReq.New = templateVersion createdByName, err := getUsernameByUserID(r.Context(), api.Database, templateVersion.CreatedBy) if err != nil { diff --git a/coderd/templateversions_test.go b/coderd/templateversions_test.go index af4678510e489..4bb4d8791c62d 100644 --- a/coderd/templateversions_test.go +++ b/coderd/templateversions_test.go @@ -11,7 +11,9 @@ import ( "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" + "github.com/coder/coder/coderd/audit" "github.com/coder/coder/coderd/coderdtest" + "github.com/coder/coder/coderd/database" "github.com/coder/coder/codersdk" "github.com/coder/coder/provisioner/echo" "github.com/coder/coder/provisionersdk/proto" @@ -76,7 +78,8 @@ func TestPostTemplateVersionsByOrganization(t *testing.T) { t.Run("WithParameters", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + auditor := audit.NewMock() + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true, Auditor: auditor}) user := coderdtest.CreateFirstUser(t, client) data, err := echo.Tar(&echo.Responses{ Parse: echo.ParseComplete, @@ -102,6 +105,9 @@ func TestPostTemplateVersionsByOrganization(t *testing.T) { }}, }) require.NoError(t, err) + + require.Len(t, auditor.AuditLogs, 1) + assert.Equal(t, database.AuditActionCreate, auditor.AuditLogs[0].Action) }) } @@ -545,7 +551,8 @@ func TestPatchActiveTemplateVersion(t *testing.T) { t.Run("Found", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + auditor := audit.NewMock() + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true, Auditor: auditor}) user := coderdtest.CreateFirstUser(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) @@ -557,6 +564,9 @@ func TestPatchActiveTemplateVersion(t *testing.T) { ID: version.ID, }) require.NoError(t, err) + + require.Len(t, auditor.AuditLogs, 3) + assert.Equal(t, database.AuditActionCreate, auditor.AuditLogs[0].Action) }) } From 15987d1059d566a07273fc0cc5db0ba8fef4c6fb Mon Sep 17 00:00:00 2001 From: Colin Adler Date: Thu, 8 Sep 2022 21:37:46 -0500 Subject: [PATCH 2/3] fixup! feat: add template/template version auditing --- coderd/templates_test.go | 9 +++++---- coderd/templateversions.go | 2 +- coderd/templateversions_test.go | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/coderd/templates_test.go b/coderd/templates_test.go index 6f0d7e8da10c6..e4a1c69a4c604 100644 --- a/coderd/templates_test.go +++ b/coderd/templates_test.go @@ -340,8 +340,8 @@ func TestPatchTemplateMeta(t *testing.T) { assert.Equal(t, req.MaxTTLMillis, updated.MaxTTLMillis) assert.Equal(t, req.MinAutostartIntervalMillis, updated.MinAutostartIntervalMillis) - require.Len(t, auditor.AuditLogs, 3) - assert.Equal(t, database.AuditActionWrite, auditor.AuditLogs[2].Action) + require.Len(t, auditor.AuditLogs, 4) + assert.Equal(t, database.AuditActionWrite, auditor.AuditLogs[3].Action) }) t.Run("NoMaxTTL", func(t *testing.T) { @@ -535,8 +535,9 @@ func TestDeleteTemplate(t *testing.T) { err := client.DeleteTemplate(ctx, template.ID) require.NoError(t, err) - assert.Len(t, auditor.AuditLogs, 1) - assert.Equal(t, database.AuditActionDelete, auditor.AuditLogs[0].Action) + + require.Len(t, auditor.AuditLogs, 4) + assert.Equal(t, database.AuditActionDelete, auditor.AuditLogs[3].Action) }) t.Run("Workspaces", func(t *testing.T) { diff --git a/coderd/templateversions.go b/coderd/templateversions.go index 20d2e204c2e7f..c14e3ab9ca07c 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -563,7 +563,7 @@ func (api *API) patchActiveTemplateVersion(rw http.ResponseWriter, r *http.Reque Features: api.FeaturesService, Log: api.Logger, Request: r, - Action: database.AuditActionCreate, + Action: database.AuditActionWrite, }) ) defer commitAudit() diff --git a/coderd/templateversions_test.go b/coderd/templateversions_test.go index 4bb4d8791c62d..461460895fed6 100644 --- a/coderd/templateversions_test.go +++ b/coderd/templateversions_test.go @@ -546,7 +546,7 @@ func TestPatchActiveTemplateVersion(t *testing.T) { }) var apiErr *codersdk.Error require.ErrorAs(t, err, &apiErr) - require.Equal(t, http.StatusUnauthorized, apiErr.StatusCode()) + require.Equal(t, http.StatusBadRequest, apiErr.StatusCode()) }) t.Run("Found", func(t *testing.T) { @@ -565,8 +565,8 @@ func TestPatchActiveTemplateVersion(t *testing.T) { }) require.NoError(t, err) - require.Len(t, auditor.AuditLogs, 3) - assert.Equal(t, database.AuditActionCreate, auditor.AuditLogs[0].Action) + require.Len(t, auditor.AuditLogs, 4) + assert.Equal(t, database.AuditActionWrite, auditor.AuditLogs[3].Action) }) } From e06c4e4784c03cad21712985cad03bbba97a6df4 Mon Sep 17 00:00:00 2001 From: Colin Adler Date: Thu, 8 Sep 2022 21:43:05 -0500 Subject: [PATCH 3/3] fixup! feat: add template/template version auditing --- coderd/templates_test.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/coderd/templates_test.go b/coderd/templates_test.go index e4a1c69a4c604..9b20b5c67ab0e 100644 --- a/coderd/templates_test.go +++ b/coderd/templates_test.go @@ -95,9 +95,11 @@ func TestPostTemplateByOrganization(t *testing.T) { assert.Equal(t, expected.Name, got.Name) assert.Equal(t, expected.Description, got.Description) - require.Len(t, auditor.AuditLogs, 2) - assert.Equal(t, database.AuditActionWrite, auditor.AuditLogs[0].Action) - assert.Equal(t, database.AuditActionCreate, auditor.AuditLogs[1].Action) + + require.Len(t, auditor.AuditLogs, 3) + assert.Equal(t, database.AuditActionCreate, auditor.AuditLogs[0].Action) + assert.Equal(t, database.AuditActionWrite, auditor.AuditLogs[1].Action) + assert.Equal(t, database.AuditActionCreate, auditor.AuditLogs[2].Action) }) t.Run("AlreadyExists", func(t *testing.T) {