mirror of
https://github.com/bitwarden/server.git
synced 2025-06-30 23:52:50 -05:00
Key Connector feature toggle (#1716)
This commit is contained in:
@ -32,6 +32,7 @@ namespace Bit.Admin.Models
|
||||
MaxCollections = org.MaxCollections;
|
||||
UsePolicies = org.UsePolicies;
|
||||
UseSso = org.UseSso;
|
||||
UseKeyConnector = org.UseKeyConnector;
|
||||
UseGroups = org.UseGroups;
|
||||
UseDirectory = org.UseDirectory;
|
||||
UseEvents = org.UseEvents;
|
||||
@ -78,6 +79,8 @@ namespace Bit.Admin.Models
|
||||
public bool UsePolicies { get; set; }
|
||||
[Display(Name = "SSO")]
|
||||
public bool UseSso { get; set; }
|
||||
[Display(Name = "Key Connector with Customer Encryption")]
|
||||
public bool UseKeyConnector { get; set; }
|
||||
[Display(Name = "Groups")]
|
||||
public bool UseGroups { get; set; }
|
||||
[Display(Name = "Directory")]
|
||||
@ -123,6 +126,7 @@ namespace Bit.Admin.Models
|
||||
existingOrganization.MaxCollections = MaxCollections;
|
||||
existingOrganization.UsePolicies = UsePolicies;
|
||||
existingOrganization.UseSso = UseSso;
|
||||
existingOrganization.UseKeyConnector = UseKeyConnector;
|
||||
existingOrganization.UseGroups = UseGroups;
|
||||
existingOrganization.UseDirectory = UseDirectory;
|
||||
existingOrganization.UseEvents = UseEvents;
|
||||
|
@ -215,6 +215,10 @@
|
||||
<input type="checkbox" class="form-check-input" asp-for="UseSso">
|
||||
<label class="form-check-label" asp-for="UseSso"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" asp-for="UseKeyConnector">
|
||||
<label class="form-check-label" asp-for="UseKeyConnector"></label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" asp-for="UseDirectory">
|
||||
<label class="form-check-label" asp-for="UseDirectory"></label>
|
||||
|
@ -385,7 +385,7 @@ namespace Bit.Api.Controllers
|
||||
}
|
||||
|
||||
var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(orgGuidId);
|
||||
if (ssoConfig?.GetData()?.UseKeyConnector == true)
|
||||
if (ssoConfig?.GetData()?.KeyConnectorEnabled == true)
|
||||
{
|
||||
throw new BadRequestException("You cannot leave an Organization that is using Key Connector.");
|
||||
}
|
||||
@ -648,7 +648,7 @@ namespace Bit.Api.Controllers
|
||||
var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(id);
|
||||
ssoConfig = ssoConfig == null ? model.ToSsoConfig(id) : model.ToSsoConfig(ssoConfig);
|
||||
|
||||
await _ssoConfigService.SaveAsync(ssoConfig);
|
||||
await _ssoConfigService.SaveAsync(ssoConfig, organization);
|
||||
|
||||
return new OrganizationSsoResponseModel(organization, _globalSettings, ssoConfig);
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ namespace Bit.Core.IdentityServer
|
||||
var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(organizationId);
|
||||
var ssoConfigData = ssoConfig.GetData();
|
||||
|
||||
if (ssoConfigData is { UseKeyConnector: true } && !string.IsNullOrEmpty(ssoConfigData.KeyConnectorUrl))
|
||||
if (ssoConfigData is { KeyConnectorEnabled: true } && !string.IsNullOrEmpty(ssoConfigData.KeyConnectorUrl))
|
||||
{
|
||||
context.Result.CustomResponse["KeyConnectorUrl"] = ssoConfigData.KeyConnectorUrl;
|
||||
// Prevent clients redirecting to set-password
|
||||
|
@ -42,7 +42,7 @@ namespace Bit.Core.Models.Api
|
||||
[Required]
|
||||
public SsoType ConfigType { get; set; }
|
||||
|
||||
public bool UseKeyConnector { get; set; }
|
||||
public bool KeyConnectorEnabled { get; set; }
|
||||
public string KeyConnectorUrl { get; set; }
|
||||
|
||||
// OIDC
|
||||
@ -178,7 +178,7 @@ namespace Bit.Core.Models.Api
|
||||
return new SsoConfigurationData
|
||||
{
|
||||
ConfigType = ConfigType,
|
||||
UseKeyConnector = UseKeyConnector,
|
||||
KeyConnectorEnabled = KeyConnectorEnabled,
|
||||
KeyConnectorUrl = KeyConnectorUrl,
|
||||
Authority = Authority,
|
||||
ClientId = ClientId,
|
||||
|
@ -35,6 +35,7 @@ namespace Bit.Core.Models.Api
|
||||
MaxStorageGb = organization.MaxStorageGb;
|
||||
UsePolicies = organization.UsePolicies;
|
||||
UseSso = organization.UseSso;
|
||||
UseKeyConnector = organization.UseKeyConnector;
|
||||
UseGroups = organization.UseGroups;
|
||||
UseDirectory = organization.UseDirectory;
|
||||
UseEvents = organization.UseEvents;
|
||||
@ -65,6 +66,7 @@ namespace Bit.Core.Models.Api
|
||||
public short? MaxStorageGb { get; set; }
|
||||
public bool UsePolicies { get; set; }
|
||||
public bool UseSso { get; set; }
|
||||
public bool UseKeyConnector { get; set; }
|
||||
public bool UseGroups { get; set; }
|
||||
public bool UseDirectory { get; set; }
|
||||
public bool UseEvents { get; set; }
|
||||
|
@ -14,6 +14,7 @@ namespace Bit.Core.Models.Api
|
||||
Name = organization.Name;
|
||||
UsePolicies = organization.UsePolicies;
|
||||
UseSso = organization.UseSso;
|
||||
UseKeyConnector = organization.UseKeyConnector;
|
||||
UseGroups = organization.UseGroups;
|
||||
UseDirectory = organization.UseDirectory;
|
||||
UseEvents = organization.UseEvents;
|
||||
@ -41,7 +42,7 @@ namespace Bit.Core.Models.Api
|
||||
if (organization.SsoConfig != null)
|
||||
{
|
||||
var ssoConfigData = SsoConfigurationData.Deserialize(organization.SsoConfig);
|
||||
UsesKeyConnector = ssoConfigData.UseKeyConnector && !string.IsNullOrEmpty(ssoConfigData.KeyConnectorUrl);
|
||||
KeyConnectorEnabled = ssoConfigData.KeyConnectorEnabled && !string.IsNullOrEmpty(ssoConfigData.KeyConnectorUrl);
|
||||
KeyConnectorUrl = ssoConfigData.KeyConnectorUrl;
|
||||
}
|
||||
}
|
||||
@ -50,6 +51,7 @@ namespace Bit.Core.Models.Api
|
||||
public string Name { get; set; }
|
||||
public bool UsePolicies { get; set; }
|
||||
public bool UseSso { get; set; }
|
||||
public bool UseKeyConnector { get; set; }
|
||||
public bool UseGroups { get; set; }
|
||||
public bool UseDirectory { get; set; }
|
||||
public bool UseEvents { get; set; }
|
||||
@ -74,7 +76,7 @@ namespace Bit.Core.Models.Api
|
||||
public bool HasPublicAndPrivateKeys { get; set; }
|
||||
public string ProviderId { get; set; }
|
||||
public string ProviderName { get; set; }
|
||||
public bool UsesKeyConnector { get; set; }
|
||||
public bool KeyConnectorEnabled { get; set; }
|
||||
public string KeyConnectorUrl { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ namespace Bit.Core.Models.Api
|
||||
Name = organization.Name;
|
||||
UsePolicies = organization.UsePolicies;
|
||||
UseSso = organization.UseSso;
|
||||
UseKeyConnector = organization.UseKeyConnector;
|
||||
UseGroups = organization.UseGroups;
|
||||
UseDirectory = organization.UseDirectory;
|
||||
UseEvents = organization.UseEvents;
|
||||
|
@ -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(7); // TODO: bump to version 8
|
||||
Version = version.GetValueOrDefault(CURRENT_LICENSE_FILE_VERSION); // TODO: Remember to change the constant
|
||||
LicenseKey = org.LicenseKey;
|
||||
InstallationId = installationId;
|
||||
Id = org.Id;
|
||||
@ -34,6 +34,7 @@ namespace Bit.Core.Models.Business
|
||||
MaxCollections = org.MaxCollections;
|
||||
UsePolicies = org.UsePolicies;
|
||||
UseSso = org.UseSso;
|
||||
UseKeyConnector = org.UseKeyConnector;
|
||||
UseGroups = org.UseGroups;
|
||||
UseEvents = org.UseEvents;
|
||||
UseDirectory = org.UseDirectory;
|
||||
@ -104,6 +105,7 @@ namespace Bit.Core.Models.Business
|
||||
public short? MaxCollections { get; set; }
|
||||
public bool UsePolicies { get; set; }
|
||||
public bool UseSso { get; set; }
|
||||
public bool UseKeyConnector { get; set; }
|
||||
public bool UseGroups { get; set; }
|
||||
public bool UseEvents { get; set; }
|
||||
public bool UseDirectory { get; set; }
|
||||
@ -124,10 +126,19 @@ namespace Bit.Core.Models.Business
|
||||
[JsonIgnore]
|
||||
public byte[] SignatureBytes => Convert.FromBase64String(Signature);
|
||||
|
||||
/// <summary>
|
||||
/// Represents the current version of the license format. Should be updated whenever new fields are added.
|
||||
/// </summary>
|
||||
private const int CURRENT_LICENSE_FILE_VERSION = 8;
|
||||
private bool ValidLicenseVersion
|
||||
{
|
||||
get => Version is >= 1 and <= 9;
|
||||
}
|
||||
|
||||
public byte[] GetDataBytes(bool forHash = false)
|
||||
{
|
||||
string data = null;
|
||||
if (Version >= 1 && Version <= 8)
|
||||
if (ValidLicenseVersion)
|
||||
{
|
||||
var props = typeof(OrganizationLicense)
|
||||
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
||||
@ -148,6 +159,8 @@ namespace Bit.Core.Models.Business
|
||||
(Version >= 7 || !p.Name.Equals(nameof(UseSso))) &&
|
||||
// UseResetPassword was added in Version 8
|
||||
(Version >= 8 || !p.Name.Equals(nameof(UseResetPassword))) &&
|
||||
// UseKeyConnector was added in Version 9
|
||||
(Version >= 9 || !p.Name.Equals(nameof(UseKeyConnector))) &&
|
||||
(
|
||||
!forHash ||
|
||||
(
|
||||
@ -184,7 +197,7 @@ namespace Bit.Core.Models.Business
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Version >= 1 && Version <= 8)
|
||||
if (ValidLicenseVersion)
|
||||
{
|
||||
return InstallationId == globalSettings.Installation.Id && SelfHost;
|
||||
}
|
||||
@ -201,7 +214,7 @@ namespace Bit.Core.Models.Business
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Version >= 1 && Version <= 8)
|
||||
if (ValidLicenseVersion)
|
||||
{
|
||||
var valid =
|
||||
globalSettings.Installation.Id == InstallationId &&
|
||||
@ -245,12 +258,17 @@ namespace Bit.Core.Models.Business
|
||||
{
|
||||
valid = organization.UseSso == UseSso;
|
||||
}
|
||||
|
||||
|
||||
if (valid && Version >= 8)
|
||||
{
|
||||
valid = organization.UseResetPassword == UseResetPassword;
|
||||
}
|
||||
|
||||
if (valid && Version >= 9)
|
||||
{
|
||||
valid = organization.UseKeyConnector == UseKeyConnector;
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
else
|
||||
|
@ -17,6 +17,7 @@ namespace Bit.Core.Models.Data
|
||||
UsersGetPremium = organization.UsersGetPremium;
|
||||
Enabled = organization.Enabled;
|
||||
UseSso = organization.UseSso;
|
||||
UseKeyConnector = organization.UseKeyConnector;
|
||||
UseResetPassword = organization.UseResetPassword;
|
||||
}
|
||||
|
||||
@ -27,6 +28,7 @@ namespace Bit.Core.Models.Data
|
||||
public bool UsersGetPremium { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public bool UseSso { get; set; }
|
||||
public bool UseKeyConnector { get; set; }
|
||||
public bool UseResetPassword { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ namespace Bit.Core.Models.Data
|
||||
public string Name { get; set; }
|
||||
public bool UsePolicies { get; set; }
|
||||
public bool UseSso { get; set; }
|
||||
public bool UseKeyConnector { get; set; }
|
||||
public bool UseGroups { get; set; }
|
||||
public bool UseDirectory { get; set; }
|
||||
public bool UseEvents { get; set; }
|
||||
|
@ -10,6 +10,7 @@ namespace Bit.Core.Models.Data
|
||||
public string Name { get; set; }
|
||||
public bool UsePolicies { get; set; }
|
||||
public bool UseSso { get; set; }
|
||||
public bool UseKeyConnector { get; set; }
|
||||
public bool UseGroups { get; set; }
|
||||
public bool UseDirectory { get; set; }
|
||||
public bool UseEvents { get; set; }
|
||||
|
@ -27,7 +27,7 @@ namespace Bit.Core.Models.Data
|
||||
|
||||
public SsoType ConfigType { get; set; }
|
||||
|
||||
public bool UseKeyConnector { get; set; }
|
||||
public bool KeyConnectorEnabled { get; set; }
|
||||
public string KeyConnectorUrl { get; set; }
|
||||
|
||||
// OIDC
|
||||
|
@ -33,6 +33,7 @@ namespace Bit.Core.Models.StaticStore
|
||||
public bool Has2fa { get; set; }
|
||||
public bool HasApi { get; set; }
|
||||
public bool HasSso { get; set; }
|
||||
public bool HasKeyConnector { get; set; }
|
||||
public bool HasResetPassword { get; set; }
|
||||
public bool UsersGetPremium { get; set; }
|
||||
|
||||
|
@ -38,6 +38,7 @@ namespace Bit.Core.Models.Table
|
||||
public short? MaxCollections { get; set; }
|
||||
public bool UsePolicies { get; set; }
|
||||
public bool UseSso { get; set; }
|
||||
public bool UseKeyConnector { get; set; }
|
||||
public bool UseGroups { get; set; }
|
||||
public bool UseDirectory { get; set; }
|
||||
public bool UseEvents { get; set; }
|
||||
|
@ -87,6 +87,7 @@ namespace Bit.Core.Repositories.EntityFramework
|
||||
UsersGetPremium = e.UsersGetPremium,
|
||||
Using2fa = e.Use2fa && e.TwoFactorProviders != null,
|
||||
UseSso = e.UseSso,
|
||||
UseKeyConnector = e.UseKeyConnector,
|
||||
}).ToListAsync();
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ namespace Bit.Core.Repositories.EntityFramework.Queries
|
||||
Enabled = x.o.Enabled,
|
||||
UsePolicies = x.o.UsePolicies,
|
||||
UseSso = x.o.UseSso,
|
||||
UseKeyConnector = x.o.UseKeyConnector,
|
||||
UseGroups = x.o.UseGroups,
|
||||
UseDirectory = x.o.UseDirectory,
|
||||
UseEvents = x.o.UseEvents,
|
||||
|
@ -21,6 +21,7 @@ namespace Bit.Core.Repositories.EntityFramework.Queries
|
||||
Enabled = x.o.Enabled,
|
||||
UsePolicies = x.o.UsePolicies,
|
||||
UseSso = x.o.UseSso,
|
||||
UseKeyConnector = x.o.UseKeyConnector,
|
||||
UseGroups = x.o.UseGroups,
|
||||
UseDirectory = x.o.UseDirectory,
|
||||
UseEvents = x.o.UseEvents,
|
||||
|
@ -5,6 +5,6 @@ namespace Bit.Core.Services
|
||||
{
|
||||
public interface ISsoConfigService
|
||||
{
|
||||
Task SaveAsync(SsoConfig config);
|
||||
Task SaveAsync(SsoConfig config, Organization organization);
|
||||
}
|
||||
}
|
||||
|
@ -247,6 +247,16 @@ namespace Bit.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
if (!newPlan.HasKeyConnector && organization.UseKeyConnector)
|
||||
{
|
||||
var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(organization.Id);
|
||||
if (ssoConfig != null && ssoConfig.GetData().KeyConnectorEnabled)
|
||||
{
|
||||
throw new BadRequestException("Your new plan does not allow the Key Connector feature. " +
|
||||
"Disable your Key Connector.");
|
||||
}
|
||||
}
|
||||
|
||||
if (!newPlan.HasResetPassword && organization.UseResetPassword)
|
||||
{
|
||||
var resetPasswordPolicy =
|
||||
@ -295,6 +305,7 @@ namespace Bit.Core.Services
|
||||
organization.Use2fa = newPlan.Has2fa;
|
||||
organization.UseApi = newPlan.HasApi;
|
||||
organization.UseSso = newPlan.HasSso;
|
||||
organization.UseKeyConnector = newPlan.HasKeyConnector;
|
||||
organization.UseResetPassword = newPlan.HasResetPassword;
|
||||
organization.SelfHost = newPlan.HasSelfHost;
|
||||
organization.UsersGetPremium = newPlan.UsersGetPremium || upgrade.PremiumAccessAddon;
|
||||
@ -687,6 +698,7 @@ namespace Bit.Core.Services
|
||||
MaxStorageGb = _globalSettings.SelfHosted ? 10240 : license.MaxStorageGb, // 10 TB
|
||||
UsePolicies = license.UsePolicies,
|
||||
UseSso = license.UseSso,
|
||||
UseKeyConnector = license.UseKeyConnector,
|
||||
UseGroups = license.UseGroups,
|
||||
UseDirectory = license.UseDirectory,
|
||||
UseEvents = license.UseEvents,
|
||||
@ -865,6 +877,16 @@ namespace Bit.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
if (!license.UseKeyConnector && organization.UseKeyConnector)
|
||||
{
|
||||
var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(organization.Id);
|
||||
if (ssoConfig != null && ssoConfig.GetData().KeyConnectorEnabled)
|
||||
{
|
||||
throw new BadRequestException($"Your organization currently has Key Connector enabled. " +
|
||||
$"Your new license does not allow for the use of Key Connector. Disable your Key Connector.");
|
||||
}
|
||||
}
|
||||
|
||||
if (!license.UseResetPassword && organization.UseResetPassword)
|
||||
{
|
||||
var resetPasswordPolicy =
|
||||
@ -895,6 +917,7 @@ namespace Bit.Core.Services
|
||||
organization.UseApi = license.UseApi;
|
||||
organization.UsePolicies = license.UsePolicies;
|
||||
organization.UseSso = license.UseSso;
|
||||
organization.UseKeyConnector = license.UseKeyConnector;
|
||||
organization.UseResetPassword = license.UseResetPassword;
|
||||
organization.SelfHost = license.SelfHost;
|
||||
organization.UsersGetPremium = license.UsersGetPremium;
|
||||
@ -2141,7 +2164,7 @@ namespace Bit.Core.Services
|
||||
private async Task ValidateDeleteOrganizationAsync(Organization organization)
|
||||
{
|
||||
var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(organization.Id);
|
||||
if (ssoConfig?.GetData()?.UseKeyConnector == true)
|
||||
if (ssoConfig?.GetData()?.KeyConnectorEnabled == true)
|
||||
{
|
||||
throw new BadRequestException("You cannot delete an Organization that is using Key Connector.");
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
|
||||
var ssoConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(org.Id);
|
||||
if (ssoConfig?.GetData()?.UseKeyConnector == true)
|
||||
if (ssoConfig?.GetData()?.KeyConnectorEnabled == true)
|
||||
{
|
||||
throw new BadRequestException("Key Connector is enabled.");
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ namespace Bit.Core.Services
|
||||
_eventService = eventService;
|
||||
}
|
||||
|
||||
public async Task SaveAsync(SsoConfig config)
|
||||
public async Task SaveAsync(SsoConfig config, Organization organization)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
config.RevisionDate = now;
|
||||
@ -39,14 +39,14 @@ namespace Bit.Core.Services
|
||||
config.CreationDate = now;
|
||||
}
|
||||
|
||||
var useKeyConnector = config.GetData().UseKeyConnector;
|
||||
var useKeyConnector = config.GetData().KeyConnectorEnabled;
|
||||
if (useKeyConnector)
|
||||
{
|
||||
await VerifyDependenciesAsync(config);
|
||||
await VerifyDependenciesAsync(config, organization);
|
||||
}
|
||||
|
||||
var oldConfig = await _ssoConfigRepository.GetByOrganizationIdAsync(config.OrganizationId);
|
||||
var disabledKeyConnector = oldConfig?.GetData()?.UseKeyConnector == true && !useKeyConnector;
|
||||
var disabledKeyConnector = oldConfig?.GetData()?.KeyConnectorEnabled == true && !useKeyConnector;
|
||||
if (disabledKeyConnector && await AnyOrgUserHasKeyConnectorEnabledAsync(config.OrganizationId))
|
||||
{
|
||||
throw new BadRequestException("Key Connector cannot be disabled at this moment.");
|
||||
@ -63,8 +63,13 @@ namespace Bit.Core.Services
|
||||
return userDetails.Any(u => u.UsesKeyConnector);
|
||||
}
|
||||
|
||||
private async Task VerifyDependenciesAsync(SsoConfig config)
|
||||
private async Task VerifyDependenciesAsync(SsoConfig config, Organization organization)
|
||||
{
|
||||
if (!organization.UseKeyConnector)
|
||||
{
|
||||
throw new BadRequestException("Organization cannot use Key Connector.");
|
||||
}
|
||||
|
||||
var singleOrgPolicy = await _policyRepository.GetByOrganizationIdTypeAsync(config.OrganizationId, PolicyType.SingleOrg);
|
||||
if (singleOrgPolicy is not { Enabled: true })
|
||||
{
|
||||
@ -91,10 +96,10 @@ namespace Bit.Core.Services
|
||||
await _eventService.LogOrganizationEventAsync(organization, e);
|
||||
}
|
||||
|
||||
var useKeyConnector = config.GetData().UseKeyConnector;
|
||||
if (oldConfig?.GetData()?.UseKeyConnector != useKeyConnector)
|
||||
var keyConnectorEnabled = config.GetData().KeyConnectorEnabled;
|
||||
if (oldConfig?.GetData()?.KeyConnectorEnabled != keyConnectorEnabled)
|
||||
{
|
||||
var e = useKeyConnector
|
||||
var e = keyConnectorEnabled
|
||||
? EventType.Organization_EnabledKeyConnector
|
||||
: EventType.Organization_DisabledKeyConnector;
|
||||
await _eventService.LogOrganizationEventAsync(organization, e);
|
||||
|
@ -646,7 +646,7 @@ namespace Bit.Core.Services
|
||||
|
||||
if (user.UsesKeyConnector)
|
||||
{
|
||||
Logger.LogWarning("Already uses key connector.");
|
||||
Logger.LogWarning("Already uses Key Connector.");
|
||||
return IdentityResult.Failed(_identityErrorDescriber.UserAlreadyHasPassword());
|
||||
}
|
||||
|
||||
@ -671,7 +671,7 @@ namespace Bit.Core.Services
|
||||
|
||||
if (user.UsesKeyConnector)
|
||||
{
|
||||
Logger.LogWarning("Already uses key connector.");
|
||||
Logger.LogWarning("Already uses Key Connector.");
|
||||
return IdentityResult.Failed(_identityErrorDescriber.UserAlreadyHasPassword());
|
||||
}
|
||||
|
||||
@ -740,7 +740,7 @@ namespace Bit.Core.Services
|
||||
|
||||
if (user.UsesKeyConnector)
|
||||
{
|
||||
throw new BadRequestException("Cannot reset password of a user with key connector.");
|
||||
throw new BadRequestException("Cannot reset password of a user with Key Connector.");
|
||||
}
|
||||
|
||||
var result = await UpdatePasswordHash(user, newMasterPassword);
|
||||
@ -1387,7 +1387,7 @@ namespace Bit.Core.Services
|
||||
|
||||
if (!user.UsesKeyConnector)
|
||||
{
|
||||
throw new BadRequestException("Not using key connector.");
|
||||
throw new BadRequestException("Not using Key Connector.");
|
||||
}
|
||||
|
||||
var token = await base.GenerateUserTokenAsync(user, TokenOptions.DefaultEmailProvider,
|
||||
|
@ -410,6 +410,7 @@ namespace Bit.Core.Utilities
|
||||
Has2fa = true,
|
||||
HasApi = true,
|
||||
HasSso = true,
|
||||
HasKeyConnector = true,
|
||||
HasResetPassword = true,
|
||||
UsersGetPremium = true,
|
||||
|
||||
@ -448,6 +449,7 @@ namespace Bit.Core.Utilities
|
||||
HasApi = true,
|
||||
HasSelfHost = true,
|
||||
HasSso = true,
|
||||
HasKeyConnector = true,
|
||||
HasResetPassword = true,
|
||||
UsersGetPremium = true,
|
||||
|
||||
|
@ -40,7 +40,8 @@
|
||||
@CreationDate DATETIME2(7),
|
||||
@RevisionDate DATETIME2(7),
|
||||
@OwnersNotifiedOfAutoscaling DATETIME2(7),
|
||||
@MaxAutoscaleSeats INT
|
||||
@MaxAutoscaleSeats INT,
|
||||
@UseKeyConnector BIT = 0
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
@ -88,7 +89,8 @@ BEGIN
|
||||
[CreationDate],
|
||||
[RevisionDate],
|
||||
[OwnersNotifiedOfAutoscaling],
|
||||
[MaxAutoscaleSeats]
|
||||
[MaxAutoscaleSeats],
|
||||
[UseKeyConnector]
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
@ -133,6 +135,7 @@ BEGIN
|
||||
@CreationDate,
|
||||
@RevisionDate,
|
||||
@OwnersNotifiedOfAutoscaling,
|
||||
@MaxAutoscaleSeats
|
||||
@MaxAutoscaleSeats,
|
||||
@UseKeyConnector
|
||||
)
|
||||
END
|
||||
|
@ -15,6 +15,7 @@ BEGIN
|
||||
END AS [Using2fa],
|
||||
[UsersGetPremium],
|
||||
[UseSso],
|
||||
[UseKeyConnector],
|
||||
[UseResetPassword],
|
||||
[Enabled]
|
||||
FROM
|
||||
|
@ -40,7 +40,8 @@
|
||||
@CreationDate DATETIME2(7),
|
||||
@RevisionDate DATETIME2(7),
|
||||
@OwnersNotifiedOfAutoscaling DATETIME2(7),
|
||||
@MaxAutoscaleSeats INT
|
||||
@MaxAutoscaleSeats INT,
|
||||
@UseKeyConnector BIT = 0
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
@ -88,7 +89,8 @@ BEGIN
|
||||
[CreationDate] = @CreationDate,
|
||||
[RevisionDate] = @RevisionDate,
|
||||
[OwnersNotifiedOfAutoscaling] = @OwnersNotifiedOfAutoscaling,
|
||||
[MaxAutoscaleSeats] = @MaxAutoscaleSeats
|
||||
[MaxAutoscaleSeats] = @MaxAutoscaleSeats,
|
||||
[UseKeyConnector] = @UseKeyConnector
|
||||
WHERE
|
||||
[Id] = @Id
|
||||
END
|
||||
|
@ -41,6 +41,7 @@
|
||||
[RevisionDate] DATETIME2 (7) NOT NULL,
|
||||
[OwnersNotifiedOfAutoscaling] DATETIME2(7) NULL,
|
||||
[MaxAutoscaleSeats] INT NULL,
|
||||
[UseKeyConnector] BIT NOT NULL,
|
||||
CONSTRAINT [PK_Organization] PRIMARY KEY CLUSTERED ([Id] ASC)
|
||||
);
|
||||
|
||||
|
@ -7,6 +7,7 @@ SELECT
|
||||
O.[Enabled],
|
||||
O.[UsePolicies],
|
||||
O.[UseSso],
|
||||
O.[UseKeyConnector],
|
||||
O.[UseGroups],
|
||||
O.[UseDirectory],
|
||||
O.[UseEvents],
|
||||
|
@ -7,6 +7,7 @@ SELECT
|
||||
O.[Enabled],
|
||||
O.[UsePolicies],
|
||||
O.[UseSso],
|
||||
O.[UseKeyConnector],
|
||||
O.[UseGroups],
|
||||
O.[UseDirectory],
|
||||
O.[UseEvents],
|
||||
|
Reference in New Issue
Block a user