fix: use AlwaysEnable for licenses with all features (#9808)

* fix: use AlwaysEnable for licenses with all features

Signed-off-by: Spike Curtis <spike@coder.com>

* use dbtime.Now() intead of time.Now()

Signed-off-by: Spike Curtis <spike@coder.com>

---------

Signed-off-by: Spike Curtis <spike@coder.com>
This commit is contained in:
Spike Curtis
2023-09-22 05:02:28 +00:00
committed by GitHub
parent 94a0612cd2
commit e9077f3bd2
2 changed files with 63 additions and 2 deletions
+16 -2
View File
@@ -61,6 +61,7 @@ func Entitlements(
}
allFeatures := false
allFeaturesEntitlement := codersdk.EntitlementNotEntitled
// Here we loop through licenses to detect enabled features.
for _, l := range licenses {
@@ -117,7 +118,7 @@ func Entitlements(
}
default:
entitlements.Features[featureName] = codersdk.Feature{
Entitlement: entitlement,
Entitlement: maxEntitlement(entitlements.Features[featureName].Entitlement, entitlement),
Enabled: enablements[featureName] || featureName.AlwaysEnable(),
}
}
@@ -125,6 +126,7 @@ func Entitlements(
if claims.AllFeatures {
allFeatures = true
allFeaturesEntitlement = maxEntitlement(allFeaturesEntitlement, entitlement)
}
entitlements.RequireTelemetry = entitlements.RequireTelemetry || claims.RequireTelemetry
}
@@ -136,7 +138,8 @@ func Entitlements(
continue
}
feature := entitlements.Features[featureName]
feature.Entitlement = codersdk.EntitlementEntitled
feature.Entitlement = maxEntitlement(feature.Entitlement, allFeaturesEntitlement)
feature.Enabled = enablements[featureName] || featureName.AlwaysEnable()
entitlements.Features[featureName] = feature
}
}
@@ -324,3 +327,14 @@ func keyFunc(keys map[string]ed25519.PublicKey) func(*jwt.Token) (interface{}, e
return k, nil
}
}
// maxEntitlement is the "greater" entitlement between the given values
func maxEntitlement(e1, e2 codersdk.Entitlement) codersdk.Entitlement {
if e1 == codersdk.EntitlementEntitled || e2 == codersdk.EntitlementEntitled {
return codersdk.EntitlementEntitled
}
if e1 == codersdk.EntitlementGracePeriod || e2 == codersdk.EntitlementGracePeriod {
return codersdk.EntitlementGracePeriod
}
return codersdk.EntitlementNotEntitled
}
+47
View File
@@ -378,6 +378,53 @@ func TestEntitlements(t *testing.T) {
}
})
t.Run("AllFeaturesAlwaysEnable", func(t *testing.T) {
t.Parallel()
db := dbfake.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
Exp: dbtime.Now().Add(time.Hour),
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
AllFeatures: true,
}),
})
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)
for _, featureName := range codersdk.FeatureNames {
if featureName == codersdk.FeatureUserLimit {
continue
}
feature := entitlements.Features[featureName]
require.Equal(t, featureName.AlwaysEnable(), feature.Enabled)
require.Equal(t, codersdk.EntitlementEntitled, feature.Entitlement)
}
})
t.Run("AllFeaturesGrace", func(t *testing.T) {
t.Parallel()
db := dbfake.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
Exp: dbtime.Now().Add(time.Hour),
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
AllFeatures: true,
GraceAt: dbtime.Now().Add(-time.Hour),
ExpiresAt: dbtime.Now().Add(time.Hour),
}),
})
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 1, 1, coderdenttest.Keys, all)
require.NoError(t, err)
require.True(t, entitlements.HasLicense)
require.False(t, entitlements.Trial)
for _, featureName := range codersdk.FeatureNames {
if featureName == codersdk.FeatureUserLimit {
continue
}
require.True(t, entitlements.Features[featureName].Enabled)
require.Equal(t, codersdk.EntitlementGracePeriod, entitlements.Features[featureName].Entitlement)
}
})
t.Run("MultipleReplicasNoLicense", func(t *testing.T) {
t.Parallel()
db := dbfake.New()