1
0
mirror of https://github.com/bitwarden/server.git synced 2025-02-22 02:51:33 +01:00

api endpoints for seats, upgrade, and cancel org

This commit is contained in:
Kyle Spearrin 2017-04-10 11:49:53 -04:00
parent f8baf3abb3
commit ce93d4b07e
5 changed files with 76 additions and 6 deletions

View File

@ -128,6 +128,45 @@ namespace Bit.Api.Controllers
await _organizationService.ReplacePaymentMethodAsync(orgIdGuid, model.PaymentToken);
}
[HttpPut("{id}/upgrade")]
[HttpPost("{id}/upgrade")]
public async Task PutUpgrade(string id, [FromBody]OrganizationUpgradeRequestModel model)
{
var orgIdGuid = new Guid(id);
if(!_currentContext.OrganizationOwner(orgIdGuid))
{
throw new NotFoundException();
}
await _organizationService.UpgradePlanAsync(orgIdGuid, model.PlanType, model.AdditionalSeats);
}
[HttpPut("{id}/seat")]
[HttpPost("{id}/seat")]
public async Task PutSeat(string id, [FromBody]OrganizationSeatRequestModel model)
{
var orgIdGuid = new Guid(id);
if(!_currentContext.OrganizationOwner(orgIdGuid))
{
throw new NotFoundException();
}
await _organizationService.AdjustSeatsAsync(orgIdGuid, model.SeatAdjustment.Value);
}
[HttpPut("{id}/cancel")]
[HttpPost("{id}/cancel")]
public async Task PutCancel(string id, [FromBody]OrganizationSeatRequestModel model)
{
var orgIdGuid = new Guid(id);
if(!_currentContext.OrganizationOwner(orgIdGuid))
{
throw new NotFoundException();
}
await _organizationService.CancelSubscriptionAsync(orgIdGuid, true);
}
[HttpDelete("{id}")]
[HttpPost("{id}/delete")]
public async Task Delete(string id)

View File

@ -0,0 +1,10 @@
using System.ComponentModel.DataAnnotations;
namespace Bit.Core.Models.Api
{
public class OrganizationSeatRequestModel
{
[Required]
public int? SeatAdjustment { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using Bit.Core.Enums;
using System.ComponentModel.DataAnnotations;
namespace Bit.Core.Models.Api
{
public class OrganizationUpgradeRequestModel
{
public PlanType PlanType { get; set; }
[Range(0, double.MaxValue)]
public short AdditionalSeats { get; set; }
}
}

View File

@ -3,6 +3,7 @@ using Bit.Core.Models.Business;
using Bit.Core.Models.Table;
using System;
using System.Collections.Generic;
using Bit.Core.Enums;
namespace Bit.Core.Services
{
@ -11,6 +12,8 @@ namespace Bit.Core.Services
Task<OrganizationBilling> GetBillingAsync(Organization organization);
Task ReplacePaymentMethodAsync(Guid organizationId, string paymentToken);
Task CancelSubscriptionAsync(Guid organizationId, bool endOfPeriod = false);
Task UpgradePlanAsync(Guid organizationId, PlanType plan, int additionalSeats);
Task AdjustSeatsAsync(Guid organizationId, int seatAdjustment);
Task<Tuple<Organization, OrganizationUser>> SignUpAsync(OrganizationSignup organizationSignup);
Task<OrganizationUser> InviteUserAsync(Guid organizationId, Guid invitingUserId, string email,
Enums.OrganizationUserType type, IEnumerable<SubvaultUser> subvaults);

View File

@ -175,7 +175,7 @@ namespace Bit.Core.Services
}
}
public async Task UpgradePlanAsync(Guid organizationId, PlanType plan, short additionalSeats)
public async Task UpgradePlanAsync(Guid organizationId, PlanType plan, int additionalSeats)
{
var organization = await _organizationRepository.GetByIdAsync(organizationId);
if(organization == null)
@ -300,7 +300,7 @@ namespace Bit.Core.Services
}
}
public async Task AdjustAdditionalSeatsAsync(Guid organizationId, short additionalSeats)
public async Task AdjustSeatsAsync(Guid organizationId, int seatAdjustment)
{
var organization = await _organizationRepository.GetByIdAsync(organizationId);
if(organization == null)
@ -329,20 +329,26 @@ namespace Bit.Core.Services
throw new BadRequestException("Plan does not allow additional seats.");
}
var newSeatTotal = organization.Seats + seatAdjustment;
if(plan.BaseSeats > newSeatTotal)
{
throw new BadRequestException($"Plan has a minimum of {plan.BaseSeats} seats.");
}
var additionalSeats = newSeatTotal - plan.BaseSeats;
if(plan.MaxAdditionalSeats.HasValue && additionalSeats > plan.MaxAdditionalSeats.Value)
{
throw new BadRequestException($"Organization plan allows a maximum of " +
$"{plan.MaxAdditionalSeats.Value} additional seats.");
}
var planNewSeats = (short)(plan.BaseSeats + additionalSeats);
if(!organization.Seats.HasValue || organization.Seats.Value > planNewSeats)
if(!organization.Seats.HasValue || organization.Seats.Value > newSeatTotal)
{
var userCount = await _organizationUserRepository.GetCountByOrganizationIdAsync(organization.Id);
if(userCount >= planNewSeats)
if(userCount > newSeatTotal)
{
throw new BadRequestException($"Your organization currently has {userCount} seats filled. Your new plan " +
$"only has ({planNewSeats}) seats. Remove some users.");
$"only has ({newSeatTotal}) seats. Remove some users.");
}
}