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

Conversation

lizard-boy
Copy link

@lizard-boy lizard-boy commented Oct 19, 2024

Type of change

- [ ] Bug fix
- [X] New feature development
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
- [ ] Build/deploy pipeline (DevOps)
- [ ] Other

Objective

Adding Secrets Manager price during the subscription if an organization wants to add a secrets manager.

Code changes

  • src/Api/Controllers/OrganizationsController.cs: This file was changed to call the _organizationUpgradePlanCommand that handles the validation and subscription
  • src/Core/Models/Business/SubscriptionCreateOptions.cs: This file was changed to handles secrets manager seats and service account during subscription

Before you submit

  • Please check for formatting errors (dotnet format --verify-no-changes) (required)
  • If making database changes - make sure you also update Entity Framework queries and/or migrations
  • Please add unit tests where it makes sense to do so (encouraged but not required)
  • If this change requires a documentation update - notify the documentation team
  • If this change has particular deployment requirements - notify the DevOps team

Greptile Summary

Integrated Secrets Manager pricing into subscription process, focusing on organization management and billing.

  • Added support for Secrets Manager seats and service accounts in organization creation and upgrade models
  • Introduced new validation strategies for Password Manager and Secrets Manager sign-ups
  • Updated plan retrieval methods to specifically use Password Manager plans where appropriate
  • Created new commands and queries for handling organization upgrades with Secrets Manager integration
  • Modified StripeController to consider both Password Manager and Secrets Manager plans in subscription processing

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

30 file(s) reviewed, 62 comment(s)
Edit PR Review Bot Settings | Greptile

Comment on lines +253 to +256
var result = !_featureService.IsEnabled(FeatureFlagKeys.SecretManagerGaBilling, _currentContext) &&
!model.UseSecretsManager
? await _organizationService.SignUpAsync(organizationSignup)
: await _organizationSignUpCommand.SignUpAsync(organizationSignup);
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

Comment on lines +322 to +325
var result = !_featureService.IsEnabled(FeatureFlagKeys.SecretManagerGaBilling, _currentContext) &&
!model.UseSecretsManager
? await _organizationService.UpgradePlanAsync(orgIdGuid, model.ToOrganizationUpgrade())
: await _organizationUpgradePlanCommand.UpgradePlanAsync(orgIdGuid, model.ToOrganizationUpgrade());
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

Comment on lines 21 to +26
public ListResponseModel<PlanResponseModel> Get()
{
var data = StaticStore.PasswordManagerPlans;
var responses = data.Select(plan => new PlanResponseModel(plan));
return new ListResponseModel<PlanResponseModel>(responses);
}
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.

[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.

Comment on lines +67 to +69
AdditionalSmSeats = AdditionalSmSeats.GetValueOrDefault(0),
AdditionalServiceAccount = AdditionalServiceAccount.GetValueOrDefault(0),
UseSecretsManager = UseSecretsManager,
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

Comment on lines 51 to +54
var requiredSponsoredProductType = StaticStore.GetSponsoredPlan(sponsorship.PlanSponsorshipType.Value)?.SponsoredProductType;
if (requiredSponsoredProductType == null ||
sponsoredOrganization == null ||
StaticStore.GetPlan(sponsoredOrganization.PlanType).Product != requiredSponsoredProductType.Value)
StaticStore.GetPasswordManagerPlan(sponsoredOrganization.PlanType).Product != requiredSponsoredProductType.Value)
Copy link

Choose a reason for hiding this comment

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

logic: The change from GetPlan to GetPasswordManagerPlan might affect how plan types are validated. Ensure this doesn't unintentionally exclude valid plan types.

@@ -51,7 +51,7 @@ public async Task SetUpSponsorshipAsync(OrganizationSponsorship sponsorship,
var requiredSponsoredProductType = StaticStore.GetSponsoredPlan(sponsorship.PlanSponsorshipType.Value)?.SponsoredProductType;
if (requiredSponsoredProductType == null ||
sponsoredOrganization == null ||
StaticStore.GetPlan(sponsoredOrganization.PlanType).Product != requiredSponsoredProductType.Value)
StaticStore.GetPasswordManagerPlan(sponsoredOrganization.PlanType).Product != requiredSponsoredProductType.Value)
{
throw new BadRequestException("Can only redeem sponsorship offer on families organizations.");
Copy link

Choose a reason for hiding this comment

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

style: The error message 'Can only redeem sponsorship offer on families organizations' may need to be updated if Secrets Manager plans are now included.

Comment on lines 32 to +35
var requiredSponsoringProductType = StaticStore.GetSponsoredPlan(sponsorshipType)?.SponsoringProductType;
if (requiredSponsoringProductType == null ||
sponsoringOrg == null ||
StaticStore.GetPlan(sponsoringOrg.PlanType).Product != requiredSponsoringProductType.Value)
StaticStore.GetPasswordManagerPlan(sponsoringOrg.PlanType).Product != requiredSponsoringProductType.Value)
Copy link

Choose a reason for hiding this comment

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

logic: The change from GetPlan to GetPasswordManagerPlan suggests a separation of Password Manager and Secrets Manager plans. Ensure this change is consistent across the codebase and that it doesn't unintentionally exclude Secrets Manager plans from sponsorship eligibility.

@@ -40,4 +40,6 @@ Task<OrganizationUserOrganizationDetails> GetDetailsByUserAsync(Guid userId, Gui
Task RevokeAsync(Guid id);
Task RestoreAsync(Guid id, OrganizationUserStatusType status);
Task<IEnumerable<OrganizationUserPolicyDetails>> GetByUserIdWithPolicyDetailsAsync(Guid userId, PolicyType policyType);
Task<int> GetOccupiedSmSeatCountByOrganizationIdAsync(Guid organizationId);
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 method to explain its purpose and usage

@@ -40,4 +40,6 @@ Task<OrganizationUserOrganizationDetails> GetDetailsByUserAsync(Guid userId, Gui
Task RevokeAsync(Guid id);
Task RestoreAsync(Guid id, OrganizationUserStatusType status);
Task<IEnumerable<OrganizationUserPolicyDetails>> GetByUserIdWithPolicyDetailsAsync(Guid userId, PolicyType policyType);
Task<int> GetOccupiedSmSeatCountByOrganizationIdAsync(Guid organizationId);
Task<int> GetOccupiedServiceAccountCountByOrganizationIdAsync(Guid organizationId);
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 method to explain its purpose and usage

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants