mirror of
https://github.com/bitwarden/server.git
synced 2025-04-05 05:00:19 -05:00
Made HasSecretsManagerStandalone return if org doesn't have sm. Added overload for lighter weight model and moved common code to private method.
This commit is contained in:
parent
edbf1cea41
commit
a2b155e81c
@ -29,12 +29,10 @@ public class ScimUserRequestModel : BaseScimUserModel
|
|||||||
|
|
||||||
public OrganizationUserSingleEmailInvite ToRequest(
|
public OrganizationUserSingleEmailInvite ToRequest(
|
||||||
ScimProviderType scimProvider,
|
ScimProviderType scimProvider,
|
||||||
bool hasSecretsManager,
|
|
||||||
InviteOrganization inviteOrganization,
|
InviteOrganization inviteOrganization,
|
||||||
DateTimeOffset performedAt) =>
|
DateTimeOffset performedAt) =>
|
||||||
new(
|
new(
|
||||||
email: EmailForInvite(scimProvider),
|
email: EmailForInvite(scimProvider),
|
||||||
hasSecretsManager: hasSecretsManager,
|
|
||||||
inviteOrganization: inviteOrganization,
|
inviteOrganization: inviteOrganization,
|
||||||
performedAt: performedAt,
|
performedAt: performedAt,
|
||||||
externalId: ExternalIdForInvite());
|
externalId: ExternalIdForInvite());
|
||||||
|
@ -65,15 +65,15 @@ public class PostUserCommand(
|
|||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasStandaloneSecretsManager = await paymentService.HasSecretsManagerStandalone(organization);
|
|
||||||
invite.AccessSecretsManager = hasStandaloneSecretsManager;
|
|
||||||
|
|
||||||
if (featureService.IsEnabled(FeatureFlagKeys.ScimInviteUserOptimization))
|
if (featureService.IsEnabled(FeatureFlagKeys.ScimInviteUserOptimization))
|
||||||
{
|
{
|
||||||
return await InviteScimOrganizationUserAsync(model, organization, scimProvider,
|
return await InviteScimOrganizationUserAsync(model, organization, scimProvider);
|
||||||
hasStandaloneSecretsManager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hasStandaloneSecretsManager = await paymentService.HasSecretsManagerStandalone(organization);
|
||||||
|
invite.AccessSecretsManager = hasStandaloneSecretsManager;
|
||||||
|
|
||||||
var invitedOrgUser = await organizationService.InviteUserAsync(organizationId, invitingUserId: null,
|
var invitedOrgUser = await organizationService.InviteUserAsync(organizationId, invitingUserId: null,
|
||||||
EventSystemUser.SCIM,
|
EventSystemUser.SCIM,
|
||||||
invite, externalId);
|
invite, externalId);
|
||||||
@ -83,7 +83,7 @@ public class PostUserCommand(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task<OrganizationUserUserDetails?> InviteScimOrganizationUserAsync(ScimUserRequestModel model,
|
private async Task<OrganizationUserUserDetails?> InviteScimOrganizationUserAsync(ScimUserRequestModel model,
|
||||||
Organization organization, ScimProviderType scimProvider, bool hasStandaloneSecretsManager)
|
Organization organization, ScimProviderType scimProvider)
|
||||||
{
|
{
|
||||||
var plan = await pricingClient.GetPlan(organization.PlanType);
|
var plan = await pricingClient.GetPlan(organization.PlanType);
|
||||||
|
|
||||||
@ -96,7 +96,6 @@ public class PostUserCommand(
|
|||||||
|
|
||||||
var request = model.ToRequest(
|
var request = model.ToRequest(
|
||||||
scimProvider: scimProvider,
|
scimProvider: scimProvider,
|
||||||
hasSecretsManager: hasStandaloneSecretsManager,
|
|
||||||
inviteOrganization: new InviteOrganization(organization, plan),
|
inviteOrganization: new InviteOrganization(organization, plan),
|
||||||
performedAt: timeProvider.GetUtcNow());
|
performedAt: timeProvider.GetUtcNow());
|
||||||
|
|
||||||
|
@ -41,7 +41,9 @@ public class InviteOrganizationUsersCommand(IEventService eventService,
|
|||||||
|
|
||||||
public async Task<CommandResult<ScimInviteOrganizationUsersResponse>> InviteScimOrganizationUserAsync(OrganizationUserSingleEmailInvite request)
|
public async Task<CommandResult<ScimInviteOrganizationUsersResponse>> InviteScimOrganizationUserAsync(OrganizationUserSingleEmailInvite request)
|
||||||
{
|
{
|
||||||
var result = await InviteOrganizationUsersAsync(new InviteOrganizationUsersRequest(request));
|
var hasSecretsManager = await paymentService.HasSecretsManagerStandalone(request.InviteOrganization);
|
||||||
|
|
||||||
|
var result = await InviteOrganizationUsersAsync(new InviteOrganizationUsersRequest(request, hasSecretsManager));
|
||||||
|
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
|
@ -20,8 +20,8 @@ public class InviteOrganizationUsersRequest
|
|||||||
PerformedAt = performedAt;
|
PerformedAt = performedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InviteOrganizationUsersRequest(OrganizationUserSingleEmailInvite request) :
|
public InviteOrganizationUsersRequest(OrganizationUserSingleEmailInvite request, bool hasStandaloneSecretsManager) :
|
||||||
this([OrganizationUserInvite.Create(request)],
|
this([OrganizationUserInvite.Create(request, hasStandaloneSecretsManager)],
|
||||||
request.InviteOrganization,
|
request.InviteOrganization,
|
||||||
Guid.Empty,
|
Guid.Empty,
|
||||||
request.PerformedAt)
|
request.PerformedAt)
|
||||||
|
@ -42,13 +42,13 @@ public class OrganizationUserInvite
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OrganizationUserInvite Create(OrganizationUserSingleEmailInvite invite) =>
|
public static OrganizationUserInvite Create(OrganizationUserSingleEmailInvite invite, bool hasStandaloneSecretsManager) =>
|
||||||
Create([invite.Email],
|
Create([invite.Email],
|
||||||
invite.AccessibleCollections,
|
invite.AccessibleCollections,
|
||||||
invite.Type,
|
invite.Type,
|
||||||
invite.Permissions,
|
invite.Permissions,
|
||||||
invite.ExternalId,
|
invite.ExternalId,
|
||||||
invite.AccessSecretsManager);
|
hasStandaloneSecretsManager);
|
||||||
|
|
||||||
private static void ValidateEmailAddresses(string[] emails)
|
private static void ValidateEmailAddresses(string[] emails)
|
||||||
{
|
{
|
||||||
|
@ -14,21 +14,18 @@ public record OrganizationUserSingleEmailInvite
|
|||||||
public CollectionAccessSelection[] AccessibleCollections { get; init; } = [];
|
public CollectionAccessSelection[] AccessibleCollections { get; init; } = [];
|
||||||
public Permissions Permissions { get; init; } = new();
|
public Permissions Permissions { get; init; } = new();
|
||||||
public OrganizationUserType Type { get; init; } = OrganizationUserType.User;
|
public OrganizationUserType Type { get; init; } = OrganizationUserType.User;
|
||||||
public bool AccessSecretsManager { get; init; }
|
|
||||||
public InviteOrganization InviteOrganization { get; private init; }
|
public InviteOrganization InviteOrganization { get; private init; }
|
||||||
public DateTimeOffset PerformedAt { get; private init; }
|
public DateTimeOffset PerformedAt { get; private init; }
|
||||||
public string ExternalId { get; private init; } = string.Empty;
|
public string ExternalId { get; private init; } = string.Empty;
|
||||||
|
|
||||||
public OrganizationUserSingleEmailInvite(string email,
|
public OrganizationUserSingleEmailInvite(string email,
|
||||||
bool hasSecretsManager,
|
|
||||||
InviteOrganization inviteOrganization,
|
InviteOrganization inviteOrganization,
|
||||||
DateTimeOffset performedAt,
|
DateTimeOffset performedAt,
|
||||||
string externalId) : this(
|
string externalId) : this(
|
||||||
email: email,
|
email: email,
|
||||||
accessibleCollections: [],
|
accessibleCollections: [],
|
||||||
type: OrganizationUserType.User,
|
type: OrganizationUserType.User,
|
||||||
permissions: new Permissions(),
|
permissions: new Permissions())
|
||||||
accessSecretsManager: hasSecretsManager)
|
|
||||||
{
|
{
|
||||||
InviteOrganization = inviteOrganization;
|
InviteOrganization = inviteOrganization;
|
||||||
PerformedAt = performedAt;
|
PerformedAt = performedAt;
|
||||||
@ -38,8 +35,7 @@ public record OrganizationUserSingleEmailInvite
|
|||||||
public OrganizationUserSingleEmailInvite(string email,
|
public OrganizationUserSingleEmailInvite(string email,
|
||||||
IEnumerable<CollectionAccessSelection> accessibleCollections,
|
IEnumerable<CollectionAccessSelection> accessibleCollections,
|
||||||
OrganizationUserType type,
|
OrganizationUserType type,
|
||||||
Permissions permissions,
|
Permissions permissions)
|
||||||
bool accessSecretsManager)
|
|
||||||
{
|
{
|
||||||
if (!email.IsValidEmail())
|
if (!email.IsValidEmail())
|
||||||
{
|
{
|
||||||
@ -55,6 +51,5 @@ public record OrganizationUserSingleEmailInvite
|
|||||||
AccessibleCollections = accessibleCollections.ToArray();
|
AccessibleCollections = accessibleCollections.ToArray();
|
||||||
Type = type;
|
Type = type;
|
||||||
Permissions = permissions;
|
Permissions = permissions;
|
||||||
AccessSecretsManager = accessSecretsManager;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using Bit.Core.AdminConsole.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.AdminConsole.Entities.Provider;
|
using Bit.Core.AdminConsole.Entities.Provider;
|
||||||
|
using Bit.Core.AdminConsole.Models.Business;
|
||||||
using Bit.Core.Billing.Models;
|
using Bit.Core.Billing.Models;
|
||||||
using Bit.Core.Billing.Models.Api.Requests.Accounts;
|
using Bit.Core.Billing.Models.Api.Requests.Accounts;
|
||||||
using Bit.Core.Billing.Models.Api.Requests.Organizations;
|
using Bit.Core.Billing.Models.Api.Requests.Organizations;
|
||||||
@ -44,9 +45,28 @@ public interface IPaymentService
|
|||||||
Task<SubscriptionInfo> GetSubscriptionAsync(ISubscriber subscriber);
|
Task<SubscriptionInfo> GetSubscriptionAsync(ISubscriber subscriber);
|
||||||
Task<TaxInfo> GetTaxInfoAsync(ISubscriber subscriber);
|
Task<TaxInfo> GetTaxInfoAsync(ISubscriber subscriber);
|
||||||
Task SaveTaxInfoAsync(ISubscriber subscriber, TaxInfo taxInfo);
|
Task SaveTaxInfoAsync(ISubscriber subscriber, TaxInfo taxInfo);
|
||||||
Task<string> AddSecretsManagerToSubscription(Organization org, Plan plan, int additionalSmSeats,
|
Task<string> AddSecretsManagerToSubscription(Organization org, Plan plan, int additionalSmSeats, int additionalServiceAccount);
|
||||||
int additionalServiceAccount);
|
/// <summary>
|
||||||
|
/// Secrets Manager Standalone is a discount in Stripe that is used to give an organization access to Secrets Manager.
|
||||||
|
/// Usually, this also implies that when they invite a user to their organization, they are doing so for both Password
|
||||||
|
/// Manager and Secrets Manger.
|
||||||
|
///
|
||||||
|
/// This will not call out to Stripe if they don't have a GatewayId or if they don't have Secrets Manager.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="organization">Organization Entity</param>
|
||||||
|
/// <returns>If the organization has Secrets Manager and has the Standalone Stripe Discount</returns>
|
||||||
Task<bool> HasSecretsManagerStandalone(Organization organization);
|
Task<bool> HasSecretsManagerStandalone(Organization organization);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Secrets Manager Standalone is a discount in Stripe that is used to give an organization access to Secrets Manager.
|
||||||
|
/// Usually, this also implies that when they invite a user to their organization, they are doing so for both Password
|
||||||
|
/// Manager and Secrets Manger.
|
||||||
|
///
|
||||||
|
/// This will not call out to Stripe if they don't have a GatewayId or if they don't have Secrets Manager.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="organization">Organization Representation used for Inviting Organization Users</param>
|
||||||
|
/// <returns>If the organization has Secrets Manager and has the Standalone Stripe Discount</returns>
|
||||||
|
Task<bool> HasSecretsManagerStandalone(InviteOrganization organization);
|
||||||
Task<PreviewInvoiceResponseModel> PreviewInvoiceAsync(PreviewIndividualInvoiceRequestBody parameters, string gatewayCustomerId, string gatewaySubscriptionId);
|
Task<PreviewInvoiceResponseModel> PreviewInvoiceAsync(PreviewIndividualInvoiceRequestBody parameters, string gatewayCustomerId, string gatewaySubscriptionId);
|
||||||
Task<PreviewInvoiceResponseModel> PreviewInvoiceAsync(PreviewOrganizationInvoiceRequestBody parameters, string gatewayCustomerId, string gatewaySubscriptionId);
|
Task<PreviewInvoiceResponseModel> PreviewInvoiceAsync(PreviewOrganizationInvoiceRequestBody parameters, string gatewayCustomerId, string gatewaySubscriptionId);
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using Bit.Core.AdminConsole.Entities;
|
using Bit.Core.AdminConsole.Entities;
|
||||||
using Bit.Core.AdminConsole.Entities.Provider;
|
using Bit.Core.AdminConsole.Entities.Provider;
|
||||||
|
using Bit.Core.AdminConsole.Models.Business;
|
||||||
using Bit.Core.Billing.Constants;
|
using Bit.Core.Billing.Constants;
|
||||||
using Bit.Core.Billing.Extensions;
|
using Bit.Core.Billing.Extensions;
|
||||||
using Bit.Core.Billing.Models;
|
using Bit.Core.Billing.Models;
|
||||||
@ -1079,14 +1080,27 @@ public class StripePaymentService : IPaymentService
|
|||||||
new SecretsManagerSubscribeUpdate(org, plan, additionalSmSeats, additionalServiceAccount),
|
new SecretsManagerSubscribeUpdate(org, plan, additionalSmSeats, additionalServiceAccount),
|
||||||
true);
|
true);
|
||||||
|
|
||||||
public async Task<bool> HasSecretsManagerStandalone(Organization organization)
|
public async Task<bool> HasSecretsManagerStandalone(Organization organization) =>
|
||||||
|
await HasSecretsManagerAsync(gatewayCustomerId: organization.GatewayCustomerId,
|
||||||
|
organizationHasSecretsManager: organization.UseSecretsManager);
|
||||||
|
|
||||||
|
public async Task<bool> HasSecretsManagerStandalone(InviteOrganization organization) =>
|
||||||
|
await HasSecretsManagerAsync(gatewayCustomerId: organization.GatewayCustomerId,
|
||||||
|
organizationHasSecretsManager: organization.UseSecretsManager);
|
||||||
|
|
||||||
|
private async Task<bool> HasSecretsManagerAsync(string gatewayCustomerId, bool organizationHasSecretsManager)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(organization.GatewayCustomerId))
|
if (string.IsNullOrEmpty(gatewayCustomerId))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var customer = await _stripeAdapter.CustomerGetAsync(organization.GatewayCustomerId);
|
if (organizationHasSecretsManager is false)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var customer = await _stripeAdapter.CustomerGetAsync(gatewayCustomerId);
|
||||||
|
|
||||||
return customer?.Discount?.Coupon?.Id == SecretsManagerStandaloneDiscountId;
|
return customer?.Discount?.Coupon?.Id == SecretsManagerStandaloneDiscountId;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user