Skip to content

Commit f92c1ce

Browse files
committed
add revoked license test, and remove perms test
1 parent 277aa0d commit f92c1ce

File tree

2 files changed

+112
-14
lines changed

2 files changed

+112
-14
lines changed

coderd/database/dbauthz/dbauthz.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ func (q *querier) canAssignRoles(ctx context.Context, orgID *uuid.UUID, added, r
633633
// Stop at the first one found. We could make a better error that
634634
// returns them all, but then someone could pass in a large list to make us do
635635
// a lot of loop iterations.
636-
if !slices.ContainsFunc(expandedCustomRoles, func(customRole database.CustomRole) bool {
636+
if !slices.ContainsFunc(expandedCustomRoles, func(customRole rbac.Role) bool {
637637
return strings.EqualFold(customRole.Name, role)
638638
}) {
639639
return xerrors.Errorf("%q is not a supported role", role)

enterprise/coderd/roles_test.go

Lines changed: 111 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package coderd_test
22

33
import (
4+
"bytes"
45
"testing"
56

67
"github.com/stretchr/testify/require"
@@ -10,14 +11,26 @@ import (
1011
"github.com/coder/coder/v2/codersdk"
1112
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
1213
"github.com/coder/coder/v2/enterprise/coderd/license"
14+
"github.com/coder/coder/v2/provisioner/echo"
1315
"github.com/coder/coder/v2/testutil"
1416
)
1517

1618
func TestCustomRole(t *testing.T) {
1719
t.Parallel()
20+
templateAdminCustom := codersdk.Role{
21+
Name: "test-role",
22+
DisplayName: "Testing Purposes",
23+
// Basically creating a template admin manually
24+
SitePermissions: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
25+
codersdk.ResourceTemplate: {codersdk.ActionCreate, codersdk.ActionRead, codersdk.ActionUpdate, codersdk.ActionViewInsights},
26+
codersdk.ResourceFile: {codersdk.ActionCreate, codersdk.ActionRead},
27+
codersdk.ResourceWorkspace: {codersdk.ActionRead},
28+
}),
29+
OrganizationPermissions: nil,
30+
UserPermissions: nil,
31+
}
1832

1933
// Create, assign, and use a custom role
20-
//nolint:gocritic
2134
t.Run("Success", func(t *testing.T) {
2235
t.Parallel()
2336
dv := coderdtest.DeploymentValues(t)
@@ -36,18 +49,7 @@ func TestCustomRole(t *testing.T) {
3649
ctx := testutil.Context(t, testutil.WaitMedium)
3750

3851
//nolint:gocritic // owner is required for this
39-
role, err := owner.PatchRole(ctx, codersdk.Role{
40-
Name: "test-role",
41-
DisplayName: "Testing Purposes",
42-
// Basically creating a template admin manually
43-
SitePermissions: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
44-
codersdk.ResourceTemplate: {codersdk.ActionCreate, codersdk.ActionRead, codersdk.ActionUpdate, codersdk.ActionViewInsights},
45-
codersdk.ResourceFile: {codersdk.ActionCreate, codersdk.ActionRead},
46-
codersdk.ResourceWorkspace: {codersdk.ActionRead},
47-
}),
48-
OrganizationPermissions: nil,
49-
UserPermissions: nil,
50-
})
52+
role, err := owner.PatchRole(ctx, templateAdminCustom)
5153
require.NoError(t, err, "upsert role")
5254

5355
// Assign the custom template admin role
@@ -69,4 +71,100 @@ func TestCustomRole(t *testing.T) {
6971
// return selected.Name == role.Name
7072
//}), "role missing from site role list")
7173
})
74+
75+
// Revoked licenses cannot modify/create custom roles, but they can
76+
// use the existing roles.
77+
t.Run("Revoked License", func(t *testing.T) {
78+
t.Parallel()
79+
dv := coderdtest.DeploymentValues(t)
80+
dv.Experiments = []string{string(codersdk.ExperimentCustomRoles)}
81+
owner, first := coderdenttest.New(t, &coderdenttest.Options{
82+
Options: &coderdtest.Options{
83+
DeploymentValues: dv,
84+
},
85+
LicenseOptions: &coderdenttest.LicenseOptions{
86+
Features: license.Features{
87+
codersdk.FeatureCustomRoles: 1,
88+
},
89+
},
90+
})
91+
92+
ctx := testutil.Context(t, testutil.WaitMedium)
93+
94+
//nolint:gocritic // owner is required for this
95+
role, err := owner.PatchRole(ctx, templateAdminCustom)
96+
require.NoError(t, err, "upsert role")
97+
98+
// Remove the license to block enterprise functionality
99+
licenses, err := owner.Licenses(ctx)
100+
require.NoError(t, err, "get licenses")
101+
for _, license := range licenses {
102+
// Should be only 1...
103+
err := owner.DeleteLicense(ctx, license.ID)
104+
require.NoError(t, err, "delete license")
105+
}
106+
107+
// Verify functionality is lost
108+
_, err = owner.PatchRole(ctx, templateAdminCustom)
109+
require.ErrorContains(t, err, "Custom roles is an Enterprise feature", "upsert role")
110+
111+
// Assign the custom template admin role
112+
tmplAdmin, _ := coderdtest.CreateAnotherUser(t, owner, first.OrganizationID, role.Name)
113+
114+
// Try to create a template version, eg using the custom role
115+
coderdtest.CreateTemplateVersion(t, tmplAdmin, first.OrganizationID, nil)
116+
})
117+
118+
// Role patches are complete, as in the request overrides the existing role.
119+
t.Run("RoleOverrides", func(t *testing.T) {
120+
t.Parallel()
121+
dv := coderdtest.DeploymentValues(t)
122+
dv.Experiments = []string{string(codersdk.ExperimentCustomRoles)}
123+
owner, first := coderdenttest.New(t, &coderdenttest.Options{
124+
Options: &coderdtest.Options{
125+
DeploymentValues: dv,
126+
},
127+
LicenseOptions: &coderdenttest.LicenseOptions{
128+
Features: license.Features{
129+
codersdk.FeatureCustomRoles: 1,
130+
},
131+
},
132+
})
133+
134+
ctx := testutil.Context(t, testutil.WaitMedium)
135+
//nolint:gocritic // owner is required for this
136+
role, err := owner.PatchRole(ctx, templateAdminCustom)
137+
require.NoError(t, err, "upsert role")
138+
139+
// Assign the custom template admin role
140+
tmplAdmin, _ := coderdtest.CreateAnotherUser(t, owner, first.OrganizationID, role.Name)
141+
142+
// Try to create a template version, eg using the custom role
143+
coderdtest.CreateTemplateVersion(t, tmplAdmin, first.OrganizationID, nil)
144+
145+
//nolint:gocritic // owner is required for this
146+
role, err = owner.PatchRole(ctx, codersdk.Role{
147+
Name: templateAdminCustom.Name,
148+
DisplayName: templateAdminCustom.DisplayName,
149+
// These are all left nil, which sets the custom role to have 0
150+
// permissions. Omitting this does not "inherit" what already
151+
// exists.
152+
SitePermissions: nil,
153+
OrganizationPermissions: nil,
154+
UserPermissions: nil,
155+
})
156+
require.NoError(t, err, "upsert role with override")
157+
158+
// The role should no longer have template perms
159+
data, err := echo.TarWithOptions(ctx, tmplAdmin.Logger(), nil)
160+
require.NoError(t, err)
161+
file, err := tmplAdmin.Upload(ctx, codersdk.ContentTypeTar, bytes.NewReader(data))
162+
require.NoError(t, err)
163+
_, err = tmplAdmin.CreateTemplateVersion(ctx, first.OrganizationID, codersdk.CreateTemplateVersionRequest{
164+
FileID: file.ID,
165+
StorageMethod: codersdk.ProvisionerStorageMethodFile,
166+
Provisioner: codersdk.ProvisionerTypeEcho,
167+
})
168+
require.ErrorContains(t, err, "forbidden")
169+
})
72170
}

0 commit comments

Comments
 (0)