From 69529d394b07c28619513e0d2ee849f786eef252 Mon Sep 17 00:00:00 2001 From: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> Date: Mon, 16 Oct 2023 15:47:12 -0500 Subject: [PATCH] [SM-891] Include Secrets Manager in organization license for self-hosting (#3222) * Remove self-hosted restrictions from SM endpoints * Add SM properties to organization license --- .../Controllers/AccessPoliciesController.cs | 2 -- .../Controllers/ProjectsController.cs | 2 -- .../Controllers/SecretsController.cs | 2 -- .../SecretsManagerPortingController.cs | 2 -- .../Controllers/SecretsTrashController.cs | 2 -- .../Controllers/ServiceAccountsController.cs | 2 -- src/Core/Entities/Organization.cs | 4 ++++ .../Models/Business/OrganizationLicense.cs | 22 +++++++++++++++++-- .../Implementations/OrganizationService.cs | 6 ++++- 9 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/Api/SecretsManager/Controllers/AccessPoliciesController.cs b/src/Api/SecretsManager/Controllers/AccessPoliciesController.cs index 64dacfa0a..3e07d505d 100644 --- a/src/Api/SecretsManager/Controllers/AccessPoliciesController.cs +++ b/src/Api/SecretsManager/Controllers/AccessPoliciesController.cs @@ -10,14 +10,12 @@ using Bit.Core.SecretsManager.Commands.AccessPolicies.Interfaces; using Bit.Core.SecretsManager.Entities; using Bit.Core.SecretsManager.Repositories; using Bit.Core.Services; -using Bit.Core.Utilities; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Bit.Api.SecretsManager.Controllers; [Authorize("secrets")] -[SelfHosted(NotSelfHostedOnly = true)] [Route("access-policies")] public class AccessPoliciesController : Controller { diff --git a/src/Api/SecretsManager/Controllers/ProjectsController.cs b/src/Api/SecretsManager/Controllers/ProjectsController.cs index e59918593..a436e9601 100644 --- a/src/Api/SecretsManager/Controllers/ProjectsController.cs +++ b/src/Api/SecretsManager/Controllers/ProjectsController.cs @@ -10,14 +10,12 @@ using Bit.Core.SecretsManager.Entities; using Bit.Core.SecretsManager.Queries.Projects.Interfaces; using Bit.Core.SecretsManager.Repositories; using Bit.Core.Services; -using Bit.Core.Utilities; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Bit.Api.SecretsManager.Controllers; [Authorize("secrets")] -[SelfHosted(NotSelfHostedOnly = true)] public class ProjectsController : Controller { private readonly ICurrentContext _currentContext; diff --git a/src/Api/SecretsManager/Controllers/SecretsController.cs b/src/Api/SecretsManager/Controllers/SecretsController.cs index a88a784be..d8e09fe17 100644 --- a/src/Api/SecretsManager/Controllers/SecretsController.cs +++ b/src/Api/SecretsManager/Controllers/SecretsController.cs @@ -14,14 +14,12 @@ using Bit.Core.Services; using Bit.Core.Tools.Enums; using Bit.Core.Tools.Models.Business; using Bit.Core.Tools.Services; -using Bit.Core.Utilities; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Bit.Api.SecretsManager.Controllers; [Authorize("secrets")] -[SelfHosted(NotSelfHostedOnly = true)] public class SecretsController : Controller { private readonly ICurrentContext _currentContext; diff --git a/src/Api/SecretsManager/Controllers/SecretsManagerPortingController.cs b/src/Api/SecretsManager/Controllers/SecretsManagerPortingController.cs index 3d26c8f70..19ef56e56 100644 --- a/src/Api/SecretsManager/Controllers/SecretsManagerPortingController.cs +++ b/src/Api/SecretsManager/Controllers/SecretsManagerPortingController.cs @@ -7,14 +7,12 @@ using Bit.Core.SecretsManager.Commands.Porting.Interfaces; using Bit.Core.SecretsManager.Queries.Projects.Interfaces; using Bit.Core.SecretsManager.Repositories; using Bit.Core.Services; -using Bit.Core.Utilities; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Bit.Api.SecretsManager.Controllers; [Authorize("secrets")] -[SelfHosted(NotSelfHostedOnly = true)] public class SecretsManagerPortingController : Controller { private readonly ISecretRepository _secretRepository; diff --git a/src/Api/SecretsManager/Controllers/SecretsTrashController.cs b/src/Api/SecretsManager/Controllers/SecretsTrashController.cs index aaaebf5fe..1bf9d3135 100644 --- a/src/Api/SecretsManager/Controllers/SecretsTrashController.cs +++ b/src/Api/SecretsManager/Controllers/SecretsTrashController.cs @@ -3,14 +3,12 @@ using Bit.Core.Context; using Bit.Core.Exceptions; using Bit.Core.SecretsManager.Commands.Trash.Interfaces; using Bit.Core.SecretsManager.Repositories; -using Bit.Core.Utilities; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Bit.Api.SecretsManager.Controllers; [Authorize("secrets")] -[SelfHosted(NotSelfHostedOnly = true)] public class TrashController : Controller { private readonly ICurrentContext _currentContext; diff --git a/src/Api/SecretsManager/Controllers/ServiceAccountsController.cs b/src/Api/SecretsManager/Controllers/ServiceAccountsController.cs index bb28276b0..28fb96710 100644 --- a/src/Api/SecretsManager/Controllers/ServiceAccountsController.cs +++ b/src/Api/SecretsManager/Controllers/ServiceAccountsController.cs @@ -14,14 +14,12 @@ using Bit.Core.SecretsManager.Entities; using Bit.Core.SecretsManager.Queries.ServiceAccounts.Interfaces; using Bit.Core.SecretsManager.Repositories; using Bit.Core.Services; -using Bit.Core.Utilities; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Bit.Api.SecretsManager.Controllers; [Authorize("secrets")] -[SelfHosted(NotSelfHostedOnly = true)] [Route("service-accounts")] public class ServiceAccountsController : Controller { diff --git a/src/Core/Entities/Organization.cs b/src/Core/Entities/Organization.cs index fc76b399c..7deab3299 100644 --- a/src/Core/Entities/Organization.cs +++ b/src/Core/Entities/Organization.cs @@ -250,5 +250,9 @@ public class Organization : ITableObject, ISubscriber, IStorable, IStorabl ExpirationDate = license.Expires; LicenseKey = license.LicenseKey; RevisionDate = DateTime.UtcNow; + UsePasswordManager = license.UsePasswordManager; + UseSecretsManager = license.UseSecretsManager; + SmSeats = license.SmSeats; + SmServiceAccounts = license.SmServiceAccounts; } } diff --git a/src/Core/Models/Business/OrganizationLicense.cs b/src/Core/Models/Business/OrganizationLicense.cs index c72430d94..c8060263c 100644 --- a/src/Core/Models/Business/OrganizationLicense.cs +++ b/src/Core/Models/Business/OrganizationLicense.cs @@ -47,6 +47,10 @@ public class OrganizationLicense : ILicense UsersGetPremium = org.UsersGetPremium; UseCustomPermissions = org.UseCustomPermissions; Issued = DateTime.UtcNow; + UsePasswordManager = org.UsePasswordManager; + UseSecretsManager = org.UseSecretsManager; + SmSeats = org.SmSeats; + SmServiceAccounts = org.SmServiceAccounts; if (subscriptionInfo?.Subscription == null) { @@ -125,6 +129,10 @@ public class OrganizationLicense : ILicense public DateTime? Refresh { get; set; } public DateTime? Expires { get; set; } public DateTime? ExpirationWithoutGracePeriod { get; set; } + public bool UsePasswordManager { get; set; } + public bool UseSecretsManager { get; set; } + public int? SmSeats { get; set; } + public int? SmServiceAccounts { get; set; } public bool Trial { get; set; } public LicenseType? LicenseType { get; set; } public string Hash { get; set; } @@ -137,10 +145,10 @@ public class OrganizationLicense : ILicense /// /// Intentionally set one version behind to allow self hosted users some time to update before /// getting out of date license errors - private const int CURRENT_LICENSE_FILE_VERSION = 11; + private const int CURRENT_LICENSE_FILE_VERSION = 12; private bool ValidLicenseVersion { - get => Version is >= 1 and <= 12; + get => Version is >= 1 and <= 13; } public byte[] GetDataBytes(bool forHash = false) @@ -176,6 +184,8 @@ public class OrganizationLicense : ILicense (Version >= 11 || !p.Name.Equals(nameof(UseCustomPermissions))) && // ExpirationWithoutGracePeriod was added in Version 12 (Version >= 12 || !p.Name.Equals(nameof(ExpirationWithoutGracePeriod))) && + // UseSecretsManager was added in Version 13 + (Version >= 13 || !p.Name.Equals(nameof(UseSecretsManager))) && ( !forHash || ( @@ -315,6 +325,14 @@ public class OrganizationLicense : ILicense valid = organization.UseCustomPermissions == UseCustomPermissions; } + if (valid && Version >= 13) + { + valid = organization.UseSecretsManager == UseSecretsManager && + organization.UsePasswordManager == UsePasswordManager && + organization.SmSeats == SmSeats && + organization.SmServiceAccounts == SmServiceAccounts; + } + return valid; } else diff --git a/src/Core/Services/Implementations/OrganizationService.cs b/src/Core/Services/Implementations/OrganizationService.cs index 2388faded..e8be0ff03 100644 --- a/src/Core/Services/Implementations/OrganizationService.cs +++ b/src/Core/Services/Implementations/OrganizationService.cs @@ -573,7 +573,11 @@ public class OrganizationService : IOrganizationService PrivateKey = privateKey, CreationDate = DateTime.UtcNow, RevisionDate = DateTime.UtcNow, - Status = OrganizationStatusType.Created + Status = OrganizationStatusType.Created, + UsePasswordManager = license.UsePasswordManager, + UseSecretsManager = license.UseSecretsManager, + SmSeats = license.SmSeats, + SmServiceAccounts = license.SmServiceAccounts }; var result = await SignUpAsync(organization, owner.Id, ownerKey, collectionName, false);