1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-30 07:36:14 -05:00

[PM-17777] sponsorships consume seats (#5694)

* Admin initiated sponsorships now use seats similarly to inviting an organization user

* Updated f4e endpoint to not expect a user ID, and instead just send a boolean

* Fixed failing tests

* Updated OrganizationUserReadOccupiedSeatCountByOrganizationIdQuery to ensure both left and right sides are selecting the same columns
This commit is contained in:
Conner Turnbull
2025-04-24 10:53:34 -04:00
committed by GitHub
parent d265e62f6d
commit 8a2012bb83
10 changed files with 165 additions and 73 deletions

View File

@ -86,9 +86,9 @@ public class OrganizationSponsorshipsController : Controller
if (!_featureService.IsEnabled(Bit.Core.FeatureFlagKeys.PM17772_AdminInitiatedSponsorships))
{
if (model.SponsoringUserId.HasValue)
if (model.IsAdminInitiated.GetValueOrDefault())
{
throw new NotFoundException();
throw new BadRequestException();
}
if (!string.IsNullOrWhiteSpace(model.Notes))
@ -97,13 +97,13 @@ public class OrganizationSponsorshipsController : Controller
}
}
var targetUser = model.SponsoringUserId ?? _currentContext.UserId!.Value;
var sponsorship = await _createSponsorshipCommand.CreateSponsorshipAsync(
sponsoringOrg,
await _organizationUserRepository.GetByOrganizationAsync(sponsoringOrgId, targetUser),
await _organizationUserRepository.GetByOrganizationAsync(sponsoringOrgId, _currentContext.UserId ?? default),
model.PlanSponsorshipType,
model.SponsoredEmail,
model.FriendlyName,
model.IsAdminInitiated.GetValueOrDefault(),
model.Notes);
await _sendSponsorshipOfferCommand.SendSponsorshipOfferAsync(sponsorship, sponsoringOrg.Name);
}

View File

@ -47,9 +47,9 @@ public class SelfHostedOrganizationSponsorshipsController : Controller
{
if (!_featureService.IsEnabled(Bit.Core.FeatureFlagKeys.PM17772_AdminInitiatedSponsorships))
{
if (model.SponsoringUserId.HasValue)
if (model.IsAdminInitiated.GetValueOrDefault())
{
throw new NotFoundException();
throw new BadRequestException();
}
if (!string.IsNullOrWhiteSpace(model.Notes))
@ -60,8 +60,12 @@ public class SelfHostedOrganizationSponsorshipsController : Controller
await _offerSponsorshipCommand.CreateSponsorshipAsync(
await _organizationRepository.GetByIdAsync(sponsoringOrgId),
await _organizationUserRepository.GetByOrganizationAsync(sponsoringOrgId, model.SponsoringUserId ?? _currentContext.UserId ?? default),
model.PlanSponsorshipType, model.SponsoredEmail, model.FriendlyName, model.Notes);
await _organizationUserRepository.GetByOrganizationAsync(sponsoringOrgId, _currentContext.UserId ?? default),
model.PlanSponsorshipType,
model.SponsoredEmail,
model.FriendlyName,
model.IsAdminInitiated.GetValueOrDefault(),
model.Notes);
}
[HttpDelete("{sponsoringOrgId}")]

View File

@ -17,11 +17,7 @@ public class OrganizationSponsorshipCreateRequestModel
[StringLength(256)]
public string FriendlyName { get; set; }
/// <summary>
/// (optional) The user to target for the sponsorship.
/// </summary>
/// <remarks>Left empty when creating a sponsorship for the authenticated user.</remarks>
public Guid? SponsoringUserId { get; set; }
public bool? IsAdminInitiated { get; set; }
[EncryptedString]
[EncryptedStringLength(512)]