mirror of
https://github.com/bitwarden/server.git
synced 2025-04-07 14:08:13 -05:00
installation validation and self host applied
This commit is contained in:
parent
ee9ec680a9
commit
dd288a7071
@ -23,7 +23,6 @@ namespace Bit.Api.Controllers
|
|||||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||||
private readonly IOrganizationService _organizationService;
|
private readonly IOrganizationService _organizationService;
|
||||||
private readonly IUserService _userService;
|
private readonly IUserService _userService;
|
||||||
private readonly ILicensingService _licensingService;
|
|
||||||
private readonly CurrentContext _currentContext;
|
private readonly CurrentContext _currentContext;
|
||||||
private readonly GlobalSettings _globalSettings;
|
private readonly GlobalSettings _globalSettings;
|
||||||
private readonly UserManager<User> _userManager;
|
private readonly UserManager<User> _userManager;
|
||||||
@ -33,7 +32,6 @@ namespace Bit.Api.Controllers
|
|||||||
IOrganizationUserRepository organizationUserRepository,
|
IOrganizationUserRepository organizationUserRepository,
|
||||||
IOrganizationService organizationService,
|
IOrganizationService organizationService,
|
||||||
IUserService userService,
|
IUserService userService,
|
||||||
ILicensingService licensingService,
|
|
||||||
CurrentContext currentContext,
|
CurrentContext currentContext,
|
||||||
GlobalSettings globalSettings,
|
GlobalSettings globalSettings,
|
||||||
UserManager<User> userManager)
|
UserManager<User> userManager)
|
||||||
@ -44,7 +42,6 @@ namespace Bit.Api.Controllers
|
|||||||
_userService = userService;
|
_userService = userService;
|
||||||
_currentContext = currentContext;
|
_currentContext = currentContext;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_licensingService = licensingService;
|
|
||||||
_globalSettings = globalSettings;
|
_globalSettings = globalSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,15 +104,13 @@ namespace Bit.Api.Controllers
|
|||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
var organization = await _organizationRepository.GetByIdAsync(orgIdGuid);
|
var license = await _organizationService.GenerateLicenseAsync(orgIdGuid, installationId);
|
||||||
if(organization == null)
|
if(license == null)
|
||||||
{
|
{
|
||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
var paymentService = new StripePaymentService();
|
return license;
|
||||||
var billingInfo = await paymentService.GetBillingAsync(organization);
|
|
||||||
return new OrganizationLicense(organization, billingInfo, installationId, _licensingService);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("")]
|
[HttpGet("")]
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models.Table;
|
using Bit.Core.Models.Table;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
@ -39,7 +40,7 @@ namespace Bit.Core.Models.Business
|
|||||||
Trial = true;
|
Trial = true;
|
||||||
}
|
}
|
||||||
else if(billingInfo.Subscription.TrialEndDate.HasValue &&
|
else if(billingInfo.Subscription.TrialEndDate.HasValue &&
|
||||||
billingInfo.Subscription.TrialEndDate.Value < DateTime.UtcNow)
|
billingInfo.Subscription.TrialEndDate.Value > DateTime.UtcNow)
|
||||||
{
|
{
|
||||||
Expires = Refresh = billingInfo.Subscription.TrialEndDate.Value;
|
Expires = Refresh = billingInfo.Subscription.TrialEndDate.Value;
|
||||||
Trial = true;
|
Trial = true;
|
||||||
@ -89,6 +90,7 @@ namespace Bit.Core.Models.Business
|
|||||||
public DateTime? Expires { get; set; }
|
public DateTime? Expires { get; set; }
|
||||||
public bool Trial { get; set; }
|
public bool Trial { get; set; }
|
||||||
public string Signature { get; set; }
|
public string Signature { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
public byte[] SignatureBytes => Convert.FromBase64String(Signature);
|
public byte[] SignatureBytes => Convert.FromBase64String(Signature);
|
||||||
|
|
||||||
public byte[] GetSignatureData()
|
public byte[] GetSignatureData()
|
||||||
@ -124,19 +126,14 @@ namespace Bit.Core.Models.Business
|
|||||||
|
|
||||||
public bool CanUse(Guid installationId)
|
public bool CanUse(Guid installationId)
|
||||||
{
|
{
|
||||||
if(Issued > DateTime.UtcNow)
|
if(!Enabled || Issued > DateTime.UtcNow || Expires < DateTime.UtcNow)
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Expires < DateTime.UtcNow)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Version == 1)
|
if(Version == 1)
|
||||||
{
|
{
|
||||||
return InstallationId == installationId;
|
return InstallationId == installationId && SelfHost;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -146,12 +143,7 @@ namespace Bit.Core.Models.Business
|
|||||||
|
|
||||||
public bool VerifyData(Organization organization)
|
public bool VerifyData(Organization organization)
|
||||||
{
|
{
|
||||||
if(Issued > DateTime.UtcNow)
|
if(Issued > DateTime.UtcNow || Expires < DateTime.UtcNow)
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Expires < DateTime.UtcNow)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -185,7 +177,15 @@ namespace Bit.Core.Models.Business
|
|||||||
|
|
||||||
public byte[] Sign(X509Certificate2 certificate)
|
public byte[] Sign(X509Certificate2 certificate)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
if(!certificate.HasPrivateKey)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("You don't have the private key!");
|
||||||
|
}
|
||||||
|
|
||||||
|
using(var rsa = certificate.GetRSAPrivateKey())
|
||||||
|
{
|
||||||
|
return rsa.SignData(GetSignatureData(), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,19 +70,14 @@ namespace Bit.Core.Models.Business
|
|||||||
|
|
||||||
public bool CanUse(User user)
|
public bool CanUse(User user)
|
||||||
{
|
{
|
||||||
if(Issued > DateTime.UtcNow)
|
if(Issued > DateTime.UtcNow || Expires < DateTime.UtcNow)
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Expires < DateTime.UtcNow)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Version == 1)
|
if(Version == 1)
|
||||||
{
|
{
|
||||||
return user.Email.Equals(Email, StringComparison.InvariantCultureIgnoreCase);
|
return user.EmailVerified && user.Email.Equals(Email, StringComparison.InvariantCultureIgnoreCase);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -92,12 +87,7 @@ namespace Bit.Core.Models.Business
|
|||||||
|
|
||||||
public bool VerifyData(User user)
|
public bool VerifyData(User user)
|
||||||
{
|
{
|
||||||
if(Issued > DateTime.UtcNow)
|
if(Issued > DateTime.UtcNow || Expires < DateTime.UtcNow)
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Expires < DateTime.UtcNow)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -22,5 +22,6 @@ namespace Bit.Core.Models.StaticStore
|
|||||||
public int UpgradeSortOrder { get; set; }
|
public int UpgradeSortOrder { get; set; }
|
||||||
public bool Disabled { get; set; }
|
public bool Disabled { get; set; }
|
||||||
public int? TrialPeriodDays { get; set; }
|
public int? TrialPeriodDays { get; set; }
|
||||||
|
public bool SelfHost { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ namespace Bit.Core.Services
|
|||||||
Task SaveUserAsync(OrganizationUser user, Guid savingUserId, IEnumerable<SelectionReadOnly> collections);
|
Task SaveUserAsync(OrganizationUser user, Guid savingUserId, IEnumerable<SelectionReadOnly> collections);
|
||||||
Task DeleteUserAsync(Guid organizationId, Guid organizationUserId, Guid deletingUserId);
|
Task DeleteUserAsync(Guid organizationId, Guid organizationUserId, Guid deletingUserId);
|
||||||
Task DeleteUserAsync(Guid organizationId, Guid userId);
|
Task DeleteUserAsync(Guid organizationId, Guid userId);
|
||||||
|
Task<OrganizationLicense> GenerateLicenseAsync(Guid organizationId, Guid installationId);
|
||||||
Task ImportAsync(Guid organizationId, Guid importingUserId, IEnumerable<ImportedGroup> groups,
|
Task ImportAsync(Guid organizationId, Guid importingUserId, IEnumerable<ImportedGroup> groups,
|
||||||
IEnumerable<ImportedOrganizationUser> newUsers, IEnumerable<string> removeUserExternalIds);
|
IEnumerable<ImportedOrganizationUser> newUsers, IEnumerable<string> removeUserExternalIds);
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ namespace Bit.Core.Services
|
|||||||
private readonly IPushRegistrationService _pushRegistrationService;
|
private readonly IPushRegistrationService _pushRegistrationService;
|
||||||
private readonly IDeviceRepository _deviceRepository;
|
private readonly IDeviceRepository _deviceRepository;
|
||||||
private readonly ILicensingService _licensingService;
|
private readonly ILicensingService _licensingService;
|
||||||
|
private readonly IInstallationRepository _installationRepository;
|
||||||
private readonly StripePaymentService _stripePaymentService;
|
private readonly StripePaymentService _stripePaymentService;
|
||||||
private readonly GlobalSettings _globalSettings;
|
private readonly GlobalSettings _globalSettings;
|
||||||
|
|
||||||
@ -44,6 +45,7 @@ namespace Bit.Core.Services
|
|||||||
IPushRegistrationService pushRegistrationService,
|
IPushRegistrationService pushRegistrationService,
|
||||||
IDeviceRepository deviceRepository,
|
IDeviceRepository deviceRepository,
|
||||||
ILicensingService licensingService,
|
ILicensingService licensingService,
|
||||||
|
IInstallationRepository installationRepository,
|
||||||
GlobalSettings globalSettings)
|
GlobalSettings globalSettings)
|
||||||
{
|
{
|
||||||
_organizationRepository = organizationRepository;
|
_organizationRepository = organizationRepository;
|
||||||
@ -57,6 +59,7 @@ namespace Bit.Core.Services
|
|||||||
_pushRegistrationService = pushRegistrationService;
|
_pushRegistrationService = pushRegistrationService;
|
||||||
_deviceRepository = deviceRepository;
|
_deviceRepository = deviceRepository;
|
||||||
_licensingService = licensingService;
|
_licensingService = licensingService;
|
||||||
|
_installationRepository = installationRepository;
|
||||||
_stripePaymentService = new StripePaymentService();
|
_stripePaymentService = new StripePaymentService();
|
||||||
_globalSettings = globalSettings;
|
_globalSettings = globalSettings;
|
||||||
}
|
}
|
||||||
@ -522,6 +525,7 @@ namespace Bit.Core.Services
|
|||||||
UseGroups = plan.UseGroups,
|
UseGroups = plan.UseGroups,
|
||||||
UseDirectory = plan.UseDirectory,
|
UseDirectory = plan.UseDirectory,
|
||||||
UseTotp = plan.UseTotp,
|
UseTotp = plan.UseTotp,
|
||||||
|
SelfHost = plan.SelfHost,
|
||||||
Plan = plan.Name,
|
Plan = plan.Name,
|
||||||
Gateway = GatewayType.Stripe,
|
Gateway = GatewayType.Stripe,
|
||||||
GatewayCustomerId = customer?.Id,
|
GatewayCustomerId = customer?.Id,
|
||||||
@ -563,6 +567,7 @@ namespace Bit.Core.Services
|
|||||||
UseDirectory = license.UseDirectory,
|
UseDirectory = license.UseDirectory,
|
||||||
UseTotp = license.UseTotp,
|
UseTotp = license.UseTotp,
|
||||||
Plan = license.Plan,
|
Plan = license.Plan,
|
||||||
|
SelfHost = license.SelfHost,
|
||||||
Gateway = null,
|
Gateway = null,
|
||||||
GatewayCustomerId = null,
|
GatewayCustomerId = null,
|
||||||
GatewaySubscriptionId = null,
|
GatewaySubscriptionId = null,
|
||||||
@ -999,6 +1004,25 @@ namespace Bit.Core.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<OrganizationLicense> GenerateLicenseAsync(Guid organizationId, Guid installationId)
|
||||||
|
{
|
||||||
|
var organization = await _organizationRepository.GetByIdAsync(organizationId);
|
||||||
|
if(organization == null)
|
||||||
|
{
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
var installation = await _installationRepository.GetByIdAsync(installationId);
|
||||||
|
if(installation == null || !installation.Enabled)
|
||||||
|
{
|
||||||
|
throw new BadRequestException("Invalid installation id");
|
||||||
|
}
|
||||||
|
|
||||||
|
var paymentService = new StripePaymentService();
|
||||||
|
var billingInfo = await paymentService.GetBillingAsync(organization);
|
||||||
|
return new OrganizationLicense(organization, billingInfo, installationId, _licensingService);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task ImportAsync(Guid organizationId,
|
public async Task ImportAsync(Guid organizationId,
|
||||||
Guid importingUserId,
|
Guid importingUserId,
|
||||||
IEnumerable<ImportedGroup> groups,
|
IEnumerable<ImportedGroup> groups,
|
||||||
|
@ -164,7 +164,8 @@ namespace Bit.Core.Utilities
|
|||||||
UseGroups = true,
|
UseGroups = true,
|
||||||
UseDirectory = true,
|
UseDirectory = true,
|
||||||
UseTotp = true,
|
UseTotp = true,
|
||||||
MaxStorageGb = 1
|
MaxStorageGb = 1,
|
||||||
|
SelfHost = true
|
||||||
},
|
},
|
||||||
new Plan
|
new Plan
|
||||||
{
|
{
|
||||||
@ -182,7 +183,8 @@ namespace Bit.Core.Utilities
|
|||||||
UseGroups = true,
|
UseGroups = true,
|
||||||
UseDirectory = true,
|
UseDirectory = true,
|
||||||
UseTotp = true,
|
UseTotp = true,
|
||||||
MaxStorageGb = 1
|
MaxStorageGb = 1,
|
||||||
|
SelfHost = true
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user