mirror of
https://github.com/bitwarden/server.git
synced 2025-05-09 21:52:17 -05:00
rename OrganizatinUserInvite for command, implement command
This commit is contained in:
parent
1f5ea44a07
commit
f47a65cfad
@ -4,7 +4,7 @@ using Bit.Api.Models.Public.Response;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||
using Bit.Core.Settings;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@ -15,18 +15,18 @@ namespace Bit.Api.AdminConsole.Public.Controllers;
|
||||
[Authorize("Organization")]
|
||||
public class OrganizationController : Controller
|
||||
{
|
||||
private readonly IOrganizationService _organizationService;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly IImportOrganizationUserCommand _importOrganizationUserCommand;
|
||||
|
||||
public OrganizationController(
|
||||
IOrganizationService organizationService,
|
||||
ICurrentContext currentContext,
|
||||
GlobalSettings globalSettings)
|
||||
GlobalSettings globalSettings,
|
||||
IImportOrganizationUserCommand importOrganizationUserCommand)
|
||||
{
|
||||
_organizationService = organizationService;
|
||||
_currentContext = currentContext;
|
||||
_globalSettings = globalSettings;
|
||||
_importOrganizationUserCommand = importOrganizationUserCommand;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -47,7 +47,7 @@ public class OrganizationController : Controller
|
||||
throw new BadRequestException("You cannot import this much data at once.");
|
||||
}
|
||||
|
||||
await _organizationService.ImportAsync(
|
||||
await _importOrganizationUserCommand.ImportAsync(
|
||||
_currentContext.OrganizationId.Value,
|
||||
model.Groups.Select(g => g.ToImportedGroup(_currentContext.OrganizationId.Value)),
|
||||
model.Members.Where(u => !u.Deleted).Select(u => u.ToImportedOrganizationUser()),
|
||||
|
@ -1,12 +1,15 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Models.Business;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models;
|
||||
using Bit.Core.AdminConsole.Repositories;
|
||||
using Bit.Core.Billing.Pricing;
|
||||
using Bit.Core.Context;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Commands;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
using Bit.Core.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||
using Bit.Core.Repositories;
|
||||
@ -14,7 +17,6 @@ using Bit.Core.Services;
|
||||
using Bit.Core.Tools.Enums;
|
||||
using Bit.Core.Tools.Models.Business;
|
||||
using Bit.Core.Tools.Services;
|
||||
using OrganizationUserInvite = Bit.Core.Models.Business.OrganizationUserInvite;
|
||||
|
||||
public class ImportOrganizationUserCommand : IImportOrganizationUserCommand
|
||||
{
|
||||
@ -26,6 +28,8 @@ public class ImportOrganizationUserCommand : IImportOrganizationUserCommand
|
||||
private readonly IReferenceEventService _referenceEventService;
|
||||
private readonly ICurrentContext _currentContext;
|
||||
private readonly IOrganizationService _organizationService;
|
||||
private readonly IInviteOrganizationUsersCommand _inviteOrganizationUsersCommand;
|
||||
private readonly IPricingClient _pricingClient;
|
||||
|
||||
public ImportOrganizationUserCommand(IOrganizationRepository organizationRepository,
|
||||
IOrganizationUserRepository organizationUserRepository,
|
||||
@ -34,7 +38,9 @@ public class ImportOrganizationUserCommand : IImportOrganizationUserCommand
|
||||
IEventService eventService,
|
||||
IReferenceEventService referenceEventService,
|
||||
ICurrentContext currentContext,
|
||||
IOrganizationService organizationService
|
||||
IOrganizationService organizationService,
|
||||
IInviteOrganizationUsersCommand inviteOrganizationUsersCommand,
|
||||
IPricingClient pricingClient
|
||||
)
|
||||
{
|
||||
_organizationRepository = organizationRepository;
|
||||
@ -45,6 +51,8 @@ public class ImportOrganizationUserCommand : IImportOrganizationUserCommand
|
||||
_referenceEventService = referenceEventService;
|
||||
_currentContext = currentContext;
|
||||
_organizationService = organizationService;
|
||||
_inviteOrganizationUsersCommand = inviteOrganizationUsersCommand;
|
||||
_pricingClient = pricingClient;
|
||||
}
|
||||
|
||||
public async Task ImportAsync(Guid organizationId,
|
||||
@ -187,7 +195,7 @@ public class ImportOrganizationUserCommand : IImportOrganizationUserCommand
|
||||
|
||||
var hasStandaloneSecretsManager = await _paymentService.HasSecretsManagerStandalone(organization);
|
||||
|
||||
var userInvites = new List<(OrganizationUserInvite, string)>();
|
||||
var userInvites = new List<OrganizationUserInviteCommandModel>();
|
||||
foreach (var user in newUsers)
|
||||
{
|
||||
if (!usersToAdd.Contains(user.ExternalId) || string.IsNullOrWhiteSpace(user.Email))
|
||||
@ -197,14 +205,8 @@ public class ImportOrganizationUserCommand : IImportOrganizationUserCommand
|
||||
|
||||
try
|
||||
{
|
||||
var invite = new OrganizationUserInvite
|
||||
{
|
||||
Emails = new List<string> { user.Email },
|
||||
Type = OrganizationUserType.User,
|
||||
Collections = new List<CollectionAccessSelection>(),
|
||||
AccessSecretsManager = hasStandaloneSecretsManager
|
||||
};
|
||||
userInvites.Add((invite, user.ExternalId));
|
||||
var invite = new OrganizationUserInviteCommandModel(user.Email, user.ExternalId);
|
||||
userInvites.Add(new OrganizationUserInviteCommandModel(invite, hasStandaloneSecretsManager));
|
||||
}
|
||||
catch (BadRequestException)
|
||||
{
|
||||
@ -213,12 +215,23 @@ public class ImportOrganizationUserCommand : IImportOrganizationUserCommand
|
||||
}
|
||||
}
|
||||
|
||||
//@TODO: replace with command
|
||||
var invitedUsers = await _organizationService.InviteUsersAsync(organization.Id, invitingUserId: null, systemUser: eventSystemUser, userInvites);
|
||||
foreach (var invitedUser in invitedUsers)
|
||||
{
|
||||
importData.ExistingExternalUsersIdDict.Add(invitedUser.ExternalId, invitedUser.Id);
|
||||
}
|
||||
var commandResult = await InviteUsersAsync(userInvites, organization);
|
||||
|
||||
//@TODO: replace with command, add invited users from commandResult to importData
|
||||
//var invitedUsers = await _organizationService.InviteUsersAsync(organization.Id, invitingUserId: null, systemUser: eventSystemUser, userInvites);
|
||||
//foreach (var invitedUser in invitedUsers)
|
||||
//{
|
||||
// importData.ExistingExternalUsersIdDict.Add(invitedUser.ExternalId, invitedUser.Id);
|
||||
//}
|
||||
}
|
||||
|
||||
private async Task<CommandResult<ScimInviteOrganizationUsersResponse>> InviteUsersAsync(List<OrganizationUserInviteCommandModel> invites, Organization organization)
|
||||
{
|
||||
var plan = await _pricingClient.GetPlanOrThrow(organization.PlanType);
|
||||
var inviteOrganization = new InviteOrganization(organization, plan);
|
||||
var request = new InviteOrganizationUsersRequest(invites.ToArray(), inviteOrganization, Guid.Empty, DateTimeOffset.UtcNow);
|
||||
|
||||
return await _inviteOrganizationUsersCommand.InviteScimOrganizationUserAsync(request);
|
||||
}
|
||||
|
||||
private async Task OverwriteExisting(
|
||||
|
@ -19,7 +19,6 @@ using Bit.Core.Tools.Enums;
|
||||
using Bit.Core.Tools.Models.Business;
|
||||
using Bit.Core.Tools.Services;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using OrganizationUserInvite = Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models.OrganizationUserInvite;
|
||||
|
||||
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers;
|
||||
|
||||
@ -146,7 +145,7 @@ public class InviteOrganizationUsersCommand(IEventService eventService,
|
||||
organizationId: organization!.Id));
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<OrganizationUserInvite>> FilterExistingUsersAsync(InviteOrganizationUsersRequest request)
|
||||
private async Task<IEnumerable<OrganizationUserInviteCommandModel>> FilterExistingUsersAsync(InviteOrganizationUsersRequest request)
|
||||
{
|
||||
var existingEmails = new HashSet<string>(await organizationUserRepository.SelectKnownEmailsAsync(
|
||||
request.InviteOrganization.OrganizationId, request.Invites.Select(i => i.Email), false),
|
||||
|
@ -7,7 +7,7 @@ namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUse
|
||||
|
||||
public static class CreateOrganizationUserExtensions
|
||||
{
|
||||
public static CreateOrganizationUser MapToDataModel(this OrganizationUserInvite organizationUserInvite,
|
||||
public static CreateOrganizationUser MapToDataModel(this OrganizationUserInviteCommandModel organizationUserInvite,
|
||||
DateTimeOffset performedAt,
|
||||
InviteOrganization organization) =>
|
||||
new()
|
||||
|
@ -4,12 +4,12 @@ namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUse
|
||||
|
||||
public class InviteOrganizationUsersRequest
|
||||
{
|
||||
public OrganizationUserInvite[] Invites { get; } = [];
|
||||
public OrganizationUserInviteCommandModel[] Invites { get; } = [];
|
||||
public InviteOrganization InviteOrganization { get; }
|
||||
public Guid PerformedBy { get; }
|
||||
public DateTimeOffset PerformedAt { get; }
|
||||
|
||||
public InviteOrganizationUsersRequest(OrganizationUserInvite[] invites,
|
||||
public InviteOrganizationUsersRequest(OrganizationUserInviteCommandModel[] invites,
|
||||
InviteOrganization inviteOrganization,
|
||||
Guid performedBy,
|
||||
DateTimeOffset performedAt)
|
||||
|
@ -29,7 +29,7 @@ public class InviteOrganizationUsersValidationRequest
|
||||
SecretsManagerSubscriptionUpdate = smSubscriptionUpdate;
|
||||
}
|
||||
|
||||
public OrganizationUserInvite[] Invites { get; init; } = [];
|
||||
public OrganizationUserInviteCommandModel[] Invites { get; init; } = [];
|
||||
public InviteOrganization InviteOrganization { get; init; }
|
||||
public Guid PerformedBy { get; init; }
|
||||
public DateTimeOffset PerformedAt { get; init; }
|
||||
|
@ -7,7 +7,7 @@ using static Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Invite
|
||||
|
||||
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models;
|
||||
|
||||
public class OrganizationUserInvite
|
||||
public class OrganizationUserInviteCommandModel
|
||||
{
|
||||
public string Email { get; private init; }
|
||||
public CollectionAccessSelection[] AssignedCollections { get; private init; }
|
||||
@ -17,7 +17,7 @@ public class OrganizationUserInvite
|
||||
public bool AccessSecretsManager { get; private init; }
|
||||
public Guid[] Groups { get; private init; }
|
||||
|
||||
public OrganizationUserInvite(string email, string externalId) :
|
||||
public OrganizationUserInviteCommandModel(string email, string externalId) :
|
||||
this(
|
||||
email: email,
|
||||
assignedCollections: [],
|
||||
@ -29,7 +29,7 @@ public class OrganizationUserInvite
|
||||
{
|
||||
}
|
||||
|
||||
public OrganizationUserInvite(OrganizationUserInvite invite, bool accessSecretsManager) :
|
||||
public OrganizationUserInviteCommandModel(OrganizationUserInviteCommandModel invite, bool accessSecretsManager) :
|
||||
this(invite.Email,
|
||||
invite.AssignedCollections,
|
||||
invite.Groups,
|
||||
@ -41,7 +41,7 @@ public class OrganizationUserInvite
|
||||
|
||||
}
|
||||
|
||||
public OrganizationUserInvite(string email,
|
||||
public OrganizationUserInviteCommandModel(string email,
|
||||
IEnumerable<CollectionAccessSelection> assignedCollections,
|
||||
IEnumerable<Guid> groups,
|
||||
OrganizationUserType type,
|
@ -6,7 +6,6 @@ using Bit.Core.Models.Business;
|
||||
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Services;
|
||||
using OrganizationUserInvite = Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models.OrganizationUserInvite;
|
||||
|
||||
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation;
|
||||
|
||||
@ -38,7 +37,7 @@ public class InviteOrganizationUsersValidator(
|
||||
request = new InviteOrganizationUsersValidationRequest(request)
|
||||
{
|
||||
Invites = request.Invites
|
||||
.Select(x => new OrganizationUserInvite(x, accessSecretsManager: true))
|
||||
.Select(x => new OrganizationUserInviteCommandModel(x, accessSecretsManager: true))
|
||||
.ToArray()
|
||||
};
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
using System.Security.Claims;
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Models.Business;
|
||||
using Bit.Core.Auth.Enums;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
@ -39,9 +38,6 @@ public interface IOrganizationService
|
||||
Task<IEnumerable<Tuple<OrganizationUser, string>>> ResendInvitesAsync(Guid organizationId, Guid? invitingUserId, IEnumerable<Guid> organizationUsersId);
|
||||
Task ResendInviteAsync(Guid organizationId, Guid? invitingUserId, Guid organizationUserId, bool initOrganization = false);
|
||||
Task UpdateUserResetPasswordEnrollmentAsync(Guid organizationId, Guid userId, string resetPasswordKey, Guid? callingUserId);
|
||||
Task ImportAsync(Guid organizationId, IEnumerable<ImportedGroup> groups,
|
||||
IEnumerable<ImportedOrganizationUser> newUsers, IEnumerable<string> removeUserExternalIds,
|
||||
bool overwriteExisting, EventSystemUser eventSystemUser);
|
||||
Task DeleteSsoUserAsync(Guid userId, Guid? organizationId);
|
||||
Task RevokeUserAsync(OrganizationUser organizationUser, Guid? revokingUserId);
|
||||
Task RevokeUserAsync(OrganizationUser organizationUser, EventSystemUser systemUser);
|
||||
|
@ -3,7 +3,6 @@ using System.Text.Json;
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Enums;
|
||||
using Bit.Core.AdminConsole.Enums.Provider;
|
||||
using Bit.Core.AdminConsole.Models.Business;
|
||||
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers;
|
||||
@ -26,7 +25,6 @@ using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Business;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
|
||||
using Bit.Core.OrganizationFeatures.OrganizationUsers.Interfaces;
|
||||
using Bit.Core.Platform.Push;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Settings;
|
||||
@ -74,7 +72,6 @@ public class OrganizationService : IOrganizationService
|
||||
private readonly IPricingClient _pricingClient;
|
||||
private readonly IPolicyRequirementQuery _policyRequirementQuery;
|
||||
private readonly ISendOrganizationInvitesCommand _sendOrganizationInvitesCommand;
|
||||
private readonly IImportOrganizationUserCommand _importOrganizationUserCommand;
|
||||
|
||||
public OrganizationService(
|
||||
IOrganizationRepository organizationRepository,
|
||||
@ -108,8 +105,7 @@ public class OrganizationService : IOrganizationService
|
||||
IHasConfirmedOwnersExceptQuery hasConfirmedOwnersExceptQuery,
|
||||
IPricingClient pricingClient,
|
||||
IPolicyRequirementQuery policyRequirementQuery,
|
||||
ISendOrganizationInvitesCommand sendOrganizationInvitesCommand,
|
||||
IImportOrganizationUserCommand importOrganizationUserCommand
|
||||
ISendOrganizationInvitesCommand sendOrganizationInvitesCommand
|
||||
)
|
||||
{
|
||||
_organizationRepository = organizationRepository;
|
||||
@ -144,7 +140,6 @@ public class OrganizationService : IOrganizationService
|
||||
_pricingClient = pricingClient;
|
||||
_policyRequirementQuery = policyRequirementQuery;
|
||||
_sendOrganizationInvitesCommand = sendOrganizationInvitesCommand;
|
||||
_importOrganizationUserCommand = importOrganizationUserCommand;
|
||||
}
|
||||
|
||||
public async Task ReplacePaymentMethodAsync(Guid organizationId, string paymentToken,
|
||||
@ -1203,23 +1198,6 @@ public class OrganizationService : IOrganizationService
|
||||
EventType.OrganizationUser_ResetPassword_Enroll : EventType.OrganizationUser_ResetPassword_Withdraw);
|
||||
}
|
||||
|
||||
public async Task ImportAsync(Guid organizationId,
|
||||
IEnumerable<ImportedGroup> groups,
|
||||
IEnumerable<ImportedOrganizationUser> newUsers,
|
||||
IEnumerable<string> removeUserExternalIds,
|
||||
bool overwriteExisting,
|
||||
EventSystemUser eventSystemUser
|
||||
)
|
||||
{
|
||||
// @TODO DEVELOPMENT FLAG FOR TESTING ---- REVERT THIS LATER
|
||||
await _importOrganizationUserCommand.ImportAsync(organizationId,
|
||||
groups,
|
||||
newUsers,
|
||||
removeUserExternalIds,
|
||||
overwriteExisting,
|
||||
eventSystemUser);
|
||||
}
|
||||
|
||||
public async Task DeleteSsoUserAsync(Guid userId, Guid? organizationId)
|
||||
{
|
||||
await _ssoUserRepository.DeleteAsync(userId, organizationId);
|
||||
|
Loading…
x
Reference in New Issue
Block a user