diff --git a/coderd/coderdtest/coderdtest.go b/coderd/coderdtest/coderdtest.go index 0799e72f91..6688c8aa1b 100644 --- a/coderd/coderdtest/coderdtest.go +++ b/coderd/coderdtest/coderdtest.go @@ -762,6 +762,25 @@ func CreateTemplate(t testing.TB, client *codersdk.Client, organization uuid.UUI return template } +// CreateGroup creates a group with the given name and members. +func CreateGroup(t testing.TB, client *codersdk.Client, organizationID uuid.UUID, name string, members ...codersdk.User) codersdk.Group { + t.Helper() + group, err := client.CreateGroup(context.Background(), organizationID, codersdk.CreateGroupRequest{ + Name: name, + }) + require.NoError(t, err, "failed to create group") + memberIDs := make([]string, 0) + for _, member := range members { + memberIDs = append(memberIDs, member.ID.String()) + } + group, err = client.PatchGroup(context.Background(), group.ID, codersdk.PatchGroupRequest{ + AddUsers: memberIDs, + }) + + require.NoError(t, err, "failed to add members to group") + return group +} + // UpdateTemplateVersion creates a new template version with the "echo" provisioner // and associates it with the given templateID. func UpdateTemplateVersion(t testing.TB, client *codersdk.Client, organizationID uuid.UUID, res *echo.Responses, templateID uuid.UUID) codersdk.TemplateVersion { @@ -787,6 +806,14 @@ func UpdateActiveTemplateVersion(t testing.TB, client *codersdk.Client, template require.NoError(t, err) } +// UpdateTemplateMeta updates the template meta for the given template. +func UpdateTemplateMeta(t testing.TB, client *codersdk.Client, templateID uuid.UUID, meta codersdk.UpdateTemplateMeta) codersdk.Template { + t.Helper() + updated, err := client.UpdateTemplateMeta(context.Background(), templateID, meta) + require.NoError(t, err) + return updated +} + // AwaitTemplateVersionJobRunning waits for the build to be picked up by a provisioner. func AwaitTemplateVersionJobRunning(t testing.TB, client *codersdk.Client, version uuid.UUID) codersdk.TemplateVersion { t.Helper() diff --git a/enterprise/cli/features_test.go b/enterprise/cli/features_test.go index 406e626d36..b09c4fbc6a 100644 --- a/enterprise/cli/features_test.go +++ b/enterprise/cli/features_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" "github.com/coder/coder/v2/cli/clitest" + "github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest" "github.com/coder/coder/v2/pty/ptytest" @@ -18,9 +19,10 @@ func TestFeaturesList(t *testing.T) { t.Parallel() t.Run("Table", func(t *testing.T) { t.Parallel() - client, _ := coderdenttest.New(t, &coderdenttest.Options{DontAddLicense: true}) + client, admin := coderdenttest.New(t, &coderdenttest.Options{DontAddLicense: true}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID) inv, conf := newCLI(t, "features", "list") - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, anotherClient, conf) pty := ptytest.New(t).Attach(inv) clitest.Start(t, inv) pty.ExpectMatch("user_limit") @@ -29,9 +31,10 @@ func TestFeaturesList(t *testing.T) { t.Run("JSON", func(t *testing.T) { t.Parallel() - client, _ := coderdenttest.New(t, &coderdenttest.Options{DontAddLicense: true}) + client, admin := coderdenttest.New(t, &coderdenttest.Options{DontAddLicense: true}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID) inv, conf := newCLI(t, "features", "list", "-o", "json") - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, anotherClient, conf) doneChan := make(chan struct{}) buf := bytes.NewBuffer(nil) diff --git a/enterprise/cli/groupcreate_test.go b/enterprise/cli/groupcreate_test.go index 783ce12f7c..6f5754ec93 100644 --- a/enterprise/cli/groupcreate_test.go +++ b/enterprise/cli/groupcreate_test.go @@ -10,6 +10,8 @@ import ( "github.com/coder/coder/v2/cli/clitest" "github.com/coder/coder/v2/cli/cliui" + "github.com/coder/coder/v2/coderd/coderdtest" + "github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest" "github.com/coder/coder/v2/enterprise/coderd/license" @@ -22,11 +24,12 @@ func TestCreateGroup(t *testing.T) { t.Run("OK", func(t *testing.T) { t.Parallel() - client, _ := coderdenttest.New(t, &coderdenttest.Options{LicenseOptions: &coderdenttest.LicenseOptions{ + client, admin := coderdenttest.New(t, &coderdenttest.Options{LicenseOptions: &coderdenttest.LicenseOptions{ Features: license.Features{ codersdk.FeatureTemplateRBAC: 1, }, }}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID, rbac.RoleUserAdmin()) var ( groupName = "test" @@ -40,7 +43,7 @@ func TestCreateGroup(t *testing.T) { pty := ptytest.New(t) inv.Stdout = pty.Output() - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, anotherClient, conf) err := inv.Run() require.NoError(t, err) diff --git a/enterprise/cli/groupdelete_test.go b/enterprise/cli/groupdelete_test.go index 21aa6391bd..000198adfa 100644 --- a/enterprise/cli/groupdelete_test.go +++ b/enterprise/cli/groupdelete_test.go @@ -10,11 +10,12 @@ import ( "github.com/coder/coder/v2/cli/clitest" "github.com/coder/coder/v2/cli/cliui" + "github.com/coder/coder/v2/coderd/coderdtest" + "github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest" "github.com/coder/coder/v2/enterprise/coderd/license" "github.com/coder/coder/v2/pty/ptytest" - "github.com/coder/coder/v2/testutil" ) func TestGroupDelete(t *testing.T) { @@ -28,12 +29,9 @@ func TestGroupDelete(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID, rbac.RoleUserAdmin()) - ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, admin.OrganizationID, codersdk.CreateGroupRequest{ - Name: "alpha", - }) - require.NoError(t, err) + group := coderdtest.CreateGroup(t, client, admin.OrganizationID, "alpha") inv, conf := newCLI(t, "groups", "delete", group.Name, @@ -42,9 +40,9 @@ func TestGroupDelete(t *testing.T) { pty := ptytest.New(t) inv.Stdout = pty.Output() - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, anotherClient, conf) - err = inv.Run() + err := inv.Run() require.NoError(t, err) pty.ExpectMatch(fmt.Sprintf("Successfully deleted group %s", pretty.Sprint(cliui.DefaultStyles.Keyword, group.Name))) @@ -53,18 +51,19 @@ func TestGroupDelete(t *testing.T) { t.Run("NoArg", func(t *testing.T) { t.Parallel() - client, _ := coderdenttest.New(t, &coderdenttest.Options{LicenseOptions: &coderdenttest.LicenseOptions{ + client, admin := coderdenttest.New(t, &coderdenttest.Options{LicenseOptions: &coderdenttest.LicenseOptions{ Features: license.Features{ codersdk.FeatureTemplateRBAC: 1, }, }}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID, rbac.RoleUserAdmin()) inv, conf := newCLI( t, "groups", "delete", ) - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, anotherClient, conf) err := inv.Run() require.Error(t, err) diff --git a/enterprise/cli/groupedit_test.go b/enterprise/cli/groupedit_test.go index a0d192854f..e6bc8ce86a 100644 --- a/enterprise/cli/groupedit_test.go +++ b/enterprise/cli/groupedit_test.go @@ -11,11 +11,11 @@ import ( "github.com/coder/coder/v2/cli/clitest" "github.com/coder/coder/v2/cli/cliui" "github.com/coder/coder/v2/coderd/coderdtest" + "github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest" "github.com/coder/coder/v2/enterprise/coderd/license" "github.com/coder/coder/v2/pty/ptytest" - "github.com/coder/coder/v2/testutil" ) func TestGroupEdit(t *testing.T) { @@ -29,23 +29,13 @@ func TestGroupEdit(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID, rbac.RoleUserAdmin()) - ctx := testutil.Context(t, testutil.WaitLong) _, user1 := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID) _, user3 := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID) - group, err := client.CreateGroup(ctx, admin.OrganizationID, codersdk.CreateGroupRequest{ - Name: "alpha", - }) - require.NoError(t, err) - - // We use the sdk here as opposed to the CLI since adding this user - // is considered setup. They will be removed in the proper CLI test. - group, err = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ - AddUsers: []string{user3.ID.String()}, - }) - require.NoError(t, err) + group := coderdtest.CreateGroup(t, client, admin.OrganizationID, "alpha", user3) expectedName := "beta" @@ -62,9 +52,9 @@ func TestGroupEdit(t *testing.T) { pty := ptytest.New(t) inv.Stdout = pty.Output() - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, anotherClient, conf) - err = inv.Run() + err := inv.Run() require.NoError(t, err) pty.ExpectMatch(fmt.Sprintf("Successfully patched group %s", pretty.Sprint(cliui.DefaultStyles.Keyword, expectedName))) @@ -79,12 +69,8 @@ func TestGroupEdit(t *testing.T) { }, }}) - ctx := testutil.Context(t, testutil.WaitLong) - - group, err := client.CreateGroup(ctx, admin.OrganizationID, codersdk.CreateGroupRequest{ - Name: "alpha", - }) - require.NoError(t, err) + // Create a group with no members. + group := coderdtest.CreateGroup(t, client, admin.OrganizationID, "alpha") inv, conf := newCLI( t, @@ -92,26 +78,26 @@ func TestGroupEdit(t *testing.T) { "-a", "foo", ) - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, client, conf) //nolint:gocritic // intentional usage of owner - err = inv.Run() - require.Error(t, err) - require.Contains(t, err.Error(), "must be a valid UUID or email address") + err := inv.Run() + require.ErrorContains(t, err, "must be a valid UUID or email address") }) t.Run("NoArg", func(t *testing.T) { t.Parallel() - client, _ := coderdenttest.New(t, &coderdenttest.Options{LicenseOptions: &coderdenttest.LicenseOptions{ + client, user := coderdenttest.New(t, &coderdenttest.Options{LicenseOptions: &coderdenttest.LicenseOptions{ Features: license.Features{ codersdk.FeatureTemplateRBAC: 1, }, }}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) inv, conf := newCLI(t, "groups", "edit") - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, anotherClient, conf) err := inv.Run() - require.Error(t, err) + require.ErrorContains(t, err, "wanted 1 args but got 0") }) } diff --git a/enterprise/cli/grouplist_test.go b/enterprise/cli/grouplist_test.go index 2787893fae..ac168b348b 100644 --- a/enterprise/cli/grouplist_test.go +++ b/enterprise/cli/grouplist_test.go @@ -7,11 +7,11 @@ import ( "github.com/coder/coder/v2/cli/clitest" "github.com/coder/coder/v2/coderd/coderdtest" + "github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest" "github.com/coder/coder/v2/enterprise/coderd/license" "github.com/coder/coder/v2/pty/ptytest" - "github.com/coder/coder/v2/testutil" ) func TestGroupList(t *testing.T) { @@ -25,42 +25,25 @@ func TestGroupList(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID, rbac.RoleUserAdmin()) - ctx := testutil.Context(t, testutil.WaitLong) _, user1 := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID) // We intentionally create the first group as beta so that we // can assert that things are being sorted by name intentionally // and not by chance (or some other parameter like created_at). - group1, err := client.CreateGroup(ctx, admin.OrganizationID, codersdk.CreateGroupRequest{ - Name: "beta", - }) - require.NoError(t, err) - - group2, err := client.CreateGroup(ctx, admin.OrganizationID, codersdk.CreateGroupRequest{ - Name: "alpha", - }) - require.NoError(t, err) - - _, err = client.PatchGroup(ctx, group1.ID, codersdk.PatchGroupRequest{ - AddUsers: []string{user1.ID.String()}, - }) - require.NoError(t, err) - - _, err = client.PatchGroup(ctx, group2.ID, codersdk.PatchGroupRequest{ - AddUsers: []string{user2.ID.String()}, - }) - require.NoError(t, err) + group1 := coderdtest.CreateGroup(t, client, admin.OrganizationID, "beta", user1) + group2 := coderdtest.CreateGroup(t, client, admin.OrganizationID, "alpha", user2) inv, conf := newCLI(t, "groups", "list") pty := ptytest.New(t) inv.Stdout = pty.Output() - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, anotherClient, conf) - err = inv.Run() + err := inv.Run() require.NoError(t, err) matches := []string{ @@ -77,25 +60,26 @@ func TestGroupList(t *testing.T) { t.Run("Everyone", func(t *testing.T) { t.Parallel() - client, user := coderdenttest.New(t, &coderdenttest.Options{LicenseOptions: &coderdenttest.LicenseOptions{ + client, admin := coderdenttest.New(t, &coderdenttest.Options{LicenseOptions: &coderdenttest.LicenseOptions{ Features: license.Features{ codersdk.FeatureTemplateRBAC: 1, }, }}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID, rbac.RoleUserAdmin()) inv, conf := newCLI(t, "groups", "list") pty := ptytest.New(t) inv.Stdout = pty.Output() - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, anotherClient, conf) err := inv.Run() require.NoError(t, err) matches := []string{ "NAME", "ORGANIZATION ID", "MEMBERS", " AVATAR URL", - "Everyone", user.OrganizationID.String(), coderdtest.FirstUserParams.Email, "", + "Everyone", admin.OrganizationID.String(), coderdtest.FirstUserParams.Email, "", } for _, match := range matches { diff --git a/enterprise/cli/licenses_test.go b/enterprise/cli/licenses_test.go index 178068840d..b8c9844179 100644 --- a/enterprise/cli/licenses_test.go +++ b/enterprise/cli/licenses_test.go @@ -122,7 +122,7 @@ func TestLicensesAddReal(t *testing.T) { t, "licenses", "add", "-l", fakeLicenseJWT, ) - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, client, conf) //nolint:gocritic // requires owner waiter := clitest.StartWithWaiter(t, inv) var coderError *codersdk.Error @@ -180,7 +180,7 @@ func TestLicensesListReal(t *testing.T) { inv.Stdout = stdout stderr := new(bytes.Buffer) inv.Stderr = stderr - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, client, conf) //nolint:gocritic // requires owner ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) defer cancel() errC := make(chan error) @@ -216,7 +216,7 @@ func TestLicensesDeleteReal(t *testing.T) { inv, conf := newCLI( t, "licenses", "delete", "1") - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, client, conf) //nolint:gocritic // requires owner var coderError *codersdk.Error clitest.StartWithWaiter(t, inv).RequireAs(&coderError) diff --git a/enterprise/cli/provisionerdaemons_test.go b/enterprise/cli/provisionerdaemons_test.go index 038ba97ec7..ff8ca63f57 100644 --- a/enterprise/cli/provisionerdaemons_test.go +++ b/enterprise/cli/provisionerdaemons_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/require" "github.com/coder/coder/v2/cli/clitest" + "github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest" "github.com/coder/coder/v2/enterprise/coderd/license" @@ -37,20 +38,43 @@ func TestProvisionerDaemon_PSK(t *testing.T) { func TestProvisionerDaemon_SessionToken(t *testing.T) { t.Parallel() - - client, _ := coderdenttest.New(t, &coderdenttest.Options{ - ProvisionerDaemonPSK: "provisionersftw", - LicenseOptions: &coderdenttest.LicenseOptions{ - Features: license.Features{ - codersdk.FeatureExternalProvisionerDaemons: 1, + t.Run("ScopeUser", func(t *testing.T) { + t.Parallel() + client, admin := coderdenttest.New(t, &coderdenttest.Options{ + ProvisionerDaemonPSK: "provisionersftw", + LicenseOptions: &coderdenttest.LicenseOptions{ + Features: license.Features{ + codersdk.FeatureExternalProvisionerDaemons: 1, + }, }, - }, + }) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID) + inv, conf := newCLI(t, "provisionerd", "start", "--tag", "scope=user") + clitest.SetupConfig(t, anotherClient, conf) + pty := ptytest.New(t).Attach(inv) + ctx, cancel := context.WithTimeout(inv.Context(), testutil.WaitLong) + defer cancel() + clitest.Start(t, inv) + pty.ExpectMatchContext(ctx, "starting provisioner daemon") + }) + + t.Run("ScopeOrg", func(t *testing.T) { + t.Parallel() + client, admin := coderdenttest.New(t, &coderdenttest.Options{ + ProvisionerDaemonPSK: "provisionersftw", + LicenseOptions: &coderdenttest.LicenseOptions{ + Features: license.Features{ + codersdk.FeatureExternalProvisionerDaemons: 1, + }, + }, + }) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID) + inv, conf := newCLI(t, "provisionerd", "start", "--tag", "scope=organization") + clitest.SetupConfig(t, anotherClient, conf) + pty := ptytest.New(t).Attach(inv) + ctx, cancel := context.WithTimeout(inv.Context(), testutil.WaitLong) + defer cancel() + clitest.Start(t, inv) + pty.ExpectMatchContext(ctx, "starting provisioner daemon") }) - inv, conf := newCLI(t, "provisionerd", "start") - clitest.SetupConfig(t, client, conf) - pty := ptytest.New(t).Attach(inv) - ctx, cancel := context.WithTimeout(inv.Context(), testutil.WaitLong) - defer cancel() - clitest.Start(t, inv) - pty.ExpectMatchContext(ctx, "starting provisioner daemon") } diff --git a/enterprise/cli/root_test.go b/enterprise/cli/root_test.go index 3017b6cb0b..a9faff7a73 100644 --- a/enterprise/cli/root_test.go +++ b/enterprise/cli/root_test.go @@ -47,7 +47,7 @@ func TestCheckWarnings(t *testing.T) { var buf bytes.Buffer inv.Stderr = &buf - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, client, conf) //nolint:gocritic // owners should see this err := inv.Run() require.NoError(t, err) diff --git a/enterprise/cli/start_test.go b/enterprise/cli/start_test.go index be6101e7f9..8f3903dd63 100644 --- a/enterprise/cli/start_test.go +++ b/enterprise/cli/start_test.go @@ -37,50 +37,37 @@ func TestStart(t *testing.T) { }, }, }) + templateAdminClient, templateAdmin := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID, rbac.RoleTemplateAdmin()) // Create an initial version. - oldVersion := coderdtest.CreateTemplateVersion(t, ownerClient, owner.OrganizationID, nil) + oldVersion := coderdtest.CreateTemplateVersion(t, templateAdminClient, owner.OrganizationID, nil) // Create a template that mandates the promoted version. // This should be enforced for everyone except template admins. - template := coderdtest.CreateTemplate(t, ownerClient, owner.OrganizationID, oldVersion.ID) - coderdtest.AwaitTemplateVersionJobCompleted(t, ownerClient, oldVersion.ID) + template := coderdtest.CreateTemplate(t, templateAdminClient, owner.OrganizationID, oldVersion.ID) + coderdtest.AwaitTemplateVersionJobCompleted(t, templateAdminClient, oldVersion.ID) require.Equal(t, oldVersion.ID, template.ActiveVersionID) - template, err := ownerClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ + template = coderdtest.UpdateTemplateMeta(t, templateAdminClient, template.ID, codersdk.UpdateTemplateMeta{ RequireActiveVersion: true, }) - require.NoError(t, err) require.True(t, template.RequireActiveVersion) // Create a new version that we will promote. - activeVersion := coderdtest.CreateTemplateVersion(t, ownerClient, owner.OrganizationID, nil, func(ctvr *codersdk.CreateTemplateVersionRequest) { + activeVersion := coderdtest.CreateTemplateVersion(t, templateAdminClient, owner.OrganizationID, nil, func(ctvr *codersdk.CreateTemplateVersionRequest) { ctvr.TemplateID = template.ID }) - coderdtest.AwaitTemplateVersionJobCompleted(t, ownerClient, activeVersion.ID) - err = ownerClient.UpdateActiveTemplateVersion(ctx, template.ID, codersdk.UpdateActiveTemplateVersion{ - ID: activeVersion.ID, - }) - require.NoError(t, err) - err = ownerClient.UpdateActiveTemplateVersion(ctx, template.ID, codersdk.UpdateActiveTemplateVersion{ + coderdtest.AwaitTemplateVersionJobCompleted(t, templateAdminClient, activeVersion.ID) + err := templateAdminClient.UpdateActiveTemplateVersion(ctx, template.ID, codersdk.UpdateActiveTemplateVersion{ ID: activeVersion.ID, }) require.NoError(t, err) - templateAdminClient, templateAdmin := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID, rbac.RoleTemplateAdmin()) templateACLAdminClient, templateACLAdmin := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID) templateGroupACLAdminClient, templateGroupACLAdmin := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID) memberClient, member := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID) // Create a group so we can also test group template admin ownership. - group, err := ownerClient.CreateGroup(ctx, owner.OrganizationID, codersdk.CreateGroupRequest{ - Name: "test", - }) - require.NoError(t, err) - // Add the user who gains template admin via group membership. - group, err = ownerClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ - AddUsers: []string{templateGroupACLAdmin.ID.String()}, - }) - require.NoError(t, err) + group := coderdtest.CreateGroup(t, ownerClient, owner.OrganizationID, "test", templateGroupACLAdmin) // Update the template for both users and groups. err = ownerClient.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ diff --git a/enterprise/cli/templatecreate_test.go b/enterprise/cli/templatecreate_test.go index 7fe699d531..8bbc84aba7 100644 --- a/enterprise/cli/templatecreate_test.go +++ b/enterprise/cli/templatecreate_test.go @@ -8,6 +8,7 @@ import ( "github.com/coder/coder/v2/cli/clitest" "github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/database" + "github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest" "github.com/coder/coder/v2/enterprise/coderd/license" @@ -37,6 +38,7 @@ func TestTemplateCreate(t *testing.T) { IncludeProvisionerDaemon: true, }, }) + templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) source := clitest.CreateTemplateVersionSource(t, &echo.Responses{ Parse: echo.ParseComplete, @@ -51,13 +53,13 @@ func TestTemplateCreate(t *testing.T) { "-y", ) - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, templateAdmin, conf) err := inv.Run() require.NoError(t, err) ctx := testutil.Context(t, testutil.WaitMedium) - template, err := client.TemplateByName(ctx, user.OrganizationID, "new") + template, err := templateAdmin.TemplateByName(ctx, user.OrganizationID, "new") require.NoError(t, err) require.True(t, template.RequireActiveVersion) }) @@ -70,7 +72,7 @@ func TestTemplateCreate(t *testing.T) { string(codersdk.ExperimentTemplateUpdatePolicies), } - client, _ := coderdenttest.New(t, &coderdenttest.Options{ + client, admin := coderdenttest.New(t, &coderdenttest.Options{ LicenseOptions: &coderdenttest.LicenseOptions{ Features: license.Features{}, }, @@ -79,6 +81,7 @@ func TestTemplateCreate(t *testing.T) { IncludeProvisionerDaemon: true, }, }) + templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID, rbac.RoleTemplateAdmin()) inv, conf := newCLI(t, "templates", "create", "new", @@ -86,7 +89,7 @@ func TestTemplateCreate(t *testing.T) { "-y", ) - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, templateAdmin, conf) err := inv.Run() require.Error(t, err) diff --git a/enterprise/cli/templateedit_test.go b/enterprise/cli/templateedit_test.go index 5c26c19d82..c1b069e938 100644 --- a/enterprise/cli/templateedit_test.go +++ b/enterprise/cli/templateedit_test.go @@ -77,6 +77,7 @@ func TestTemplateEdit(t *testing.T) { IncludeProvisionerDaemon: true, }, }) + templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin()) version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil) _ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) @@ -89,7 +90,7 @@ func TestTemplateEdit(t *testing.T) { "-y", ) - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, templateAdmin, conf) err := inv.Run() require.Error(t, err) diff --git a/enterprise/cli/workspaceproxy_test.go b/enterprise/cli/workspaceproxy_test.go index fd9d241172..df3c955af4 100644 --- a/enterprise/cli/workspaceproxy_test.go +++ b/enterprise/cli/workspaceproxy_test.go @@ -53,7 +53,7 @@ func Test_ProxyCRUD(t *testing.T) { pty := ptytest.New(t) inv.Stdout = pty.Output() - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, client, conf) //nolint:gocritic // create wsproxy requires owner err := inv.WithContext(ctx).Run() require.NoError(t, err) @@ -72,14 +72,14 @@ func Test_ProxyCRUD(t *testing.T) { pty = ptytest.New(t) inv.Stdout = pty.Output() - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, client, conf) //nolint:gocritic // requires owner err = inv.WithContext(ctx).Run() require.NoError(t, err) pty.ExpectMatch(expectedName) // Also check via the api - proxies, err := client.WorkspaceProxies(ctx) + proxies, err := client.WorkspaceProxies(ctx) //nolint:gocritic // requires owner require.NoError(t, err, "failed to get workspace proxies") // Include primary require.Len(t, proxies.Regions, 2, "expected 1 proxy") @@ -128,12 +128,12 @@ func Test_ProxyCRUD(t *testing.T) { pty := ptytest.New(t) inv.Stdout = pty.Output() - clitest.SetupConfig(t, client, conf) + clitest.SetupConfig(t, client, conf) //nolint:gocritic // requires owner err = inv.WithContext(ctx).Run() require.NoError(t, err) - proxies, err := client.WorkspaceProxies(ctx) + proxies, err := client.WorkspaceProxies(ctx) //nolint:gocritic // requires owner require.NoError(t, err, "failed to get workspace proxies") require.Len(t, proxies.Regions, 1, "expected only primary proxy") }) diff --git a/enterprise/coderd/appearance_test.go b/enterprise/coderd/appearance_test.go index 05edf7c11c..ca82e40168 100644 --- a/enterprise/coderd/appearance_test.go +++ b/enterprise/coderd/appearance_test.go @@ -28,13 +28,15 @@ func TestCustomLogoAndCompanyName(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) defer cancel() - adminClient, _ := coderdenttest.New(t, &coderdenttest.Options{DontAddLicense: true}) + adminClient, adminUser := coderdenttest.New(t, &coderdenttest.Options{DontAddLicense: true}) coderdenttest.AddLicense(t, adminClient, coderdenttest.LicenseOptions{ Features: license.Features{ codersdk.FeatureAppearance: 1, }, }) + anotherClient, _ := coderdtest.CreateAnotherUser(t, adminClient, adminUser.OrganizationID) + // Update logo and application name uac := codersdk.UpdateAppearanceConfig{ ApplicationName: "ACME Ltd", @@ -45,7 +47,7 @@ func TestCustomLogoAndCompanyName(t *testing.T) { require.NoError(t, err) // Verify update - got, err := adminClient.Appearance(ctx) + got, err := anotherClient.Appearance(ctx) require.NoError(t, err) require.Equal(t, uac.ApplicationName, got.ApplicationName) @@ -62,9 +64,10 @@ func TestServiceBanners(t *testing.T) { defer cancel() adminClient, adminUser := coderdenttest.New(t, &coderdenttest.Options{DontAddLicense: true}) + basicUserClient, _ := coderdtest.CreateAnotherUser(t, adminClient, adminUser.OrganizationID) // Even without a license, the banner should return as disabled. - sb, err := adminClient.Appearance(ctx) + sb, err := basicUserClient.Appearance(ctx) require.NoError(t, err) require.False(t, sb.ServiceBanner.Enabled) @@ -75,12 +78,10 @@ func TestServiceBanners(t *testing.T) { }) // Default state - sb, err = adminClient.Appearance(ctx) + sb, err = basicUserClient.Appearance(ctx) require.NoError(t, err) require.False(t, sb.ServiceBanner.Enabled) - basicUserClient, _ := coderdtest.CreateAnotherUser(t, adminClient, adminUser.OrganizationID) - uac := codersdk.UpdateAppearanceConfig{ ServiceBanner: sb.ServiceBanner, } @@ -100,7 +101,7 @@ func TestServiceBanners(t *testing.T) { wantBanner.ServiceBanner.BackgroundColor = "#00FF00" err = adminClient.UpdateAppearance(ctx, wantBanner) require.NoError(t, err) - gotBanner, err := adminClient.Appearance(ctx) + gotBanner, err := adminClient.Appearance(ctx) //nolint:gocritic // we should assert at least once that the owner can get the banner require.NoError(t, err) gotBanner.SupportLinks = nil // clean "support links" before comparison require.Equal(t, wantBanner.ServiceBanner, gotBanner.ServiceBanner) @@ -200,7 +201,7 @@ func TestCustomSupportLinks(t *testing.T) { Value: supportLinks, } - client, _ := coderdenttest.New(t, &coderdenttest.Options{ + adminClient, adminUser := coderdenttest.New(t, &coderdenttest.Options{ Options: &coderdtest.Options{ DeploymentValues: cfg, }, @@ -211,10 +212,11 @@ func TestCustomSupportLinks(t *testing.T) { }, }) + anotherClient, _ := coderdtest.CreateAnotherUser(t, adminClient, adminUser.OrganizationID) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium) defer cancel() - appearance, err := client.Appearance(ctx) + appearance, err := anotherClient.Appearance(ctx) require.NoError(t, err) require.Equal(t, supportLinks, appearance.SupportLinks) } @@ -223,12 +225,13 @@ func TestDefaultSupportLinks(t *testing.T) { t.Parallel() // Don't need to set the license, as default links are passed without it. - client, _ := coderdenttest.New(t, &coderdenttest.Options{DontAddLicense: true}) + adminClient, adminUser := coderdenttest.New(t, &coderdenttest.Options{DontAddLicense: true}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, adminClient, adminUser.OrganizationID) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium) defer cancel() - appearance, err := client.Appearance(ctx) + appearance, err := anotherClient.Appearance(ctx) require.NoError(t, err) require.Equal(t, coderd.DefaultSupportLinks, appearance.SupportLinks) } diff --git a/enterprise/coderd/coderd_test.go b/enterprise/coderd/coderd_test.go index 855ecef059..59fbe1818c 100644 --- a/enterprise/coderd/coderd_test.go +++ b/enterprise/coderd/coderd_test.go @@ -38,17 +38,18 @@ func TestEntitlements(t *testing.T) { t.Parallel() t.Run("NoLicense", func(t *testing.T) { t.Parallel() - client, _ := coderdenttest.New(t, &coderdenttest.Options{ + adminClient, adminUser := coderdenttest.New(t, &coderdenttest.Options{ DontAddLicense: true, }) - res, err := client.Entitlements(context.Background()) + anotherClient, _ := coderdtest.CreateAnotherUser(t, adminClient, adminUser.OrganizationID) + res, err := anotherClient.Entitlements(context.Background()) require.NoError(t, err) require.False(t, res.HasLicense) require.Empty(t, res.Warnings) }) t.Run("FullLicense", func(t *testing.T) { t.Parallel() - client, _ := coderdenttest.New(t, &coderdenttest.Options{ + adminClient, _ := coderdenttest.New(t, &coderdenttest.Options{ AuditLogging: true, DontAddLicense: true, }) @@ -58,11 +59,11 @@ func TestEntitlements(t *testing.T) { features[feature] = 1 } features[codersdk.FeatureUserLimit] = 100 - coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{ + coderdenttest.AddLicense(t, adminClient, coderdenttest.LicenseOptions{ Features: features, GraceAt: time.Now().Add(59 * 24 * time.Hour), }) - res, err := client.Entitlements(context.Background()) + res, err := adminClient.Entitlements(context.Background()) //nolint:gocritic // adding another user would put us over user limit require.NoError(t, err) assert.True(t, res.HasLicense) ul := res.Features[codersdk.FeatureUserLimit] @@ -83,27 +84,28 @@ func TestEntitlements(t *testing.T) { }) t.Run("FullLicenseToNone", func(t *testing.T) { t.Parallel() - client, _ := coderdenttest.New(t, &coderdenttest.Options{ + adminClient, adminUser := coderdenttest.New(t, &coderdenttest.Options{ AuditLogging: true, DontAddLicense: true, }) - license := coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{ + anotherClient, _ := coderdtest.CreateAnotherUser(t, adminClient, adminUser.OrganizationID) + license := coderdenttest.AddLicense(t, adminClient, coderdenttest.LicenseOptions{ Features: license.Features{ codersdk.FeatureUserLimit: 100, codersdk.FeatureAuditLog: 1, }, }) - res, err := client.Entitlements(context.Background()) + res, err := anotherClient.Entitlements(context.Background()) require.NoError(t, err) assert.True(t, res.HasLicense) al := res.Features[codersdk.FeatureAuditLog] assert.Equal(t, codersdk.EntitlementEntitled, al.Entitlement) assert.True(t, al.Enabled) - err = client.DeleteLicense(context.Background(), license.ID) + err = adminClient.DeleteLicense(context.Background(), license.ID) require.NoError(t, err) - res, err = client.Entitlements(context.Background()) + res, err = anotherClient.Entitlements(context.Background()) require.NoError(t, err) assert.False(t, res.HasLicense) al = res.Features[codersdk.FeatureAuditLog] @@ -112,8 +114,9 @@ func TestEntitlements(t *testing.T) { }) t.Run("Pubsub", func(t *testing.T) { t.Parallel() - client, _, api, _ := coderdenttest.NewWithAPI(t, &coderdenttest.Options{DontAddLicense: true}) - entitlements, err := client.Entitlements(context.Background()) + adminClient, _, api, adminUser := coderdenttest.NewWithAPI(t, &coderdenttest.Options{DontAddLicense: true}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, adminClient, adminUser.OrganizationID) + entitlements, err := anotherClient.Entitlements(context.Background()) require.NoError(t, err) require.False(t, entitlements.HasLicense) //nolint:gocritic // unit test @@ -131,18 +134,19 @@ func TestEntitlements(t *testing.T) { err = api.Pubsub.Publish(coderd.PubsubEventLicenses, []byte{}) require.NoError(t, err) require.Eventually(t, func() bool { - entitlements, err := client.Entitlements(context.Background()) + entitlements, err := anotherClient.Entitlements(context.Background()) assert.NoError(t, err) return entitlements.HasLicense }, testutil.WaitShort, testutil.IntervalFast) }) t.Run("Resync", func(t *testing.T) { t.Parallel() - client, _, api, _ := coderdenttest.NewWithAPI(t, &coderdenttest.Options{ + adminClient, _, api, adminUser := coderdenttest.NewWithAPI(t, &coderdenttest.Options{ EntitlementsUpdateInterval: 25 * time.Millisecond, DontAddLicense: true, }) - entitlements, err := client.Entitlements(context.Background()) + anotherClient, _ := coderdtest.CreateAnotherUser(t, adminClient, adminUser.OrganizationID) + entitlements, err := anotherClient.Entitlements(context.Background()) require.NoError(t, err) require.False(t, entitlements.HasLicense) // Valid @@ -177,7 +181,7 @@ func TestEntitlements(t *testing.T) { }) require.NoError(t, err) require.Eventually(t, func() bool { - entitlements, err := client.Entitlements(context.Background()) + entitlements, err := anotherClient.Entitlements(context.Background()) assert.NoError(t, err) return entitlements.HasLicense }, testutil.WaitShort, testutil.IntervalFast) @@ -224,7 +228,7 @@ func TestAuditLogging(t *testing.T) { DontAddLicense: true, }) workspace, agent := setupWorkspaceAgent(t, client, user, 0) - conn, err := client.DialWorkspaceAgent(ctx, agent.ID, nil) + conn, err := client.DialWorkspaceAgent(ctx, agent.ID, nil) //nolint:gocritic // RBAC is not the purpose of this test require.NoError(t, err) defer conn.Close() connected := conn.AwaitReachable(ctx) diff --git a/enterprise/coderd/groups_test.go b/enterprise/coderd/groups_test.go index bfbfffa5ee..90d52ea92b 100644 --- a/enterprise/coderd/groups_test.go +++ b/enterprise/coderd/groups_test.go @@ -10,6 +10,7 @@ import ( "github.com/coder/coder/v2/coderd/audit" "github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/database" + "github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/coderd/util/ptr" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest" @@ -28,8 +29,9 @@ func TestCreateGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", AvatarURL: "https://example.com", }) @@ -58,18 +60,21 @@ func TestCreateGroup(t *testing.T) { }, }, }) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) ctx := testutil.Context(t, testutil.WaitLong) numLogs := len(auditor.AuditLogs()) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.NoError(t, err) numLogs++ require.Len(t, auditor.AuditLogs(), numLogs) - require.Equal(t, database.AuditActionCreate, auditor.AuditLogs()[numLogs-1].Action) - require.Equal(t, group.ID, auditor.AuditLogs()[numLogs-1].ResourceID) + require.True(t, auditor.Contains(t, database.AuditLog{ + Action: database.AuditActionCreate, + ResourceID: group.ID, + })) }) t.Run("Conflict", func(t *testing.T) { @@ -80,13 +85,14 @@ func TestCreateGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) ctx := testutil.Context(t, testutil.WaitLong) - _, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + _, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.NoError(t, err) - _, err = client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + _, err = userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.Error(t, err) @@ -103,8 +109,9 @@ func TestCreateGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) ctx := testutil.Context(t, testutil.WaitLong) - _, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + _, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: database.EveryoneGroup, }) require.Error(t, err) @@ -125,9 +132,10 @@ func TestPatchGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) const displayName = "foobar" ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", AvatarURL: "https://example.com", QuotaAllowance: 10, @@ -136,7 +144,7 @@ func TestPatchGroup(t *testing.T) { require.NoError(t, err) require.Equal(t, 10, group.QuotaAllowance) - group, err = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ + group, err = userAdminClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ Name: "bye", AvatarURL: ptr.Ref("https://google.com"), QuotaAllowance: ptr.Ref(20), @@ -157,9 +165,10 @@ func TestPatchGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) const displayName = "foobar" ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", AvatarURL: "https://example.com", QuotaAllowance: 10, @@ -168,7 +177,7 @@ func TestPatchGroup(t *testing.T) { require.NoError(t, err) require.Equal(t, 10, group.QuotaAllowance) - group, err = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ + group, err = userAdminClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ Name: "bye", AvatarURL: ptr.Ref("https://google.com"), QuotaAllowance: ptr.Ref(20), @@ -191,13 +200,14 @@ func TestPatchGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.NoError(t, err) - group, err = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ + group, err = userAdminClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ Name: "hi", }) require.NoError(t, err) @@ -212,16 +222,17 @@ func TestPatchGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user3 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.NoError(t, err) - group, err = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ + group, err = userAdminClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ AddUsers: []string{user2.ID.String(), user3.ID.String()}, }) require.NoError(t, err) @@ -237,24 +248,25 @@ func TestPatchGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user3 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user4 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.NoError(t, err) - group, err = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ + group, err = userAdminClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ AddUsers: []string{user2.ID.String(), user3.ID.String(), user4.ID.String()}, }) require.NoError(t, err) require.Contains(t, group.Members, user2) require.Contains(t, group.Members, user3) - group, err = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ + group, err = userAdminClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ RemoveUsers: []string{user2.ID.String(), user3.ID.String()}, }) require.NoError(t, err) @@ -280,15 +292,16 @@ func TestPatchGroup(t *testing.T) { }, }, }) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.NoError(t, err) numLogs := len(auditor.AuditLogs()) - group, err = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ + group, err = userAdminClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ Name: "bye", }) require.NoError(t, err) @@ -306,19 +319,20 @@ func TestPatchGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) ctx := testutil.Context(t, testutil.WaitLong) - group1, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group1, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", AvatarURL: "https://example.com", }) require.NoError(t, err) - group2, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group2, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "bye", }) require.NoError(t, err) - group1, err = client.PatchGroup(ctx, group1.ID, codersdk.PatchGroupRequest{ + group1, err = userAdminClient.PatchGroup(ctx, group1.ID, codersdk.PatchGroupRequest{ Name: group2.Name, AvatarURL: ptr.Ref("https://google.com"), }) @@ -336,13 +350,14 @@ func TestPatchGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.NoError(t, err) - group, err = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ + group, err = userAdminClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ AddUsers: []string{uuid.NewString()}, }) require.Error(t, err) @@ -359,13 +374,14 @@ func TestPatchGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.NoError(t, err) - group, err = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ + group, err = userAdminClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ AddUsers: []string{"yeet"}, }) require.Error(t, err) @@ -382,14 +398,15 @@ func TestPatchGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.NoError(t, err) - group, err = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ + group, err = userAdminClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ AddUsers: []string{user2.ID.String(), user2.ID.String()}, }) require.Error(t, err) @@ -407,13 +424,14 @@ func TestPatchGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.NoError(t, err) - group, err = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ + group, err = userAdminClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ Name: database.EveryoneGroup, }) require.Error(t, err) @@ -432,8 +450,9 @@ func TestPatchGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) ctx := testutil.Context(t, testutil.WaitLong) - _, err := client.PatchGroup(ctx, user.OrganizationID, codersdk.PatchGroupRequest{ + _, err := userAdminClient.PatchGroup(ctx, user.OrganizationID, codersdk.PatchGroupRequest{ Name: "hi", }) require.Error(t, err) @@ -450,8 +469,9 @@ func TestPatchGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) ctx := testutil.Context(t, testutil.WaitLong) - _, err := client.PatchGroup(ctx, user.OrganizationID, codersdk.PatchGroupRequest{ + _, err := userAdminClient.PatchGroup(ctx, user.OrganizationID, codersdk.PatchGroupRequest{ DisplayName: ptr.Ref("hi"), }) require.Error(t, err) @@ -468,10 +488,11 @@ func TestPatchGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) ctx := testutil.Context(t, testutil.WaitLong) - _, err := client.PatchGroup(ctx, user.OrganizationID, codersdk.PatchGroupRequest{ + _, err := userAdminClient.PatchGroup(ctx, user.OrganizationID, codersdk.PatchGroupRequest{ AddUsers: []string{user2.ID.String()}, }) require.Error(t, err) @@ -488,9 +509,10 @@ func TestPatchGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) ctx := testutil.Context(t, testutil.WaitLong) - _, err := client.PatchGroup(ctx, user.OrganizationID, codersdk.PatchGroupRequest{ + _, err := userAdminClient.PatchGroup(ctx, user.OrganizationID, codersdk.PatchGroupRequest{ RemoveUsers: []string{user.UserID.String()}, }) require.Error(t, err) @@ -507,15 +529,16 @@ func TestPatchGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.Group(ctx, user.OrganizationID) + group, err := userAdminClient.Group(ctx, user.OrganizationID) require.NoError(t, err) require.Equal(t, 0, group.QuotaAllowance) expectedQuota := 123 - group, err = client.PatchGroup(ctx, user.OrganizationID, codersdk.PatchGroupRequest{ + group, err = userAdminClient.PatchGroup(ctx, user.OrganizationID, codersdk.PatchGroupRequest{ QuotaAllowance: ptr.Ref(expectedQuota), }) require.NoError(t, err) @@ -536,13 +559,14 @@ func TestGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.NoError(t, err) - ggroup, err := client.Group(ctx, group.ID) + ggroup, err := userAdminClient.Group(ctx, group.ID) require.NoError(t, err) require.Equal(t, group, ggroup) }) @@ -555,13 +579,14 @@ func TestGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.NoError(t, err) - ggroup, err := client.GroupByOrgAndName(ctx, group.OrganizationID, group.Name) + ggroup, err := userAdminClient.GroupByOrgAndName(ctx, group.OrganizationID, group.Name) require.NoError(t, err) require.Equal(t, group, ggroup) }) @@ -574,23 +599,24 @@ func TestGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user3 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.NoError(t, err) - group, err = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ + group, err = userAdminClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ AddUsers: []string{user2.ID.String(), user3.ID.String()}, }) require.NoError(t, err) require.Contains(t, group.Members, user2) require.Contains(t, group.Members, user3) - ggroup, err := client.Group(ctx, group.ID) + ggroup, err := userAdminClient.Group(ctx, group.ID) require.NoError(t, err) require.Equal(t, group, ggroup) }) @@ -606,6 +632,7 @@ func TestGroup(t *testing.T) { client1, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) ctx := testutil.Context(t, testutil.WaitLong) + //nolint:gocritic // test setup group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) @@ -623,27 +650,28 @@ func TestGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) _, user1 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.NoError(t, err) - group, err = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ + group, err = userAdminClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ AddUsers: []string{user1.ID.String(), user2.ID.String()}, }) require.NoError(t, err) require.Contains(t, group.Members, user1) require.Contains(t, group.Members, user2) - err = client.DeleteUser(ctx, user1.ID) + err = userAdminClient.DeleteUser(ctx, user1.ID) require.NoError(t, err) - group, err = client.Group(ctx, group.ID) + group, err = userAdminClient.Group(ctx, group.ID) require.NoError(t, err) require.NotContains(t, group.Members, user1) }) @@ -656,17 +684,18 @@ func TestGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) _, user1 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.NoError(t, err) - group, err = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ + group, err = userAdminClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ AddUsers: []string{user1.ID.String(), user2.ID.String()}, }) require.NoError(t, err) @@ -674,17 +703,17 @@ func TestGroup(t *testing.T) { require.Contains(t, group.Members, user1) require.Contains(t, group.Members, user2) - user1, err = client.UpdateUserStatus(ctx, user1.ID.String(), codersdk.UserStatusSuspended) + user1, err = userAdminClient.UpdateUserStatus(ctx, user1.ID.String(), codersdk.UserStatusSuspended) require.NoError(t, err) - group, err = client.Group(ctx, group.ID) + group, err = userAdminClient.Group(ctx, group.ID) require.NoError(t, err) require.Len(t, group.Members, 2) require.Contains(t, group.Members, user1) require.Contains(t, group.Members, user2) // cannot explicitly set a dormant user status so must create a new user - anotherUser, err := client.CreateUser(ctx, codersdk.CreateUserRequest{ + anotherUser, err := userAdminClient.CreateUser(ctx, codersdk.CreateUserRequest{ Email: "coder@coder.com", Username: "coder", Password: "SomeStrongPassword!", @@ -695,11 +724,11 @@ func TestGroup(t *testing.T) { // Ensure that new user has dormant account require.Equal(t, codersdk.UserStatusDormant, anotherUser.Status) - group, _ = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ + group, _ = userAdminClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ AddUsers: []string{anotherUser.ID.String()}, }) - group, err = client.Group(ctx, group.ID) + group, err = userAdminClient.Group(ctx, group.ID) require.NoError(t, err) require.Len(t, group.Members, 3) require.Contains(t, group.Members, user1) @@ -714,14 +743,15 @@ func TestGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) _, user1 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) ctx := testutil.Context(t, testutil.WaitLong) // The 'Everyone' group always has an ID that matches the organization ID. - group, err := client.Group(ctx, user.OrganizationID) + group, err := userAdminClient.Group(ctx, user.OrganizationID) require.NoError(t, err) - require.Len(t, group.Members, 3) + require.Len(t, group.Members, 4) require.Equal(t, "Everyone", group.Name) require.Equal(t, user.OrganizationID, group.OrganizationID) require.Contains(t, group.Members, user1, user2) @@ -740,33 +770,34 @@ func TestGroups(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user3 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user4 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user5 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) ctx := testutil.Context(t, testutil.WaitLong) - group1, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group1, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.NoError(t, err) - group2, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group2, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hey", }) require.NoError(t, err) - group1, err = client.PatchGroup(ctx, group1.ID, codersdk.PatchGroupRequest{ + group1, err = userAdminClient.PatchGroup(ctx, group1.ID, codersdk.PatchGroupRequest{ AddUsers: []string{user2.ID.String(), user3.ID.String()}, }) require.NoError(t, err) - group2, err = client.PatchGroup(ctx, group2.ID, codersdk.PatchGroupRequest{ + group2, err = userAdminClient.PatchGroup(ctx, group2.ID, codersdk.PatchGroupRequest{ AddUsers: []string{user4.ID.String(), user5.ID.String()}, }) require.NoError(t, err) - groups, err := client.GroupsByOrganization(ctx, user.OrganizationID) + groups, err := userAdminClient.GroupsByOrganization(ctx, user.OrganizationID) require.NoError(t, err) // 'Everyone' group + 2 custom groups. require.Len(t, groups, 3) @@ -786,16 +817,17 @@ func TestDeleteGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) ctx := testutil.Context(t, testutil.WaitLong) - group1, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group1, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.NoError(t, err) - err = client.DeleteGroup(ctx, group1.ID) + err = userAdminClient.DeleteGroup(ctx, group1.ID) require.NoError(t, err) - _, err = client.Group(ctx, group1.ID) + _, err = userAdminClient.Group(ctx, group1.ID) require.Error(t, err) cerr, ok := codersdk.AsError(err) require.True(t, ok) @@ -813,6 +845,7 @@ func TestDeleteGroup(t *testing.T) { Auditor: auditor, }, }) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) _ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{ Features: license.Features{ @@ -822,19 +855,21 @@ func TestDeleteGroup(t *testing.T) { }) ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "hi", }) require.NoError(t, err) numLogs := len(auditor.AuditLogs()) - err = client.DeleteGroup(ctx, group.ID) + err = userAdminClient.DeleteGroup(ctx, group.ID) require.NoError(t, err) numLogs++ require.Len(t, auditor.AuditLogs(), numLogs) - require.Equal(t, database.AuditActionDelete, auditor.AuditLogs()[numLogs-1].Action) - require.Equal(t, group.ID, auditor.AuditLogs()[numLogs-1].ResourceID) + require.True(t, auditor.Contains(t, database.AuditLog{ + Action: database.AuditActionDelete, + ResourceID: group.ID, + })) }) t.Run("allUsers", func(t *testing.T) { @@ -845,8 +880,9 @@ func TestDeleteGroup(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin()) ctx := testutil.Context(t, testutil.WaitLong) - err := client.DeleteGroup(ctx, user.OrganizationID) + err := userAdminClient.DeleteGroup(ctx, user.OrganizationID) require.Error(t, err) cerr, ok := codersdk.AsError(err) require.True(t, ok) diff --git a/enterprise/coderd/insights_test.go b/enterprise/coderd/insights_test.go index 0af7b7ad94..22753ee60f 100644 --- a/enterprise/coderd/insights_test.go +++ b/enterprise/coderd/insights_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/require" "github.com/coder/coder/v2/coderd/coderdtest" + "github.com/coder/coder/v2/coderd/rbac" "github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest" "github.com/coder/coder/v2/enterprise/coderd/license" @@ -41,6 +42,7 @@ func TestTemplateInsightsWithTemplateAdminACL(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + templateAdminClient, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID, rbac.RoleTemplateAdmin()) version := coderdtest.CreateTemplateVersion(t, client, admin.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, admin.OrganizationID, version.ID) @@ -50,7 +52,7 @@ func TestTemplateInsightsWithTemplateAdminACL(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort) defer cancel() - err := client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ + err := templateAdminClient.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ UserPerms: map[string]codersdk.TemplateRole{ regularUser.ID.String(): codersdk.TemplateRoleAdmin, }, diff --git a/enterprise/coderd/licenses_test.go b/enterprise/coderd/licenses_test.go index be340e44d3..e6f27717e2 100644 --- a/enterprise/coderd/licenses_test.go +++ b/enterprise/coderd/licenses_test.go @@ -148,6 +148,7 @@ func TestDeleteLicense(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) defer cancel() + //nolint:gocritic // RBAC is irrelevant here. resp, err := client.Request(ctx, http.MethodDelete, "/api/v2/licenses/drivers", nil) require.NoError(t, err) assert.Equal(t, http.StatusNotFound, resp.StatusCode) diff --git a/enterprise/coderd/provisionerdaemons_test.go b/enterprise/coderd/provisionerdaemons_test.go index b5516bff2a..b1348c2878 100644 --- a/enterprise/coderd/provisionerdaemons_test.go +++ b/enterprise/coderd/provisionerdaemons_test.go @@ -36,9 +36,10 @@ func TestProvisionerDaemonServe(t *testing.T) { codersdk.FeatureExternalProvisionerDaemons: 1, }, }}) + templateAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) defer cancel() - srv, err := client.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{ + srv, err := templateAdminClient.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{ Organization: user.OrganizationID, Provisioners: []codersdk.ProvisionerType{ codersdk.ProvisionerTypeEcho, @@ -52,9 +53,10 @@ func TestProvisionerDaemonServe(t *testing.T) { t.Run("NoLicense", func(t *testing.T) { t.Parallel() client, user := coderdenttest.New(t, &coderdenttest.Options{DontAddLicense: true}) + templateAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) defer cancel() - _, err := client.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{ + _, err := templateAdminClient.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{ Organization: user.OrganizationID, Provisioners: []codersdk.ProvisionerType{ codersdk.ProvisionerTypeEcho, @@ -149,6 +151,7 @@ func TestProvisionerDaemonServe(t *testing.T) { ProvisionApply: echo.ProvisionApplyWithAgent(authToken), }) require.NoError(t, err) + //nolint:gocritic // Not testing file upload in this test. file, err := client.Upload(context.Background(), codersdk.ContentTypeTar, bytes.NewReader(data)) require.NoError(t, err) @@ -258,6 +261,7 @@ func TestProvisionerDaemonServe(t *testing.T) { defer pd.Close() // Patch the 'Everyone' group to give the user quota to build their workspace. + //nolint:gocritic // Not testing RBAC here. _, err := client.PatchGroup(ctx, user.OrganizationID, codersdk.PatchGroupRequest{ QuotaAllowance: ptr.Ref(1), }) diff --git a/enterprise/coderd/scim_test.go b/enterprise/coderd/scim_test.go index 3d12c3402a..95d297605e 100644 --- a/enterprise/coderd/scim_test.go +++ b/enterprise/coderd/scim_test.go @@ -51,6 +51,7 @@ func setScimAuth(key []byte) func(*http.Request) { } } +//nolint:gocritic // SCIM authenticates via a special header and bypasses internal RBAC. func TestScim(t *testing.T) { t.Parallel() diff --git a/enterprise/coderd/templates_test.go b/enterprise/coderd/templates_test.go index 6b51e706e2..9ff7799553 100644 --- a/enterprise/coderd/templates_test.go +++ b/enterprise/coderd/templates_test.go @@ -39,6 +39,7 @@ func TestTemplates(t *testing.T) { }, }, }) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) exp := 24 * time.Hour.Milliseconds() @@ -56,7 +57,7 @@ func TestTemplates(t *testing.T) { TemplateID: template.ID, Name: "testing", } - ws, err := client.CreateWorkspace(ctx, template.OrganizationID, codersdk.Me, req) + ws, err := anotherClient.CreateWorkspace(ctx, template.OrganizationID, codersdk.Me, req) require.NoError(t, err) require.NotNil(t, ws.TTLMillis) require.EqualValues(t, exp, *ws.TTLMillis) @@ -64,7 +65,7 @@ func TestTemplates(t *testing.T) { // Editing a workspace to have a higher TTL than the template's max // should error exp = exp + time.Minute.Milliseconds() - err = client.UpdateWorkspaceTTL(ctx, ws.ID, codersdk.UpdateWorkspaceTTLRequest{ + err = anotherClient.UpdateWorkspaceTTL(ctx, ws.ID, codersdk.UpdateWorkspaceTTLRequest{ TTLMillis: &exp, }) require.Error(t, err) @@ -78,7 +79,7 @@ func TestTemplates(t *testing.T) { // Creating workspace with TTL higher than max should error req.Name = "testing2" req.TTLMillis = &exp - ws, err = client.CreateWorkspace(ctx, template.OrganizationID, codersdk.Me, req) + ws, err = anotherClient.CreateWorkspace(ctx, template.OrganizationID, codersdk.Me, req) require.Error(t, err) apiErr = nil require.ErrorAs(t, err, &apiErr) @@ -100,6 +101,7 @@ func TestTemplates(t *testing.T) { }, }, }) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) exp := 24 * time.Hour.Milliseconds() @@ -116,27 +118,27 @@ func TestTemplates(t *testing.T) { TemplateID: template.ID, Name: "testing", } - ws, err := client.CreateWorkspace(ctx, template.OrganizationID, codersdk.Me, req) + ws, err := anotherClient.CreateWorkspace(ctx, template.OrganizationID, codersdk.Me, req) require.NoError(t, err) require.NotNil(t, ws.TTLMillis) require.EqualValues(t, exp, *ws.TTLMillis) // Editing a workspace to disable the TTL should do nothing - err = client.UpdateWorkspaceTTL(ctx, ws.ID, codersdk.UpdateWorkspaceTTLRequest{ + err = anotherClient.UpdateWorkspaceTTL(ctx, ws.ID, codersdk.UpdateWorkspaceTTLRequest{ TTLMillis: nil, }) require.NoError(t, err) - ws, err = client.Workspace(ctx, ws.ID) + ws, err = anotherClient.Workspace(ctx, ws.ID) require.NoError(t, err) require.EqualValues(t, exp, *ws.TTLMillis) // Editing a workspace to have a TTL of 0 should do nothing zero := int64(0) - err = client.UpdateWorkspaceTTL(ctx, ws.ID, codersdk.UpdateWorkspaceTTLRequest{ + err = anotherClient.UpdateWorkspaceTTL(ctx, ws.ID, codersdk.UpdateWorkspaceTTLRequest{ TTLMillis: &zero, }) require.NoError(t, err) - ws, err = client.Workspace(ctx, ws.ID) + ws, err = anotherClient.Workspace(ctx, ws.ID) require.NoError(t, err) require.EqualValues(t, exp, *ws.TTLMillis) }) @@ -154,6 +156,7 @@ func TestTemplates(t *testing.T) { }, }, }) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) @@ -161,7 +164,7 @@ func TestTemplates(t *testing.T) { require.Equal(t, []string{"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"}, template.AutostartRequirement.DaysOfWeek) ctx := testutil.Context(t, testutil.WaitLong) - updated, err := client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ + updated, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ Name: template.Name, DisplayName: template.DisplayName, Description: template.Description, @@ -173,12 +176,12 @@ func TestTemplates(t *testing.T) { require.NoError(t, err) require.Equal(t, []string{"monday", "saturday"}, updated.AutostartRequirement.DaysOfWeek) - template, err = client.Template(ctx, template.ID) + template, err = anotherClient.Template(ctx, template.ID) require.NoError(t, err) require.Equal(t, []string{"monday", "saturday"}, template.AutostartRequirement.DaysOfWeek) // Ensure a missing field is a noop - updated, err = client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ + updated, err = anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ Name: template.Name, DisplayName: template.DisplayName, Description: template.Description, @@ -187,7 +190,7 @@ func TestTemplates(t *testing.T) { require.NoError(t, err) require.Equal(t, []string{"monday", "saturday"}, updated.AutostartRequirement.DaysOfWeek) - template, err = client.Template(ctx, template.ID) + template, err = anotherClient.Template(ctx, template.ID) require.NoError(t, err) require.Equal(t, []string{"monday", "saturday"}, template.AutostartRequirement.DaysOfWeek) }) @@ -205,6 +208,7 @@ func TestTemplates(t *testing.T) { }, }, }) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) @@ -212,7 +216,7 @@ func TestTemplates(t *testing.T) { require.Equal(t, []string{"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"}, template.AutostartRequirement.DaysOfWeek) ctx := testutil.Context(t, testutil.WaitLong) - _, err := client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ + _, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ Name: template.Name, DisplayName: template.DisplayName, Description: template.Description, @@ -237,6 +241,7 @@ func TestTemplates(t *testing.T) { }, }, }) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) @@ -244,9 +249,8 @@ func TestTemplates(t *testing.T) { require.Empty(t, 0, template.AutostopRequirement.DaysOfWeek) require.EqualValues(t, 1, template.AutostopRequirement.Weeks) - // ctx := testutil.Context(t, testutil.WaitLong) ctx := context.Background() - updated, err := client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ + updated, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ Name: template.Name, DisplayName: template.DisplayName, Description: template.Description, @@ -262,7 +266,7 @@ func TestTemplates(t *testing.T) { require.Equal(t, []string{"monday", "saturday"}, updated.AutostopRequirement.DaysOfWeek) require.EqualValues(t, 3, updated.AutostopRequirement.Weeks) - template, err = client.Template(ctx, template.ID) + template, err = anotherClient.Template(ctx, template.ID) require.NoError(t, err) require.Equal(t, []string{"monday", "saturday"}, template.AutostopRequirement.DaysOfWeek) require.EqualValues(t, 3, template.AutostopRequirement.Weeks) @@ -283,6 +287,7 @@ func TestTemplates(t *testing.T) { }, }, }) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) @@ -297,7 +302,7 @@ func TestTemplates(t *testing.T) { dormantTTL = 3 * time.Minute ) - updated, err := client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ + updated, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ Name: template.Name, DisplayName: template.DisplayName, Description: template.Description, @@ -314,7 +319,7 @@ func TestTemplates(t *testing.T) { // Validate fetching the template returns the same values as updating // the template. - template, err = client.Template(ctx, template.ID) + template, err = anotherClient.Template(ctx, template.ID) require.NoError(t, err) require.Equal(t, failureTTL.Milliseconds(), updated.FailureTTLMillis) require.Equal(t, inactivityTTL.Milliseconds(), updated.TimeTilDormantMillis) @@ -335,6 +340,7 @@ func TestTemplates(t *testing.T) { }, }, }) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) @@ -367,7 +373,7 @@ func TestTemplates(t *testing.T) { // nolint: paralleltest // context is from parent t.Run t.Run(c.Name, func(t *testing.T) { - _, err := client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ + _, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ Name: template.Name, DisplayName: template.DisplayName, Description: template.Description, @@ -401,19 +407,20 @@ func TestTemplates(t *testing.T) { }, }, }) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) - activeWS := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) - dormantWS := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) + activeWS := coderdtest.CreateWorkspace(t, anotherClient, user.OrganizationID, template.ID) + dormantWS := coderdtest.CreateWorkspace(t, anotherClient, user.OrganizationID, template.ID) require.Nil(t, activeWS.DeletingAt) require.Nil(t, dormantWS.DeletingAt) _ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, activeWS.LatestBuild.ID) _ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, dormantWS.LatestBuild.ID) - err := client.UpdateWorkspaceDormancy(ctx, dormantWS.ID, codersdk.UpdateWorkspaceDormancy{ + err := anotherClient.UpdateWorkspaceDormancy(ctx, dormantWS.ID, codersdk.UpdateWorkspaceDormancy{ Dormant: true, }) require.NoError(t, err) @@ -424,7 +431,7 @@ func TestTemplates(t *testing.T) { require.Nil(t, dormantWS.DeletingAt) dormantTTL := time.Minute - updated, err := client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ + updated, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ TimeTilDormantAutoDeleteMillis: dormantTTL.Milliseconds(), }) require.NoError(t, err) @@ -442,7 +449,7 @@ func TestTemplates(t *testing.T) { // Disable the time_til_dormant_auto_delete on the template, then we can assert that the workspaces // no longer have a deleting_at field. - updated, err = client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ + updated, err = anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ TimeTilDormantAutoDeleteMillis: 0, }) require.NoError(t, err) @@ -474,19 +481,20 @@ func TestTemplates(t *testing.T) { }, }, }) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) - activeWS := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) - dormantWS := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) + activeWS := coderdtest.CreateWorkspace(t, anotherClient, user.OrganizationID, template.ID) + dormantWS := coderdtest.CreateWorkspace(t, anotherClient, user.OrganizationID, template.ID) require.Nil(t, activeWS.DeletingAt) require.Nil(t, dormantWS.DeletingAt) _ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, activeWS.LatestBuild.ID) _ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, dormantWS.LatestBuild.ID) - err := client.UpdateWorkspaceDormancy(ctx, dormantWS.ID, codersdk.UpdateWorkspaceDormancy{ + err := anotherClient.UpdateWorkspaceDormancy(ctx, dormantWS.ID, codersdk.UpdateWorkspaceDormancy{ Dormant: true, }) require.NoError(t, err) @@ -497,6 +505,7 @@ func TestTemplates(t *testing.T) { require.Nil(t, dormantWS.DeletingAt) dormantTTL := time.Minute + //nolint:gocritic // non-template-admin cannot update template meta updated, err := client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ TimeTilDormantAutoDeleteMillis: dormantTTL.Milliseconds(), UpdateWorkspaceDormantAt: true, @@ -530,19 +539,20 @@ func TestTemplates(t *testing.T) { }, }, }) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) - activeWorkspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) - dormantWorkspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) + activeWorkspace := coderdtest.CreateWorkspace(t, anotherClient, user.OrganizationID, template.ID) + dormantWorkspace := coderdtest.CreateWorkspace(t, anotherClient, user.OrganizationID, template.ID) require.Nil(t, activeWorkspace.DeletingAt) require.Nil(t, dormantWorkspace.DeletingAt) _ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, activeWorkspace.LatestBuild.ID) _ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, dormantWorkspace.LatestBuild.ID) - err := client.UpdateWorkspaceDormancy(ctx, dormantWorkspace.ID, codersdk.UpdateWorkspaceDormancy{ + err := anotherClient.UpdateWorkspaceDormancy(ctx, dormantWorkspace.ID, codersdk.UpdateWorkspaceDormancy{ Dormant: true, }) require.NoError(t, err) @@ -553,7 +563,7 @@ func TestTemplates(t *testing.T) { require.Nil(t, dormantWorkspace.DeletingAt) inactivityTTL := time.Minute - updated, err := client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ + updated, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ TimeTilDormantMillis: inactivityTTL.Milliseconds(), UpdateWorkspaceLastUsedAt: true, }) @@ -586,6 +596,7 @@ func TestTemplates(t *testing.T) { }, }, }) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID, func(ctr *codersdk.CreateTemplateRequest) { @@ -598,14 +609,14 @@ func TestTemplates(t *testing.T) { defer cancel() // Update the field and assert it persists. - updatedTemplate, err := client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ + updatedTemplate, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ RequireActiveVersion: false, }) require.NoError(t, err) require.False(t, updatedTemplate.RequireActiveVersion) // Flip it back to ensure we aren't hardcoding to a default value. - updatedTemplate, err = client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ + updatedTemplate, err = anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ RequireActiveVersion: true, }) require.NoError(t, err) @@ -613,7 +624,7 @@ func TestTemplates(t *testing.T) { // Assert that fetching a template is no different from the response // when updating. - template, err = client.Template(ctx, template.ID) + template, err = anotherClient.Template(ctx, template.ID) require.NoError(t, err) require.Equal(t, updatedTemplate, template) }) @@ -629,6 +640,7 @@ func TestTemplateACL(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user3 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) @@ -637,7 +649,7 @@ func TestTemplateACL(t *testing.T) { ctx := testutil.Context(t, testutil.WaitLong) - err := client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ + err := anotherClient.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ UserPerms: map[string]codersdk.TemplateRole{ user2.ID.String(): codersdk.TemplateRoleUse, user3.ID.String(): codersdk.TemplateRoleAdmin, @@ -645,7 +657,7 @@ func TestTemplateACL(t *testing.T) { }) require.NoError(t, err) - acl, err := client.TemplateACL(ctx, template.ID) + acl, err := anotherClient.TemplateACL(ctx, template.ID) require.NoError(t, err) templateUser2 := codersdk.TemplateUser{ @@ -672,14 +684,14 @@ func TestTemplateACL(t *testing.T) { }}) // Create a user to assert they aren't returned in the response. - _, _ = coderdtest.CreateAnotherUser(t, client, user.OrganizationID) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) defer cancel() - acl, err := client.TemplateACL(ctx, template.ID) + acl, err := anotherClient.TemplateACL(ctx, template.ID) require.NoError(t, err) require.Len(t, acl.Groups, 1) @@ -702,6 +714,7 @@ func TestTemplateACL(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) defer cancel() + //nolint:gocritic // non-template-admin cannot update template acl acl, err := client.TemplateACL(ctx, template.ID) require.NoError(t, err) @@ -721,6 +734,7 @@ func TestTemplateACL(t *testing.T) { }) require.NoError(t, err) + //nolint:gocritic // non-template-admin cannot update template acl acl, err = client.TemplateACL(ctx, template.ID) require.NoError(t, err) @@ -744,6 +758,7 @@ func TestTemplateACL(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin(), rbac.RoleUserAdmin()) _, user1 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) @@ -751,24 +766,24 @@ func TestTemplateACL(t *testing.T) { ctx := testutil.Context(t, testutil.WaitLong) - err := client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ + err := anotherClient.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ UserPerms: map[string]codersdk.TemplateRole{ user1.ID.String(): codersdk.TemplateRoleUse, }, }) require.NoError(t, err) - acl, err := client.TemplateACL(ctx, template.ID) + acl, err := anotherClient.TemplateACL(ctx, template.ID) require.NoError(t, err) require.Contains(t, acl.Users, codersdk.TemplateUser{ User: user1, Role: codersdk.TemplateRoleUse, }) - err = client.DeleteUser(ctx, user1.ID) + err = anotherClient.DeleteUser(ctx, user1.ID) require.NoError(t, err) - acl, err = client.TemplateACL(ctx, template.ID) + acl, err = anotherClient.TemplateACL(ctx, template.ID) require.NoError(t, err) require.Len(t, acl.Users, 0, "deleted users should be filtered") }) @@ -782,6 +797,7 @@ func TestTemplateACL(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin(), rbac.RoleUserAdmin()) _, user1 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) @@ -789,24 +805,24 @@ func TestTemplateACL(t *testing.T) { ctx := testutil.Context(t, testutil.WaitLong) - err := client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ + err := anotherClient.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ UserPerms: map[string]codersdk.TemplateRole{ user1.ID.String(): codersdk.TemplateRoleUse, }, }) require.NoError(t, err) - acl, err := client.TemplateACL(ctx, template.ID) + acl, err := anotherClient.TemplateACL(ctx, template.ID) require.NoError(t, err) require.Contains(t, acl.Users, codersdk.TemplateUser{ User: user1, Role: codersdk.TemplateRoleUse, }) - _, err = client.UpdateUserStatus(ctx, user1.ID.String(), codersdk.UserStatusSuspended) + _, err = anotherClient.UpdateUserStatus(ctx, user1.ID.String(), codersdk.UserStatusSuspended) require.NoError(t, err) - acl, err = client.TemplateACL(ctx, template.ID) + acl, err = anotherClient.TemplateACL(ctx, template.ID) require.NoError(t, err) require.Len(t, acl.Users, 0, "suspended users should be filtered") }) @@ -820,25 +836,26 @@ func TestTemplateACL(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin(), rbac.RoleUserAdmin()) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) ctx := testutil.Context(t, testutil.WaitLong) - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := anotherClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "test", }) require.NoError(t, err) - err = client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ + err = anotherClient.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ GroupPerms: map[string]codersdk.TemplateRole{ group.ID.String(): codersdk.TemplateRoleUse, }, }) require.NoError(t, err) - acl, err := client.TemplateACL(ctx, template.ID) + acl, err := anotherClient.TemplateACL(ctx, template.ID) require.NoError(t, err) // Length should be 2 for test group and the implicit allUsers group. require.Len(t, acl.Groups, 2) @@ -848,10 +865,10 @@ func TestTemplateACL(t *testing.T) { Role: codersdk.TemplateRoleUse, }) - err = client.DeleteGroup(ctx, group.ID) + err = anotherClient.DeleteGroup(ctx, group.ID) require.NoError(t, err) - acl, err = client.TemplateACL(ctx, template.ID) + acl, err = anotherClient.TemplateACL(ctx, template.ID) require.NoError(t, err) // Length should be 1 for the allUsers group. require.Len(t, acl.Groups, 1) @@ -875,6 +892,7 @@ func TestTemplateACL(t *testing.T) { ctx := testutil.Context(t, testutil.WaitLong) + //nolint:gocritic // test setup err := client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ UserPerms: map[string]codersdk.TemplateRole{ user1.ID.String(): codersdk.TemplateRoleUse, @@ -896,6 +914,7 @@ func TestTemplateACL(t *testing.T) { }) require.Error(t, err) + //nolint:gocritic // test setup err = client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ UserPerms: map[string]codersdk.TemplateRole{ user1.ID.String(): codersdk.TemplateRoleAdmin, @@ -924,6 +943,7 @@ func TestUpdateTemplateACL(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user3 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) @@ -933,7 +953,7 @@ func TestUpdateTemplateACL(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) defer cancel() - err := client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ + err := anotherClient.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ UserPerms: map[string]codersdk.TemplateRole{ user2.ID.String(): codersdk.TemplateRoleUse, user3.ID.String(): codersdk.TemplateRoleAdmin, @@ -941,7 +961,7 @@ func TestUpdateTemplateACL(t *testing.T) { }) require.NoError(t, err) - acl, err := client.TemplateACL(ctx, template.ID) + acl, err := anotherClient.TemplateACL(ctx, template.ID) require.NoError(t, err) templateUser2 := codersdk.TemplateUser{ @@ -976,6 +996,7 @@ func TestUpdateTemplateACL(t *testing.T) { }, }, }) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) @@ -989,13 +1010,15 @@ func TestUpdateTemplateACL(t *testing.T) { user.OrganizationID.String(): codersdk.TemplateRoleDeleted, }, } - err := client.UpdateTemplateACL(ctx, template.ID, req) + err := anotherClient.UpdateTemplateACL(ctx, template.ID, req) require.NoError(t, err) numLogs++ require.Len(t, auditor.AuditLogs(), numLogs) - require.Equal(t, database.AuditActionWrite, auditor.AuditLogs()[numLogs-1].Action) - require.Equal(t, template.ID, auditor.AuditLogs()[numLogs-1].ResourceID) + require.True(t, auditor.Contains(t, database.AuditLog{ + Action: database.AuditActionWrite, + ResourceID: template.ID, + })) }) t.Run("DeleteUser", func(t *testing.T) { @@ -1006,6 +1029,7 @@ func TestUpdateTemplateACL(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user3 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) @@ -1021,10 +1045,10 @@ func TestUpdateTemplateACL(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) defer cancel() - err := client.UpdateTemplateACL(ctx, template.ID, req) + err := anotherClient.UpdateTemplateACL(ctx, template.ID, req) require.NoError(t, err) - acl, err := client.TemplateACL(ctx, template.ID) + acl, err := anotherClient.TemplateACL(ctx, template.ID) require.NoError(t, err) require.Contains(t, acl.Users, codersdk.TemplateUser{ User: user2, @@ -1042,10 +1066,10 @@ func TestUpdateTemplateACL(t *testing.T) { }, } - err = client.UpdateTemplateACL(ctx, template.ID, req) + err = anotherClient.UpdateTemplateACL(ctx, template.ID, req) require.NoError(t, err) - acl, err = client.TemplateACL(ctx, template.ID) + acl, err = anotherClient.TemplateACL(ctx, template.ID) require.NoError(t, err) require.Contains(t, acl.Users, codersdk.TemplateUser{ @@ -1078,6 +1102,7 @@ func TestUpdateTemplateACL(t *testing.T) { ctx := testutil.Context(t, testutil.WaitLong) + //nolint:gocritic // we're testing invalid UUID so testing RBAC is not relevant here. err := client.UpdateTemplateACL(ctx, template.ID, req) require.Error(t, err) cerr, _ := codersdk.AsError(err) @@ -1103,6 +1128,7 @@ func TestUpdateTemplateACL(t *testing.T) { ctx := testutil.Context(t, testutil.WaitLong) + //nolint:gocritic // we're testing invalid user so testing RBAC is not relevant here. err := client.UpdateTemplateACL(ctx, template.ID, req) require.Error(t, err) cerr, _ := codersdk.AsError(err) @@ -1129,6 +1155,7 @@ func TestUpdateTemplateACL(t *testing.T) { ctx := testutil.Context(t, testutil.WaitLong) + //nolint:gocritic // we're testing invalid role so testing RBAC is not relevant here. err := client.UpdateTemplateACL(ctx, template.ID, req) require.Error(t, err) cerr, _ := codersdk.AsError(err) @@ -1144,6 +1171,8 @@ func TestUpdateTemplateACL(t *testing.T) { }, }}) + client1, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) + client2, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) @@ -1155,7 +1184,7 @@ func TestUpdateTemplateACL(t *testing.T) { ctx := testutil.Context(t, testutil.WaitLong) - err := client.UpdateTemplateACL(ctx, template.ID, req) + err := client1.UpdateTemplateACL(ctx, template.ID, req) require.NoError(t, err) req = codersdk.UpdateTemplateACL{ @@ -1178,6 +1207,7 @@ func TestUpdateTemplateACL(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + client1, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) client2, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user3 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) @@ -1191,7 +1221,7 @@ func TestUpdateTemplateACL(t *testing.T) { ctx := testutil.Context(t, testutil.WaitLong) - err := client.UpdateTemplateACL(ctx, template.ID, req) + err := client1.UpdateTemplateACL(ctx, template.ID, req) require.NoError(t, err) // Should be able to see user 3 @@ -1234,6 +1264,7 @@ func TestUpdateTemplateACL(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) @@ -1241,7 +1272,7 @@ func TestUpdateTemplateACL(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) defer cancel() - acl, err := client.TemplateACL(ctx, template.ID) + acl, err := anotherClient.TemplateACL(ctx, template.ID) require.NoError(t, err) require.Len(t, acl.Groups, 1) @@ -1256,6 +1287,7 @@ func TestUpdateTemplateACL(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin(), rbac.RoleUserAdmin()) client1, user1 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) @@ -1264,18 +1296,18 @@ func TestUpdateTemplateACL(t *testing.T) { ctx := testutil.Context(t, testutil.WaitLong) // Create a group to add to the template. - group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ + group, err := anotherClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ Name: "test", }) require.NoError(t, err) // Check that the only current group is the allUsers group. - acl, err := client.TemplateACL(ctx, template.ID) + acl, err := anotherClient.TemplateACL(ctx, template.ID) require.NoError(t, err) require.Len(t, acl.Groups, 1) // Update the template to only allow access to the 'test' group. - err = client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ + err = anotherClient.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ GroupPerms: map[string]codersdk.TemplateRole{ // The allUsers group shares the same ID as the organization. user.OrganizationID.String(): codersdk.TemplateRoleDeleted, @@ -1286,7 +1318,7 @@ func TestUpdateTemplateACL(t *testing.T) { // Get the ACL list for the template and assert the test group is // present. - acl, err = client.TemplateACL(ctx, template.ID) + acl, err = anotherClient.TemplateACL(ctx, template.ID) require.NoError(t, err) require.Len(t, acl.Groups, 1) @@ -1302,7 +1334,7 @@ func TestUpdateTemplateACL(t *testing.T) { require.Equal(t, http.StatusNotFound, cerr.StatusCode()) // Patch the group to add the regular user. - group, err = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ + group, err = anotherClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ AddUsers: []string{user1.ID.String()}, }) require.NoError(t, err) @@ -1321,6 +1353,7 @@ func TestUpdateTemplateACL(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) client1, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) @@ -1329,7 +1362,7 @@ func TestUpdateTemplateACL(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) defer cancel() - acl, err := client.TemplateACL(ctx, template.ID) + acl, err := anotherClient.TemplateACL(ctx, template.ID) require.NoError(t, err) require.Len(t, acl.Groups, 1) @@ -1341,14 +1374,14 @@ func TestUpdateTemplateACL(t *testing.T) { allUsers := acl.Groups[0] - err = client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ + err = anotherClient.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ GroupPerms: map[string]codersdk.TemplateRole{ allUsers.ID.String(): codersdk.TemplateRoleDeleted, }, }) require.NoError(t, err) - acl, err = client.TemplateACL(ctx, template.ID) + acl, err = anotherClient.TemplateACL(ctx, template.ID) require.NoError(t, err) require.Len(t, acl.Groups, 0) @@ -1377,6 +1410,7 @@ func TestReadFileWithTemplateUpdate(t *testing.T) { ctx := testutil.Context(t, testutil.WaitLong) + //nolint:gocritic // regular user cannot create file resp, err := client.Upload(ctx, codersdk.ContentTypeTar, bytes.NewReader(make([]byte, 1024))) require.NoError(t, err) @@ -1397,6 +1431,7 @@ func TestReadFileWithTemplateUpdate(t *testing.T) { _, _, err = member.Download(ctx, resp.ID) require.Error(t, err, "not in acl yet") + //nolint:gocritic // regular user cannot update template acl err = client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ UserPerms: map[string]codersdk.TemplateRole{ memberData.ID.String(): codersdk.TemplateRoleAdmin, diff --git a/enterprise/coderd/users_test.go b/enterprise/coderd/users_test.go index 1c90570c1f..de7865f7d3 100644 --- a/enterprise/coderd/users_test.go +++ b/enterprise/coderd/users_test.go @@ -153,6 +153,7 @@ func TestUserQuietHours(t *testing.T) { }) ctx := testutil.Context(t, testutil.WaitLong) + //nolint:gocritic // We want to test the lack of entitlement, not RBAC. _, err := client.UserQuietHoursSchedule(ctx, user.UserID.String()) require.Error(t, err) var sdkErr *codersdk.Error @@ -181,6 +182,7 @@ func TestUserQuietHours(t *testing.T) { }) ctx := testutil.Context(t, testutil.WaitLong) + //nolint:gocritic // We want to test the lack of feature, not RBAC. _, err := client.UserQuietHoursSchedule(ctx, user.UserID.String()) require.Error(t, err) var sdkErr *codersdk.Error @@ -208,6 +210,7 @@ func TestUserQuietHours(t *testing.T) { }) ctx := testutil.Context(t, testutil.WaitLong) + //nolint:gocritic // We want to test the lack of feature, not RBAC. _, err := client.UserQuietHoursSchedule(ctx, user.UserID.String()) require.Error(t, err) var sdkErr *codersdk.Error diff --git a/enterprise/coderd/workspaceagents_test.go b/enterprise/coderd/workspaceagents_test.go index a5c4ef2063..7745eb7289 100644 --- a/enterprise/coderd/workspaceagents_test.go +++ b/enterprise/coderd/workspaceagents_test.go @@ -45,6 +45,7 @@ func TestBlockNonBrowser(t *testing.T) { }, }) _, agent := setupWorkspaceAgent(t, client, user, 0) + //nolint:gocritic // Testing that even the owner gets blocked. _, err := client.DialWorkspaceAgent(context.Background(), agent.ID, nil) var apiErr *codersdk.Error require.ErrorAs(t, err, &apiErr) @@ -63,6 +64,7 @@ func TestBlockNonBrowser(t *testing.T) { }, }) _, agent := setupWorkspaceAgent(t, client, user, 0) + //nolint:gocritic // Testing RBAC is not the point of this test. conn, err := client.DialWorkspaceAgent(context.Background(), agent.ID, nil) require.NoError(t, err) _ = conn.Close() diff --git a/enterprise/coderd/workspacebuilds_test.go b/enterprise/coderd/workspacebuilds_test.go index 615991a65d..e90ea07e24 100644 --- a/enterprise/coderd/workspacebuilds_test.go +++ b/enterprise/coderd/workspacebuilds_test.go @@ -40,10 +40,9 @@ func TestWorkspaceBuild(t *testing.T) { template := coderdtest.CreateTemplate(t, ownerClient, owner.OrganizationID, oldVersion.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, ownerClient, oldVersion.ID) require.Equal(t, oldVersion.ID, template.ActiveVersionID) - template, err := ownerClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ + template = coderdtest.UpdateTemplateMeta(t, ownerClient, template.ID, codersdk.UpdateTemplateMeta{ RequireActiveVersion: true, }) - require.NoError(t, err) require.True(t, template.RequireActiveVersion) // Create a new version that we will promote. @@ -51,10 +50,7 @@ func TestWorkspaceBuild(t *testing.T) { ctvr.TemplateID = template.ID }) coderdtest.AwaitTemplateVersionJobCompleted(t, ownerClient, activeVersion.ID) - err = ownerClient.UpdateActiveTemplateVersion(ctx, template.ID, codersdk.UpdateActiveTemplateVersion{ - ID: activeVersion.ID, - }) - require.NoError(t, err) + coderdtest.UpdateActiveTemplateVersion(t, ownerClient, template.ID, activeVersion.ID) templateAdminClient, _ := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID, rbac.RoleTemplateAdmin()) templateACLAdminClient, templateACLAdmin := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID) @@ -62,19 +58,12 @@ func TestWorkspaceBuild(t *testing.T) { memberClient, _ := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID) // Create a group so we can also test group template admin ownership. - group, err := ownerClient.CreateGroup(ctx, owner.OrganizationID, codersdk.CreateGroupRequest{ - Name: "test", - }) - require.NoError(t, err) - // Add the user who gains template admin via group membership. - group, err = ownerClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ - AddUsers: []string{templateGroupACLAdmin.ID.String()}, - }) - require.NoError(t, err) + group := coderdtest.CreateGroup(t, ownerClient, owner.OrganizationID, "test", templateGroupACLAdmin) // Update the template for both users and groups. - err = ownerClient.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ + //nolint:gocritic // test setup + err := ownerClient.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ UserPerms: map[string]codersdk.TemplateRole{ templateACLAdmin.ID.String(): codersdk.TemplateRoleAdmin, }, diff --git a/enterprise/coderd/workspaces_test.go b/enterprise/coderd/workspaces_test.go index a80107d379..fecc488b7b 100644 --- a/enterprise/coderd/workspaces_test.go +++ b/enterprise/coderd/workspaces_test.go @@ -16,6 +16,7 @@ import ( "github.com/coder/coder/v2/coderd/autobuild" "github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/database" + "github.com/coder/coder/v2/coderd/rbac" agplschedule "github.com/coder/coder/v2/coderd/schedule" "github.com/coder/coder/v2/coderd/schedule/cron" "github.com/coder/coder/v2/coderd/util/ptr" @@ -50,6 +51,7 @@ func TestCreateWorkspace(t *testing.T) { codersdk.FeatureTemplateRBAC: 1, }, }}) + templateAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) @@ -57,13 +59,13 @@ func TestCreateWorkspace(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) defer cancel() - acl, err := client.TemplateACL(ctx, template.ID) + acl, err := templateAdminClient.TemplateACL(ctx, template.ID) require.NoError(t, err) require.Len(t, acl.Groups, 1) require.Len(t, acl.Users, 0) - err = client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ + err = templateAdminClient.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ GroupPerms: map[string]codersdk.TemplateRole{ acl.Groups[0].ID.String(): codersdk.TemplateRoleDeleted, }, @@ -504,6 +506,7 @@ func TestWorkspaceAutobuild(t *testing.T) { _ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, ws.LatestBuild.ID) // Assert that the workspace is actually deleted. + //nolint:gocritic // ensuring workspace is deleted and not just invisible to us due to RBAC _, err := client.Workspace(testutil.Context(t, testutil.WaitShort), ws.ID) require.Error(t, err) cerr, ok := codersdk.AsError(err) @@ -531,6 +534,7 @@ func TestWorkspaceAutobuild(t *testing.T) { Features: license.Features{codersdk.FeatureAdvancedTemplateScheduling: 1}, }, }) + anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, ProvisionPlan: echo.PlanComplete, @@ -540,12 +544,12 @@ func TestWorkspaceAutobuild(t *testing.T) { ctr.TimeTilDormantAutoDeleteMillis = ptr.Ref[int64](dormantTTL.Milliseconds()) }) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) - ws := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) - build := coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, ws.LatestBuild.ID) + ws := coderdtest.CreateWorkspace(t, anotherClient, user.OrganizationID, template.ID) + build := coderdtest.AwaitWorkspaceBuildJobCompleted(t, anotherClient, ws.LatestBuild.ID) require.Equal(t, codersdk.WorkspaceStatusRunning, build.Status) ctx := testutil.Context(t, testutil.WaitMedium) - err := client.UpdateWorkspaceDormancy(ctx, ws.ID, codersdk.UpdateWorkspaceDormancy{ + err := anotherClient.UpdateWorkspaceDormancy(ctx, ws.ID, codersdk.UpdateWorkspaceDormancy{ Dormant: true, }) require.NoError(t, err) @@ -559,7 +563,7 @@ func TestWorkspaceAutobuild(t *testing.T) { // Expect no transitions since not enough time has elapsed. require.Len(t, stats.Transitions, 0) - _, err = client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ + _, err = anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ TimeTilDormantAutoDeleteMillis: dormantTTL.Milliseconds(), }) require.NoError(t, err) @@ -671,6 +675,7 @@ func TestWorkspaceAutobuild(t *testing.T) { Features: license.Features{codersdk.FeatureAdvancedTemplateScheduling: 1}, }, }) + templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) // Create a template version that passes to get a functioning workspace. version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ @@ -682,8 +687,8 @@ func TestWorkspaceAutobuild(t *testing.T) { template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) - ws := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) - coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, ws.LatestBuild.ID) + ws := coderdtest.CreateWorkspace(t, templateAdmin, user.OrganizationID, template.ID) + coderdtest.AwaitWorkspaceBuildJobCompleted(t, templateAdmin, ws.LatestBuild.ID) // Create a new version that will fail when we try to delete a workspace. version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ @@ -696,7 +701,7 @@ func TestWorkspaceAutobuild(t *testing.T) { coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) // Try to delete the workspace. This simulates a "failed" autodelete. - build, err := client.CreateWorkspaceBuild(ctx, ws.ID, codersdk.CreateWorkspaceBuildRequest{ + build, err := templateAdmin.CreateWorkspaceBuild(ctx, ws.ID, codersdk.CreateWorkspaceBuildRequest{ Transition: codersdk.WorkspaceTransitionDelete, TemplateVersionID: version.ID, }) @@ -706,13 +711,13 @@ func TestWorkspaceAutobuild(t *testing.T) { require.NotEmpty(t, build.Job.Error) // Update our workspace to be dormant so that it qualifies for auto-deletion. - err = client.UpdateWorkspaceDormancy(ctx, ws.ID, codersdk.UpdateWorkspaceDormancy{ + err = templateAdmin.UpdateWorkspaceDormancy(ctx, ws.ID, codersdk.UpdateWorkspaceDormancy{ Dormant: true, }) require.NoError(t, err) // Enable auto-deletion for the template. - _, err = client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ + _, err = templateAdmin.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ TimeTilDormantAutoDeleteMillis: transitionTTL.Milliseconds(), }) require.NoError(t, err) @@ -901,6 +906,7 @@ func TestWorkspacesFiltering(t *testing.T) { Features: license.Features{codersdk.FeatureAdvancedTemplateScheduling: 1}, }, }) + templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin()) // Create a template version that passes to get a functioning workspace. version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ @@ -912,22 +918,22 @@ func TestWorkspacesFiltering(t *testing.T) { template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) - dormantWS1 := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) - coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, dormantWS1.LatestBuild.ID) + dormantWS1 := coderdtest.CreateWorkspace(t, templateAdmin, user.OrganizationID, template.ID) + coderdtest.AwaitWorkspaceBuildJobCompleted(t, templateAdmin, dormantWS1.LatestBuild.ID) - dormantWS2 := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) - coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, dormantWS2.LatestBuild.ID) + dormantWS2 := coderdtest.CreateWorkspace(t, templateAdmin, user.OrganizationID, template.ID) + coderdtest.AwaitWorkspaceBuildJobCompleted(t, templateAdmin, dormantWS2.LatestBuild.ID) - activeWS := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) - coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, activeWS.LatestBuild.ID) + activeWS := coderdtest.CreateWorkspace(t, templateAdmin, user.OrganizationID, template.ID) + coderdtest.AwaitWorkspaceBuildJobCompleted(t, templateAdmin, activeWS.LatestBuild.ID) - err := client.UpdateWorkspaceDormancy(ctx, dormantWS1.ID, codersdk.UpdateWorkspaceDormancy{Dormant: true}) + err := templateAdmin.UpdateWorkspaceDormancy(ctx, dormantWS1.ID, codersdk.UpdateWorkspaceDormancy{Dormant: true}) require.NoError(t, err) - err = client.UpdateWorkspaceDormancy(ctx, dormantWS2.ID, codersdk.UpdateWorkspaceDormancy{Dormant: true}) + err = templateAdmin.UpdateWorkspaceDormancy(ctx, dormantWS2.ID, codersdk.UpdateWorkspaceDormancy{Dormant: true}) require.NoError(t, err) - resp, err := client.Workspaces(ctx, codersdk.WorkspaceFilter{ + resp, err := templateAdmin.Workspaces(ctx, codersdk.WorkspaceFilter{ FilterQuery: "is-dormant:true", }) require.NoError(t, err) @@ -968,6 +974,7 @@ func TestWorkspacesWithoutTemplatePerms(t *testing.T) { defer cancel() // Remove everyone access + //nolint:gocritic // creating a separate user just for this is overkill err := client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ GroupPerms: map[string]codersdk.TemplateRole{ first.OrganizationID.String(): codersdk.TemplateRoleDeleted, diff --git a/scripts/check_enterprise_imports.sh b/scripts/check_enterprise_imports.sh index 340453a62d..0807a11d7e 100755 --- a/scripts/check_enterprise_imports.sh +++ b/scripts/check_enterprise_imports.sh @@ -13,6 +13,7 @@ find . -regex ".*\.go" | grep -v "./enterprise" | grep -v ./scripts/auditdocgen/ --include="*.go" | grep -v ./scripts/clidocgen/ --include="*.go" | + grep -v ./scripts/rules.go | xargs grep -n "github.com/coder/coder/v2/enterprise" # reverse the exit code because we want this script to fail if grep finds anything. status=$? diff --git a/scripts/rules.go b/scripts/rules.go index b21830bcee..246fe29381 100644 --- a/scripts/rules.go +++ b/scripts/rules.go @@ -52,17 +52,54 @@ func dbauthzAuthorizationContext(m dsl.Matcher) { func testingWithOwnerUser(m dsl.Matcher) { m.Import("testing") m.Import("github.com/coder/coder/v2/cli/clitest") + m.Import("github.com/coder/coder/v2/enterprise/coderd/coderenttest") + // For both AGPL and enterprise code, we check for SetupConfig being called with a + // client authenticated as the Owner user. m.Match(` - $_ := coderdtest.CreateFirstUser($t, $client) - $*_ - clitest.$SetupConfig($t, $client, $_) + $_ := coderdtest.CreateFirstUser($t, $client) + $*_ + clitest.$SetupConfig($t, $client, $_) `). Where(m["t"].Type.Implements("testing.TB") && m["SetupConfig"].Text.Matches("^SetupConfig$") && m.File().Name.Matches(`_test\.go$`)). At(m["SetupConfig"]). Report(`The CLI will be operating as the owner user, which has unrestricted permissions. Consider creating a different user.`) + + m.Match(` + $client, $_ := coderdenttest.New($t, $*_) + $*_ + clitest.$SetupConfig($t, $client, $_) + `).Where(m["t"].Type.Implements("testing.TB") && + m["SetupConfig"].Text.Matches("^SetupConfig$") && + m.File().Name.Matches(`_test\.go$`)). + At(m["SetupConfig"]). + Report(`The CLI will be operating as the owner user, which has unrestricted permissions. Consider creating a different user.`) + + // For the enterprise code, we check for any method called on the client. + // While we want to be a bit stricter here, some methods are known to require + // the owner user, so we exclude them. + m.Match(` + $client, $_ := coderdenttest.New($t, $*_) + $*_ + $_, $_ := $client.$Method($*_) + `).Where(m["t"].Type.Implements("testing.TB") && + m.File().Name.Matches(`_test\.go$`) && + !m["Method"].Text.Matches(`^(UpdateAppearance|Licenses|AddLicense|InsertLicense|DeleteLicense|CreateWorkspaceProxy|Replicas|Regions)$`)). + At(m["Method"]). + Report(`This client is operating as the owner user, which has unrestricted permissions. Consider creating a different user.`) + + // Sadly, we need to match both one- and two-valued assignments separately. + m.Match(` + $client, $_ := coderdenttest.New($t, $*_) + $*_ + $_ := $client.$Method($*_) + `).Where(m["t"].Type.Implements("testing.TB") && + m.File().Name.Matches(`_test\.go$`) && + !m["Method"].Text.Matches(`^(UpdateAppearance|Licenses|AddLicense|InsertLicense|DeleteLicense|CreateWorkspaceProxy|Replicas|Regions)$`)). + At(m["Method"]). + Report(`This client is operating as the owner user, which has unrestricted permissions. Consider creating a different user.`) } // Use xerrors everywhere! It provides additional stacktrace info!