1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-30 07:36:14 -05:00

[PM-11516] Initial license file refactor (#5002)

* Added the ability to create a JWT on an organization license that contains all license properties as claims

* Added the ability to create a JWT on a user license that contains all license properties as claims

* Added ability to consume JWT licenses

* Resolved generic type issues when getting claim value

* Now validating the jwt signature, exp, and iat

* Moved creation of ClaimsPrincipal outside of licenses given dependecy on cert

* Ran dotnet format. Resolved identity error

* Updated claim types to use string constants

* Updated jwt expires to be one year

* Fixed bug requiring email verification to be on the token

* dotnet format

* Patch build process

---------

Co-authored-by: Matt Bishop <mbishop@bitwarden.com>
This commit is contained in:
Conner Turnbull
2024-12-05 09:31:14 -05:00
committed by GitHub
parent 0e32dcccad
commit 04cf513d78
23 changed files with 846 additions and 106 deletions

View File

@ -1,4 +1,5 @@
using System.Text.Json;
using System.Security.Claims;
using System.Text.Json;
using Bit.Core.Models.Business;
using Bit.Core.Services;
using Bit.Core.Settings;
@ -36,7 +37,7 @@ public class OrganizationLicenseTests
[Theory]
[BitAutoData(OrganizationLicense.CurrentLicenseFileVersion)] // Previous version (this property is 1 behind)
[BitAutoData(OrganizationLicense.CurrentLicenseFileVersion + 1)] // Current version
public void OrganizationLicense_LoadedFromDisk_VerifyData_Passes(int licenseVersion)
public void OrganizationLicense_LoadedFromDisk_VerifyData_Passes(int licenseVersion, ClaimsPrincipal claimsPrincipal)
{
var license = OrganizationLicenseFileFixtures.GetVersion(licenseVersion);
@ -49,7 +50,7 @@ public class OrganizationLicenseTests
{
Id = new Guid(OrganizationLicenseFileFixtures.InstallationId)
});
Assert.True(license.VerifyData(organization, globalSettings));
Assert.True(license.VerifyData(organization, claimsPrincipal, globalSettings));
}
/// <summary>

View File

@ -1,4 +1,5 @@
using Bit.Core.AdminConsole.Entities;
using System.Security.Claims;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Enums;
using Bit.Core.Models.Business;
using Bit.Core.Models.Data.Organizations;
@ -48,6 +49,9 @@ public class UpdateOrganizationLicenseCommandTests
license.InstallationId = globalSettings.Installation.Id;
license.LicenseType = LicenseType.Organization;
sutProvider.GetDependency<ILicensingService>().VerifyLicense(license).Returns(true);
sutProvider.GetDependency<ILicensingService>()
.GetClaimsPrincipalFromLicense(license)
.Returns((ClaimsPrincipal)null);
// Passing values for SelfHostedOrganizationDetails.CanUseLicense
// NSubstitute cannot override non-virtual members so we have to ensure the real method passes
@ -79,10 +83,11 @@ public class UpdateOrganizationLicenseCommandTests
.Received(1)
.ReplaceAndUpdateCacheAsync(Arg.Is<Organization>(
org => AssertPropertyEqual(license, org,
"Id", "MaxStorageGb", "Issued", "Refresh", "Version", "Trial", "LicenseType",
"Hash", "Signature", "SignatureBytes", "InstallationId", "Expires", "ExpirationWithoutGracePeriod") &&
// Same property but different name, use explicit mapping
org.ExpirationDate == license.Expires));
"Id", "MaxStorageGb", "Issued", "Refresh", "Version", "Trial", "LicenseType",
"Hash", "Signature", "SignatureBytes", "InstallationId", "Expires",
"ExpirationWithoutGracePeriod", "Token") &&
// Same property but different name, use explicit mapping
org.ExpirationDate == license.Expires));
}
finally
{

View File

@ -1,4 +1,5 @@
using System.Text.Json;
using System.Security.Claims;
using System.Text.Json;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
using Bit.Core.AdminConsole.Repositories;
@ -62,6 +63,9 @@ public class UserServiceTests
sutProvider.GetDependency<ILicensingService>()
.VerifyLicense(userLicense)
.Returns(true);
sutProvider.GetDependency<ILicensingService>()
.GetClaimsPrincipalFromLicense(userLicense)
.Returns((ClaimsPrincipal)null);
await sutProvider.Sut.UpdateLicenseAsync(user, userLicense);