mirror of
https://github.com/bitwarden/server.git
synced 2025-06-27 22:26:13 -05:00
Moved ValidateOrganizationsAsync
out of LicensingService
since its only usage was in ValidateOrganizationsJob
This commit is contained in:
parent
208d70d50e
commit
fa6427f3bf
@ -1,5 +1,11 @@
|
|||||||
using Bit.Core.Jobs;
|
using Bit.Core;
|
||||||
|
using Bit.Core.AdminConsole.Entities;
|
||||||
|
using Bit.Core.Billing.Licenses.Extensions;
|
||||||
|
using Bit.Core.Jobs;
|
||||||
|
using Bit.Core.Models.Business;
|
||||||
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
|
using Bit.Core.Settings;
|
||||||
using Quartz;
|
using Quartz;
|
||||||
|
|
||||||
namespace Bit.Api.Jobs;
|
namespace Bit.Api.Jobs;
|
||||||
@ -7,17 +13,98 @@ namespace Bit.Api.Jobs;
|
|||||||
public class ValidateOrganizationsJob : BaseJob
|
public class ValidateOrganizationsJob : BaseJob
|
||||||
{
|
{
|
||||||
private readonly ILicensingService _licensingService;
|
private readonly ILicensingService _licensingService;
|
||||||
|
private readonly IGlobalSettings _globalSettings;
|
||||||
|
private readonly IOrganizationRepository _organizationRepository;
|
||||||
|
private readonly IMailService _mailService;
|
||||||
|
|
||||||
public ValidateOrganizationsJob(
|
public ValidateOrganizationsJob(
|
||||||
ILicensingService licensingService,
|
ILicensingService licensingService,
|
||||||
|
IGlobalSettings globalSettings,
|
||||||
|
IOrganizationRepository organizationRepository,
|
||||||
|
IMailService mailService,
|
||||||
ILogger<ValidateOrganizationsJob> logger)
|
ILogger<ValidateOrganizationsJob> logger)
|
||||||
: base(logger)
|
: base(logger)
|
||||||
{
|
{
|
||||||
_licensingService = licensingService;
|
_licensingService = licensingService;
|
||||||
|
_globalSettings = globalSettings;
|
||||||
|
_organizationRepository = organizationRepository;
|
||||||
|
_mailService = mailService;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async override Task ExecuteJobAsync(IJobExecutionContext context)
|
protected async override Task ExecuteJobAsync(IJobExecutionContext context)
|
||||||
{
|
{
|
||||||
await _licensingService.ValidateOrganizationsAsync();
|
await ValidateOrganizationsAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ValidateOrganizationsAsync()
|
||||||
|
{
|
||||||
|
if (!_globalSettings.SelfHosted)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var enabledOrgs = await _organizationRepository.GetManyByEnabledAsync();
|
||||||
|
|
||||||
|
_logger.LogInformation(Constants.BypassFiltersEventId, null,
|
||||||
|
"Validating licenses for {NumberOfOrganizations} organizations.", enabledOrgs.Count);
|
||||||
|
|
||||||
|
var exceptions = new List<Exception>();
|
||||||
|
|
||||||
|
foreach (var org in enabledOrgs)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var license = await _licensingService.ReadOrganizationLicenseAsync(org);
|
||||||
|
if (license == null)
|
||||||
|
{
|
||||||
|
await DisableOrganizationAsync(org, null, "No license file.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var totalLicensedOrgs = enabledOrgs.Count(o => string.Equals(o.LicenseKey, license.LicenseKey));
|
||||||
|
if (totalLicensedOrgs > 1)
|
||||||
|
{
|
||||||
|
await DisableOrganizationAsync(org, license, "Multiple organizations.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!license.VerifyData(org, _licensingService.GetClaimsPrincipalFromLicense(license), _globalSettings))
|
||||||
|
{
|
||||||
|
await DisableOrganizationAsync(org, license, "Invalid data.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_licensingService.VerifyLicense(license))
|
||||||
|
{
|
||||||
|
await DisableOrganizationAsync(org, license, "Invalid signature.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
exceptions.Add(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exceptions.Count != 0)
|
||||||
|
{
|
||||||
|
throw new AggregateException("There were one or more exceptions while validating organizations.", exceptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DisableOrganizationAsync(Organization org, ILicense license, string reason)
|
||||||
|
{
|
||||||
|
_logger.LogInformation(Constants.BypassFiltersEventId, null,
|
||||||
|
"Organization {OrganizationId} ({OrganizationName}) has an invalid license and is being disabled. Reason: {Reason}",
|
||||||
|
org.Id,
|
||||||
|
org.DisplayName(),
|
||||||
|
reason);
|
||||||
|
|
||||||
|
org.Enabled = false;
|
||||||
|
org.ExpirationDate = license?.Expires ?? DateTime.UtcNow;
|
||||||
|
org.RevisionDate = DateTime.UtcNow;
|
||||||
|
|
||||||
|
await _organizationRepository.ReplaceAsync(org);
|
||||||
|
await _mailService.SendLicenseExpiredAsync([org.BillingEmail], org.DisplayName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ namespace Bit.Core.Services;
|
|||||||
|
|
||||||
public interface ILicensingService
|
public interface ILicensingService
|
||||||
{
|
{
|
||||||
Task ValidateOrganizationsAsync();
|
|
||||||
Task ValidateUsersAsync();
|
Task ValidateUsersAsync();
|
||||||
Task<bool> ValidateUserPremiumAsync(User user);
|
Task<bool> ValidateUserPremiumAsync(User user);
|
||||||
bool VerifyLicense(ILicense license);
|
bool VerifyLicense(ILicense license);
|
||||||
|
@ -84,74 +84,6 @@ public class LicensingService : ILicensingService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ValidateOrganizationsAsync()
|
|
||||||
{
|
|
||||||
if (!_globalSettings.SelfHosted)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var enabledOrgs = await _organizationRepository.GetManyByEnabledAsync();
|
|
||||||
_logger.LogInformation(Constants.BypassFiltersEventId, null,
|
|
||||||
"Validating licenses for {NumberOfOrganizations} organizations.", enabledOrgs.Count);
|
|
||||||
|
|
||||||
var exceptions = new List<Exception>();
|
|
||||||
|
|
||||||
foreach (var org in enabledOrgs)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var license = await ReadOrganizationLicenseAsync(org);
|
|
||||||
if (license == null)
|
|
||||||
{
|
|
||||||
await DisableOrganizationAsync(org, null, "No license file.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var totalLicensedOrgs = enabledOrgs.Count(o => string.Equals(o.LicenseKey, license.LicenseKey));
|
|
||||||
if (totalLicensedOrgs > 1)
|
|
||||||
{
|
|
||||||
await DisableOrganizationAsync(org, license, "Multiple organizations.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!license.VerifyData(org, GetClaimsPrincipalFromLicense(license), _globalSettings))
|
|
||||||
{
|
|
||||||
await DisableOrganizationAsync(org, license, "Invalid data.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(license.Token) && !license.VerifySignature(_certificate))
|
|
||||||
{
|
|
||||||
await DisableOrganizationAsync(org, license, "Invalid signature.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
exceptions.Add(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exceptions.Any())
|
|
||||||
{
|
|
||||||
throw new AggregateException("There were one or more exceptions while validating organizations.", exceptions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task DisableOrganizationAsync(Organization org, ILicense license, string reason)
|
|
||||||
{
|
|
||||||
_logger.LogInformation(Constants.BypassFiltersEventId, null,
|
|
||||||
"Organization {0} ({1}) has an invalid license and is being disabled. Reason: {2}",
|
|
||||||
org.Id, org.DisplayName(), reason);
|
|
||||||
org.Enabled = false;
|
|
||||||
org.ExpirationDate = license?.Expires ?? DateTime.UtcNow;
|
|
||||||
org.RevisionDate = DateTime.UtcNow;
|
|
||||||
await _organizationRepository.ReplaceAsync(org);
|
|
||||||
|
|
||||||
await _mailService.SendLicenseExpiredAsync(new List<string> { org.BillingEmail }, org.DisplayName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ValidateUsersAsync()
|
public async Task ValidateUsersAsync()
|
||||||
{
|
{
|
||||||
if (!_globalSettings.SelfHosted)
|
if (!_globalSettings.SelfHosted)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user