1212using Bit . Core . AdminConsole . Utilities . Commands ;
1313using Bit . Core . AdminConsole . Utilities . Errors ;
1414using Bit . Core . AdminConsole . Utilities . Validation ;
15+ using Bit . Core . Billing . Pricing ;
1516using Bit . Core . Entities ;
1617using Bit . Core . Enums ;
1718using Bit . Core . Models . Business ;
1819using Bit . Core . OrganizationFeatures . OrganizationSubscriptions . Interface ;
1920using Bit . Core . Repositories ;
2021using Bit . Core . Services ;
22+ using Bit . Core . Settings ;
2123using Microsoft . Extensions . Logging ;
2224
2325namespace Bit . Core . AdminConsole . OrganizationFeatures . OrganizationUsers . InviteUsers ;
@@ -32,7 +34,9 @@ public class InviteOrganizationUsersCommand(IEventService eventService,
3234 IUpdateSecretsManagerSubscriptionCommand updateSecretsManagerSubscriptionCommand ,
3335 ISendOrganizationInvitesCommand sendOrganizationInvitesCommand ,
3436 IProviderOrganizationRepository providerOrganizationRepository ,
35- IProviderUserRepository providerUserRepository
37+ IProviderUserRepository providerUserRepository ,
38+ IPricingClient pricingClient ,
39+ IGlobalSettings globalSettings
3640 ) : IInviteOrganizationUsersCommand
3741{
3842
@@ -83,7 +87,7 @@ public async Task<CommandResult<InviteOrganizationUsersResponse>> InviteImported
8387 return new Failure < InviteOrganizationUsersResponse > (
8488 new Error < InviteOrganizationUsersResponse > (
8589 failure . Error . Message ,
86- new InviteOrganizationUsersResponse ( failure . Error . ErroredValue . InvitedUsers , request . InviteOrganization . OrganizationId )
90+ new InviteOrganizationUsersResponse ( failure . Error . ErroredValue . InvitedUsers , request . Organization . Id )
8791 )
8892 ) ;
8993
@@ -97,34 +101,45 @@ public async Task<CommandResult<InviteOrganizationUsersResponse>> InviteImported
97101
98102 await eventService . LogOrganizationUserEventsAsync ( events ) ;
99103
100- return new Success < InviteOrganizationUsersResponse > ( new InviteOrganizationUsersResponse ( success . Value . InvitedUsers , request . InviteOrganization . OrganizationId )
104+ return new Success < InviteOrganizationUsersResponse > ( new InviteOrganizationUsersResponse ( success . Value . InvitedUsers , request . Organization . Id )
101105 ) ;
102106
103107 default :
104108 return new Failure < InviteOrganizationUsersResponse > (
105109 new InvalidResultTypeError < InviteOrganizationUsersResponse > (
106- new InviteOrganizationUsersResponse ( request . InviteOrganization . OrganizationId ) ) ) ;
110+ new InviteOrganizationUsersResponse ( request . Organization . Id ) ) ) ;
107111 }
108112 }
109113
110114 private async Task < CommandResult < InviteOrganizationUsersResponse > > InviteOrganizationUsersAsync ( InviteOrganizationUsersRequest request )
111115 {
116+ var plan = await pricingClient . GetPlan ( request . Organization . PlanType ) ;
117+ if ( plan is null && ! globalSettings . SelfHosted )
118+ {
119+ return new Failure < InviteOrganizationUsersResponse > (
120+ new Error < InviteOrganizationUsersResponse > (
121+ "Organization plan could not be found." ,
122+ new InviteOrganizationUsersResponse ( request . Organization . Id ) ) ) ;
123+ }
124+
125+ var inviteOrganization = new InviteOrganization ( request . Organization , plan ) ;
126+
112127 var invitesToSend = ( await FilterExistingUsersAsync ( request ) ) . ToArray ( ) ;
113128
114129 if ( invitesToSend . Length == 0 )
115130 {
116131 return new Failure < InviteOrganizationUsersResponse > ( new NoUsersToInviteError (
117- new InviteOrganizationUsersResponse ( request . InviteOrganization . OrganizationId ) ) ) ;
132+ new InviteOrganizationUsersResponse ( inviteOrganization . OrganizationId ) ) ) ;
118133 }
119134
120135 var validationResult = await inviteUsersValidator . ValidateAsync ( new InviteOrganizationUsersValidationRequest
121136 {
122137 Invites = invitesToSend . ToArray ( ) ,
123- InviteOrganization = request . InviteOrganization ,
138+ InviteOrganization = inviteOrganization ,
124139 PerformedBy = request . PerformedBy ,
125140 PerformedAt = request . PerformedAt ,
126- OccupiedPmSeats = ( await organizationRepository . GetOccupiedSeatCountByOrganizationIdAsync ( request . InviteOrganization . OrganizationId ) ) . Total ,
127- OccupiedSmSeats = await organizationUserRepository . GetOccupiedSmSeatCountByOrganizationIdAsync ( request . InviteOrganization . OrganizationId )
141+ OccupiedPmSeats = ( await organizationRepository . GetOccupiedSeatCountByOrganizationIdAsync ( inviteOrganization . OrganizationId ) ) . Total ,
142+ OccupiedSmSeats = await organizationUserRepository . GetOccupiedSmSeatCountByOrganizationIdAsync ( inviteOrganization . OrganizationId )
128143 } ) ;
129144
130145 if ( validationResult is Invalid < InviteOrganizationUsersValidationRequest > invalid )
@@ -177,7 +192,7 @@ private async Task<CommandResult<InviteOrganizationUsersResponse>> InviteOrganiz
177192 private async Task < IEnumerable < OrganizationUserInviteCommandModel > > FilterExistingUsersAsync ( InviteOrganizationUsersRequest request )
178193 {
179194 var existingEmails = new HashSet < string > ( await organizationUserRepository . SelectKnownEmailsAsync (
180- request . InviteOrganization . OrganizationId , request . Invites . Select ( i => i . Email ) , false ) ,
195+ request . Organization . Id , request . Invites . Select ( i => i . Email ) , false ) ,
181196 StringComparer . OrdinalIgnoreCase ) ;
182197
183198 return request . Invites
@@ -198,7 +213,8 @@ private async Task RevertPasswordManagerChangesAsync(Valid<InviteOrganizationUse
198213
199214 private async Task RevertSecretsManagerChangesAsync ( Valid < InviteOrganizationUsersValidationRequest > validatedResult , Organization organization , int ? initialSmSeats )
200215 {
201- if ( validatedResult . Value . SecretsManagerSubscriptionUpdate ? . SmSeatsChanged is true )
216+ if ( validatedResult . Value . SecretsManagerSubscriptionUpdate ? . SmSeatsChanged is true
217+ && validatedResult . Value . InviteOrganization . Plan is not null )
202218 {
203219 var smSubscriptionUpdateRevert = new SecretsManagerSubscriptionUpdate (
204220 organization : organization ,
0 commit comments