mirror of
https://github.com/bitwarden/server.git
synced 2025-07-17 07:30:59 -05:00
Remove design patterns
This commit is contained in:
@ -1,49 +1,108 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Billing.Extensions;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Interfaces;
|
||||
using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.SponsorshipCreation;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise;
|
||||
|
||||
public class CreateSponsorshipCommand : ICreateSponsorshipCommand
|
||||
public class CreateSponsorshipCommand(
|
||||
ICurrentContext currentContext,
|
||||
IFeatureService featureService,
|
||||
IOrganizationSponsorshipRepository organizationSponsorshipRepository,
|
||||
IUserService userService) : ICreateSponsorshipCommand
|
||||
{
|
||||
private readonly IOrganizationSponsorshipRepository _organizationSponsorshipRepository;
|
||||
|
||||
private readonly BaseCreateSponsorshipHandler _createSponsorshipHandler;
|
||||
|
||||
public CreateSponsorshipCommand(
|
||||
IFeatureService featureService,
|
||||
IOrganizationSponsorshipRepository organizationSponsorshipRepository,
|
||||
IUserService userService,
|
||||
ICurrentContext currentContext)
|
||||
public async Task<OrganizationSponsorship> CreateSponsorshipAsync(Organization sponsoringOrganization,
|
||||
OrganizationUser sponsoringMember, PlanSponsorshipType sponsorshipType, string sponsoredEmail,
|
||||
string friendlyName, string notes)
|
||||
{
|
||||
_organizationSponsorshipRepository = organizationSponsorshipRepository;
|
||||
var sponsoringUser = await userService.GetUserByIdAsync(sponsoringMember.UserId!.Value);
|
||||
|
||||
var adminInitiatedSponsorshipHandler = new CreateAdminInitiatedSponsorshipHandler(currentContext, featureService);
|
||||
_createSponsorshipHandler = new CreateSponsorshipHandler(userService, organizationSponsorshipRepository);
|
||||
_createSponsorshipHandler.SetNext(adminInitiatedSponsorshipHandler);
|
||||
}
|
||||
if (sponsoringUser == null || string.Equals(sponsoringUser.Email, sponsoredEmail, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
throw new BadRequestException("Cannot offer a Families Organization Sponsorship to yourself. Choose a different email.");
|
||||
}
|
||||
|
||||
public async Task<OrganizationSponsorship> CreateSponsorshipAsync(Organization sponsoringOrg, OrganizationUser sponsoringOrgUser,
|
||||
PlanSponsorshipType sponsorshipType, string sponsoredEmail, string friendlyName, string notes)
|
||||
{
|
||||
var createSponsorshipRequest = new CreateSponsorshipRequest(sponsoringOrg, sponsoringOrgUser, sponsorshipType, sponsoredEmail, friendlyName, notes);
|
||||
var sponsorship = await _createSponsorshipHandler.HandleAsync(createSponsorshipRequest);
|
||||
var requiredSponsoringProductType = StaticStore.GetSponsoredPlan(sponsorshipType)?.SponsoringProductTierType;
|
||||
var sponsoringOrgProductTier = sponsoringOrganization.PlanType.GetProductTier();
|
||||
|
||||
if (requiredSponsoringProductType == null ||
|
||||
sponsoringOrgProductTier != requiredSponsoringProductType.Value)
|
||||
{
|
||||
throw new BadRequestException("Specified Organization cannot sponsor other organizations.");
|
||||
}
|
||||
|
||||
if (sponsoringMember.Status != OrganizationUserStatusType.Confirmed)
|
||||
{
|
||||
throw new BadRequestException("Only confirmed users can sponsor other organizations.");
|
||||
}
|
||||
|
||||
var existingOrgSponsorship = await organizationSponsorshipRepository
|
||||
.GetBySponsoringOrganizationUserIdAsync(sponsoringMember.Id);
|
||||
if (existingOrgSponsorship?.SponsoredOrganizationId != null)
|
||||
{
|
||||
throw new BadRequestException("Can only sponsor one organization per Organization User.");
|
||||
}
|
||||
|
||||
var sponsorship = new OrganizationSponsorship();
|
||||
sponsorship.SponsoringOrganizationId = sponsoringOrganization.Id;
|
||||
sponsorship.SponsoringOrganizationUserId = sponsoringMember.Id;
|
||||
sponsorship.FriendlyName = friendlyName;
|
||||
sponsorship.OfferedToEmail = sponsoredEmail;
|
||||
sponsorship.PlanSponsorshipType = sponsorshipType;
|
||||
|
||||
if (existingOrgSponsorship != null)
|
||||
{
|
||||
// Replace existing invalid offer with our new sponsorship offer
|
||||
sponsorship.Id = existingOrgSponsorship.Id;
|
||||
}
|
||||
|
||||
var isAdminInitiated = false;
|
||||
if (currentContext.UserId != sponsoringMember.UserId)
|
||||
{
|
||||
if (!featureService.IsEnabled(FeatureFlagKeys.PM17772_AdminInitiatedSponsorships))
|
||||
{
|
||||
throw new BadRequestException("Feature 'pm-17772-admin-initiated-sponsorships' is not enabled.");
|
||||
}
|
||||
|
||||
var organization = currentContext.Organizations.First(x => x.Id == sponsoringOrganization.Id);
|
||||
OrganizationUserType[] allowedUserTypes =
|
||||
[
|
||||
OrganizationUserType.Admin,
|
||||
OrganizationUserType.Owner
|
||||
];
|
||||
|
||||
if (!organization.Permissions.ManageUsers && allowedUserTypes.All(x => x != organization.Type))
|
||||
{
|
||||
throw new UnauthorizedAccessException("You do not have permissions to send sponsorships on behalf of the organization.");
|
||||
}
|
||||
|
||||
if (!sponsoringOrganization.UseAdminSponsoredFamilies)
|
||||
{
|
||||
throw new BadRequestException("Sponsoring organization cannot sponsor other Family organizations.");
|
||||
}
|
||||
|
||||
isAdminInitiated = true;
|
||||
}
|
||||
|
||||
sponsorship.IsAdminInitiated = isAdminInitiated;
|
||||
sponsorship.Notes = notes;
|
||||
|
||||
try
|
||||
{
|
||||
await _organizationSponsorshipRepository.UpsertAsync(sponsorship);
|
||||
await organizationSponsorshipRepository.UpsertAsync(sponsorship);
|
||||
return sponsorship;
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (sponsorship.Id != Guid.Empty)
|
||||
{
|
||||
await _organizationSponsorshipRepository.DeleteAsync(sponsorship);
|
||||
await organizationSponsorshipRepository.DeleteAsync(sponsorship);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
using Bit.Core.Entities;
|
||||
|
||||
namespace Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.SponsorshipCreation;
|
||||
|
||||
public abstract class BaseCreateSponsorshipHandler
|
||||
{
|
||||
private BaseCreateSponsorshipHandler _next;
|
||||
|
||||
public BaseCreateSponsorshipHandler SetNext(BaseCreateSponsorshipHandler next)
|
||||
{
|
||||
_next = next;
|
||||
return next;
|
||||
}
|
||||
|
||||
public virtual async Task<OrganizationSponsorship> HandleAsync(CreateSponsorshipRequest request)
|
||||
{
|
||||
if (_next != null)
|
||||
{
|
||||
return await _next.HandleAsync(request);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Services;
|
||||
|
||||
namespace Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.SponsorshipCreation;
|
||||
|
||||
/// <summary>
|
||||
/// Responsible for validating a request and building the <see cref="OrganizationSponsorship" /> entity to create a
|
||||
/// sponsorship initiated by organization members with specific permissions to manage members/users.
|
||||
/// </summary>
|
||||
public class CreateAdminInitiatedSponsorshipHandler(
|
||||
ICurrentContext currentContext,
|
||||
IFeatureService featureService) : BaseCreateSponsorshipHandler
|
||||
{
|
||||
public override async Task<OrganizationSponsorship> HandleAsync(CreateSponsorshipRequest request)
|
||||
{
|
||||
var isAdminInitiated = false;
|
||||
if (currentContext.UserId != request.SponsoringMember.UserId)
|
||||
{
|
||||
if (!featureService.IsEnabled(FeatureFlagKeys.PM17772_AdminInitiatedSponsorships))
|
||||
{
|
||||
throw new BadRequestException("Feature 'pm-17772-admin-initiated-sponsorships' is not enabled.");
|
||||
}
|
||||
|
||||
var organization = currentContext.Organizations.First(x => x.Id == request.SponsoringOrganization.Id);
|
||||
OrganizationUserType[] allowedUserTypes =
|
||||
[
|
||||
OrganizationUserType.Admin,
|
||||
OrganizationUserType.Owner
|
||||
];
|
||||
|
||||
if (!organization.Permissions.ManageUsers && allowedUserTypes.All(x => x != organization.Type))
|
||||
{
|
||||
throw new UnauthorizedAccessException("You do not have permissions to send sponsorships on behalf of the organization.");
|
||||
}
|
||||
|
||||
if (!request.SponsoringOrganization.UseAdminSponsoredFamilies)
|
||||
{
|
||||
throw new BadRequestException("Sponsoring organization cannot sponsor other Family organizations.");
|
||||
}
|
||||
|
||||
isAdminInitiated = true;
|
||||
}
|
||||
|
||||
var sponsorship = await base.HandleAsync(request) ?? new OrganizationSponsorship();
|
||||
|
||||
sponsorship.IsAdminInitiated = isAdminInitiated;
|
||||
sponsorship.Notes = request.Notes;
|
||||
|
||||
return sponsorship;
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
using Bit.Core.Billing.Extensions;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.SponsorshipCreation;
|
||||
|
||||
/// <summary>
|
||||
/// Responsible for validating a request and building the <see cref="OrganizationSponsorship" /> entity to create a
|
||||
/// sponsorship.
|
||||
/// </summary>
|
||||
public class CreateSponsorshipHandler(
|
||||
IUserService userService,
|
||||
IOrganizationSponsorshipRepository organizationSponsorshipRepository) : BaseCreateSponsorshipHandler
|
||||
{
|
||||
public override async Task<OrganizationSponsorship> HandleAsync(CreateSponsorshipRequest request)
|
||||
{
|
||||
var sponsoringUser = await userService.GetUserByIdAsync(request.SponsoringMember.UserId.Value);
|
||||
|
||||
if (sponsoringUser == null || string.Equals(sponsoringUser.Email, request.SponsoredEmail, System.StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
throw new BadRequestException("Cannot offer a Families Organization Sponsorship to yourself. Choose a different email.");
|
||||
}
|
||||
|
||||
var requiredSponsoringProductType = StaticStore.GetSponsoredPlan(request.SponsorshipType)?.SponsoringProductTierType;
|
||||
var sponsoringOrgProductTier = request.SponsoringOrganization.PlanType.GetProductTier();
|
||||
|
||||
if (requiredSponsoringProductType == null ||
|
||||
sponsoringOrgProductTier != requiredSponsoringProductType.Value)
|
||||
{
|
||||
throw new BadRequestException("Specified Organization cannot sponsor other organizations.");
|
||||
}
|
||||
|
||||
if (request.SponsoringMember == null || request.SponsoringMember.Status != OrganizationUserStatusType.Confirmed)
|
||||
{
|
||||
throw new BadRequestException("Only confirmed users can sponsor other organizations.");
|
||||
}
|
||||
|
||||
var existingOrgSponsorship = await organizationSponsorshipRepository
|
||||
.GetBySponsoringOrganizationUserIdAsync(request.SponsoringMember.Id);
|
||||
if (existingOrgSponsorship?.SponsoredOrganizationId != null)
|
||||
{
|
||||
throw new BadRequestException("Can only sponsor one organization per Organization User.");
|
||||
}
|
||||
|
||||
var sponsorship = await base.HandleAsync(request) ?? new OrganizationSponsorship();
|
||||
|
||||
sponsorship.SponsoringOrganizationId = request.SponsoringOrganization.Id;
|
||||
sponsorship.SponsoringOrganizationUserId = request.SponsoringMember.Id;
|
||||
sponsorship.FriendlyName = request.FriendlyName;
|
||||
sponsorship.OfferedToEmail = request.SponsoredEmail;
|
||||
sponsorship.PlanSponsorshipType = request.SponsorshipType;
|
||||
|
||||
if (existingOrgSponsorship != null)
|
||||
{
|
||||
// Replace existing invalid offer with our new sponsorship offer
|
||||
sponsorship.Id = existingOrgSponsorship.Id;
|
||||
}
|
||||
|
||||
return sponsorship;
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
|
||||
namespace Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.SponsorshipCreation;
|
||||
|
||||
public record CreateSponsorshipRequest(
|
||||
Organization SponsoringOrganization,
|
||||
OrganizationUser SponsoringMember,
|
||||
PlanSponsorshipType SponsorshipType,
|
||||
string SponsoredEmail,
|
||||
string FriendlyName,
|
||||
string Notes);
|
Reference in New Issue
Block a user