1
0
mirror of https://github.com/bitwarden/server.git synced 2025-05-10 06:02:24 -05:00

implement command

This commit is contained in:
Brandon 2025-05-09 11:06:14 -04:00
parent f47a65cfad
commit f76d6fde62
No known key found for this signature in database
GPG Key ID: A0E0EF0B207BA40D
3 changed files with 61 additions and 9 deletions

View File

@ -217,21 +217,29 @@ public class ImportOrganizationUserCommand : IImportOrganizationUserCommand
var commandResult = await InviteUsersAsync(userInvites, organization); var commandResult = await InviteUsersAsync(userInvites, organization);
//@TODO: replace with command, add invited users from commandResult to importData switch (commandResult)
//var invitedUsers = await _organizationService.InviteUsersAsync(organization.Id, invitingUserId: null, systemUser: eventSystemUser, userInvites); {
//foreach (var invitedUser in invitedUsers) case Success<InviteOrganizationUsersResponse> success:
//{ var result = success.Value;
// importData.ExistingExternalUsersIdDict.Add(invitedUser.ExternalId, invitedUser.Id); foreach (var u in result.InvitedUsers)
//} {
importData.ExistingExternalUsersIdDict.Add(u.ExternalId, u.Id);
}
break;
case Failure<InviteOrganizationUsersResponse> failure:
throw new BadRequestException(failure.ErrorMessage);
default:
throw new InvalidOperationException($"Unhandled commandResult type: {commandResult.GetType().Name}");
}
} }
private async Task<CommandResult<ScimInviteOrganizationUsersResponse>> InviteUsersAsync(List<OrganizationUserInviteCommandModel> invites, Organization organization) private async Task<CommandResult<InviteOrganizationUsersResponse>> InviteUsersAsync(List<OrganizationUserInviteCommandModel> invites, Organization organization)
{ {
var plan = await _pricingClient.GetPlanOrThrow(organization.PlanType); var plan = await _pricingClient.GetPlanOrThrow(organization.PlanType);
var inviteOrganization = new InviteOrganization(organization, plan); var inviteOrganization = new InviteOrganization(organization, plan);
var request = new InviteOrganizationUsersRequest(invites.ToArray(), inviteOrganization, Guid.Empty, DateTimeOffset.UtcNow); var request = new InviteOrganizationUsersRequest(invites.ToArray(), inviteOrganization, Guid.Empty, DateTimeOffset.UtcNow);
return await _inviteOrganizationUsersCommand.InviteScimOrganizationUserAsync(request); return await _inviteOrganizationUsersCommand.InviteImportedOrganizationUsersAsync(request, organization.Id);
} }
private async Task OverwriteExisting( private async Task OverwriteExisting(

View File

@ -19,4 +19,14 @@ public interface IInviteOrganizationUsersCommand
/// </param> /// </param>
/// <returns>Response from InviteScimOrganiation<see cref="ScimInviteOrganizationUsersResponse"/></returns> /// <returns>Response from InviteScimOrganiation<see cref="ScimInviteOrganizationUsersResponse"/></returns>
Task<CommandResult<ScimInviteOrganizationUsersResponse>> InviteScimOrganizationUserAsync(InviteOrganizationUsersRequest request); Task<CommandResult<ScimInviteOrganizationUsersResponse>> InviteScimOrganizationUserAsync(InviteOrganizationUsersRequest request);
/// <summary>
/// Sends invitations to add imported organization users via directory connector or public API.
/// This can be a Success or a Failure. Failure will contain the Error along with a representation of the errored value.
/// Success will be the successful return object.
/// </summary>
/// <param name="request">
/// Contains the details for inviting the imported organization users.
/// </param>
/// <returns>Response from InviteOrganiationUsersAsync<see cref="InviteOrganizationUsersResponse"/></returns>
Task<CommandResult<InviteOrganizationUsersResponse>> InviteImportedOrganizationUsersAsync(InviteOrganizationUsersRequest request, Guid organizationId);
} }

View File

@ -76,6 +76,40 @@ public class InviteOrganizationUsersCommand(IEventService eventService,
} }
} }
public async Task<CommandResult<InviteOrganizationUsersResponse>> InviteImportedOrganizationUsersAsync(InviteOrganizationUsersRequest request, Guid organizationId)
{
var result = await InviteOrganizationUsersAsync(request);
switch (result)
{
case Failure<InviteOrganizationUsersResponse> failure:
return new Failure<InviteOrganizationUsersResponse>(
failure.Errors.Select(error => new Error<InviteOrganizationUsersResponse>(error.Message,
new InviteOrganizationUsersResponse(error.ErroredValue.InvitedUsers, organizationId)
)));
case Success<InviteOrganizationUsersResponse> success when success.Value.InvitedUsers.Any():
// add a bulk method?
foreach (var user in success.Value.InvitedUsers)
{
await eventService.LogOrganizationUserEventAsync<IOrganizationUser>(
organizationUser: user,
type: EventType.OrganizationUser_Invited,
systemUser: EventSystemUser.PublicApi,
date: request.PerformedAt.UtcDateTime);
}
return new Success<InviteOrganizationUsersResponse>(new InviteOrganizationUsersResponse(success.Value.InvitedUsers, organizationId)
);
default:
return new Failure<InviteOrganizationUsersResponse>(
new InvalidResultTypeError<InviteOrganizationUsersResponse>(
new InviteOrganizationUsersResponse(organizationId)));
}
}
private async Task<CommandResult<InviteOrganizationUsersResponse>> InviteOrganizationUsersAsync(InviteOrganizationUsersRequest request) private async Task<CommandResult<InviteOrganizationUsersResponse>> InviteOrganizationUsersAsync(InviteOrganizationUsersRequest request)
{ {
var invitesToSend = (await FilterExistingUsersAsync(request)).ToArray(); var invitesToSend = (await FilterExistingUsersAsync(request)).ToArray();