refactor: deduplicate / type license feature code (#5734)

This commit is contained in:
Ammar Bandukwala
2023-01-17 17:04:29 -06:00
committed by GitHub
parent ea1b03f7c9
commit 501cfa9e8d
39 changed files with 648 additions and 396 deletions

View File

@ -11,6 +11,7 @@ import (
"github.com/coder/coder/coderd/coderdtest"
"github.com/coder/coder/codersdk"
"github.com/coder/coder/enterprise/coderd/coderdenttest"
"github.com/coder/coder/enterprise/coderd/license"
"github.com/coder/coder/testutil"
)
@ -30,7 +31,9 @@ func TestServiceBanners(t *testing.T) {
require.False(t, sb.ServiceBanner.Enabled)
coderdenttest.AddLicense(t, adminClient, coderdenttest.LicenseOptions{
ServiceBanners: true,
Features: license.Features{
codersdk.FeatureAppearance: 1,
},
})
// Default state

View File

@ -11,6 +11,7 @@ import (
"github.com/coder/coder/coderd/rbac"
"github.com/coder/coder/codersdk"
"github.com/coder/coder/enterprise/coderd/coderdenttest"
"github.com/coder/coder/enterprise/coderd/license"
"github.com/coder/coder/testutil"
)
@ -28,7 +29,9 @@ func TestCheckACLPermissions(t *testing.T) {
// Create adminClient, member, and org adminClient
adminUser := coderdtest.CreateFirstUser(t, adminClient)
_ = coderdenttest.AddLicense(t, adminClient, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
memberClient := coderdtest.CreateAnotherUser(t, adminClient, adminUser.OrganizationID)

View File

@ -238,7 +238,7 @@ func (api *API) updateEntitlements(ctx context.Context) error {
api.entitlementsMu.Lock()
defer api.entitlementsMu.Unlock()
entitlements, err := license.Entitlements(ctx, api.Database, api.Logger, len(api.replicaManager.All()), len(api.GitAuthConfigs), api.Keys, map[string]bool{
entitlements, err := license.Entitlements(ctx, api.Database, api.Logger, len(api.replicaManager.All()), len(api.GitAuthConfigs), api.Keys, map[codersdk.FeatureName]bool{
codersdk.FeatureAuditLog: api.AuditLogging,
codersdk.FeatureBrowserOnly: api.BrowserOnly,
codersdk.FeatureSCIM: len(api.SCIMAPIKey) != 0,
@ -252,7 +252,7 @@ func (api *API) updateEntitlements(ctx context.Context) error {
}
entitlements.Experimental = api.DeploymentConfig.Experimental.Value
featureChanged := func(featureName string) (changed bool, enabled bool) {
featureChanged := func(featureName codersdk.FeatureName) (changed bool, enabled bool) {
if api.entitlements.Features == nil {
return true, entitlements.Features[featureName].Enabled
}

View File

@ -17,6 +17,7 @@ import (
"github.com/coder/coder/enterprise/audit"
"github.com/coder/coder/enterprise/coderd"
"github.com/coder/coder/enterprise/coderd/coderdenttest"
"github.com/coder/coder/enterprise/coderd/license"
"github.com/coder/coder/testutil"
)
@ -41,10 +42,12 @@ func TestEntitlements(t *testing.T) {
})
_ = coderdtest.CreateFirstUser(t, client)
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
UserLimit: 100,
AuditLog: true,
TemplateRBAC: true,
ExternalProvisionerDaemons: true,
Features: license.Features{
codersdk.FeatureUserLimit: 100,
codersdk.FeatureAuditLog: 1,
codersdk.FeatureTemplateRBAC: 1,
codersdk.FeatureExternalProvisionerDaemons: 1,
},
})
res, err := client.Entitlements(context.Background())
require.NoError(t, err)
@ -68,8 +71,10 @@ func TestEntitlements(t *testing.T) {
})
_ = coderdtest.CreateFirstUser(t, client)
license := coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
UserLimit: 100,
AuditLog: true,
Features: license.Features{
codersdk.FeatureUserLimit: 100,
codersdk.FeatureAuditLog: 1,
},
})
res, err := client.Entitlements(context.Background())
require.NoError(t, err)
@ -99,7 +104,9 @@ func TestEntitlements(t *testing.T) {
UploadedAt: database.Now(),
Exp: database.Now().AddDate(1, 0, 0),
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
AuditLog: true,
Features: license.Features{
codersdk.FeatureAuditLog: 1,
},
}),
})
require.NoError(t, err)
@ -125,7 +132,9 @@ func TestEntitlements(t *testing.T) {
UploadedAt: database.Now(),
Exp: database.Now().AddDate(1, 0, 0),
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
AuditLog: true,
Features: license.Features{
codersdk.FeatureAuditLog: 1,
},
}),
})
require.NoError(t, err)
@ -165,7 +174,9 @@ func TestAuditLogging(t *testing.T) {
})
coderdtest.CreateFirstUser(t, client)
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
AuditLog: true,
Features: license.Features{
codersdk.FeatureAuditLog: 1,
},
})
auditor := *api.AGPL.Auditor.Load()
ea := audit.NewAuditor(audit.DefaultFilter)

View File

@ -99,21 +99,13 @@ func NewWithAPI(t *testing.T, options *Options) (*codersdk.Client, io.Closer, *c
}
type LicenseOptions struct {
AccountType string
AccountID string
Trial bool
AllFeatures bool
GraceAt time.Time
ExpiresAt time.Time
UserLimit int64
AuditLog bool
BrowserOnly bool
SCIM bool
TemplateRBAC bool
HighAvailability bool
MultipleGitAuth bool
ExternalProvisionerDaemons bool
ServiceBanners bool
AccountType string
AccountID string
Trial bool
AllFeatures bool
GraceAt time.Time
ExpiresAt time.Time
Features license.Features
}
// AddLicense generates a new license with the options provided and inserts it.
@ -133,42 +125,6 @@ func GenerateLicense(t *testing.T, options LicenseOptions) string {
if options.GraceAt.IsZero() {
options.GraceAt = time.Now().Add(time.Hour)
}
var auditLog int64
if options.AuditLog {
auditLog = 1
}
var browserOnly int64
if options.BrowserOnly {
browserOnly = 1
}
var scim int64
if options.SCIM {
scim = 1
}
highAvailability := int64(0)
if options.HighAvailability {
highAvailability = 1
}
rbacEnabled := int64(0)
if options.TemplateRBAC {
rbacEnabled = 1
}
multipleGitAuth := int64(0)
if options.MultipleGitAuth {
multipleGitAuth = 1
}
externalProvisionerDaemons := int64(0)
if options.ExternalProvisionerDaemons {
externalProvisionerDaemons = 1
}
serviceBanners := int64(0)
if options.ServiceBanners {
serviceBanners = 1
}
c := &license.Claims{
RegisteredClaims: jwt.RegisteredClaims{
@ -183,17 +139,7 @@ func GenerateLicense(t *testing.T, options LicenseOptions) string {
Trial: options.Trial,
Version: license.CurrentVersion,
AllFeatures: options.AllFeatures,
Features: license.Features{
UserLimit: options.UserLimit,
AuditLog: auditLog,
BrowserOnly: browserOnly,
SCIM: scim,
HighAvailability: highAvailability,
TemplateRBAC: rbacEnabled,
MultipleGitAuth: multipleGitAuth,
ExternalProvisionerDaemons: externalProvisionerDaemons,
Appearance: serviceBanners,
},
Features: options.Features,
}
tok := jwt.NewWithClaims(jwt.SigningMethodEdDSA, c)
tok.Header[license.HeaderKeyID] = testKeyID

View File

@ -12,6 +12,7 @@ import (
"github.com/coder/coder/coderd/rbac"
"github.com/coder/coder/codersdk"
"github.com/coder/coder/enterprise/coderd/coderdenttest"
"github.com/coder/coder/enterprise/coderd/license"
"github.com/coder/coder/testutil"
)
@ -32,9 +33,11 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
})
ctx, _ := testutil.Context(t)
admin := coderdtest.CreateFirstUser(t, client)
license := coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
ExternalProvisionerDaemons: true,
lic := coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
codersdk.FeatureExternalProvisionerDaemons: 1,
},
})
group, err := client.CreateGroup(ctx, admin.OrganizationID, codersdk.CreateGroupRequest{
Name: "testgroup",
@ -43,7 +46,7 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
groupObj := rbac.ResourceGroup.InOrg(admin.OrganizationID)
a := coderdtest.NewAuthTester(ctx, t, client, api.AGPL, admin)
a.URLParams["licenses/{id}"] = fmt.Sprintf("licenses/%d", license.ID)
a.URLParams["licenses/{id}"] = fmt.Sprintf("licenses/%d", lic.ID)
a.URLParams["groups/{group}"] = fmt.Sprintf("groups/%s", group.ID.String())
a.URLParams["{groupName}"] = group.Name

View File

@ -13,6 +13,7 @@ import (
"github.com/coder/coder/coderd/database"
"github.com/coder/coder/codersdk"
"github.com/coder/coder/enterprise/coderd/coderdenttest"
"github.com/coder/coder/enterprise/coderd/license"
"github.com/coder/coder/testutil"
)
@ -26,7 +27,9 @@ func TestCreateGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
ctx, _ := testutil.Context(t)
group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
@ -54,8 +57,10 @@ func TestCreateGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
AuditLog: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
codersdk.FeatureAuditLog: 1,
},
})
ctx, _ := testutil.Context(t)
@ -78,7 +83,9 @@ func TestCreateGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
ctx, _ := testutil.Context(t)
_, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
@ -102,7 +109,9 @@ func TestCreateGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
ctx, _ := testutil.Context(t)
_, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
@ -125,7 +134,9 @@ func TestPatchGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
ctx, _ := testutil.Context(t)
group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
@ -157,7 +168,9 @@ func TestPatchGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
ctx, _ := testutil.Context(t)
group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
@ -179,7 +192,9 @@ func TestPatchGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
_, user2 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
_, user3 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -205,7 +220,9 @@ func TestPatchGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
_, user2 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
_, user3 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -248,8 +265,10 @@ func TestPatchGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
AuditLog: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
codersdk.FeatureAuditLog: 1,
},
})
ctx, _ := testutil.Context(t)
@ -277,7 +296,9 @@ func TestPatchGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
ctx, _ := testutil.Context(t)
group1, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
@ -308,7 +329,9 @@ func TestPatchGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
ctx, _ := testutil.Context(t)
group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
@ -332,7 +355,9 @@ func TestPatchGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
ctx, _ := testutil.Context(t)
group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
@ -356,7 +381,9 @@ func TestPatchGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
_, user2 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
ctx, _ := testutil.Context(t)
@ -382,7 +409,9 @@ func TestPatchGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
ctx, _ := testutil.Context(t)
group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
@ -411,7 +440,9 @@ func TestGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
ctx, _ := testutil.Context(t)
group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
@ -431,7 +462,9 @@ func TestGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
ctx, _ := testutil.Context(t)
group, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
@ -451,7 +484,9 @@ func TestGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
_, user2 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
_, user3 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -481,7 +516,9 @@ func TestGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
client1, _ := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -502,7 +539,9 @@ func TestGroup(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
_, user1 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -535,7 +574,9 @@ func TestGroup(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
_, user1 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -576,7 +617,9 @@ func TestGroups(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
_, user2 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
_, user3 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -622,7 +665,9 @@ func TestDeleteGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
ctx, _ := testutil.Context(t)
group1, err := client.CreateGroup(ctx, user.OrganizationID, codersdk.CreateGroupRequest{
@ -654,8 +699,10 @@ func TestDeleteGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
AuditLog: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
codersdk.FeatureAuditLog: 1,
},
})
ctx, _ := testutil.Context(t)
@ -681,7 +728,9 @@ func TestDeleteGroup(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
ctx, _ := testutil.Context(t)
err := client.DeleteGroup(ctx, user.OrganizationID)

View File

@ -4,7 +4,6 @@ import (
"context"
"crypto/ed25519"
"fmt"
"strings"
"time"
"github.com/golang-jwt/jwt/v4"
@ -24,12 +23,12 @@ func Entitlements(
replicaCount int,
gitAuthCount int,
keys map[string]ed25519.PublicKey,
enablements map[string]bool,
enablements map[codersdk.FeatureName]bool,
) (codersdk.Entitlements, error) {
now := time.Now()
// Default all entitlements to be disabled.
entitlements := codersdk.Entitlements{
Features: map[string]codersdk.Feature{},
Features: map[codersdk.FeatureName]codersdk.Feature{},
Warnings: []string{},
Errors: []string{},
}
@ -68,67 +67,34 @@ func Entitlements(
// LicenseExpires we must be in grace period.
entitlement = codersdk.EntitlementGracePeriod
}
if claims.Features.UserLimit > 0 {
limit := claims.Features.UserLimit
priorLimit := entitlements.Features[codersdk.FeatureUserLimit]
if priorLimit.Limit != nil && *priorLimit.Limit > limit {
limit = *priorLimit.Limit
for featureName, featureValue := range claims.Features {
// Can this be negative?
if featureValue <= 0 {
continue
}
entitlements.Features[codersdk.FeatureUserLimit] = codersdk.Feature{
Enabled: true,
Entitlement: entitlement,
Limit: &limit,
Actual: &activeUserCount,
}
}
if claims.Features.AuditLog > 0 {
entitlements.Features[codersdk.FeatureAuditLog] = codersdk.Feature{
Entitlement: entitlement,
Enabled: enablements[codersdk.FeatureAuditLog],
}
}
if claims.Features.BrowserOnly > 0 {
entitlements.Features[codersdk.FeatureBrowserOnly] = codersdk.Feature{
Entitlement: entitlement,
Enabled: enablements[codersdk.FeatureBrowserOnly],
}
}
if claims.Features.SCIM > 0 {
entitlements.Features[codersdk.FeatureSCIM] = codersdk.Feature{
Entitlement: entitlement,
Enabled: enablements[codersdk.FeatureSCIM],
}
}
if claims.Features.HighAvailability > 0 {
entitlements.Features[codersdk.FeatureHighAvailability] = codersdk.Feature{
Entitlement: entitlement,
Enabled: enablements[codersdk.FeatureHighAvailability],
}
}
if claims.Features.TemplateRBAC > 0 {
entitlements.Features[codersdk.FeatureTemplateRBAC] = codersdk.Feature{
Entitlement: entitlement,
Enabled: enablements[codersdk.FeatureTemplateRBAC],
}
}
if claims.Features.MultipleGitAuth > 0 {
entitlements.Features[codersdk.FeatureMultipleGitAuth] = codersdk.Feature{
Entitlement: entitlement,
Enabled: true,
}
}
if claims.Features.ExternalProvisionerDaemons > 0 {
entitlements.Features[codersdk.FeatureExternalProvisionerDaemons] = codersdk.Feature{
Entitlement: entitlement,
Enabled: true,
}
}
if claims.Features.Appearance > 0 {
entitlements.Features[codersdk.FeatureAppearance] = codersdk.Feature{
Entitlement: entitlement,
Enabled: true,
switch featureName {
// User limit has special treatment as our only non-boolean feature.
case codersdk.FeatureUserLimit:
limit := featureValue
priorLimit := entitlements.Features[codersdk.FeatureUserLimit]
if priorLimit.Limit != nil && *priorLimit.Limit > limit {
limit = *priorLimit.Limit
}
entitlements.Features[codersdk.FeatureUserLimit] = codersdk.Feature{
Enabled: true,
Entitlement: entitlement,
Limit: &limit,
Actual: &activeUserCount,
}
default:
entitlements.Features[featureName] = codersdk.Feature{
Entitlement: entitlement,
Enabled: enablements[featureName] || featureName.AlwaysEnable(),
}
}
}
if claims.AllFeatures {
allFeatures = true
}
@ -171,7 +137,7 @@ func Entitlements(
if !feature.Enabled {
continue
}
niceName := strings.Title(strings.ReplaceAll(featureName, "_", " "))
niceName := featureName.Humanize()
switch feature.Entitlement {
case codersdk.EntitlementNotEntitled:
entitlements.Warnings = append(entitlements.Warnings,
@ -249,17 +215,7 @@ var (
ErrMissingLicenseExpires = xerrors.New("license missing license_expires")
)
type Features struct {
UserLimit int64 `json:"user_limit"`
AuditLog int64 `json:"audit_log"`
BrowserOnly int64 `json:"browser_only"`
SCIM int64 `json:"scim"`
TemplateRBAC int64 `json:"template_rbac"`
HighAvailability int64 `json:"high_availability"`
MultipleGitAuth int64 `json:"multiple_git_auth"`
ExternalProvisionerDaemons int64 `json:"external_provisioner_daemons"`
Appearance int64 `json:"appearance"`
}
type Features map[codersdk.FeatureName]int64
type Claims struct {
jwt.RegisteredClaims

View File

@ -3,7 +3,6 @@ package license_test
import (
"context"
"fmt"
"strings"
"testing"
"time"
@ -19,17 +18,13 @@ import (
func TestEntitlements(t *testing.T) {
t.Parallel()
all := map[string]bool{
codersdk.FeatureAuditLog: true,
codersdk.FeatureBrowserOnly: true,
codersdk.FeatureSCIM: true,
codersdk.FeatureHighAvailability: true,
codersdk.FeatureTemplateRBAC: true,
codersdk.FeatureMultipleGitAuth: true,
codersdk.FeatureExternalProvisionerDaemons: true,
codersdk.FeatureAppearance: true,
all := make(map[codersdk.FeatureName]bool)
for _, n := range codersdk.FeatureNames {
all[n] = true
}
empty := map[codersdk.FeatureName]bool{}
t.Run("Defaults", func(t *testing.T) {
t.Parallel()
db := databasefake.New()
@ -49,7 +44,7 @@ func TestEntitlements(t *testing.T) {
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{}),
Exp: time.Now().Add(time.Hour),
})
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 1, 1, coderdenttest.Keys, map[string]bool{})
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 1, 1, coderdenttest.Keys, empty)
require.NoError(t, err)
require.True(t, entitlements.HasLicense)
require.False(t, entitlements.Trial)
@ -63,19 +58,17 @@ func TestEntitlements(t *testing.T) {
db := databasefake.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
UserLimit: 100,
AuditLog: true,
BrowserOnly: true,
SCIM: true,
HighAvailability: true,
TemplateRBAC: true,
MultipleGitAuth: true,
ExternalProvisionerDaemons: true,
ServiceBanners: true,
Features: func() license.Features {
f := make(license.Features)
for _, name := range codersdk.FeatureNames {
f[name] = 1
}
return f
}(),
}),
Exp: time.Now().Add(time.Hour),
})
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 1, 1, coderdenttest.Keys, map[string]bool{})
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 1, 1, coderdenttest.Keys, empty)
require.NoError(t, err)
require.True(t, entitlements.HasLicense)
require.False(t, entitlements.Trial)
@ -88,16 +81,13 @@ func TestEntitlements(t *testing.T) {
db := databasefake.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
UserLimit: 100,
AuditLog: true,
BrowserOnly: true,
SCIM: true,
HighAvailability: true,
TemplateRBAC: true,
ExternalProvisionerDaemons: true,
ServiceBanners: true,
GraceAt: time.Now().Add(-time.Hour),
ExpiresAt: time.Now().Add(time.Hour),
Features: license.Features{
codersdk.FeatureUserLimit: 100,
codersdk.FeatureAuditLog: 1,
},
GraceAt: time.Now().Add(-time.Hour),
ExpiresAt: time.Now().Add(time.Hour),
}),
Exp: time.Now().Add(time.Hour),
})
@ -105,20 +95,12 @@ func TestEntitlements(t *testing.T) {
require.NoError(t, err)
require.True(t, entitlements.HasLicense)
require.False(t, entitlements.Trial)
for _, featureName := range codersdk.FeatureNames {
if featureName == codersdk.FeatureUserLimit {
continue
}
if featureName == codersdk.FeatureHighAvailability {
continue
}
if featureName == codersdk.FeatureMultipleGitAuth {
continue
}
niceName := strings.Title(strings.ReplaceAll(featureName, "_", " "))
require.Equal(t, codersdk.EntitlementGracePeriod, entitlements.Features[featureName].Entitlement)
require.Contains(t, entitlements.Warnings, fmt.Sprintf("%s is enabled but your license for this feature is expired.", niceName))
}
require.Equal(t, codersdk.EntitlementGracePeriod, entitlements.Features[codersdk.FeatureAuditLog].Entitlement)
require.Contains(
t, entitlements.Warnings,
fmt.Sprintf("%s is enabled but your license for this feature is expired.", codersdk.FeatureAuditLog.Humanize()),
)
})
t.Run("SingleLicenseNotEntitled", func(t *testing.T) {
t.Parallel()
@ -141,7 +123,7 @@ func TestEntitlements(t *testing.T) {
if featureName == codersdk.FeatureMultipleGitAuth {
continue
}
niceName := strings.Title(strings.ReplaceAll(featureName, "_", " "))
niceName := featureName.Humanize()
// Ensures features that are not entitled are properly disabled.
require.False(t, entitlements.Features[featureName].Enabled)
require.Equal(t, codersdk.EntitlementNotEntitled, entitlements.Features[featureName].Entitlement)
@ -159,11 +141,13 @@ func TestEntitlements(t *testing.T) {
})
db.InsertLicense(context.Background(), database.InsertLicenseParams{
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
UserLimit: 1,
Features: license.Features{
codersdk.FeatureUserLimit: 1,
},
}),
Exp: time.Now().Add(time.Hour),
})
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 1, 1, coderdenttest.Keys, map[string]bool{})
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 1, 1, coderdenttest.Keys, empty)
require.NoError(t, err)
require.True(t, entitlements.HasLicense)
require.Contains(t, entitlements.Warnings, "Your deployment has 2 active users but is only licensed for 1.")
@ -175,17 +159,21 @@ func TestEntitlements(t *testing.T) {
db.InsertUser(context.Background(), database.InsertUserParams{})
db.InsertLicense(context.Background(), database.InsertLicenseParams{
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
UserLimit: 10,
Features: license.Features{
codersdk.FeatureUserLimit: 10,
},
}),
Exp: time.Now().Add(time.Hour),
})
db.InsertLicense(context.Background(), database.InsertLicenseParams{
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
UserLimit: 1,
Features: license.Features{
codersdk.FeatureUserLimit: 1,
},
}),
Exp: time.Now().Add(time.Hour),
})
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 1, 1, coderdenttest.Keys, map[string]bool{})
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 1, 1, coderdenttest.Keys, empty)
require.NoError(t, err)
require.True(t, entitlements.HasLicense)
require.Empty(t, entitlements.Warnings)
@ -208,7 +196,7 @@ func TestEntitlements(t *testing.T) {
}),
})
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 1, 1, coderdenttest.Keys, map[string]bool{})
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 1, 1, coderdenttest.Keys, empty)
require.NoError(t, err)
require.True(t, entitlements.HasLicense)
require.False(t, entitlements.Trial)
@ -252,10 +240,12 @@ func TestEntitlements(t *testing.T) {
db.InsertLicense(context.Background(), database.InsertLicenseParams{
Exp: time.Now().Add(time.Hour),
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
AuditLog: true,
Features: license.Features{
codersdk.FeatureAuditLog: 1,
},
}),
})
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 2, 1, coderdenttest.Keys, map[string]bool{
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 2, 1, coderdenttest.Keys, map[codersdk.FeatureName]bool{
codersdk.FeatureHighAvailability: true,
})
require.NoError(t, err)
@ -269,13 +259,15 @@ func TestEntitlements(t *testing.T) {
db := databasefake.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
HighAvailability: true,
GraceAt: time.Now().Add(-time.Hour),
ExpiresAt: time.Now().Add(time.Hour),
Features: license.Features{
codersdk.FeatureHighAvailability: 1,
},
GraceAt: time.Now().Add(-time.Hour),
ExpiresAt: time.Now().Add(time.Hour),
}),
Exp: time.Now().Add(time.Hour),
})
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 2, 1, coderdenttest.Keys, map[string]bool{
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 2, 1, coderdenttest.Keys, map[codersdk.FeatureName]bool{
codersdk.FeatureHighAvailability: true,
})
require.NoError(t, err)
@ -300,10 +292,12 @@ func TestEntitlements(t *testing.T) {
db.InsertLicense(context.Background(), database.InsertLicenseParams{
Exp: time.Now().Add(time.Hour),
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
AuditLog: true,
Features: license.Features{
codersdk.FeatureAuditLog: 1,
},
}),
})
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 1, 2, coderdenttest.Keys, map[string]bool{
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 1, 2, coderdenttest.Keys, map[codersdk.FeatureName]bool{
codersdk.FeatureMultipleGitAuth: true,
})
require.NoError(t, err)
@ -317,13 +311,15 @@ func TestEntitlements(t *testing.T) {
db := databasefake.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
MultipleGitAuth: true,
GraceAt: time.Now().Add(-time.Hour),
ExpiresAt: time.Now().Add(time.Hour),
GraceAt: time.Now().Add(-time.Hour),
ExpiresAt: time.Now().Add(time.Hour),
Features: license.Features{
codersdk.FeatureMultipleGitAuth: 1,
},
}),
Exp: time.Now().Add(time.Hour),
})
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 1, 2, coderdenttest.Keys, map[string]bool{
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 1, 2, coderdenttest.Keys, map[codersdk.FeatureName]bool{
codersdk.FeatureMultipleGitAuth: true,
})
require.NoError(t, err)

View File

@ -2,7 +2,6 @@ package coderd_test
import (
"context"
"encoding/json"
"net/http"
"testing"
@ -27,14 +26,16 @@ func TestPostLicense(t *testing.T) {
respLic := coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
AccountType: license.AccountTypeSalesforce,
AccountID: "testing",
AuditLog: true,
Features: license.Features{
codersdk.FeatureAuditLog: 1,
},
})
assert.GreaterOrEqual(t, respLic.ID, int32(0))
// just a couple spot checks for sanity
assert.Equal(t, "testing", respLic.Claims["account_id"])
features, ok := respLic.Claims["features"].(map[string]interface{})
require.True(t, ok)
assert.Equal(t, json.Number("1"), features[codersdk.FeatureAuditLog])
features, err := respLic.Features()
require.NoError(t, err)
assert.EqualValues(t, 1, features[codersdk.FeatureAuditLog])
})
t.Run("Unauthorized", func(t *testing.T) {
@ -78,21 +79,24 @@ func TestGetLicense(t *testing.T) {
defer cancel()
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
AccountID: "testing",
AuditLog: true,
SCIM: true,
BrowserOnly: true,
TemplateRBAC: true,
AccountID: "testing",
Features: license.Features{
codersdk.FeatureAuditLog: 1,
codersdk.FeatureSCIM: 1,
codersdk.FeatureBrowserOnly: 1,
codersdk.FeatureTemplateRBAC: 1,
},
})
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
AccountID: "testing2",
AuditLog: true,
SCIM: true,
BrowserOnly: true,
Trial: true,
UserLimit: 200,
TemplateRBAC: false,
AccountID: "testing2",
Features: license.Features{
codersdk.FeatureAuditLog: 1,
codersdk.FeatureSCIM: 1,
codersdk.FeatureBrowserOnly: 1,
codersdk.FeatureUserLimit: 200,
},
Trial: true,
})
licenses, err := client.Licenses(ctx)
@ -100,31 +104,27 @@ func TestGetLicense(t *testing.T) {
require.Len(t, licenses, 2)
assert.Equal(t, int32(1), licenses[0].ID)
assert.Equal(t, "testing", licenses[0].Claims["account_id"])
assert.Equal(t, map[string]interface{}{
codersdk.FeatureUserLimit: json.Number("0"),
codersdk.FeatureAuditLog: json.Number("1"),
codersdk.FeatureSCIM: json.Number("1"),
codersdk.FeatureBrowserOnly: json.Number("1"),
codersdk.FeatureHighAvailability: json.Number("0"),
codersdk.FeatureTemplateRBAC: json.Number("1"),
codersdk.FeatureMultipleGitAuth: json.Number("0"),
codersdk.FeatureExternalProvisionerDaemons: json.Number("0"),
codersdk.FeatureAppearance: json.Number("0"),
}, licenses[0].Claims["features"])
features, err := licenses[0].Features()
require.NoError(t, err)
assert.Equal(t, map[codersdk.FeatureName]int64{
codersdk.FeatureAuditLog: 1,
codersdk.FeatureSCIM: 1,
codersdk.FeatureBrowserOnly: 1,
codersdk.FeatureTemplateRBAC: 1,
}, features)
assert.Equal(t, int32(2), licenses[1].ID)
assert.Equal(t, "testing2", licenses[1].Claims["account_id"])
assert.Equal(t, true, licenses[1].Claims["trial"])
assert.Equal(t, map[string]interface{}{
codersdk.FeatureUserLimit: json.Number("200"),
codersdk.FeatureAuditLog: json.Number("1"),
codersdk.FeatureSCIM: json.Number("1"),
codersdk.FeatureBrowserOnly: json.Number("1"),
codersdk.FeatureHighAvailability: json.Number("0"),
codersdk.FeatureTemplateRBAC: json.Number("0"),
codersdk.FeatureMultipleGitAuth: json.Number("0"),
codersdk.FeatureExternalProvisionerDaemons: json.Number("0"),
codersdk.FeatureAppearance: json.Number("0"),
}, licenses[1].Claims["features"])
features, err = licenses[1].Features()
require.NoError(t, err)
assert.Equal(t, map[codersdk.FeatureName]int64{
codersdk.FeatureUserLimit: 200,
codersdk.FeatureAuditLog: 1,
codersdk.FeatureSCIM: 1,
codersdk.FeatureBrowserOnly: 1,
}, features)
})
}
@ -168,12 +168,16 @@ func TestDeleteLicense(t *testing.T) {
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
AccountID: "testing",
AuditLog: true,
Features: license.Features{
codersdk.FeatureAuditLog: 1,
},
})
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
AccountID: "testing2",
AuditLog: true,
UserLimit: 200,
Features: license.Features{
codersdk.FeatureAuditLog: 1,
codersdk.FeatureUserLimit: 200,
},
})
licenses, err := client.Licenses(ctx)

View File

@ -12,6 +12,7 @@ import (
"github.com/coder/coder/coderd/provisionerdserver"
"github.com/coder/coder/codersdk"
"github.com/coder/coder/enterprise/coderd/coderdenttest"
"github.com/coder/coder/enterprise/coderd/license"
"github.com/coder/coder/provisioner/echo"
"github.com/coder/coder/provisionersdk/proto"
)
@ -36,7 +37,9 @@ func TestProvisionerDaemonServe(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
ExternalProvisionerDaemons: true,
Features: license.Features{
codersdk.FeatureExternalProvisionerDaemons: 1,
},
})
srv, err := client.ServeProvisionerDaemon(context.Background(), user.OrganizationID, []codersdk.ProvisionerType{
codersdk.ProvisionerTypeEcho,
@ -50,7 +53,9 @@ func TestProvisionerDaemonServe(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
ExternalProvisionerDaemons: true,
Features: license.Features{
codersdk.FeatureExternalProvisionerDaemons: 1,
},
})
another := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
_, err := another.ServeProvisionerDaemon(context.Background(), user.OrganizationID, []codersdk.ProvisionerType{
@ -69,7 +74,9 @@ func TestProvisionerDaemonServe(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
ExternalProvisionerDaemons: true,
Features: license.Features{
codersdk.FeatureExternalProvisionerDaemons: 1,
},
})
closer := coderdtest.NewExternalProvisionerDaemon(t, client, user.OrganizationID, map[string]string{
provisionerdserver.TagScope: provisionerdserver.ScopeUser,

View File

@ -14,6 +14,7 @@ import (
"github.com/coder/coder/coderd/database/dbtestutil"
"github.com/coder/coder/codersdk"
"github.com/coder/coder/enterprise/coderd/coderdenttest"
"github.com/coder/coder/enterprise/coderd/license"
"github.com/coder/coder/testutil"
)
@ -58,7 +59,9 @@ func TestReplicas(t *testing.T) {
})
firstUser := coderdtest.CreateFirstUser(t, firstClient)
coderdenttest.AddLicense(t, firstClient, coderdenttest.LicenseOptions{
HighAvailability: true,
Features: license.Features{
codersdk.FeatureHighAvailability: 1,
},
})
secondClient := coderdenttest.New(t, &coderdenttest.Options{
@ -100,7 +103,9 @@ func TestReplicas(t *testing.T) {
})
firstUser := coderdtest.CreateFirstUser(t, firstClient)
coderdenttest.AddLicense(t, firstClient, coderdenttest.LicenseOptions{
HighAvailability: true,
Features: license.Features{
codersdk.FeatureHighAvailability: 1,
},
})
secondClient := coderdenttest.New(t, &coderdenttest.Options{

View File

@ -15,6 +15,7 @@ import (
"github.com/coder/coder/cryptorand"
"github.com/coder/coder/enterprise/coderd"
"github.com/coder/coder/enterprise/coderd/coderdenttest"
"github.com/coder/coder/enterprise/coderd/license"
"github.com/coder/coder/testutil"
)
@ -66,7 +67,9 @@ func TestScim(t *testing.T) {
_ = coderdtest.CreateFirstUser(t, client)
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
AccountID: "coolin",
SCIM: false,
Features: license.Features{
codersdk.FeatureSCIM: 0,
},
})
res, err := client.Request(ctx, "POST", "/scim/v2/Users", struct{}{})
@ -85,7 +88,9 @@ func TestScim(t *testing.T) {
_ = coderdtest.CreateFirstUser(t, client)
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
AccountID: "coolin",
SCIM: true,
Features: license.Features{
codersdk.FeatureSCIM: 1,
},
})
res, err := client.Request(ctx, "POST", "/scim/v2/Users", struct{}{})
@ -105,7 +110,9 @@ func TestScim(t *testing.T) {
_ = coderdtest.CreateFirstUser(t, client)
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
AccountID: "coolin",
SCIM: true,
Features: license.Features{
codersdk.FeatureSCIM: 1,
},
})
sUser := makeScimUser(t)
@ -136,7 +143,9 @@ func TestScim(t *testing.T) {
_ = coderdtest.CreateFirstUser(t, client)
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
AccountID: "coolin",
SCIM: false,
Features: license.Features{
codersdk.FeatureSCIM: 0,
},
})
res, err := client.Request(ctx, "PATCH", "/scim/v2/Users/bob", struct{}{})
@ -155,7 +164,9 @@ func TestScim(t *testing.T) {
_ = coderdtest.CreateFirstUser(t, client)
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
AccountID: "coolin",
SCIM: true,
Features: license.Features{
codersdk.FeatureSCIM: 1,
},
})
res, err := client.Request(ctx, "PATCH", "/scim/v2/Users/bob", struct{}{})
@ -175,7 +186,9 @@ func TestScim(t *testing.T) {
_ = coderdtest.CreateFirstUser(t, client)
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
AccountID: "coolin",
SCIM: true,
Features: license.Features{
codersdk.FeatureSCIM: 1,
},
})
sUser := makeScimUser(t)

View File

@ -15,6 +15,7 @@ import (
"github.com/coder/coder/codersdk"
"github.com/coder/coder/cryptorand"
"github.com/coder/coder/enterprise/coderd/coderdenttest"
"github.com/coder/coder/enterprise/coderd/license"
"github.com/coder/coder/provisioner/echo"
"github.com/coder/coder/testutil"
)
@ -27,7 +28,9 @@ func TestTemplateACL(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
_, user2 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -68,7 +71,9 @@ func TestTemplateACL(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
_, user1 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -92,7 +97,9 @@ func TestTemplateACL(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
client1, _ := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -142,7 +149,9 @@ func TestTemplateACL(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
_, user1 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -180,7 +189,9 @@ func TestTemplateACL(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
_, user1 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -218,7 +229,9 @@ func TestTemplateACL(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
@ -266,7 +279,9 @@ func TestTemplateACL(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
client1, user1 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -322,7 +337,9 @@ func TestUpdateTemplateACL(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
_, user2 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -374,8 +391,10 @@ func TestUpdateTemplateACL(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
AuditLog: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
codersdk.FeatureAuditLog: 1,
},
})
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
@ -405,7 +424,9 @@ func TestUpdateTemplateACL(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
_, user2 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -466,7 +487,9 @@ func TestUpdateTemplateACL(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
@ -491,7 +514,9 @@ func TestUpdateTemplateACL(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
@ -516,7 +541,9 @@ func TestUpdateTemplateACL(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
_, user2 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -542,7 +569,9 @@ func TestUpdateTemplateACL(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
client2, user2 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -577,7 +606,9 @@ func TestUpdateTemplateACL(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
client2, user2 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -619,7 +650,9 @@ func TestUpdateTemplateACL(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
@ -641,7 +674,9 @@ func TestUpdateTemplateACL(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
client1, user1 := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -706,7 +741,9 @@ func TestUpdateTemplateACL(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
client1, _ := coderdtest.CreateAnotherUserWithUser(t, client, user.OrganizationID)
@ -764,7 +801,9 @@ func TestTemplateAccess(t *testing.T) {
ownerClient := coderdenttest.New(t, nil)
owner := coderdtest.CreateFirstUser(t, ownerClient)
_ = coderdenttest.AddLicense(t, ownerClient, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
type coderUser struct {

View File

@ -15,6 +15,7 @@ import (
"github.com/coder/coder/coderd/coderdtest"
"github.com/coder/coder/codersdk"
"github.com/coder/coder/enterprise/coderd/coderdenttest"
"github.com/coder/coder/enterprise/coderd/license"
"github.com/coder/coder/provisioner/echo"
"github.com/coder/coder/provisionersdk/proto"
"github.com/coder/coder/testutil"
@ -39,7 +40,9 @@ func TestBlockNonBrowser(t *testing.T) {
})
user := coderdtest.CreateFirstUser(t, client)
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
BrowserOnly: true,
Features: license.Features{
codersdk.FeatureBrowserOnly: 1,
},
})
_, agent := setupWorkspaceAgent(t, client, user, 0)
_, err := client.DialWorkspaceAgent(context.Background(), agent.ID, nil)
@ -56,7 +59,9 @@ func TestBlockNonBrowser(t *testing.T) {
})
user := coderdtest.CreateFirstUser(t, client)
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
BrowserOnly: false,
Features: license.Features{
codersdk.FeatureBrowserOnly: 0,
},
})
_, agent := setupWorkspaceAgent(t, client, user, 0)
conn, err := client.DialWorkspaceAgent(context.Background(), agent.ID, nil)

View File

@ -10,6 +10,7 @@ import (
"github.com/coder/coder/coderd/coderdtest"
"github.com/coder/coder/codersdk"
"github.com/coder/coder/enterprise/coderd/coderdenttest"
"github.com/coder/coder/enterprise/coderd/license"
"github.com/coder/coder/provisioner/echo"
"github.com/coder/coder/provisionersdk/proto"
"github.com/coder/coder/testutil"
@ -45,7 +46,9 @@ func TestWorkspaceQuota(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
verifyQuota(ctx, t, client, 0, 0)

View File

@ -12,6 +12,7 @@ import (
"github.com/coder/coder/coderd/util/ptr"
"github.com/coder/coder/codersdk"
"github.com/coder/coder/enterprise/coderd/coderdenttest"
"github.com/coder/coder/enterprise/coderd/license"
"github.com/coder/coder/testutil"
)
@ -26,7 +27,9 @@ func TestCreateWorkspace(t *testing.T) {
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
_ = coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
TemplateRBAC: true,
Features: license.Features{
codersdk.FeatureTemplateRBAC: 1,
},
})
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)