chore(scripts/rules.go): broaden scope of testingWithOwnerUser linter (#10548)

* Updated testingWithOwnerUser ruleguard rule to detect:
  a) Passing client from coderdenttest.New() to clitest.SetupConfig() similar to what already exists for AGPL code
  b) Usage of any method of the owner client from coderdenttest.New() - all usages of the owner client must be justified with a `//nolint:gocritic` comment.
* Fixed resulting linter complaints.
* Added new coderdtest helpers CreateGroup and UpdateTemplateMeta.
* Modified check_enterprise_import.sh to ignore scripts/rules.go.
This commit is contained in:
Cian Johnston 2023-11-08 14:54:48 +00:00 committed by GitHub
parent 057b43a935
commit 26740cf00d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 473 additions and 331 deletions

View File

@ -762,6 +762,25 @@ func CreateTemplate(t testing.TB, client *codersdk.Client, organization uuid.UUI
return template 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 // UpdateTemplateVersion creates a new template version with the "echo" provisioner
// and associates it with the given templateID. // 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 { 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) 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. // 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 { func AwaitTemplateVersionJobRunning(t testing.TB, client *codersdk.Client, version uuid.UUID) codersdk.TemplateVersion {
t.Helper() t.Helper()

View File

@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/coder/coder/v2/cli/clitest" "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/codersdk"
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
"github.com/coder/coder/v2/pty/ptytest" "github.com/coder/coder/v2/pty/ptytest"
@ -18,9 +19,10 @@ func TestFeaturesList(t *testing.T) {
t.Parallel() t.Parallel()
t.Run("Table", func(t *testing.T) { t.Run("Table", func(t *testing.T) {
t.Parallel() 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") inv, conf := newCLI(t, "features", "list")
clitest.SetupConfig(t, client, conf) clitest.SetupConfig(t, anotherClient, conf)
pty := ptytest.New(t).Attach(inv) pty := ptytest.New(t).Attach(inv)
clitest.Start(t, inv) clitest.Start(t, inv)
pty.ExpectMatch("user_limit") pty.ExpectMatch("user_limit")
@ -29,9 +31,10 @@ func TestFeaturesList(t *testing.T) {
t.Run("JSON", func(t *testing.T) { t.Run("JSON", func(t *testing.T) {
t.Parallel() 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") inv, conf := newCLI(t, "features", "list", "-o", "json")
clitest.SetupConfig(t, client, conf) clitest.SetupConfig(t, anotherClient, conf)
doneChan := make(chan struct{}) doneChan := make(chan struct{})
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)

View File

@ -10,6 +10,8 @@ import (
"github.com/coder/coder/v2/cli/clitest" "github.com/coder/coder/v2/cli/clitest"
"github.com/coder/coder/v2/cli/cliui" "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/codersdk"
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
"github.com/coder/coder/v2/enterprise/coderd/license" "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.Run("OK", func(t *testing.T) {
t.Parallel() t.Parallel()
client, _ := coderdenttest.New(t, &coderdenttest.Options{LicenseOptions: &coderdenttest.LicenseOptions{ client, admin := coderdenttest.New(t, &coderdenttest.Options{LicenseOptions: &coderdenttest.LicenseOptions{
Features: license.Features{ Features: license.Features{
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
anotherClient, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID, rbac.RoleUserAdmin())
var ( var (
groupName = "test" groupName = "test"
@ -40,7 +43,7 @@ func TestCreateGroup(t *testing.T) {
pty := ptytest.New(t) pty := ptytest.New(t)
inv.Stdout = pty.Output() inv.Stdout = pty.Output()
clitest.SetupConfig(t, client, conf) clitest.SetupConfig(t, anotherClient, conf)
err := inv.Run() err := inv.Run()
require.NoError(t, err) require.NoError(t, err)

View File

@ -10,11 +10,12 @@ import (
"github.com/coder/coder/v2/cli/clitest" "github.com/coder/coder/v2/cli/clitest"
"github.com/coder/coder/v2/cli/cliui" "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/codersdk"
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
"github.com/coder/coder/v2/enterprise/coderd/license" "github.com/coder/coder/v2/enterprise/coderd/license"
"github.com/coder/coder/v2/pty/ptytest" "github.com/coder/coder/v2/pty/ptytest"
"github.com/coder/coder/v2/testutil"
) )
func TestGroupDelete(t *testing.T) { func TestGroupDelete(t *testing.T) {
@ -28,12 +29,9 @@ func TestGroupDelete(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
anotherClient, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID, rbac.RoleUserAdmin())
ctx := testutil.Context(t, testutil.WaitLong) group := coderdtest.CreateGroup(t, client, admin.OrganizationID, "alpha")
group, err := client.CreateGroup(ctx, admin.OrganizationID, codersdk.CreateGroupRequest{
Name: "alpha",
})
require.NoError(t, err)
inv, conf := newCLI(t, inv, conf := newCLI(t,
"groups", "delete", group.Name, "groups", "delete", group.Name,
@ -42,9 +40,9 @@ func TestGroupDelete(t *testing.T) {
pty := ptytest.New(t) pty := ptytest.New(t)
inv.Stdout = pty.Output() inv.Stdout = pty.Output()
clitest.SetupConfig(t, client, conf) clitest.SetupConfig(t, anotherClient, conf)
err = inv.Run() err := inv.Run()
require.NoError(t, err) require.NoError(t, err)
pty.ExpectMatch(fmt.Sprintf("Successfully deleted group %s", pretty.Sprint(cliui.DefaultStyles.Keyword, group.Name))) 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.Run("NoArg", func(t *testing.T) {
t.Parallel() t.Parallel()
client, _ := coderdenttest.New(t, &coderdenttest.Options{LicenseOptions: &coderdenttest.LicenseOptions{ client, admin := coderdenttest.New(t, &coderdenttest.Options{LicenseOptions: &coderdenttest.LicenseOptions{
Features: license.Features{ Features: license.Features{
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
anotherClient, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID, rbac.RoleUserAdmin())
inv, conf := newCLI( inv, conf := newCLI(
t, t,
"groups", "delete", "groups", "delete",
) )
clitest.SetupConfig(t, client, conf) clitest.SetupConfig(t, anotherClient, conf)
err := inv.Run() err := inv.Run()
require.Error(t, err) require.Error(t, err)

View File

@ -11,11 +11,11 @@ import (
"github.com/coder/coder/v2/cli/clitest" "github.com/coder/coder/v2/cli/clitest"
"github.com/coder/coder/v2/cli/cliui" "github.com/coder/coder/v2/cli/cliui"
"github.com/coder/coder/v2/coderd/coderdtest" "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/codersdk"
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
"github.com/coder/coder/v2/enterprise/coderd/license" "github.com/coder/coder/v2/enterprise/coderd/license"
"github.com/coder/coder/v2/pty/ptytest" "github.com/coder/coder/v2/pty/ptytest"
"github.com/coder/coder/v2/testutil"
) )
func TestGroupEdit(t *testing.T) { func TestGroupEdit(t *testing.T) {
@ -29,23 +29,13 @@ func TestGroupEdit(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, 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) _, user1 := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID)
_, user2 := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID)
_, user3 := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID) _, user3 := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID)
group, err := client.CreateGroup(ctx, admin.OrganizationID, codersdk.CreateGroupRequest{ group := coderdtest.CreateGroup(t, client, admin.OrganizationID, "alpha", user3)
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)
expectedName := "beta" expectedName := "beta"
@ -62,9 +52,9 @@ func TestGroupEdit(t *testing.T) {
pty := ptytest.New(t) pty := ptytest.New(t)
inv.Stdout = pty.Output() inv.Stdout = pty.Output()
clitest.SetupConfig(t, client, conf) clitest.SetupConfig(t, anotherClient, conf)
err = inv.Run() err := inv.Run()
require.NoError(t, err) require.NoError(t, err)
pty.ExpectMatch(fmt.Sprintf("Successfully patched group %s", pretty.Sprint(cliui.DefaultStyles.Keyword, expectedName))) 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) // Create a group with no members.
group := coderdtest.CreateGroup(t, client, admin.OrganizationID, "alpha")
group, err := client.CreateGroup(ctx, admin.OrganizationID, codersdk.CreateGroupRequest{
Name: "alpha",
})
require.NoError(t, err)
inv, conf := newCLI( inv, conf := newCLI(
t, t,
@ -92,26 +78,26 @@ func TestGroupEdit(t *testing.T) {
"-a", "foo", "-a", "foo",
) )
clitest.SetupConfig(t, client, conf) clitest.SetupConfig(t, client, conf) //nolint:gocritic // intentional usage of owner
err = inv.Run() err := inv.Run()
require.Error(t, err) require.ErrorContains(t, err, "must be a valid UUID or email address")
require.Contains(t, err.Error(), "must be a valid UUID or email address")
}) })
t.Run("NoArg", func(t *testing.T) { t.Run("NoArg", func(t *testing.T) {
t.Parallel() t.Parallel()
client, _ := coderdenttest.New(t, &coderdenttest.Options{LicenseOptions: &coderdenttest.LicenseOptions{ client, user := coderdenttest.New(t, &coderdenttest.Options{LicenseOptions: &coderdenttest.LicenseOptions{
Features: license.Features{ Features: license.Features{
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
inv, conf := newCLI(t, "groups", "edit") inv, conf := newCLI(t, "groups", "edit")
clitest.SetupConfig(t, client, conf) clitest.SetupConfig(t, anotherClient, conf)
err := inv.Run() err := inv.Run()
require.Error(t, err) require.ErrorContains(t, err, "wanted 1 args but got 0")
}) })
} }

View File

@ -7,11 +7,11 @@ import (
"github.com/coder/coder/v2/cli/clitest" "github.com/coder/coder/v2/cli/clitest"
"github.com/coder/coder/v2/coderd/coderdtest" "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/codersdk"
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
"github.com/coder/coder/v2/enterprise/coderd/license" "github.com/coder/coder/v2/enterprise/coderd/license"
"github.com/coder/coder/v2/pty/ptytest" "github.com/coder/coder/v2/pty/ptytest"
"github.com/coder/coder/v2/testutil"
) )
func TestGroupList(t *testing.T) { func TestGroupList(t *testing.T) {
@ -25,42 +25,25 @@ func TestGroupList(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, 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) _, user1 := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID)
_, user2 := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID)
// We intentionally create the first group as beta so that we // We intentionally create the first group as beta so that we
// can assert that things are being sorted by name intentionally // can assert that things are being sorted by name intentionally
// and not by chance (or some other parameter like created_at). // and not by chance (or some other parameter like created_at).
group1, err := client.CreateGroup(ctx, admin.OrganizationID, codersdk.CreateGroupRequest{ group1 := coderdtest.CreateGroup(t, client, admin.OrganizationID, "beta", user1)
Name: "beta", group2 := coderdtest.CreateGroup(t, client, admin.OrganizationID, "alpha", user2)
})
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)
inv, conf := newCLI(t, "groups", "list") inv, conf := newCLI(t, "groups", "list")
pty := ptytest.New(t) pty := ptytest.New(t)
inv.Stdout = pty.Output() inv.Stdout = pty.Output()
clitest.SetupConfig(t, client, conf) clitest.SetupConfig(t, anotherClient, conf)
err = inv.Run() err := inv.Run()
require.NoError(t, err) require.NoError(t, err)
matches := []string{ matches := []string{
@ -77,25 +60,26 @@ func TestGroupList(t *testing.T) {
t.Run("Everyone", func(t *testing.T) { t.Run("Everyone", func(t *testing.T) {
t.Parallel() 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{ Features: license.Features{
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
anotherClient, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID, rbac.RoleUserAdmin())
inv, conf := newCLI(t, "groups", "list") inv, conf := newCLI(t, "groups", "list")
pty := ptytest.New(t) pty := ptytest.New(t)
inv.Stdout = pty.Output() inv.Stdout = pty.Output()
clitest.SetupConfig(t, client, conf) clitest.SetupConfig(t, anotherClient, conf)
err := inv.Run() err := inv.Run()
require.NoError(t, err) require.NoError(t, err)
matches := []string{ matches := []string{
"NAME", "ORGANIZATION ID", "MEMBERS", " AVATAR URL", "NAME", "ORGANIZATION ID", "MEMBERS", " AVATAR URL",
"Everyone", user.OrganizationID.String(), coderdtest.FirstUserParams.Email, "", "Everyone", admin.OrganizationID.String(), coderdtest.FirstUserParams.Email, "",
} }
for _, match := range matches { for _, match := range matches {

View File

@ -122,7 +122,7 @@ func TestLicensesAddReal(t *testing.T) {
t, t,
"licenses", "add", "-l", fakeLicenseJWT, "licenses", "add", "-l", fakeLicenseJWT,
) )
clitest.SetupConfig(t, client, conf) clitest.SetupConfig(t, client, conf) //nolint:gocritic // requires owner
waiter := clitest.StartWithWaiter(t, inv) waiter := clitest.StartWithWaiter(t, inv)
var coderError *codersdk.Error var coderError *codersdk.Error
@ -180,7 +180,7 @@ func TestLicensesListReal(t *testing.T) {
inv.Stdout = stdout inv.Stdout = stdout
stderr := new(bytes.Buffer) stderr := new(bytes.Buffer)
inv.Stderr = stderr 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) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel() defer cancel()
errC := make(chan error) errC := make(chan error)
@ -216,7 +216,7 @@ func TestLicensesDeleteReal(t *testing.T) {
inv, conf := newCLI( inv, conf := newCLI(
t, t,
"licenses", "delete", "1") "licenses", "delete", "1")
clitest.SetupConfig(t, client, conf) clitest.SetupConfig(t, client, conf) //nolint:gocritic // requires owner
var coderError *codersdk.Error var coderError *codersdk.Error
clitest.StartWithWaiter(t, inv).RequireAs(&coderError) clitest.StartWithWaiter(t, inv).RequireAs(&coderError)

View File

@ -7,6 +7,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/coder/coder/v2/cli/clitest" "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/codersdk"
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
"github.com/coder/coder/v2/enterprise/coderd/license" "github.com/coder/coder/v2/enterprise/coderd/license"
@ -37,20 +38,43 @@ func TestProvisionerDaemon_PSK(t *testing.T) {
func TestProvisionerDaemon_SessionToken(t *testing.T) { func TestProvisionerDaemon_SessionToken(t *testing.T) {
t.Parallel() t.Parallel()
t.Run("ScopeUser", func(t *testing.T) {
client, _ := coderdenttest.New(t, &coderdenttest.Options{ t.Parallel()
ProvisionerDaemonPSK: "provisionersftw", client, admin := coderdenttest.New(t, &coderdenttest.Options{
LicenseOptions: &coderdenttest.LicenseOptions{ ProvisionerDaemonPSK: "provisionersftw",
Features: license.Features{ LicenseOptions: &coderdenttest.LicenseOptions{
codersdk.FeatureExternalProvisionerDaemons: 1, 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")
} }

View File

@ -47,7 +47,7 @@ func TestCheckWarnings(t *testing.T) {
var buf bytes.Buffer var buf bytes.Buffer
inv.Stderr = &buf inv.Stderr = &buf
clitest.SetupConfig(t, client, conf) clitest.SetupConfig(t, client, conf) //nolint:gocritic // owners should see this
err := inv.Run() err := inv.Run()
require.NoError(t, err) require.NoError(t, err)

View File

@ -37,50 +37,37 @@ func TestStart(t *testing.T) {
}, },
}, },
}) })
templateAdminClient, templateAdmin := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID, rbac.RoleTemplateAdmin())
// Create an initial version. // 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. // Create a template that mandates the promoted version.
// This should be enforced for everyone except template admins. // This should be enforced for everyone except template admins.
template := coderdtest.CreateTemplate(t, ownerClient, owner.OrganizationID, oldVersion.ID) template := coderdtest.CreateTemplate(t, templateAdminClient, owner.OrganizationID, oldVersion.ID)
coderdtest.AwaitTemplateVersionJobCompleted(t, ownerClient, oldVersion.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, templateAdminClient, oldVersion.ID)
require.Equal(t, oldVersion.ID, template.ActiveVersionID) 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, RequireActiveVersion: true,
}) })
require.NoError(t, err)
require.True(t, template.RequireActiveVersion) require.True(t, template.RequireActiveVersion)
// Create a new version that we will promote. // 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 ctvr.TemplateID = template.ID
}) })
coderdtest.AwaitTemplateVersionJobCompleted(t, ownerClient, activeVersion.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, templateAdminClient, activeVersion.ID)
err = ownerClient.UpdateActiveTemplateVersion(ctx, template.ID, codersdk.UpdateActiveTemplateVersion{ err := templateAdminClient.UpdateActiveTemplateVersion(ctx, template.ID, codersdk.UpdateActiveTemplateVersion{
ID: activeVersion.ID,
})
require.NoError(t, err)
err = ownerClient.UpdateActiveTemplateVersion(ctx, template.ID, codersdk.UpdateActiveTemplateVersion{
ID: activeVersion.ID, ID: activeVersion.ID,
}) })
require.NoError(t, err) require.NoError(t, err)
templateAdminClient, templateAdmin := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID, rbac.RoleTemplateAdmin())
templateACLAdminClient, templateACLAdmin := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID) templateACLAdminClient, templateACLAdmin := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID)
templateGroupACLAdminClient, templateGroupACLAdmin := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID) templateGroupACLAdminClient, templateGroupACLAdmin := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID)
memberClient, member := 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. // 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. // Add the user who gains template admin via group membership.
group, err = ownerClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ group := coderdtest.CreateGroup(t, ownerClient, owner.OrganizationID, "test", templateGroupACLAdmin)
AddUsers: []string{templateGroupACLAdmin.ID.String()},
})
require.NoError(t, err)
// Update the template for both users and groups. // Update the template for both users and groups.
err = ownerClient.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ err = ownerClient.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{

View File

@ -8,6 +8,7 @@ import (
"github.com/coder/coder/v2/cli/clitest" "github.com/coder/coder/v2/cli/clitest"
"github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database" "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/codersdk"
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
"github.com/coder/coder/v2/enterprise/coderd/license" "github.com/coder/coder/v2/enterprise/coderd/license"
@ -37,6 +38,7 @@ func TestTemplateCreate(t *testing.T) {
IncludeProvisionerDaemon: true, IncludeProvisionerDaemon: true,
}, },
}) })
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin())
source := clitest.CreateTemplateVersionSource(t, &echo.Responses{ source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
Parse: echo.ParseComplete, Parse: echo.ParseComplete,
@ -51,13 +53,13 @@ func TestTemplateCreate(t *testing.T) {
"-y", "-y",
) )
clitest.SetupConfig(t, client, conf) clitest.SetupConfig(t, templateAdmin, conf)
err := inv.Run() err := inv.Run()
require.NoError(t, err) require.NoError(t, err)
ctx := testutil.Context(t, testutil.WaitMedium) 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.NoError(t, err)
require.True(t, template.RequireActiveVersion) require.True(t, template.RequireActiveVersion)
}) })
@ -70,7 +72,7 @@ func TestTemplateCreate(t *testing.T) {
string(codersdk.ExperimentTemplateUpdatePolicies), string(codersdk.ExperimentTemplateUpdatePolicies),
} }
client, _ := coderdenttest.New(t, &coderdenttest.Options{ client, admin := coderdenttest.New(t, &coderdenttest.Options{
LicenseOptions: &coderdenttest.LicenseOptions{ LicenseOptions: &coderdenttest.LicenseOptions{
Features: license.Features{}, Features: license.Features{},
}, },
@ -79,6 +81,7 @@ func TestTemplateCreate(t *testing.T) {
IncludeProvisionerDaemon: true, IncludeProvisionerDaemon: true,
}, },
}) })
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID, rbac.RoleTemplateAdmin())
inv, conf := newCLI(t, "templates", inv, conf := newCLI(t, "templates",
"create", "new", "create", "new",
@ -86,7 +89,7 @@ func TestTemplateCreate(t *testing.T) {
"-y", "-y",
) )
clitest.SetupConfig(t, client, conf) clitest.SetupConfig(t, templateAdmin, conf)
err := inv.Run() err := inv.Run()
require.Error(t, err) require.Error(t, err)

View File

@ -77,6 +77,7 @@ func TestTemplateEdit(t *testing.T) {
IncludeProvisionerDaemon: true, IncludeProvisionerDaemon: true,
}, },
}) })
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil) version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil)
_ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) _ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
@ -89,7 +90,7 @@ func TestTemplateEdit(t *testing.T) {
"-y", "-y",
) )
clitest.SetupConfig(t, client, conf) clitest.SetupConfig(t, templateAdmin, conf)
err := inv.Run() err := inv.Run()
require.Error(t, err) require.Error(t, err)

View File

@ -53,7 +53,7 @@ func Test_ProxyCRUD(t *testing.T) {
pty := ptytest.New(t) pty := ptytest.New(t)
inv.Stdout = pty.Output() 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() err := inv.WithContext(ctx).Run()
require.NoError(t, err) require.NoError(t, err)
@ -72,14 +72,14 @@ func Test_ProxyCRUD(t *testing.T) {
pty = ptytest.New(t) pty = ptytest.New(t)
inv.Stdout = pty.Output() inv.Stdout = pty.Output()
clitest.SetupConfig(t, client, conf) clitest.SetupConfig(t, client, conf) //nolint:gocritic // requires owner
err = inv.WithContext(ctx).Run() err = inv.WithContext(ctx).Run()
require.NoError(t, err) require.NoError(t, err)
pty.ExpectMatch(expectedName) pty.ExpectMatch(expectedName)
// Also check via the api // 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") require.NoError(t, err, "failed to get workspace proxies")
// Include primary // Include primary
require.Len(t, proxies.Regions, 2, "expected 1 proxy") require.Len(t, proxies.Regions, 2, "expected 1 proxy")
@ -128,12 +128,12 @@ func Test_ProxyCRUD(t *testing.T) {
pty := ptytest.New(t) pty := ptytest.New(t)
inv.Stdout = pty.Output() inv.Stdout = pty.Output()
clitest.SetupConfig(t, client, conf) clitest.SetupConfig(t, client, conf) //nolint:gocritic // requires owner
err = inv.WithContext(ctx).Run() err = inv.WithContext(ctx).Run()
require.NoError(t, err) 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.NoError(t, err, "failed to get workspace proxies")
require.Len(t, proxies.Regions, 1, "expected only primary proxy") require.Len(t, proxies.Regions, 1, "expected only primary proxy")
}) })

View File

@ -28,13 +28,15 @@ func TestCustomLogoAndCompanyName(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel() 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{ coderdenttest.AddLicense(t, adminClient, coderdenttest.LicenseOptions{
Features: license.Features{ Features: license.Features{
codersdk.FeatureAppearance: 1, codersdk.FeatureAppearance: 1,
}, },
}) })
anotherClient, _ := coderdtest.CreateAnotherUser(t, adminClient, adminUser.OrganizationID)
// Update logo and application name // Update logo and application name
uac := codersdk.UpdateAppearanceConfig{ uac := codersdk.UpdateAppearanceConfig{
ApplicationName: "ACME Ltd", ApplicationName: "ACME Ltd",
@ -45,7 +47,7 @@ func TestCustomLogoAndCompanyName(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
// Verify update // Verify update
got, err := adminClient.Appearance(ctx) got, err := anotherClient.Appearance(ctx)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, uac.ApplicationName, got.ApplicationName) require.Equal(t, uac.ApplicationName, got.ApplicationName)
@ -62,9 +64,10 @@ func TestServiceBanners(t *testing.T) {
defer cancel() defer cancel()
adminClient, adminUser := coderdenttest.New(t, &coderdenttest.Options{DontAddLicense: true}) 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. // 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.NoError(t, err)
require.False(t, sb.ServiceBanner.Enabled) require.False(t, sb.ServiceBanner.Enabled)
@ -75,12 +78,10 @@ func TestServiceBanners(t *testing.T) {
}) })
// Default state // Default state
sb, err = adminClient.Appearance(ctx) sb, err = basicUserClient.Appearance(ctx)
require.NoError(t, err) require.NoError(t, err)
require.False(t, sb.ServiceBanner.Enabled) require.False(t, sb.ServiceBanner.Enabled)
basicUserClient, _ := coderdtest.CreateAnotherUser(t, adminClient, adminUser.OrganizationID)
uac := codersdk.UpdateAppearanceConfig{ uac := codersdk.UpdateAppearanceConfig{
ServiceBanner: sb.ServiceBanner, ServiceBanner: sb.ServiceBanner,
} }
@ -100,7 +101,7 @@ func TestServiceBanners(t *testing.T) {
wantBanner.ServiceBanner.BackgroundColor = "#00FF00" wantBanner.ServiceBanner.BackgroundColor = "#00FF00"
err = adminClient.UpdateAppearance(ctx, wantBanner) err = adminClient.UpdateAppearance(ctx, wantBanner)
require.NoError(t, err) 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) require.NoError(t, err)
gotBanner.SupportLinks = nil // clean "support links" before comparison gotBanner.SupportLinks = nil // clean "support links" before comparison
require.Equal(t, wantBanner.ServiceBanner, gotBanner.ServiceBanner) require.Equal(t, wantBanner.ServiceBanner, gotBanner.ServiceBanner)
@ -200,7 +201,7 @@ func TestCustomSupportLinks(t *testing.T) {
Value: supportLinks, Value: supportLinks,
} }
client, _ := coderdenttest.New(t, &coderdenttest.Options{ adminClient, adminUser := coderdenttest.New(t, &coderdenttest.Options{
Options: &coderdtest.Options{ Options: &coderdtest.Options{
DeploymentValues: cfg, 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) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium)
defer cancel() defer cancel()
appearance, err := client.Appearance(ctx) appearance, err := anotherClient.Appearance(ctx)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, supportLinks, appearance.SupportLinks) require.Equal(t, supportLinks, appearance.SupportLinks)
} }
@ -223,12 +225,13 @@ func TestDefaultSupportLinks(t *testing.T) {
t.Parallel() t.Parallel()
// Don't need to set the license, as default links are passed without it. // 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) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium)
defer cancel() defer cancel()
appearance, err := client.Appearance(ctx) appearance, err := anotherClient.Appearance(ctx)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, coderd.DefaultSupportLinks, appearance.SupportLinks) require.Equal(t, coderd.DefaultSupportLinks, appearance.SupportLinks)
} }

View File

@ -38,17 +38,18 @@ func TestEntitlements(t *testing.T) {
t.Parallel() t.Parallel()
t.Run("NoLicense", func(t *testing.T) { t.Run("NoLicense", func(t *testing.T) {
t.Parallel() t.Parallel()
client, _ := coderdenttest.New(t, &coderdenttest.Options{ adminClient, adminUser := coderdenttest.New(t, &coderdenttest.Options{
DontAddLicense: true, 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.NoError(t, err)
require.False(t, res.HasLicense) require.False(t, res.HasLicense)
require.Empty(t, res.Warnings) require.Empty(t, res.Warnings)
}) })
t.Run("FullLicense", func(t *testing.T) { t.Run("FullLicense", func(t *testing.T) {
t.Parallel() t.Parallel()
client, _ := coderdenttest.New(t, &coderdenttest.Options{ adminClient, _ := coderdenttest.New(t, &coderdenttest.Options{
AuditLogging: true, AuditLogging: true,
DontAddLicense: true, DontAddLicense: true,
}) })
@ -58,11 +59,11 @@ func TestEntitlements(t *testing.T) {
features[feature] = 1 features[feature] = 1
} }
features[codersdk.FeatureUserLimit] = 100 features[codersdk.FeatureUserLimit] = 100
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{ coderdenttest.AddLicense(t, adminClient, coderdenttest.LicenseOptions{
Features: features, Features: features,
GraceAt: time.Now().Add(59 * 24 * time.Hour), 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) require.NoError(t, err)
assert.True(t, res.HasLicense) assert.True(t, res.HasLicense)
ul := res.Features[codersdk.FeatureUserLimit] ul := res.Features[codersdk.FeatureUserLimit]
@ -83,27 +84,28 @@ func TestEntitlements(t *testing.T) {
}) })
t.Run("FullLicenseToNone", func(t *testing.T) { t.Run("FullLicenseToNone", func(t *testing.T) {
t.Parallel() t.Parallel()
client, _ := coderdenttest.New(t, &coderdenttest.Options{ adminClient, adminUser := coderdenttest.New(t, &coderdenttest.Options{
AuditLogging: true, AuditLogging: true,
DontAddLicense: 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{ Features: license.Features{
codersdk.FeatureUserLimit: 100, codersdk.FeatureUserLimit: 100,
codersdk.FeatureAuditLog: 1, codersdk.FeatureAuditLog: 1,
}, },
}) })
res, err := client.Entitlements(context.Background()) res, err := anotherClient.Entitlements(context.Background())
require.NoError(t, err) require.NoError(t, err)
assert.True(t, res.HasLicense) assert.True(t, res.HasLicense)
al := res.Features[codersdk.FeatureAuditLog] al := res.Features[codersdk.FeatureAuditLog]
assert.Equal(t, codersdk.EntitlementEntitled, al.Entitlement) assert.Equal(t, codersdk.EntitlementEntitled, al.Entitlement)
assert.True(t, al.Enabled) assert.True(t, al.Enabled)
err = client.DeleteLicense(context.Background(), license.ID) err = adminClient.DeleteLicense(context.Background(), license.ID)
require.NoError(t, err) require.NoError(t, err)
res, err = client.Entitlements(context.Background()) res, err = anotherClient.Entitlements(context.Background())
require.NoError(t, err) require.NoError(t, err)
assert.False(t, res.HasLicense) assert.False(t, res.HasLicense)
al = res.Features[codersdk.FeatureAuditLog] al = res.Features[codersdk.FeatureAuditLog]
@ -112,8 +114,9 @@ func TestEntitlements(t *testing.T) {
}) })
t.Run("Pubsub", func(t *testing.T) { t.Run("Pubsub", func(t *testing.T) {
t.Parallel() t.Parallel()
client, _, api, _ := coderdenttest.NewWithAPI(t, &coderdenttest.Options{DontAddLicense: true}) adminClient, _, api, adminUser := coderdenttest.NewWithAPI(t, &coderdenttest.Options{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.NoError(t, err)
require.False(t, entitlements.HasLicense) require.False(t, entitlements.HasLicense)
//nolint:gocritic // unit test //nolint:gocritic // unit test
@ -131,18 +134,19 @@ func TestEntitlements(t *testing.T) {
err = api.Pubsub.Publish(coderd.PubsubEventLicenses, []byte{}) err = api.Pubsub.Publish(coderd.PubsubEventLicenses, []byte{})
require.NoError(t, err) require.NoError(t, err)
require.Eventually(t, func() bool { require.Eventually(t, func() bool {
entitlements, err := client.Entitlements(context.Background()) entitlements, err := anotherClient.Entitlements(context.Background())
assert.NoError(t, err) assert.NoError(t, err)
return entitlements.HasLicense return entitlements.HasLicense
}, testutil.WaitShort, testutil.IntervalFast) }, testutil.WaitShort, testutil.IntervalFast)
}) })
t.Run("Resync", func(t *testing.T) { t.Run("Resync", func(t *testing.T) {
t.Parallel() t.Parallel()
client, _, api, _ := coderdenttest.NewWithAPI(t, &coderdenttest.Options{ adminClient, _, api, adminUser := coderdenttest.NewWithAPI(t, &coderdenttest.Options{
EntitlementsUpdateInterval: 25 * time.Millisecond, EntitlementsUpdateInterval: 25 * time.Millisecond,
DontAddLicense: true, 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.NoError(t, err)
require.False(t, entitlements.HasLicense) require.False(t, entitlements.HasLicense)
// Valid // Valid
@ -177,7 +181,7 @@ func TestEntitlements(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
require.Eventually(t, func() bool { require.Eventually(t, func() bool {
entitlements, err := client.Entitlements(context.Background()) entitlements, err := anotherClient.Entitlements(context.Background())
assert.NoError(t, err) assert.NoError(t, err)
return entitlements.HasLicense return entitlements.HasLicense
}, testutil.WaitShort, testutil.IntervalFast) }, testutil.WaitShort, testutil.IntervalFast)
@ -224,7 +228,7 @@ func TestAuditLogging(t *testing.T) {
DontAddLicense: true, DontAddLicense: true,
}) })
workspace, agent := setupWorkspaceAgent(t, client, user, 0) 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) require.NoError(t, err)
defer conn.Close() defer conn.Close()
connected := conn.AwaitReachable(ctx) connected := conn.AwaitReachable(ctx)

View File

@ -10,6 +10,7 @@ import (
"github.com/coder/coder/v2/coderd/audit" "github.com/coder/coder/v2/coderd/audit"
"github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database" "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/coderd/util/ptr"
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
@ -28,8 +29,9 @@ func TestCreateGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
AvatarURL: "https://example.com", 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) ctx := testutil.Context(t, testutil.WaitLong)
numLogs := len(auditor.AuditLogs()) numLogs := len(auditor.AuditLogs())
group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ group, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
Name: "hi", Name: "hi",
}) })
require.NoError(t, err) require.NoError(t, err)
numLogs++ numLogs++
require.Len(t, auditor.AuditLogs(), numLogs) require.Len(t, auditor.AuditLogs(), numLogs)
require.Equal(t, database.AuditActionCreate, auditor.AuditLogs()[numLogs-1].Action) require.True(t, auditor.Contains(t, database.AuditLog{
require.Equal(t, group.ID, auditor.AuditLogs()[numLogs-1].ResourceID) Action: database.AuditActionCreate,
ResourceID: group.ID,
}))
}) })
t.Run("Conflict", func(t *testing.T) { t.Run("Conflict", func(t *testing.T) {
@ -80,13 +85,14 @@ func TestCreateGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
ctx := testutil.Context(t, testutil.WaitLong) ctx := testutil.Context(t, testutil.WaitLong)
_, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ _, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
Name: "hi", Name: "hi",
}) })
require.NoError(t, err) require.NoError(t, err)
_, err = client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ _, err = userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
Name: "hi", Name: "hi",
}) })
require.Error(t, err) require.Error(t, err)
@ -103,8 +109,9 @@ func TestCreateGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
ctx := testutil.Context(t, testutil.WaitLong) 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, Name: database.EveryoneGroup,
}) })
require.Error(t, err) require.Error(t, err)
@ -125,9 +132,10 @@ func TestPatchGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
const displayName = "foobar" const displayName = "foobar"
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
AvatarURL: "https://example.com", AvatarURL: "https://example.com",
QuotaAllowance: 10, QuotaAllowance: 10,
@ -136,7 +144,7 @@ func TestPatchGroup(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 10, group.QuotaAllowance) 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", Name: "bye",
AvatarURL: ptr.Ref("https://google.com"), AvatarURL: ptr.Ref("https://google.com"),
QuotaAllowance: ptr.Ref(20), QuotaAllowance: ptr.Ref(20),
@ -157,9 +165,10 @@ func TestPatchGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
const displayName = "foobar" const displayName = "foobar"
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
AvatarURL: "https://example.com", AvatarURL: "https://example.com",
QuotaAllowance: 10, QuotaAllowance: 10,
@ -168,7 +177,7 @@ func TestPatchGroup(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 10, group.QuotaAllowance) 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", Name: "bye",
AvatarURL: ptr.Ref("https://google.com"), AvatarURL: ptr.Ref("https://google.com"),
QuotaAllowance: ptr.Ref(20), QuotaAllowance: ptr.Ref(20),
@ -191,13 +200,14 @@ func TestPatchGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
}) })
require.NoError(t, err) require.NoError(t, err)
group, err = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ group, err = userAdminClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{
Name: "hi", Name: "hi",
}) })
require.NoError(t, err) require.NoError(t, err)
@ -212,16 +222,17 @@ func TestPatchGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
_, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
_, user3 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user3 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
}) })
require.NoError(t, err) 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()}, AddUsers: []string{user2.ID.String(), user3.ID.String()},
}) })
require.NoError(t, err) require.NoError(t, err)
@ -237,24 +248,25 @@ func TestPatchGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
_, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
_, user3 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user3 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
_, user4 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user4 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
}) })
require.NoError(t, err) 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()}, AddUsers: []string{user2.ID.String(), user3.ID.String(), user4.ID.String()},
}) })
require.NoError(t, err) require.NoError(t, err)
require.Contains(t, group.Members, user2) require.Contains(t, group.Members, user2)
require.Contains(t, group.Members, user3) 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()}, RemoveUsers: []string{user2.ID.String(), user3.ID.String()},
}) })
require.NoError(t, err) 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) 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", Name: "hi",
}) })
require.NoError(t, err) require.NoError(t, err)
numLogs := len(auditor.AuditLogs()) numLogs := len(auditor.AuditLogs())
group, err = client.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ group, err = userAdminClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{
Name: "bye", Name: "bye",
}) })
require.NoError(t, err) require.NoError(t, err)
@ -306,19 +319,20 @@ func TestPatchGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
AvatarURL: "https://example.com", AvatarURL: "https://example.com",
}) })
require.NoError(t, err) require.NoError(t, err)
group2, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ group2, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
Name: "bye", Name: "bye",
}) })
require.NoError(t, err) 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, Name: group2.Name,
AvatarURL: ptr.Ref("https://google.com"), AvatarURL: ptr.Ref("https://google.com"),
}) })
@ -336,13 +350,14 @@ func TestPatchGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
}) })
require.NoError(t, err) 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()}, AddUsers: []string{uuid.NewString()},
}) })
require.Error(t, err) require.Error(t, err)
@ -359,13 +374,14 @@ func TestPatchGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
}) })
require.NoError(t, err) 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"}, AddUsers: []string{"yeet"},
}) })
require.Error(t, err) require.Error(t, err)
@ -382,14 +398,15 @@ func TestPatchGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
_, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
}) })
require.NoError(t, err) 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()}, AddUsers: []string{user2.ID.String(), user2.ID.String()},
}) })
require.Error(t, err) require.Error(t, err)
@ -407,13 +424,14 @@ func TestPatchGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
}) })
require.NoError(t, err) 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, Name: database.EveryoneGroup,
}) })
require.Error(t, err) require.Error(t, err)
@ -432,8 +450,9 @@ func TestPatchGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
ctx := testutil.Context(t, testutil.WaitLong) ctx := testutil.Context(t, testutil.WaitLong)
_, err := client.PatchGroup(ctx, user.OrganizationID, codersdk.PatchGroupRequest{ _, err := userAdminClient.PatchGroup(ctx, user.OrganizationID, codersdk.PatchGroupRequest{
Name: "hi", Name: "hi",
}) })
require.Error(t, err) require.Error(t, err)
@ -450,8 +469,9 @@ func TestPatchGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
ctx := testutil.Context(t, testutil.WaitLong) 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"), DisplayName: ptr.Ref("hi"),
}) })
require.Error(t, err) require.Error(t, err)
@ -468,10 +488,11 @@ func TestPatchGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
_, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
ctx := testutil.Context(t, testutil.WaitLong) 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()}, AddUsers: []string{user2.ID.String()},
}) })
require.Error(t, err) require.Error(t, err)
@ -488,9 +509,10 @@ func TestPatchGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
ctx := testutil.Context(t, testutil.WaitLong) 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()}, RemoveUsers: []string{user.UserID.String()},
}) })
require.Error(t, err) require.Error(t, err)
@ -507,15 +529,16 @@ func TestPatchGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
ctx := testutil.Context(t, testutil.WaitLong) 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.NoError(t, err)
require.Equal(t, 0, group.QuotaAllowance) require.Equal(t, 0, group.QuotaAllowance)
expectedQuota := 123 expectedQuota := 123
group, err = client.PatchGroup(ctx, user.OrganizationID, codersdk.PatchGroupRequest{ group, err = userAdminClient.PatchGroup(ctx, user.OrganizationID, codersdk.PatchGroupRequest{
QuotaAllowance: ptr.Ref(expectedQuota), QuotaAllowance: ptr.Ref(expectedQuota),
}) })
require.NoError(t, err) require.NoError(t, err)
@ -536,13 +559,14 @@ func TestGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
}) })
require.NoError(t, err) require.NoError(t, err)
ggroup, err := client.Group(ctx, group.ID) ggroup, err := userAdminClient.Group(ctx, group.ID)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, group, ggroup) require.Equal(t, group, ggroup)
}) })
@ -555,13 +579,14 @@ func TestGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
}) })
require.NoError(t, err) 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.NoError(t, err)
require.Equal(t, group, ggroup) require.Equal(t, group, ggroup)
}) })
@ -574,23 +599,24 @@ func TestGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
_, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
_, user3 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user3 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
}) })
require.NoError(t, err) 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()}, AddUsers: []string{user2.ID.String(), user3.ID.String()},
}) })
require.NoError(t, err) require.NoError(t, err)
require.Contains(t, group.Members, user2) require.Contains(t, group.Members, user2)
require.Contains(t, group.Members, user3) 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.NoError(t, err)
require.Equal(t, group, ggroup) require.Equal(t, group, ggroup)
}) })
@ -606,6 +632,7 @@ func TestGroup(t *testing.T) {
client1, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) client1, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
ctx := testutil.Context(t, testutil.WaitLong) ctx := testutil.Context(t, testutil.WaitLong)
//nolint:gocritic // test setup
group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
Name: "hi", Name: "hi",
}) })
@ -623,27 +650,28 @@ func TestGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
_, user1 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user1 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
_, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
}) })
require.NoError(t, err) 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()}, AddUsers: []string{user1.ID.String(), user2.ID.String()},
}) })
require.NoError(t, err) require.NoError(t, err)
require.Contains(t, group.Members, user1) require.Contains(t, group.Members, user1)
require.Contains(t, group.Members, user2) require.Contains(t, group.Members, user2)
err = client.DeleteUser(ctx, user1.ID) err = userAdminClient.DeleteUser(ctx, user1.ID)
require.NoError(t, err) require.NoError(t, err)
group, err = client.Group(ctx, group.ID) group, err = userAdminClient.Group(ctx, group.ID)
require.NoError(t, err) require.NoError(t, err)
require.NotContains(t, group.Members, user1) require.NotContains(t, group.Members, user1)
}) })
@ -656,17 +684,18 @@ func TestGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
_, user1 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user1 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
_, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
}) })
require.NoError(t, err) 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()}, AddUsers: []string{user1.ID.String(), user2.ID.String()},
}) })
require.NoError(t, err) require.NoError(t, err)
@ -674,17 +703,17 @@ func TestGroup(t *testing.T) {
require.Contains(t, group.Members, user1) require.Contains(t, group.Members, user1)
require.Contains(t, group.Members, user2) 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) require.NoError(t, err)
group, err = client.Group(ctx, group.ID) group, err = userAdminClient.Group(ctx, group.ID)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, group.Members, 2) require.Len(t, group.Members, 2)
require.Contains(t, group.Members, user1) require.Contains(t, group.Members, user1)
require.Contains(t, group.Members, user2) require.Contains(t, group.Members, user2)
// cannot explicitly set a dormant user status so must create a new user // 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", Email: "coder@coder.com",
Username: "coder", Username: "coder",
Password: "SomeStrongPassword!", Password: "SomeStrongPassword!",
@ -695,11 +724,11 @@ func TestGroup(t *testing.T) {
// Ensure that new user has dormant account // Ensure that new user has dormant account
require.Equal(t, codersdk.UserStatusDormant, anotherUser.Status) 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()}, AddUsers: []string{anotherUser.ID.String()},
}) })
group, err = client.Group(ctx, group.ID) group, err = userAdminClient.Group(ctx, group.ID)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, group.Members, 3) require.Len(t, group.Members, 3)
require.Contains(t, group.Members, user1) require.Contains(t, group.Members, user1)
@ -714,14 +743,15 @@ func TestGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
_, user1 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user1 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
_, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
ctx := testutil.Context(t, testutil.WaitLong) ctx := testutil.Context(t, testutil.WaitLong)
// The 'Everyone' group always has an ID that matches the organization ID. // 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.NoError(t, err)
require.Len(t, group.Members, 3) require.Len(t, group.Members, 4)
require.Equal(t, "Everyone", group.Name) require.Equal(t, "Everyone", group.Name)
require.Equal(t, user.OrganizationID, group.OrganizationID) require.Equal(t, user.OrganizationID, group.OrganizationID)
require.Contains(t, group.Members, user1, user2) require.Contains(t, group.Members, user1, user2)
@ -740,33 +770,34 @@ func TestGroups(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
_, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
_, user3 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user3 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
_, user4 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user4 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
_, user5 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user5 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
}) })
require.NoError(t, err) require.NoError(t, err)
group2, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{ group2, err := userAdminClient.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
Name: "hey", Name: "hey",
}) })
require.NoError(t, err) 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()}, AddUsers: []string{user2.ID.String(), user3.ID.String()},
}) })
require.NoError(t, err) 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()}, AddUsers: []string{user4.ID.String(), user5.ID.String()},
}) })
require.NoError(t, err) require.NoError(t, err)
groups, err := client.GroupsByOrganization(ctx, user.OrganizationID) groups, err := userAdminClient.GroupsByOrganization(ctx, user.OrganizationID)
require.NoError(t, err) require.NoError(t, err)
// 'Everyone' group + 2 custom groups. // 'Everyone' group + 2 custom groups.
require.Len(t, groups, 3) require.Len(t, groups, 3)
@ -786,16 +817,17 @@ func TestDeleteGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
}) })
require.NoError(t, err) require.NoError(t, err)
err = client.DeleteGroup(ctx, group1.ID) err = userAdminClient.DeleteGroup(ctx, group1.ID)
require.NoError(t, err) require.NoError(t, err)
_, err = client.Group(ctx, group1.ID) _, err = userAdminClient.Group(ctx, group1.ID)
require.Error(t, err) require.Error(t, err)
cerr, ok := codersdk.AsError(err) cerr, ok := codersdk.AsError(err)
require.True(t, ok) require.True(t, ok)
@ -813,6 +845,7 @@ func TestDeleteGroup(t *testing.T) {
Auditor: auditor, Auditor: auditor,
}, },
}) })
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{ _ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
Features: license.Features{ Features: license.Features{
@ -822,19 +855,21 @@ func TestDeleteGroup(t *testing.T) {
}) })
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "hi",
}) })
require.NoError(t, err) require.NoError(t, err)
numLogs := len(auditor.AuditLogs()) numLogs := len(auditor.AuditLogs())
err = client.DeleteGroup(ctx, group.ID) err = userAdminClient.DeleteGroup(ctx, group.ID)
require.NoError(t, err) require.NoError(t, err)
numLogs++ numLogs++
require.Len(t, auditor.AuditLogs(), numLogs) require.Len(t, auditor.AuditLogs(), numLogs)
require.Equal(t, database.AuditActionDelete, auditor.AuditLogs()[numLogs-1].Action) require.True(t, auditor.Contains(t, database.AuditLog{
require.Equal(t, group.ID, auditor.AuditLogs()[numLogs-1].ResourceID) Action: database.AuditActionDelete,
ResourceID: group.ID,
}))
}) })
t.Run("allUsers", func(t *testing.T) { t.Run("allUsers", func(t *testing.T) {
@ -845,8 +880,9 @@ func TestDeleteGroup(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
userAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleUserAdmin())
ctx := testutil.Context(t, testutil.WaitLong) ctx := testutil.Context(t, testutil.WaitLong)
err := client.DeleteGroup(ctx, user.OrganizationID) err := userAdminClient.DeleteGroup(ctx, user.OrganizationID)
require.Error(t, err) require.Error(t, err)
cerr, ok := codersdk.AsError(err) cerr, ok := codersdk.AsError(err)
require.True(t, ok) require.True(t, ok)

View File

@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/coderdtest" "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/codersdk"
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest" "github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
"github.com/coder/coder/v2/enterprise/coderd/license" "github.com/coder/coder/v2/enterprise/coderd/license"
@ -41,6 +42,7 @@ func TestTemplateInsightsWithTemplateAdminACL(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
templateAdminClient, _ := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID, rbac.RoleTemplateAdmin())
version := coderdtest.CreateTemplateVersion(t, client, admin.OrganizationID, nil) version := coderdtest.CreateTemplateVersion(t, client, admin.OrganizationID, nil)
template := coderdtest.CreateTemplate(t, client, admin.OrganizationID, version.ID) 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) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
defer cancel() defer cancel()
err := client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ err := templateAdminClient.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{
UserPerms: map[string]codersdk.TemplateRole{ UserPerms: map[string]codersdk.TemplateRole{
regularUser.ID.String(): codersdk.TemplateRoleAdmin, regularUser.ID.String(): codersdk.TemplateRoleAdmin,
}, },

View File

@ -148,6 +148,7 @@ func TestDeleteLicense(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel() defer cancel()
//nolint:gocritic // RBAC is irrelevant here.
resp, err := client.Request(ctx, http.MethodDelete, "/api/v2/licenses/drivers", nil) resp, err := client.Request(ctx, http.MethodDelete, "/api/v2/licenses/drivers", nil)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, http.StatusNotFound, resp.StatusCode) assert.Equal(t, http.StatusNotFound, resp.StatusCode)

View File

@ -36,9 +36,10 @@ func TestProvisionerDaemonServe(t *testing.T) {
codersdk.FeatureExternalProvisionerDaemons: 1, codersdk.FeatureExternalProvisionerDaemons: 1,
}, },
}}) }})
templateAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin())
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel() defer cancel()
srv, err := client.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{ srv, err := templateAdminClient.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{
Organization: user.OrganizationID, Organization: user.OrganizationID,
Provisioners: []codersdk.ProvisionerType{ Provisioners: []codersdk.ProvisionerType{
codersdk.ProvisionerTypeEcho, codersdk.ProvisionerTypeEcho,
@ -52,9 +53,10 @@ func TestProvisionerDaemonServe(t *testing.T) {
t.Run("NoLicense", func(t *testing.T) { t.Run("NoLicense", func(t *testing.T) {
t.Parallel() t.Parallel()
client, user := coderdenttest.New(t, &coderdenttest.Options{DontAddLicense: true}) 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) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel() defer cancel()
_, err := client.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{ _, err := templateAdminClient.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{
Organization: user.OrganizationID, Organization: user.OrganizationID,
Provisioners: []codersdk.ProvisionerType{ Provisioners: []codersdk.ProvisionerType{
codersdk.ProvisionerTypeEcho, codersdk.ProvisionerTypeEcho,
@ -149,6 +151,7 @@ func TestProvisionerDaemonServe(t *testing.T) {
ProvisionApply: echo.ProvisionApplyWithAgent(authToken), ProvisionApply: echo.ProvisionApplyWithAgent(authToken),
}) })
require.NoError(t, err) require.NoError(t, err)
//nolint:gocritic // Not testing file upload in this test.
file, err := client.Upload(context.Background(), codersdk.ContentTypeTar, bytes.NewReader(data)) file, err := client.Upload(context.Background(), codersdk.ContentTypeTar, bytes.NewReader(data))
require.NoError(t, err) require.NoError(t, err)
@ -258,6 +261,7 @@ func TestProvisionerDaemonServe(t *testing.T) {
defer pd.Close() defer pd.Close()
// Patch the 'Everyone' group to give the user quota to build their workspace. // 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{ _, err := client.PatchGroup(ctx, user.OrganizationID, codersdk.PatchGroupRequest{
QuotaAllowance: ptr.Ref(1), QuotaAllowance: ptr.Ref(1),
}) })

View File

@ -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) { func TestScim(t *testing.T) {
t.Parallel() t.Parallel()

View File

@ -39,6 +39,7 @@ func TestTemplates(t *testing.T) {
}, },
}, },
}) })
anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
exp := 24 * time.Hour.Milliseconds() exp := 24 * time.Hour.Milliseconds()
@ -56,7 +57,7 @@ func TestTemplates(t *testing.T) {
TemplateID: template.ID, TemplateID: template.ID,
Name: "testing", 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.NoError(t, err)
require.NotNil(t, ws.TTLMillis) require.NotNil(t, ws.TTLMillis)
require.EqualValues(t, exp, *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 // Editing a workspace to have a higher TTL than the template's max
// should error // should error
exp = exp + time.Minute.Milliseconds() exp = exp + time.Minute.Milliseconds()
err = client.UpdateWorkspaceTTL(ctx, ws.ID, codersdk.UpdateWorkspaceTTLRequest{ err = anotherClient.UpdateWorkspaceTTL(ctx, ws.ID, codersdk.UpdateWorkspaceTTLRequest{
TTLMillis: &exp, TTLMillis: &exp,
}) })
require.Error(t, err) require.Error(t, err)
@ -78,7 +79,7 @@ func TestTemplates(t *testing.T) {
// Creating workspace with TTL higher than max should error // Creating workspace with TTL higher than max should error
req.Name = "testing2" req.Name = "testing2"
req.TTLMillis = &exp 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) require.Error(t, err)
apiErr = nil apiErr = nil
require.ErrorAs(t, err, &apiErr) 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) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
exp := 24 * time.Hour.Milliseconds() exp := 24 * time.Hour.Milliseconds()
@ -116,27 +118,27 @@ func TestTemplates(t *testing.T) {
TemplateID: template.ID, TemplateID: template.ID,
Name: "testing", 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.NoError(t, err)
require.NotNil(t, ws.TTLMillis) require.NotNil(t, ws.TTLMillis)
require.EqualValues(t, exp, *ws.TTLMillis) require.EqualValues(t, exp, *ws.TTLMillis)
// Editing a workspace to disable the TTL should do nothing // 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, TTLMillis: nil,
}) })
require.NoError(t, err) require.NoError(t, err)
ws, err = client.Workspace(ctx, ws.ID) ws, err = anotherClient.Workspace(ctx, ws.ID)
require.NoError(t, err) require.NoError(t, err)
require.EqualValues(t, exp, *ws.TTLMillis) require.EqualValues(t, exp, *ws.TTLMillis)
// Editing a workspace to have a TTL of 0 should do nothing // Editing a workspace to have a TTL of 0 should do nothing
zero := int64(0) zero := int64(0)
err = client.UpdateWorkspaceTTL(ctx, ws.ID, codersdk.UpdateWorkspaceTTLRequest{ err = anotherClient.UpdateWorkspaceTTL(ctx, ws.ID, codersdk.UpdateWorkspaceTTLRequest{
TTLMillis: &zero, TTLMillis: &zero,
}) })
require.NoError(t, err) require.NoError(t, err)
ws, err = client.Workspace(ctx, ws.ID) ws, err = anotherClient.Workspace(ctx, ws.ID)
require.NoError(t, err) require.NoError(t, err)
require.EqualValues(t, exp, *ws.TTLMillis) 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) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) 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) require.Equal(t, []string{"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"}, template.AutostartRequirement.DaysOfWeek)
ctx := testutil.Context(t, testutil.WaitLong) 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, Name: template.Name,
DisplayName: template.DisplayName, DisplayName: template.DisplayName,
Description: template.Description, Description: template.Description,
@ -173,12 +176,12 @@ func TestTemplates(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, []string{"monday", "saturday"}, updated.AutostartRequirement.DaysOfWeek) 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.NoError(t, err)
require.Equal(t, []string{"monday", "saturday"}, template.AutostartRequirement.DaysOfWeek) require.Equal(t, []string{"monday", "saturday"}, template.AutostartRequirement.DaysOfWeek)
// Ensure a missing field is a noop // 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, Name: template.Name,
DisplayName: template.DisplayName, DisplayName: template.DisplayName,
Description: template.Description, Description: template.Description,
@ -187,7 +190,7 @@ func TestTemplates(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, []string{"monday", "saturday"}, updated.AutostartRequirement.DaysOfWeek) 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.NoError(t, err)
require.Equal(t, []string{"monday", "saturday"}, template.AutostartRequirement.DaysOfWeek) 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) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) 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) require.Equal(t, []string{"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"}, template.AutostartRequirement.DaysOfWeek)
ctx := testutil.Context(t, testutil.WaitLong) 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, Name: template.Name,
DisplayName: template.DisplayName, DisplayName: template.DisplayName,
Description: template.Description, 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) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
@ -244,9 +249,8 @@ func TestTemplates(t *testing.T) {
require.Empty(t, 0, template.AutostopRequirement.DaysOfWeek) require.Empty(t, 0, template.AutostopRequirement.DaysOfWeek)
require.EqualValues(t, 1, template.AutostopRequirement.Weeks) require.EqualValues(t, 1, template.AutostopRequirement.Weeks)
// ctx := testutil.Context(t, testutil.WaitLong)
ctx := context.Background() ctx := context.Background()
updated, err := client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ updated, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
Name: template.Name, Name: template.Name,
DisplayName: template.DisplayName, DisplayName: template.DisplayName,
Description: template.Description, Description: template.Description,
@ -262,7 +266,7 @@ func TestTemplates(t *testing.T) {
require.Equal(t, []string{"monday", "saturday"}, updated.AutostopRequirement.DaysOfWeek) require.Equal(t, []string{"monday", "saturday"}, updated.AutostopRequirement.DaysOfWeek)
require.EqualValues(t, 3, updated.AutostopRequirement.Weeks) 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.NoError(t, err)
require.Equal(t, []string{"monday", "saturday"}, template.AutostopRequirement.DaysOfWeek) require.Equal(t, []string{"monday", "saturday"}, template.AutostopRequirement.DaysOfWeek)
require.EqualValues(t, 3, template.AutostopRequirement.Weeks) 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) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
@ -297,7 +302,7 @@ func TestTemplates(t *testing.T) {
dormantTTL = 3 * time.Minute 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, Name: template.Name,
DisplayName: template.DisplayName, DisplayName: template.DisplayName,
Description: template.Description, Description: template.Description,
@ -314,7 +319,7 @@ func TestTemplates(t *testing.T) {
// Validate fetching the template returns the same values as updating // Validate fetching the template returns the same values as updating
// the template. // the template.
template, err = client.Template(ctx, template.ID) template, err = anotherClient.Template(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, failureTTL.Milliseconds(), updated.FailureTTLMillis) require.Equal(t, failureTTL.Milliseconds(), updated.FailureTTLMillis)
require.Equal(t, inactivityTTL.Milliseconds(), updated.TimeTilDormantMillis) 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) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
@ -367,7 +373,7 @@ func TestTemplates(t *testing.T) {
// nolint: paralleltest // context is from parent t.Run // nolint: paralleltest // context is from parent t.Run
t.Run(c.Name, func(t *testing.T) { 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, Name: template.Name,
DisplayName: template.DisplayName, DisplayName: template.DisplayName,
Description: template.Description, 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) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
activeWS := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) activeWS := coderdtest.CreateWorkspace(t, anotherClient, user.OrganizationID, template.ID)
dormantWS := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) dormantWS := coderdtest.CreateWorkspace(t, anotherClient, user.OrganizationID, template.ID)
require.Nil(t, activeWS.DeletingAt) require.Nil(t, activeWS.DeletingAt)
require.Nil(t, dormantWS.DeletingAt) require.Nil(t, dormantWS.DeletingAt)
_ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, activeWS.LatestBuild.ID) _ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, activeWS.LatestBuild.ID)
_ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, dormantWS.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, Dormant: true,
}) })
require.NoError(t, err) require.NoError(t, err)
@ -424,7 +431,7 @@ func TestTemplates(t *testing.T) {
require.Nil(t, dormantWS.DeletingAt) require.Nil(t, dormantWS.DeletingAt)
dormantTTL := time.Minute dormantTTL := time.Minute
updated, err := client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ updated, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
TimeTilDormantAutoDeleteMillis: dormantTTL.Milliseconds(), TimeTilDormantAutoDeleteMillis: dormantTTL.Milliseconds(),
}) })
require.NoError(t, err) 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 // Disable the time_til_dormant_auto_delete on the template, then we can assert that the workspaces
// no longer have a deleting_at field. // 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, TimeTilDormantAutoDeleteMillis: 0,
}) })
require.NoError(t, err) 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) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
activeWS := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) activeWS := coderdtest.CreateWorkspace(t, anotherClient, user.OrganizationID, template.ID)
dormantWS := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) dormantWS := coderdtest.CreateWorkspace(t, anotherClient, user.OrganizationID, template.ID)
require.Nil(t, activeWS.DeletingAt) require.Nil(t, activeWS.DeletingAt)
require.Nil(t, dormantWS.DeletingAt) require.Nil(t, dormantWS.DeletingAt)
_ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, activeWS.LatestBuild.ID) _ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, activeWS.LatestBuild.ID)
_ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, dormantWS.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, Dormant: true,
}) })
require.NoError(t, err) require.NoError(t, err)
@ -497,6 +505,7 @@ func TestTemplates(t *testing.T) {
require.Nil(t, dormantWS.DeletingAt) require.Nil(t, dormantWS.DeletingAt)
dormantTTL := time.Minute dormantTTL := time.Minute
//nolint:gocritic // non-template-admin cannot update template meta
updated, err := client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ updated, err := client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
TimeTilDormantAutoDeleteMillis: dormantTTL.Milliseconds(), TimeTilDormantAutoDeleteMillis: dormantTTL.Milliseconds(),
UpdateWorkspaceDormantAt: true, 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) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
activeWorkspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) activeWorkspace := coderdtest.CreateWorkspace(t, anotherClient, user.OrganizationID, template.ID)
dormantWorkspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) dormantWorkspace := coderdtest.CreateWorkspace(t, anotherClient, user.OrganizationID, template.ID)
require.Nil(t, activeWorkspace.DeletingAt) require.Nil(t, activeWorkspace.DeletingAt)
require.Nil(t, dormantWorkspace.DeletingAt) require.Nil(t, dormantWorkspace.DeletingAt)
_ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, activeWorkspace.LatestBuild.ID) _ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, activeWorkspace.LatestBuild.ID)
_ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, dormantWorkspace.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, Dormant: true,
}) })
require.NoError(t, err) require.NoError(t, err)
@ -553,7 +563,7 @@ func TestTemplates(t *testing.T) {
require.Nil(t, dormantWorkspace.DeletingAt) require.Nil(t, dormantWorkspace.DeletingAt)
inactivityTTL := time.Minute inactivityTTL := time.Minute
updated, err := client.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{ updated, err := anotherClient.UpdateTemplateMeta(ctx, template.ID, codersdk.UpdateTemplateMeta{
TimeTilDormantMillis: inactivityTTL.Milliseconds(), TimeTilDormantMillis: inactivityTTL.Milliseconds(),
UpdateWorkspaceLastUsedAt: true, 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) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID, func(ctr *codersdk.CreateTemplateRequest) { template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID, func(ctr *codersdk.CreateTemplateRequest) {
@ -598,14 +609,14 @@ func TestTemplates(t *testing.T) {
defer cancel() defer cancel()
// Update the field and assert it persists. // 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, RequireActiveVersion: false,
}) })
require.NoError(t, err) require.NoError(t, err)
require.False(t, updatedTemplate.RequireActiveVersion) require.False(t, updatedTemplate.RequireActiveVersion)
// Flip it back to ensure we aren't hardcoding to a default value. // 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, RequireActiveVersion: true,
}) })
require.NoError(t, err) require.NoError(t, err)
@ -613,7 +624,7 @@ func TestTemplates(t *testing.T) {
// Assert that fetching a template is no different from the response // Assert that fetching a template is no different from the response
// when updating. // when updating.
template, err = client.Template(ctx, template.ID) template, err = anotherClient.Template(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, updatedTemplate, template) require.Equal(t, updatedTemplate, template)
}) })
@ -629,6 +640,7 @@ func TestTemplateACL(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin())
_, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
_, user3 := 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) 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{ UserPerms: map[string]codersdk.TemplateRole{
user2.ID.String(): codersdk.TemplateRoleUse, user2.ID.String(): codersdk.TemplateRoleUse,
user3.ID.String(): codersdk.TemplateRoleAdmin, user3.ID.String(): codersdk.TemplateRoleAdmin,
@ -645,7 +657,7 @@ func TestTemplateACL(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
acl, err := client.TemplateACL(ctx, template.ID) acl, err := anotherClient.TemplateACL(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
templateUser2 := codersdk.TemplateUser{ templateUser2 := codersdk.TemplateUser{
@ -672,14 +684,14 @@ func TestTemplateACL(t *testing.T) {
}}) }})
// Create a user to assert they aren't returned in the response. // 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) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel() defer cancel()
acl, err := client.TemplateACL(ctx, template.ID) acl, err := anotherClient.TemplateACL(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, acl.Groups, 1) require.Len(t, acl.Groups, 1)
@ -702,6 +714,7 @@ func TestTemplateACL(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel() defer cancel()
//nolint:gocritic // non-template-admin cannot update template acl
acl, err := client.TemplateACL(ctx, template.ID) acl, err := client.TemplateACL(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
@ -721,6 +734,7 @@ func TestTemplateACL(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
//nolint:gocritic // non-template-admin cannot update template acl
acl, err = client.TemplateACL(ctx, template.ID) acl, err = client.TemplateACL(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
@ -744,6 +758,7 @@ func TestTemplateACL(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin(), rbac.RoleUserAdmin())
_, user1 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user1 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
@ -751,24 +766,24 @@ func TestTemplateACL(t *testing.T) {
ctx := testutil.Context(t, testutil.WaitLong) 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{ UserPerms: map[string]codersdk.TemplateRole{
user1.ID.String(): codersdk.TemplateRoleUse, user1.ID.String(): codersdk.TemplateRoleUse,
}, },
}) })
require.NoError(t, err) require.NoError(t, err)
acl, err := client.TemplateACL(ctx, template.ID) acl, err := anotherClient.TemplateACL(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
require.Contains(t, acl.Users, codersdk.TemplateUser{ require.Contains(t, acl.Users, codersdk.TemplateUser{
User: user1, User: user1,
Role: codersdk.TemplateRoleUse, Role: codersdk.TemplateRoleUse,
}) })
err = client.DeleteUser(ctx, user1.ID) err = anotherClient.DeleteUser(ctx, user1.ID)
require.NoError(t, err) require.NoError(t, err)
acl, err = client.TemplateACL(ctx, template.ID) acl, err = anotherClient.TemplateACL(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, acl.Users, 0, "deleted users should be filtered") require.Len(t, acl.Users, 0, "deleted users should be filtered")
}) })
@ -782,6 +797,7 @@ func TestTemplateACL(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin(), rbac.RoleUserAdmin())
_, user1 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user1 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
@ -789,24 +805,24 @@ func TestTemplateACL(t *testing.T) {
ctx := testutil.Context(t, testutil.WaitLong) 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{ UserPerms: map[string]codersdk.TemplateRole{
user1.ID.String(): codersdk.TemplateRoleUse, user1.ID.String(): codersdk.TemplateRoleUse,
}, },
}) })
require.NoError(t, err) require.NoError(t, err)
acl, err := client.TemplateACL(ctx, template.ID) acl, err := anotherClient.TemplateACL(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
require.Contains(t, acl.Users, codersdk.TemplateUser{ require.Contains(t, acl.Users, codersdk.TemplateUser{
User: user1, User: user1,
Role: codersdk.TemplateRoleUse, 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) require.NoError(t, err)
acl, err = client.TemplateACL(ctx, template.ID) acl, err = anotherClient.TemplateACL(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, acl.Users, 0, "suspended users should be filtered") require.Len(t, acl.Users, 0, "suspended users should be filtered")
}) })
@ -820,25 +836,26 @@ func TestTemplateACL(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin(), rbac.RoleUserAdmin())
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
ctx := testutil.Context(t, testutil.WaitLong) 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", Name: "test",
}) })
require.NoError(t, err) 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{ GroupPerms: map[string]codersdk.TemplateRole{
group.ID.String(): codersdk.TemplateRoleUse, group.ID.String(): codersdk.TemplateRoleUse,
}, },
}) })
require.NoError(t, err) require.NoError(t, err)
acl, err := client.TemplateACL(ctx, template.ID) acl, err := anotherClient.TemplateACL(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
// Length should be 2 for test group and the implicit allUsers group. // Length should be 2 for test group and the implicit allUsers group.
require.Len(t, acl.Groups, 2) require.Len(t, acl.Groups, 2)
@ -848,10 +865,10 @@ func TestTemplateACL(t *testing.T) {
Role: codersdk.TemplateRoleUse, Role: codersdk.TemplateRoleUse,
}) })
err = client.DeleteGroup(ctx, group.ID) err = anotherClient.DeleteGroup(ctx, group.ID)
require.NoError(t, err) require.NoError(t, err)
acl, err = client.TemplateACL(ctx, template.ID) acl, err = anotherClient.TemplateACL(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
// Length should be 1 for the allUsers group. // Length should be 1 for the allUsers group.
require.Len(t, acl.Groups, 1) require.Len(t, acl.Groups, 1)
@ -875,6 +892,7 @@ func TestTemplateACL(t *testing.T) {
ctx := testutil.Context(t, testutil.WaitLong) ctx := testutil.Context(t, testutil.WaitLong)
//nolint:gocritic // test setup
err := client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ err := client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{
UserPerms: map[string]codersdk.TemplateRole{ UserPerms: map[string]codersdk.TemplateRole{
user1.ID.String(): codersdk.TemplateRoleUse, user1.ID.String(): codersdk.TemplateRoleUse,
@ -896,6 +914,7 @@ func TestTemplateACL(t *testing.T) {
}) })
require.Error(t, err) require.Error(t, err)
//nolint:gocritic // test setup
err = client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ err = client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{
UserPerms: map[string]codersdk.TemplateRole{ UserPerms: map[string]codersdk.TemplateRole{
user1.ID.String(): codersdk.TemplateRoleAdmin, user1.ID.String(): codersdk.TemplateRoleAdmin,
@ -924,6 +943,7 @@ func TestUpdateTemplateACL(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin())
_, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
_, user3 := 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) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel() defer cancel()
err := client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ err := anotherClient.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{
UserPerms: map[string]codersdk.TemplateRole{ UserPerms: map[string]codersdk.TemplateRole{
user2.ID.String(): codersdk.TemplateRoleUse, user2.ID.String(): codersdk.TemplateRoleUse,
user3.ID.String(): codersdk.TemplateRoleAdmin, user3.ID.String(): codersdk.TemplateRoleAdmin,
@ -941,7 +961,7 @@ func TestUpdateTemplateACL(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
acl, err := client.TemplateACL(ctx, template.ID) acl, err := anotherClient.TemplateACL(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
templateUser2 := codersdk.TemplateUser{ 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) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
@ -989,13 +1010,15 @@ func TestUpdateTemplateACL(t *testing.T) {
user.OrganizationID.String(): codersdk.TemplateRoleDeleted, user.OrganizationID.String(): codersdk.TemplateRoleDeleted,
}, },
} }
err := client.UpdateTemplateACL(ctx, template.ID, req) err := anotherClient.UpdateTemplateACL(ctx, template.ID, req)
require.NoError(t, err) require.NoError(t, err)
numLogs++ numLogs++
require.Len(t, auditor.AuditLogs(), numLogs) require.Len(t, auditor.AuditLogs(), numLogs)
require.Equal(t, database.AuditActionWrite, auditor.AuditLogs()[numLogs-1].Action) require.True(t, auditor.Contains(t, database.AuditLog{
require.Equal(t, template.ID, auditor.AuditLogs()[numLogs-1].ResourceID) Action: database.AuditActionWrite,
ResourceID: template.ID,
}))
}) })
t.Run("DeleteUser", func(t *testing.T) { t.Run("DeleteUser", func(t *testing.T) {
@ -1006,6 +1029,7 @@ func TestUpdateTemplateACL(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin())
_, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) _, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
_, user3 := 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) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel() defer cancel()
err := client.UpdateTemplateACL(ctx, template.ID, req) err := anotherClient.UpdateTemplateACL(ctx, template.ID, req)
require.NoError(t, err) require.NoError(t, err)
acl, err := client.TemplateACL(ctx, template.ID) acl, err := anotherClient.TemplateACL(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
require.Contains(t, acl.Users, codersdk.TemplateUser{ require.Contains(t, acl.Users, codersdk.TemplateUser{
User: user2, 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) require.NoError(t, err)
acl, err = client.TemplateACL(ctx, template.ID) acl, err = anotherClient.TemplateACL(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
require.Contains(t, acl.Users, codersdk.TemplateUser{ require.Contains(t, acl.Users, codersdk.TemplateUser{
@ -1078,6 +1102,7 @@ func TestUpdateTemplateACL(t *testing.T) {
ctx := testutil.Context(t, testutil.WaitLong) 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) err := client.UpdateTemplateACL(ctx, template.ID, req)
require.Error(t, err) require.Error(t, err)
cerr, _ := codersdk.AsError(err) cerr, _ := codersdk.AsError(err)
@ -1103,6 +1128,7 @@ func TestUpdateTemplateACL(t *testing.T) {
ctx := testutil.Context(t, testutil.WaitLong) 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) err := client.UpdateTemplateACL(ctx, template.ID, req)
require.Error(t, err) require.Error(t, err)
cerr, _ := codersdk.AsError(err) cerr, _ := codersdk.AsError(err)
@ -1129,6 +1155,7 @@ func TestUpdateTemplateACL(t *testing.T) {
ctx := testutil.Context(t, testutil.WaitLong) 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) err := client.UpdateTemplateACL(ctx, template.ID, req)
require.Error(t, err) require.Error(t, err)
cerr, _ := codersdk.AsError(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) client2, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
@ -1155,7 +1184,7 @@ func TestUpdateTemplateACL(t *testing.T) {
ctx := testutil.Context(t, testutil.WaitLong) ctx := testutil.Context(t, testutil.WaitLong)
err := client.UpdateTemplateACL(ctx, template.ID, req) err := client1.UpdateTemplateACL(ctx, template.ID, req)
require.NoError(t, err) require.NoError(t, err)
req = codersdk.UpdateTemplateACL{ req = codersdk.UpdateTemplateACL{
@ -1178,6 +1207,7 @@ func TestUpdateTemplateACL(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
client1, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin())
client2, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) client2, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
_, user3 := 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) ctx := testutil.Context(t, testutil.WaitLong)
err := client.UpdateTemplateACL(ctx, template.ID, req) err := client1.UpdateTemplateACL(ctx, template.ID, req)
require.NoError(t, err) require.NoError(t, err)
// Should be able to see user 3 // Should be able to see user 3
@ -1234,6 +1264,7 @@ func TestUpdateTemplateACL(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin())
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) 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) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel() defer cancel()
acl, err := client.TemplateACL(ctx, template.ID) acl, err := anotherClient.TemplateACL(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, acl.Groups, 1) require.Len(t, acl.Groups, 1)
@ -1256,6 +1287,7 @@ func TestUpdateTemplateACL(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin(), rbac.RoleUserAdmin())
client1, user1 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) client1, user1 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
@ -1264,18 +1296,18 @@ func TestUpdateTemplateACL(t *testing.T) {
ctx := testutil.Context(t, testutil.WaitLong) ctx := testutil.Context(t, testutil.WaitLong)
// Create a group to add to the template. // 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", Name: "test",
}) })
require.NoError(t, err) require.NoError(t, err)
// Check that the only current group is the allUsers group. // 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.NoError(t, err)
require.Len(t, acl.Groups, 1) require.Len(t, acl.Groups, 1)
// Update the template to only allow access to the 'test' group. // 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{ GroupPerms: map[string]codersdk.TemplateRole{
// The allUsers group shares the same ID as the organization. // The allUsers group shares the same ID as the organization.
user.OrganizationID.String(): codersdk.TemplateRoleDeleted, 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 // Get the ACL list for the template and assert the test group is
// present. // present.
acl, err = client.TemplateACL(ctx, template.ID) acl, err = anotherClient.TemplateACL(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, acl.Groups, 1) require.Len(t, acl.Groups, 1)
@ -1302,7 +1334,7 @@ func TestUpdateTemplateACL(t *testing.T) {
require.Equal(t, http.StatusNotFound, cerr.StatusCode()) require.Equal(t, http.StatusNotFound, cerr.StatusCode())
// Patch the group to add the regular user. // 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()}, AddUsers: []string{user1.ID.String()},
}) })
require.NoError(t, err) require.NoError(t, err)
@ -1321,6 +1353,7 @@ func TestUpdateTemplateACL(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin())
client1, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) client1, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) 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) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel() defer cancel()
acl, err := client.TemplateACL(ctx, template.ID) acl, err := anotherClient.TemplateACL(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, acl.Groups, 1) require.Len(t, acl.Groups, 1)
@ -1341,14 +1374,14 @@ func TestUpdateTemplateACL(t *testing.T) {
allUsers := acl.Groups[0] 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{ GroupPerms: map[string]codersdk.TemplateRole{
allUsers.ID.String(): codersdk.TemplateRoleDeleted, allUsers.ID.String(): codersdk.TemplateRoleDeleted,
}, },
}) })
require.NoError(t, err) require.NoError(t, err)
acl, err = client.TemplateACL(ctx, template.ID) acl, err = anotherClient.TemplateACL(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, acl.Groups, 0) require.Len(t, acl.Groups, 0)
@ -1377,6 +1410,7 @@ func TestReadFileWithTemplateUpdate(t *testing.T) {
ctx := testutil.Context(t, testutil.WaitLong) 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))) resp, err := client.Upload(ctx, codersdk.ContentTypeTar, bytes.NewReader(make([]byte, 1024)))
require.NoError(t, err) require.NoError(t, err)
@ -1397,6 +1431,7 @@ func TestReadFileWithTemplateUpdate(t *testing.T) {
_, _, err = member.Download(ctx, resp.ID) _, _, err = member.Download(ctx, resp.ID)
require.Error(t, err, "not in acl yet") require.Error(t, err, "not in acl yet")
//nolint:gocritic // regular user cannot update template acl
err = client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ err = client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{
UserPerms: map[string]codersdk.TemplateRole{ UserPerms: map[string]codersdk.TemplateRole{
memberData.ID.String(): codersdk.TemplateRoleAdmin, memberData.ID.String(): codersdk.TemplateRoleAdmin,

View File

@ -153,6 +153,7 @@ func TestUserQuietHours(t *testing.T) {
}) })
ctx := testutil.Context(t, testutil.WaitLong) 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()) _, err := client.UserQuietHoursSchedule(ctx, user.UserID.String())
require.Error(t, err) require.Error(t, err)
var sdkErr *codersdk.Error var sdkErr *codersdk.Error
@ -181,6 +182,7 @@ func TestUserQuietHours(t *testing.T) {
}) })
ctx := testutil.Context(t, testutil.WaitLong) 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()) _, err := client.UserQuietHoursSchedule(ctx, user.UserID.String())
require.Error(t, err) require.Error(t, err)
var sdkErr *codersdk.Error var sdkErr *codersdk.Error
@ -208,6 +210,7 @@ func TestUserQuietHours(t *testing.T) {
}) })
ctx := testutil.Context(t, testutil.WaitLong) 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()) _, err := client.UserQuietHoursSchedule(ctx, user.UserID.String())
require.Error(t, err) require.Error(t, err)
var sdkErr *codersdk.Error var sdkErr *codersdk.Error

View File

@ -45,6 +45,7 @@ func TestBlockNonBrowser(t *testing.T) {
}, },
}) })
_, agent := setupWorkspaceAgent(t, client, user, 0) _, agent := setupWorkspaceAgent(t, client, user, 0)
//nolint:gocritic // Testing that even the owner gets blocked.
_, err := client.DialWorkspaceAgent(context.Background(), agent.ID, nil) _, err := client.DialWorkspaceAgent(context.Background(), agent.ID, nil)
var apiErr *codersdk.Error var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr) require.ErrorAs(t, err, &apiErr)
@ -63,6 +64,7 @@ func TestBlockNonBrowser(t *testing.T) {
}, },
}) })
_, agent := setupWorkspaceAgent(t, client, user, 0) _, 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) conn, err := client.DialWorkspaceAgent(context.Background(), agent.ID, nil)
require.NoError(t, err) require.NoError(t, err)
_ = conn.Close() _ = conn.Close()

View File

@ -40,10 +40,9 @@ func TestWorkspaceBuild(t *testing.T) {
template := coderdtest.CreateTemplate(t, ownerClient, owner.OrganizationID, oldVersion.ID) template := coderdtest.CreateTemplate(t, ownerClient, owner.OrganizationID, oldVersion.ID)
coderdtest.AwaitTemplateVersionJobCompleted(t, ownerClient, oldVersion.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, ownerClient, oldVersion.ID)
require.Equal(t, oldVersion.ID, template.ActiveVersionID) 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, RequireActiveVersion: true,
}) })
require.NoError(t, err)
require.True(t, template.RequireActiveVersion) require.True(t, template.RequireActiveVersion)
// Create a new version that we will promote. // Create a new version that we will promote.
@ -51,10 +50,7 @@ func TestWorkspaceBuild(t *testing.T) {
ctvr.TemplateID = template.ID ctvr.TemplateID = template.ID
}) })
coderdtest.AwaitTemplateVersionJobCompleted(t, ownerClient, activeVersion.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, ownerClient, activeVersion.ID)
err = ownerClient.UpdateActiveTemplateVersion(ctx, template.ID, codersdk.UpdateActiveTemplateVersion{ coderdtest.UpdateActiveTemplateVersion(t, ownerClient, template.ID, activeVersion.ID)
ID: activeVersion.ID,
})
require.NoError(t, err)
templateAdminClient, _ := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID, rbac.RoleTemplateAdmin()) templateAdminClient, _ := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID, rbac.RoleTemplateAdmin())
templateACLAdminClient, templateACLAdmin := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID) templateACLAdminClient, templateACLAdmin := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID)
@ -62,19 +58,12 @@ func TestWorkspaceBuild(t *testing.T) {
memberClient, _ := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID) memberClient, _ := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID)
// Create a group so we can also test group template admin ownership. // 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. // Add the user who gains template admin via group membership.
group, err = ownerClient.PatchGroup(ctx, group.ID, codersdk.PatchGroupRequest{ group := coderdtest.CreateGroup(t, ownerClient, owner.OrganizationID, "test", templateGroupACLAdmin)
AddUsers: []string{templateGroupACLAdmin.ID.String()},
})
require.NoError(t, err)
// Update the template for both users and groups. // 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{ UserPerms: map[string]codersdk.TemplateRole{
templateACLAdmin.ID.String(): codersdk.TemplateRoleAdmin, templateACLAdmin.ID.String(): codersdk.TemplateRoleAdmin,
}, },

View File

@ -16,6 +16,7 @@ import (
"github.com/coder/coder/v2/coderd/autobuild" "github.com/coder/coder/v2/coderd/autobuild"
"github.com/coder/coder/v2/coderd/coderdtest" "github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/rbac"
agplschedule "github.com/coder/coder/v2/coderd/schedule" agplschedule "github.com/coder/coder/v2/coderd/schedule"
"github.com/coder/coder/v2/coderd/schedule/cron" "github.com/coder/coder/v2/coderd/schedule/cron"
"github.com/coder/coder/v2/coderd/util/ptr" "github.com/coder/coder/v2/coderd/util/ptr"
@ -50,6 +51,7 @@ func TestCreateWorkspace(t *testing.T) {
codersdk.FeatureTemplateRBAC: 1, codersdk.FeatureTemplateRBAC: 1,
}, },
}}) }})
templateAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin())
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) 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) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel() defer cancel()
acl, err := client.TemplateACL(ctx, template.ID) acl, err := templateAdminClient.TemplateACL(ctx, template.ID)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, acl.Groups, 1) require.Len(t, acl.Groups, 1)
require.Len(t, acl.Users, 0) 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{ GroupPerms: map[string]codersdk.TemplateRole{
acl.Groups[0].ID.String(): codersdk.TemplateRoleDeleted, acl.Groups[0].ID.String(): codersdk.TemplateRoleDeleted,
}, },
@ -504,6 +506,7 @@ func TestWorkspaceAutobuild(t *testing.T) {
_ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, ws.LatestBuild.ID) _ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, ws.LatestBuild.ID)
// Assert that the workspace is actually deleted. // 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) _, err := client.Workspace(testutil.Context(t, testutil.WaitShort), ws.ID)
require.Error(t, err) require.Error(t, err)
cerr, ok := codersdk.AsError(err) cerr, ok := codersdk.AsError(err)
@ -531,6 +534,7 @@ func TestWorkspaceAutobuild(t *testing.T) {
Features: license.Features{codersdk.FeatureAdvancedTemplateScheduling: 1}, Features: license.Features{codersdk.FeatureAdvancedTemplateScheduling: 1},
}, },
}) })
anotherClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin())
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
Parse: echo.ParseComplete, Parse: echo.ParseComplete,
ProvisionPlan: echo.PlanComplete, ProvisionPlan: echo.PlanComplete,
@ -540,12 +544,12 @@ func TestWorkspaceAutobuild(t *testing.T) {
ctr.TimeTilDormantAutoDeleteMillis = ptr.Ref[int64](dormantTTL.Milliseconds()) ctr.TimeTilDormantAutoDeleteMillis = ptr.Ref[int64](dormantTTL.Milliseconds())
}) })
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
ws := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) ws := coderdtest.CreateWorkspace(t, anotherClient, user.OrganizationID, template.ID)
build := coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, ws.LatestBuild.ID) build := coderdtest.AwaitWorkspaceBuildJobCompleted(t, anotherClient, ws.LatestBuild.ID)
require.Equal(t, codersdk.WorkspaceStatusRunning, build.Status) require.Equal(t, codersdk.WorkspaceStatusRunning, build.Status)
ctx := testutil.Context(t, testutil.WaitMedium) ctx := testutil.Context(t, testutil.WaitMedium)
err := client.UpdateWorkspaceDormancy(ctx, ws.ID, codersdk.UpdateWorkspaceDormancy{ err := anotherClient.UpdateWorkspaceDormancy(ctx, ws.ID, codersdk.UpdateWorkspaceDormancy{
Dormant: true, Dormant: true,
}) })
require.NoError(t, err) require.NoError(t, err)
@ -559,7 +563,7 @@ func TestWorkspaceAutobuild(t *testing.T) {
// Expect no transitions since not enough time has elapsed. // Expect no transitions since not enough time has elapsed.
require.Len(t, stats.Transitions, 0) 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(), TimeTilDormantAutoDeleteMillis: dormantTTL.Milliseconds(),
}) })
require.NoError(t, err) require.NoError(t, err)
@ -671,6 +675,7 @@ func TestWorkspaceAutobuild(t *testing.T) {
Features: license.Features{codersdk.FeatureAdvancedTemplateScheduling: 1}, 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. // Create a template version that passes to get a functioning workspace.
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ 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) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
ws := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) ws := coderdtest.CreateWorkspace(t, templateAdmin, user.OrganizationID, template.ID)
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, ws.LatestBuild.ID) coderdtest.AwaitWorkspaceBuildJobCompleted(t, templateAdmin, ws.LatestBuild.ID)
// Create a new version that will fail when we try to delete a workspace. // Create a new version that will fail when we try to delete a workspace.
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
@ -696,7 +701,7 @@ func TestWorkspaceAutobuild(t *testing.T) {
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
// Try to delete the workspace. This simulates a "failed" autodelete. // 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, Transition: codersdk.WorkspaceTransitionDelete,
TemplateVersionID: version.ID, TemplateVersionID: version.ID,
}) })
@ -706,13 +711,13 @@ func TestWorkspaceAutobuild(t *testing.T) {
require.NotEmpty(t, build.Job.Error) require.NotEmpty(t, build.Job.Error)
// Update our workspace to be dormant so that it qualifies for auto-deletion. // 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, Dormant: true,
}) })
require.NoError(t, err) require.NoError(t, err)
// Enable auto-deletion for the template. // 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(), TimeTilDormantAutoDeleteMillis: transitionTTL.Milliseconds(),
}) })
require.NoError(t, err) require.NoError(t, err)
@ -901,6 +906,7 @@ func TestWorkspacesFiltering(t *testing.T) {
Features: license.Features{codersdk.FeatureAdvancedTemplateScheduling: 1}, 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. // Create a template version that passes to get a functioning workspace.
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ 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) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
dormantWS1 := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) dormantWS1 := coderdtest.CreateWorkspace(t, templateAdmin, user.OrganizationID, template.ID)
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, dormantWS1.LatestBuild.ID) coderdtest.AwaitWorkspaceBuildJobCompleted(t, templateAdmin, dormantWS1.LatestBuild.ID)
dormantWS2 := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) dormantWS2 := coderdtest.CreateWorkspace(t, templateAdmin, user.OrganizationID, template.ID)
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, dormantWS2.LatestBuild.ID) coderdtest.AwaitWorkspaceBuildJobCompleted(t, templateAdmin, dormantWS2.LatestBuild.ID)
activeWS := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) activeWS := coderdtest.CreateWorkspace(t, templateAdmin, user.OrganizationID, template.ID)
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, activeWS.LatestBuild.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) 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) require.NoError(t, err)
resp, err := client.Workspaces(ctx, codersdk.WorkspaceFilter{ resp, err := templateAdmin.Workspaces(ctx, codersdk.WorkspaceFilter{
FilterQuery: "is-dormant:true", FilterQuery: "is-dormant:true",
}) })
require.NoError(t, err) require.NoError(t, err)
@ -968,6 +974,7 @@ func TestWorkspacesWithoutTemplatePerms(t *testing.T) {
defer cancel() defer cancel()
// Remove everyone access // Remove everyone access
//nolint:gocritic // creating a separate user just for this is overkill
err := client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{ err := client.UpdateTemplateACL(ctx, template.ID, codersdk.UpdateTemplateACL{
GroupPerms: map[string]codersdk.TemplateRole{ GroupPerms: map[string]codersdk.TemplateRole{
first.OrganizationID.String(): codersdk.TemplateRoleDeleted, first.OrganizationID.String(): codersdk.TemplateRoleDeleted,

View File

@ -13,6 +13,7 @@ find . -regex ".*\.go" |
grep -v "./enterprise" | grep -v "./enterprise" |
grep -v ./scripts/auditdocgen/ --include="*.go" | grep -v ./scripts/auditdocgen/ --include="*.go" |
grep -v ./scripts/clidocgen/ --include="*.go" | grep -v ./scripts/clidocgen/ --include="*.go" |
grep -v ./scripts/rules.go |
xargs grep -n "github.com/coder/coder/v2/enterprise" xargs grep -n "github.com/coder/coder/v2/enterprise"
# reverse the exit code because we want this script to fail if grep finds anything. # reverse the exit code because we want this script to fail if grep finds anything.
status=$? status=$?

View File

@ -52,17 +52,54 @@ func dbauthzAuthorizationContext(m dsl.Matcher) {
func testingWithOwnerUser(m dsl.Matcher) { func testingWithOwnerUser(m dsl.Matcher) {
m.Import("testing") m.Import("testing")
m.Import("github.com/coder/coder/v2/cli/clitest") 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(` m.Match(`
$_ := coderdtest.CreateFirstUser($t, $client) $_ := coderdtest.CreateFirstUser($t, $client)
$*_ $*_
clitest.$SetupConfig($t, $client, $_) clitest.$SetupConfig($t, $client, $_)
`). `).
Where(m["t"].Type.Implements("testing.TB") && Where(m["t"].Type.Implements("testing.TB") &&
m["SetupConfig"].Text.Matches("^SetupConfig$") && m["SetupConfig"].Text.Matches("^SetupConfig$") &&
m.File().Name.Matches(`_test\.go$`)). m.File().Name.Matches(`_test\.go$`)).
At(m["SetupConfig"]). At(m["SetupConfig"]).
Report(`The CLI will be operating as the owner user, which has unrestricted permissions. Consider creating a different user.`) 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! // Use xerrors everywhere! It provides additional stacktrace info!