Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AC-1449] Secrets Manager subscription Stripe Integration #72

Open
wants to merge 41 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
4c68a03
Adding the Secret manager to the Plan List
cyprain-okeke May 16, 2023
eeca1d5
Adding the unit test for the StaticStoreTests class
cyprain-okeke May 17, 2023
d00934c
Fix whitespace formatting
cyprain-okeke May 17, 2023
52f44be
Fix whitespace formatting
cyprain-okeke May 17, 2023
0bd73e6
Price update
cyprain-okeke May 18, 2023
b8b0bf1
Merge branch 'master' into ac-1408/update_plan_to_include_secrets_man…
cyprain-okeke May 18, 2023
169809b
Resolving the PR comments
cyprain-okeke May 19, 2023
9722ae5
Resolving PR comments
cyprain-okeke May 19, 2023
de0d0dd
Fixing the whitespace
cyprain-okeke May 19, 2023
c5b0e58
only password manager plans are return for now
cyprain-okeke May 19, 2023
06cfa66
format whitespace
cyprain-okeke May 19, 2023
110ee1d
Resolve the test issue
cyprain-okeke May 19, 2023
cc695b2
Fixing the failing test
cyprain-okeke May 19, 2023
ca38d32
Refactoring the Plan separation
cyprain-okeke May 23, 2023
8a00550
add a unit test for SingleOrDefault
cyprain-okeke May 23, 2023
ae3fa3c
Merge branch 'master' into ac-1408/update_plan_to_include_secrets_man…
cyprain-okeke May 23, 2023
43bb9d2
Fix the whitespace format
cyprain-okeke May 23, 2023
2b5c9a1
Separate the PM and SM plans
cyprain-okeke May 23, 2023
9ae74a1
Fixing the whitespace
cyprain-okeke May 23, 2023
c6e821c
Remove unnecessary directive
cyprain-okeke May 23, 2023
cbfd49c
Fix imports ordering
cyprain-okeke May 23, 2023
10cc837
Fix imports ordering
cyprain-okeke May 23, 2023
a607a05
Resolve imports ordering
cyprain-okeke May 23, 2023
1403d28
Fixing imports ordering
cyprain-okeke May 23, 2023
81a72a4
Merge branch 'master' into ac-1408/update_plan_to_include_secrets_man…
cyprain-okeke Jun 12, 2023
52c1067
Merge branch 'master' into ac-1408/update_plan_to_include_secrets_man…
cyprain-okeke Jun 14, 2023
8413ba9
Changes for the purchase organization
cyprain-okeke Jun 14, 2023
9721826
Changes to include sm to signup
cyprain-okeke Jun 14, 2023
0e13348
changes to add secrets manager on signup
cyprain-okeke Jun 14, 2023
906b0c5
Add the Upgrade Plan changes
cyprain-okeke Jun 14, 2023
15076a3
Add the Upgrade Plan changes
cyprain-okeke Jun 14, 2023
d487a8f
Add store procedure changes
cyprain-okeke Jun 14, 2023
44a7f82
format whitespace
cyprain-okeke Jun 14, 2023
7fcbf9b
Fix using directive is unnecessary
cyprain-okeke Jun 14, 2023
8483484
Fix imports ordering
cyprain-okeke Jun 14, 2023
b8261db
Fix the failing test
cyprain-okeke Jun 14, 2023
c71cb5a
Fix imports ordering on upgrade plan
cyprain-okeke Jun 14, 2023
4f456ac
Fix imports ordering
cyprain-okeke Jun 14, 2023
aa6cdb4
Fix imports ordering
cyprain-okeke Jun 14, 2023
e78e482
Fix imports ordering
cyprain-okeke Jun 14, 2023
cdc2e94
Fix the failed test after dotnet format
cyprain-okeke Jun 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions src/Api/Controllers/OrganizationsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
using Bit.Core.Models.Data.Organizations.Policies;
using Bit.Core.OrganizationFeatures.OrganizationApiKeys.Interfaces;
using Bit.Core.OrganizationFeatures.OrganizationLicenses.Interfaces;
using Bit.Core.OrganizationFeatures.OrganizationPlanUpgrade.Interface;
using Bit.Core.OrganizationFeatures.OrganizationSignUp.Interfaces;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Settings;
Expand Down Expand Up @@ -50,6 +52,8 @@ public class OrganizationsController : Controller
private readonly IFeatureService _featureService;
private readonly GlobalSettings _globalSettings;
private readonly ILicensingService _licensingService;
private readonly IOrganizationSignUpCommand _organizationSignUpCommand;
private readonly IOrganizationUpgradePlanCommand _organizationUpgradePlanCommand;

public OrganizationsController(
IOrganizationRepository organizationRepository,
Expand All @@ -70,7 +74,9 @@ public OrganizationsController(
ICloudGetOrganizationLicenseQuery cloudGetOrganizationLicenseQuery,
IFeatureService featureService,
GlobalSettings globalSettings,
ILicensingService licensingService)
ILicensingService licensingService,
IOrganizationSignUpCommand organizationSignUpCommand,
IOrganizationUpgradePlanCommand organizationUpgradePlanCommand)
{
_organizationRepository = organizationRepository;
_organizationUserRepository = organizationUserRepository;
Expand All @@ -91,6 +97,8 @@ public OrganizationsController(
_featureService = featureService;
_globalSettings = globalSettings;
_licensingService = licensingService;
_organizationSignUpCommand = organizationSignUpCommand;
_organizationUpgradePlanCommand = organizationUpgradePlanCommand;
}

[HttpGet("{id}")]
Expand Down Expand Up @@ -241,7 +249,12 @@ public async Task<OrganizationResponseModel> Post([FromBody] OrganizationCreateR
}

var organizationSignup = model.ToOrganizationSignup(user);
var result = await _organizationService.SignUpAsync(organizationSignup);

var result = !_featureService.IsEnabled(FeatureFlagKeys.SecretManagerGaBilling, _currentContext) &&
!model.UseSecretsManager
? await _organizationService.SignUpAsync(organizationSignup)
: await _organizationSignUpCommand.SignUpAsync(organizationSignup);
Comment on lines +253 to +256
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider extracting this condition into a separate method for better readability and reusability


return new OrganizationResponseModel(result.Item1);
}

Expand Down Expand Up @@ -306,7 +319,11 @@ public async Task<PaymentResponseModel> PostUpgrade(string id, [FromBody] Organi
throw new NotFoundException();
}

var result = await _organizationService.UpgradePlanAsync(orgIdGuid, model.ToOrganizationUpgrade());
var result = !_featureService.IsEnabled(FeatureFlagKeys.SecretManagerGaBilling, _currentContext) &&
!model.UseSecretsManager
? await _organizationService.UpgradePlanAsync(orgIdGuid, model.ToOrganizationUpgrade())
: await _organizationUpgradePlanCommand.UpgradePlanAsync(orgIdGuid, model.ToOrganizationUpgrade());
Comment on lines +322 to +325
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: This condition is identical to the one in the Post method. Consider extracting it to avoid duplication


return new PaymentResponseModel { Success = result.Item1, PaymentIntentClientSecret = result.Item2 };
}

Expand Down Expand Up @@ -487,7 +504,7 @@ public async Task<ApiKeyResponseModel> ApiKey(string id, [FromBody] Organization
if (model.Type == OrganizationApiKeyType.BillingSync || model.Type == OrganizationApiKeyType.Scim)
{
// Non-enterprise orgs should not be able to create or view an apikey of billing sync/scim key types
var plan = StaticStore.GetPlan(organization.PlanType);
var plan = StaticStore.GetPasswordManagerPlan(organization.PlanType);
if (plan.Product != ProductType.Enterprise)
{
throw new NotFoundException();
Expand Down
18 changes: 18 additions & 0 deletions src/Api/Controllers/PlansController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,30 @@ public PlansController(ITaxRateRepository taxRateRepository)
[HttpGet("")]
[AllowAnonymous]
public ListResponseModel<PlanResponseModel> Get()
{
var data = StaticStore.PasswordManagerPlans;
var responses = data.Select(plan => new PlanResponseModel(plan));
return new ListResponseModel<PlanResponseModel>(responses);
}
Comment on lines 21 to +26
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: The default Get() method now returns only PasswordManagerPlans instead of all Plans. This change might affect existing clients expecting all plans. Consider adding a comment explaining this change or updating documentation.


[HttpGet("all")]
[AllowAnonymous]
public ListResponseModel<PlanResponseModel> GetAllPlans()
{
var data = StaticStore.Plans;
var responses = data.Select(plan => new PlanResponseModel(plan));
return new ListResponseModel<PlanResponseModel>(responses);
}

[HttpGet("sm-plans")]
[AllowAnonymous]
public ListResponseModel<PlanResponseModel> GetSecretsManagerPlans()
{
var data = StaticStore.SecretManagerPlans;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syntax: SecretManagerPlans is misspelled. It should be SecretsManagerPlans to maintain consistency with the method name.

var responses = data.Select(plan => new PlanResponseModel(plan));
return new ListResponseModel<PlanResponseModel>(responses);
}

[HttpGet("sales-tax-rates")]
public async Task<ListResponseModel<TaxRateResponseModel>> GetTaxRates()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ public class OrganizationCreateRequestModel : IValidatableObject
[StringLength(2)]
public string BillingAddressCountry { get; set; }
public int? MaxAutoscaleSeats { get; set; }
[Range(0, int.MaxValue)]
public int? AdditionalSmSeats { get; set; }
[Range(0, int.MaxValue)]
public int? AdditionalServiceAccount { get; set; }
[Required]
public bool UseSecretsManager { get; set; }

public virtual OrganizationSignup ToOrganizationSignup(User user)
{
Expand All @@ -58,6 +64,9 @@ public virtual OrganizationSignup ToOrganizationSignup(User user)
BillingEmail = BillingEmail,
BusinessName = BusinessName,
CollectionName = CollectionName,
AdditionalSmSeats = AdditionalSmSeats.GetValueOrDefault(0),
AdditionalServiceAccount = AdditionalServiceAccount.GetValueOrDefault(0),
UseSecretsManager = UseSecretsManager,
Comment on lines +67 to +69
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Use null-coalescing operator (??) instead of GetValueOrDefault for consistency with other properties

TaxInfo = new TaxInfo
{
TaxIdNumber = TaxIdNumber,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ public class OrganizationUpgradeRequestModel
public int AdditionalSeats { get; set; }
[Range(0, 99)]
public short? AdditionalStorageGb { get; set; }
[Range(0, int.MaxValue)]
public int? AdditionalSmSeats { get; set; }
[Range(0, int.MaxValue)]
public int? AdditionalServiceAccount { get; set; }
public bool PremiumAccessAddon { get; set; }
[Required]
public bool UseSecretsManager { get; set; }
public string BillingAddressCountry { get; set; }
public string BillingAddressPostalCode { get; set; }
public OrganizationKeysRequestModel Keys { get; set; }
Expand All @@ -24,6 +30,9 @@ public OrganizationUpgrade ToOrganizationUpgrade()
{
AdditionalSeats = AdditionalSeats,
AdditionalStorageGb = AdditionalStorageGb.GetValueOrDefault(),
AdditionalServiceAccount = AdditionalServiceAccount.GetValueOrDefault(0),
AdditionalSmSeats = AdditionalSmSeats.GetValueOrDefault(0),
Comment on lines +33 to +34
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Use null-coalescing operator for consistency: AdditionalServiceAccount ?? 0

UseSecretsManager = UseSecretsManager,
Comment on lines +34 to +35
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Use null-coalescing operator for consistency: AdditionalSmSeats ?? 0

BusinessName = BusinessName,
Plan = PlanType,
PremiumAccessAddon = PremiumAccessAddon,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public OrganizationResponseModel(Organization organization, string obj = "organi
BusinessCountry = organization.BusinessCountry;
BusinessTaxNumber = organization.BusinessTaxNumber;
BillingEmail = organization.BillingEmail;
Plan = new PlanResponseModel(StaticStore.Plans.FirstOrDefault(plan => plan.Type == organization.PlanType));
Plan = new PlanResponseModel(StaticStore.PasswordManagerPlans.FirstOrDefault(plan => plan.Type == organization.PlanType));
PlanType = organization.PlanType;
Seats = organization.Seats;
MaxAutoscaleSeats = organization.MaxAutoscaleSeats;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public ProfileOrganizationResponseModel(OrganizationUserOrganizationDetails orga
FamilySponsorshipAvailable = FamilySponsorshipFriendlyName == null &&
StaticStore.GetSponsoredPlan(PlanSponsorshipType.FamiliesForEnterprise)
.UsersCanSponsor(organization);
PlanProductType = StaticStore.GetPlan(organization.PlanType).Product;
PlanProductType = StaticStore.GetPasswordManagerPlan(organization.PlanType).Product;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Ensure that GetPasswordManagerPlan() returns the correct plan for all organization types, including those that might not use the password manager.

FamilySponsorshipLastSyncDate = organization.FamilySponsorshipLastSyncDate;
FamilySponsorshipToDelete = organization.FamilySponsorshipToDelete;
FamilySponsorshipValidUntil = organization.FamilySponsorshipValidUntil;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ public ProfileProviderOrganizationResponseModel(ProviderUserOrganizationDetails
UserId = organization.UserId?.ToString();
ProviderId = organization.ProviderId?.ToString();
ProviderName = organization.ProviderName;
PlanProductType = StaticStore.GetPlan(organization.PlanType).Product;
PlanProductType = StaticStore.GetPasswordManagerPlan(organization.PlanType).Product;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Ensure that GetPasswordManagerPlan returns the correct plan for all possible PlanType values, including any new types that may have been introduced for Secrets Manager.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider adding a null check before accessing the Product property, in case GetPasswordManagerPlan returns null for any reason.

}
}
2 changes: 1 addition & 1 deletion src/Billing/Controllers/StripeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ await _transactionRepository.CreateAsync(new Transaction
// org
if (ids.Item1.HasValue)
{
if (subscription.Items.Any(i => StaticStore.Plans.Any(p => p.StripePlanId == i.Plan.Id)))
if (subscription.Items.Any(i => StaticStore.PasswordManagerPlans.Any(p => p.StripePlanId == i.Plan.Id)))
{
await _organizationService.EnableAsync(ids.Item1.Value, subscription.CurrentPeriodEnd);

Comment on lines +420 to 423
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: This condition now only checks for Password Manager plans. Consider adding a check for Secrets Manager plans as well to ensure proper handling of both types of subscriptions.

Expand Down
1 change: 1 addition & 0 deletions src/Core/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public static class FeatureFlagKeys
public const string DisplayEuEnvironment = "display-eu-environment";
public const string DisplayLowKdfIterationWarning = "display-kdf-iteration-warning";
public const string TrustedDeviceEncryption = "trusted-device-encryption";
public const string SecretManagerGaBilling = "sm-ga-billing";

public static List<string> GetAllKeys()
{
Expand Down
11 changes: 11 additions & 0 deletions src/Core/Enums/BitwardenProductType..cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.ComponentModel.DataAnnotations;

namespace Bit.Core.Enums;

public enum BitwardenProductType : byte
{
[Display(Name = "Password Manager")]
PasswordManager = 0,
[Display(Name = "Secrets Manager")]
SecretsManager = 1,
}
3 changes: 3 additions & 0 deletions src/Core/Models/Business/OrganizationUpgrade.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ public class OrganizationUpgrade
public TaxInfo TaxInfo { get; set; }
public string PublicKey { get; set; }
public string PrivateKey { get; set; }
public int? AdditionalSmSeats { get; set; }
public int? AdditionalServiceAccount { get; set; }
public bool UseSecretsManager { get; set; }
Comment on lines +15 to +17
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: consider adding XML documentation comments for these new properties

}
84 changes: 84 additions & 0 deletions src/Core/Models/Business/SubscriptionCreateOptions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Bit.Core.Entities;
using Bit.Core.Enums;
using Stripe;

namespace Bit.Core.Models.Business;
Expand Down Expand Up @@ -54,6 +55,80 @@ public OrganizationSubscriptionOptionsBase(Organization org, StaticStore.Plan pl
DefaultTaxRates = new List<string> { taxInfo.StripeTaxRateId };
}
}

public OrganizationSubscriptionOptionsBase(Organization org, IEnumerable<StaticStore.Plan> plans, TaxInfo taxInfo, int additionalSeats
, int additionalStorageGb, bool premiumAccessAddon, int additionalSmSeats = 0, int additionalServiceAccount = 0)
{
Comment on lines +59 to +61
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider using nullable types for optional parameters

Items = new List<SubscriptionItemOptions>();
Metadata = new Dictionary<string, string>
{
[org.GatewayIdField()] = org.Id.ToString()
};

foreach (var plan in plans)
{
if (plan.StripePlanId != null)
{
Items.Add(new SubscriptionItemOptions
{
Plan = plan.StripePlanId,
Quantity = 1
});
}

if (additionalSeats > 0 && plan.StripeSeatPlanId != null && plan.BitwardenProduct == BitwardenProductType.PasswordManager)
{
Items.Add(new SubscriptionItemOptions
{
Plan = plan.StripeSeatPlanId,
Quantity = additionalSeats
});
}
Comment on lines +79 to +86
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Duplicate logic for PasswordManager. Consider extracting to a separate method


if (additionalStorageGb > 0 && plan.BitwardenProduct == BitwardenProductType.PasswordManager)
{
Items.Add(new SubscriptionItemOptions
{
Plan = plan.StripeStoragePlanId,
Quantity = additionalStorageGb
});
}

if (additionalSmSeats > 0 && plan.StripePlanId != null && plan.BitwardenProduct == BitwardenProductType.SecretsManager)
{
Items.Add(new SubscriptionItemOptions
{
Plan = plan.StripePlanId,
Quantity = additionalSmSeats
});
Comment on lines +97 to +103
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Potential issue: using StripePlanId for SecretsManager seats instead of a dedicated seat plan ID

}

if (additionalServiceAccount > 0 && plan.StripePlanId != null && plan.BitwardenProduct == BitwardenProductType.SecretsManager)
{
Items.Add(new SubscriptionItemOptions
{
Plan = plan.StripePlanId,
Quantity = additionalServiceAccount
});
Comment on lines +106 to +112
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Potential issue: using StripePlanId for service accounts instead of a dedicated plan ID

}

if (premiumAccessAddon && plan.StripePremiumAccessPlanId != null && plan.BitwardenProduct == BitwardenProductType.PasswordManager)
{
Items.Add(new SubscriptionItemOptions
{
Plan = plan.StripePremiumAccessPlanId,
Quantity = 1
});
}
}


if (!string.IsNullOrWhiteSpace(taxInfo?.StripeTaxRateId))
{
DefaultTaxRates = new List<string> { taxInfo.StripeTaxRateId };
}

}
}

public class OrganizationPurchaseSubscriptionOptions : OrganizationSubscriptionOptionsBase
Expand All @@ -67,6 +142,15 @@ public OrganizationPurchaseSubscriptionOptions(
OffSession = true;
TrialPeriodDays = plan.TrialPeriodDays;
}

public OrganizationPurchaseSubscriptionOptions(Organization org, IEnumerable<StaticStore.Plan> plans, TaxInfo taxInfo, int additionalSeats = 0
, int additionalStorageGb = 0, bool premiumAccessAddon = false
, int additionalSmSeats = 0, int additionalServiceAccount = 0) :
base(org, plans, taxInfo, additionalSeats, additionalStorageGb, premiumAccessAddon, additionalSmSeats, additionalServiceAccount)
{
OffSession = true;
TrialPeriodDays = plans.FirstOrDefault().TrialPeriodDays;
}
Comment on lines +146 to +153
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Consider adding null check for plans.FirstOrDefault()

}

public class OrganizationUpgradeSubscriptionOptions : OrganizationSubscriptionOptionsBase
Expand Down
5 changes: 5 additions & 0 deletions src/Core/Models/StaticStore/Plan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,9 @@ public class Plan
public decimal SeatPrice { get; set; }
public decimal AdditionalStoragePricePerGb { get; set; }
public decimal PremiumAccessOptionPrice { get; set; }
public decimal? AdditionalPricePerServiceAccount { get; set; }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider adding XML documentation for this new property to explain its purpose and usage.

public short? BaseServiceAccount { get; set; }
public short? MaxServiceAccount { get; set; }
Comment on lines +56 to +57
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: These properties should probably be nullable ints (int?) instead of nullable shorts (short?) for consistency with other similar properties in the class (e.g., MaxUsers).

public bool HasAdditionalServiceAccountOption { get; set; }
public BitwardenProductType BitwardenProduct { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Bit.Core.Models.Business;

namespace Bit.Core.OrganizationFeatures.OrganizationPlanUpgrade.Interface;

public interface IOrganizationUpgradePlanCommand
{
Task<Tuple<bool, string>> UpgradePlanAsync(Guid organizationId, OrganizationUpgrade upgrade);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider adding XML documentation to describe the purpose of this method, its parameters, and return value

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Models.StaticStore;

namespace Bit.Core.OrganizationFeatures.OrganizationPlanUpgrade.Interface;

public interface IOrganizationUpgradeQuery
{
Plan ExistingPlan(PlanType planType);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider adding a return type annotation for clarity


List<Plan> NewPlans(PlanType planType);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider adding a return type annotation for clarity


Task<Organization> GetOrgById(Guid id);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Method name could be more descriptive, e.g., 'GetOrganizationById'

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Bit.Core.Entities;
using Bit.Core.Models.Business;
using Bit.Core.Models.StaticStore;

namespace Bit.Core.OrganizationFeatures.OrganizationPlanUpgrade.Interface;

public interface IValidateUpgradeCommand
{
void ValidatePlan(Plan newPlan, Plan existingPlan);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider adding XML documentation comments to describe the purpose and parameters of each method

Task ValidateSeatsAsync(Organization organization, Plan passwordManagerPlan, OrganizationUpgrade upgrade);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: passwordManagerPlan parameter name inconsistent with newPlan in other methods

Task ValidateSmSeatsAsync(Organization organization, Plan newPlan, OrganizationUpgrade upgrade);
Task ValidateServiceAccountAsync(Organization organization, Plan newPlan, OrganizationUpgrade upgrade);
Task ValidateCollectionsAsync(Organization organization, Plan newPlan);
Task ValidateGroupsAsync(Organization organization, Plan newPlan);
Task ValidatePoliciesAsync(Organization organization, Plan newPlan);
Task ValidateSsoAsync(Organization organization, Plan newPlan);
Task ValidateKeyConnectorAsync(Organization organization, Plan newPlan);
Task ValidateResetPasswordAsync(Organization organization, Plan newPlan);
Task ValidateScimAsync(Organization organization, Plan newPlan);
Task ValidateCustomPermissionsAsync(Organization organization, Plan newPlan);

}
Loading
Loading