mirror of
https://github.com/bitwarden/server.git
synced 2025-07-01 08:02:49 -05:00
[Reset Password] Organization Key Pair (#1292)
* [Reset Password] Organization Key Pair * Fixed type in Organization_ReadAbilites sproc * Fixed broken unit test by making sure premium addon was false * Updated PublicKey decorator and removed unecessary validation
This commit is contained in:
@ -20,6 +20,7 @@ namespace Bit.Core.Models.Api.Public
|
||||
Type = user.Type;
|
||||
AccessAll = user.AccessAll;
|
||||
ExternalId = user.ExternalId;
|
||||
ResetPasswordEnrolled = user.ResetPasswordKey != null;
|
||||
}
|
||||
|
||||
public MemberBaseModel(OrganizationUserUserDetails user)
|
||||
@ -32,6 +33,7 @@ namespace Bit.Core.Models.Api.Public
|
||||
Type = user.Type;
|
||||
AccessAll = user.AccessAll;
|
||||
ExternalId = user.ExternalId;
|
||||
ResetPasswordEnrolled = user.ResetPasswordKey != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -51,5 +53,10 @@ namespace Bit.Core.Models.Api.Public
|
||||
/// <example>external_id_123456</example>
|
||||
[StringLength(300)]
|
||||
public string ExternalId { get; set; }
|
||||
/// <summary>
|
||||
/// Returns <c>true</c> if the member has enrolled in Password Reset assistance within the organization
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool ResetPasswordEnrolled { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -10,5 +10,6 @@ namespace Bit.Core.Models.Api
|
||||
[EncryptedString]
|
||||
[EncryptedStringLength(1000)]
|
||||
public string CollectionName { get; set; }
|
||||
public OrganizationKeysRequestModel Keys { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ namespace Bit.Core.Models.Api
|
||||
public PlanType PlanType { get; set; }
|
||||
[Required]
|
||||
public string Key { get; set; }
|
||||
public OrganizationKeysRequestModel Keys { get; set; }
|
||||
public PaymentMethodType? PaymentMethodType { get; set; }
|
||||
public string PaymentToken { get; set; }
|
||||
[Range(0, double.MaxValue)]
|
||||
@ -42,7 +43,7 @@ namespace Bit.Core.Models.Api
|
||||
|
||||
public virtual OrganizationSignup ToOrganizationSignup(User user)
|
||||
{
|
||||
return new OrganizationSignup
|
||||
var orgSignup = new OrganizationSignup
|
||||
{
|
||||
Owner = user,
|
||||
OwnerKey = Key,
|
||||
@ -67,6 +68,10 @@ namespace Bit.Core.Models.Api
|
||||
BillingAddressCountry = BillingAddressCountry,
|
||||
},
|
||||
};
|
||||
|
||||
Keys?.ToOrganizationSignup(orgSignup);
|
||||
|
||||
return orgSignup;
|
||||
}
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
|
@ -0,0 +1,59 @@
|
||||
using Bit.Core.Models.Table;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Bit.Core.Models.Business;
|
||||
|
||||
namespace Bit.Core.Models.Api
|
||||
{
|
||||
public class OrganizationKeysRequestModel
|
||||
{
|
||||
[Required]
|
||||
public string PublicKey { get; set; }
|
||||
[Required]
|
||||
public string EncryptedPrivateKey { get; set; }
|
||||
|
||||
public OrganizationSignup ToOrganizationSignup(OrganizationSignup existingSignup)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(existingSignup.PublicKey))
|
||||
{
|
||||
existingSignup.PublicKey = PublicKey;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(existingSignup.PrivateKey))
|
||||
{
|
||||
existingSignup.PrivateKey = EncryptedPrivateKey;
|
||||
}
|
||||
|
||||
return existingSignup;
|
||||
}
|
||||
|
||||
public OrganizationUpgrade ToOrganizationUpgrade(OrganizationUpgrade existingUpgrade)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(existingUpgrade.PublicKey))
|
||||
{
|
||||
existingUpgrade.PublicKey = PublicKey;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(existingUpgrade.PrivateKey))
|
||||
{
|
||||
existingUpgrade.PrivateKey = EncryptedPrivateKey;
|
||||
}
|
||||
|
||||
return existingUpgrade;
|
||||
}
|
||||
|
||||
public Organization ToOrganization(Organization existingOrg)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(existingOrg.PublicKey))
|
||||
{
|
||||
existingOrg.PublicKey = PublicKey;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(existingOrg.PrivateKey))
|
||||
{
|
||||
existingOrg.PrivateKey = EncryptedPrivateKey;
|
||||
}
|
||||
|
||||
return existingOrg;
|
||||
}
|
||||
}
|
||||
}
|
@ -18,8 +18,8 @@ namespace Bit.Core.Models.Api
|
||||
[Required]
|
||||
[StringLength(256)]
|
||||
public string BillingEmail { get; set; }
|
||||
|
||||
public Permissions Permissions { get; set; }
|
||||
public OrganizationKeysRequestModel Keys { get; set; }
|
||||
|
||||
public virtual Organization ToOrganization(Organization existingOrganization, GlobalSettings globalSettings)
|
||||
{
|
||||
@ -31,6 +31,7 @@ namespace Bit.Core.Models.Api
|
||||
existingOrganization.BillingEmail = BillingEmail?.ToLowerInvariant()?.Trim();
|
||||
}
|
||||
existingOrganization.Identifier = Identifier;
|
||||
Keys?.ToOrganization(existingOrganization);
|
||||
return existingOrganization;
|
||||
}
|
||||
}
|
||||
|
@ -16,10 +16,11 @@ namespace Bit.Core.Models.Api
|
||||
public bool PremiumAccessAddon { get; set; }
|
||||
public string BillingAddressCountry { get; set; }
|
||||
public string BillingAddressPostalCode { get; set; }
|
||||
public OrganizationKeysRequestModel Keys { get; set; }
|
||||
|
||||
public OrganizationUpgrade ToOrganizationUpgrade()
|
||||
{
|
||||
return new OrganizationUpgrade
|
||||
var orgUpgrade = new OrganizationUpgrade
|
||||
{
|
||||
AdditionalSeats = AdditionalSeats,
|
||||
AdditionalStorageGb = AdditionalStorageGb.GetValueOrDefault(),
|
||||
@ -32,6 +33,10 @@ namespace Bit.Core.Models.Api
|
||||
BillingAddressPostalCode = BillingAddressPostalCode
|
||||
}
|
||||
};
|
||||
|
||||
Keys.ToOrganizationUpgrade(orgUpgrade);
|
||||
|
||||
return orgUpgrade;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,8 +40,10 @@ namespace Bit.Core.Models.Api
|
||||
UseTotp = organization.UseTotp;
|
||||
Use2fa = organization.Use2fa;
|
||||
UseApi = organization.UseApi;
|
||||
UseResetPassword = organization.UseResetPassword;
|
||||
UsersGetPremium = organization.UsersGetPremium;
|
||||
SelfHost = organization.SelfHost;
|
||||
HasPublicAndPrivateKeys = organization.PublicKey != null && organization.PrivateKey != null;
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
@ -67,8 +69,10 @@ namespace Bit.Core.Models.Api
|
||||
public bool UseTotp { get; set; }
|
||||
public bool Use2fa { get; set; }
|
||||
public bool UseApi { get; set; }
|
||||
public bool UseResetPassword { get; set; }
|
||||
public bool UsersGetPremium { get; set; }
|
||||
public bool SelfHost { get; set; }
|
||||
public bool HasPublicAndPrivateKeys { get; set; }
|
||||
}
|
||||
|
||||
public class OrganizationSubscriptionResponseModel : OrganizationResponseModel
|
||||
|
@ -39,6 +39,7 @@ namespace Bit.Core.Models.Api
|
||||
HasTotp = plan.HasTotp;
|
||||
Has2fa = plan.Has2fa;
|
||||
HasSso = plan.HasSso;
|
||||
HasResetPassword = plan.HasResetPassword;
|
||||
UsersGetPremium = plan.UsersGetPremium;
|
||||
UpgradeSortOrder = plan.UpgradeSortOrder;
|
||||
DisplaySortOrder = plan.DisplaySortOrder;
|
||||
@ -81,6 +82,7 @@ namespace Bit.Core.Models.Api
|
||||
public bool Has2fa { get; set; }
|
||||
public bool HasApi { get; set; }
|
||||
public bool HasSso { get; set; }
|
||||
public bool HasResetPassword { get; set; }
|
||||
public bool UsersGetPremium { get; set; }
|
||||
|
||||
public int UpgradeSortOrder { get; set; }
|
||||
|
@ -18,12 +18,14 @@ namespace Bit.Core.Models.Api
|
||||
UseTotp = organization.UseTotp;
|
||||
Use2fa = organization.Use2fa;
|
||||
UseApi = organization.UseApi;
|
||||
UseResetPassword = organization.UseResetPassword;
|
||||
UsersGetPremium = organization.UsersGetPremium;
|
||||
SelfHost = organization.SelfHost;
|
||||
Seats = organization.Seats;
|
||||
MaxCollections = organization.MaxCollections;
|
||||
MaxStorageGb = organization.MaxStorageGb;
|
||||
Key = organization.Key;
|
||||
HasPublicAndPrivateKeys = organization.PublicKey != null && organization.PrivateKey != null;
|
||||
Status = organization.Status;
|
||||
Type = organization.Type;
|
||||
Enabled = organization.Enabled;
|
||||
@ -44,6 +46,7 @@ namespace Bit.Core.Models.Api
|
||||
public bool UseTotp { get; set; }
|
||||
public bool Use2fa { get; set; }
|
||||
public bool UseApi { get; set; }
|
||||
public bool UseResetPassword { get; set; }
|
||||
public bool UseBusinessPortal => UsePolicies || UseSso; // TODO add events if needed
|
||||
public bool UsersGetPremium { get; set; }
|
||||
public bool SelfHost { get; set; }
|
||||
@ -59,5 +62,6 @@ namespace Bit.Core.Models.Api
|
||||
public Permissions Permissions { get; set; }
|
||||
public bool ResetPasswordEnrolled { get; set; }
|
||||
public string UserId { get; set; }
|
||||
public bool HasPublicAndPrivateKeys { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ namespace Bit.Core.Models.Business
|
||||
public OrganizationLicense(Organization org, SubscriptionInfo subscriptionInfo, Guid installationId,
|
||||
ILicensingService licenseService, int? version = null)
|
||||
{
|
||||
Version = version.GetValueOrDefault(6); // TODO: bump to version 7
|
||||
Version = version.GetValueOrDefault(7); // TODO: bump to version 8
|
||||
LicenseKey = org.LicenseKey;
|
||||
InstallationId = installationId;
|
||||
Id = org.Id;
|
||||
@ -40,6 +40,7 @@ namespace Bit.Core.Models.Business
|
||||
UseTotp = org.UseTotp;
|
||||
Use2fa = org.Use2fa;
|
||||
UseApi = org.UseApi;
|
||||
UseResetPassword = org.UseResetPassword;
|
||||
MaxStorageGb = org.MaxStorageGb;
|
||||
SelfHost = org.SelfHost;
|
||||
UsersGetPremium = org.UsersGetPremium;
|
||||
@ -109,6 +110,7 @@ namespace Bit.Core.Models.Business
|
||||
public bool UseTotp { get; set; }
|
||||
public bool Use2fa { get; set; }
|
||||
public bool UseApi { get; set; }
|
||||
public bool UseResetPassword { get; set; }
|
||||
public short? MaxStorageGb { get; set; }
|
||||
public bool SelfHost { get; set; }
|
||||
public bool UsersGetPremium { get; set; }
|
||||
@ -125,7 +127,7 @@ namespace Bit.Core.Models.Business
|
||||
public byte[] GetDataBytes(bool forHash = false)
|
||||
{
|
||||
string data = null;
|
||||
if (Version >= 1 && Version <= 7)
|
||||
if (Version >= 1 && Version <= 8)
|
||||
{
|
||||
var props = typeof(OrganizationLicense)
|
||||
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
||||
@ -144,6 +146,8 @@ namespace Bit.Core.Models.Business
|
||||
(Version >= 6 || !p.Name.Equals(nameof(UsePolicies))) &&
|
||||
// UseSso was added in Version 7
|
||||
(Version >= 7 || !p.Name.Equals(nameof(UseSso))) &&
|
||||
// UseResetPassword was added in Version 8
|
||||
(Version >= 8 || !p.Name.Equals(nameof(UseResetPassword))) &&
|
||||
(
|
||||
!forHash ||
|
||||
(
|
||||
@ -180,7 +184,7 @@ namespace Bit.Core.Models.Business
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Version >= 1 && Version <= 7)
|
||||
if (Version >= 1 && Version <= 8)
|
||||
{
|
||||
return InstallationId == globalSettings.Installation.Id && SelfHost;
|
||||
}
|
||||
@ -197,7 +201,7 @@ namespace Bit.Core.Models.Business
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Version >= 1 && Version <= 7)
|
||||
if (Version >= 1 && Version <= 8)
|
||||
{
|
||||
var valid =
|
||||
globalSettings.Installation.Id == InstallationId &&
|
||||
@ -241,6 +245,11 @@ namespace Bit.Core.Models.Business
|
||||
{
|
||||
valid = organization.UseSso == UseSso;
|
||||
}
|
||||
|
||||
if (valid && Version >= 8)
|
||||
{
|
||||
valid = organization.UseResetPassword == UseResetPassword;
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
@ -10,5 +10,7 @@ namespace Bit.Core.Models.Business
|
||||
public short AdditionalStorageGb { get; set; }
|
||||
public bool PremiumAccessAddon { get; set; }
|
||||
public TaxInfo TaxInfo { get; set; }
|
||||
public string PublicKey { get; set; }
|
||||
public string PrivateKey { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ namespace Bit.Core.Models.Data
|
||||
UsersGetPremium = organization.UsersGetPremium;
|
||||
Enabled = organization.Enabled;
|
||||
UseSso = organization.UseSso;
|
||||
UseResetPassword = organization.UseResetPassword;
|
||||
}
|
||||
|
||||
public Guid Id { get; set; }
|
||||
@ -26,5 +27,6 @@ namespace Bit.Core.Models.Data
|
||||
public bool UsersGetPremium { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public bool UseSso { get; set; }
|
||||
public bool UseResetPassword { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ namespace Bit.Core.Models.Data
|
||||
public bool UseTotp { get; set; }
|
||||
public bool Use2fa { get; set; }
|
||||
public bool UseApi{ get; set; }
|
||||
public bool UseResetPassword { get; set; }
|
||||
public bool UseBusinessPortal => UsePolicies || UseSso;
|
||||
public bool SelfHost { get; set; }
|
||||
public bool UsersGetPremium { get; set; }
|
||||
@ -29,5 +30,7 @@ namespace Bit.Core.Models.Data
|
||||
public string Identifier { get; set; }
|
||||
public string Permissions { get; set; }
|
||||
public string ResetPasswordKey { get; set; }
|
||||
public string PublicKey { get; set; }
|
||||
public string PrivateKey { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ namespace Bit.Core.Models.StaticStore
|
||||
public bool Has2fa { get; set; }
|
||||
public bool HasApi { get; set; }
|
||||
public bool HasSso { get; set; }
|
||||
public bool HasResetPassword { get; set; }
|
||||
public bool UsersGetPremium { get; set; }
|
||||
|
||||
public int UpgradeSortOrder { get; set; }
|
||||
|
@ -33,6 +33,7 @@ namespace Bit.Core.Models.Table
|
||||
public bool UseTotp { get; set; }
|
||||
public bool Use2fa { get; set; }
|
||||
public bool UseApi { get; set; }
|
||||
public bool UseResetPassword { get; set; }
|
||||
public bool SelfHost { get; set; }
|
||||
public bool UsersGetPremium { get; set; }
|
||||
public long? Storage { get; set; }
|
||||
@ -44,6 +45,8 @@ namespace Bit.Core.Models.Table
|
||||
public bool Enabled { get; set; } = true;
|
||||
public string LicenseKey { get; set; }
|
||||
public string ApiKey { get; set; }
|
||||
public string PublicKey { get; set; }
|
||||
public string PrivateKey { get; set; }
|
||||
public string TwoFactorProviders { get; set; }
|
||||
public DateTime? ExpirationDate { get; set; }
|
||||
public DateTime CreationDate { get; internal set; } = DateTime.UtcNow;
|
||||
|
Reference in New Issue
Block a user