1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-22 12:15:36 +01:00

added max subvault count. check max org users.

This commit is contained in:
Kyle Spearrin 2017-04-07 16:41:04 -04:00
parent e3cc1b9411
commit 51e8d3f1a7
12 changed files with 78 additions and 3 deletions

View File

@ -32,7 +32,7 @@ namespace Bit.Core.Models.Api
public string BillingEmail { get; set; }
public string Plan { get; set; }
public Enums.PlanType PlanType { get; set; }
public short MaxUsers { get; set; }
public short? MaxUsers { get; set; }
}
public class OrganizationBillingResponseModel : OrganizationResponseModel

View File

@ -18,6 +18,7 @@ namespace Bit.Core.Models.StaticStore
public decimal UserMonthlyPrice { get; set; }
public decimal BaseAnnualPrice { get; set; }
public decimal UserAnnualPrice { get; set; }
public short? MaxSubvaults { get; set; }
public bool Disabled { get; set; }
}
}

View File

@ -12,7 +12,7 @@ namespace Bit.Core.Models.Table
public string BillingEmail { get; set; }
public string Plan { get; set; }
public PlanType PlanType { get; set; }
public short MaxUsers { get; set; }
public short? MaxUsers { get; set; }
public short? MaxSubvaults { get; set; }
public string StripeCustomerId { get; set; }
public string StripeSubscriptionId { get; set; }

View File

@ -9,6 +9,7 @@ namespace Bit.Core.Repositories
{
public interface IOrganizationUserRepository : IRepository<OrganizationUser, Guid>
{
Task<int> GetCountByOrganizationIdAsync(Guid organizationId);
Task<int> GetCountByFreeOrganizationAdminUserAsync(Guid userId);
Task<ICollection<OrganizationUser>> GetManyByUserAsync(Guid userId);
Task<ICollection<OrganizationUser>> GetManyByOrganizationAsync(Guid organizationId, OrganizationUserType? type);

View File

@ -7,6 +7,7 @@ namespace Bit.Core.Repositories
{
public interface ISubvaultRepository : IRepository<Subvault, Guid>
{
Task<int> GetCountByOrganizationIdAsync(Guid organizationId);
Task<ICollection<Subvault>> GetManyByOrganizationIdAsync(Guid organizationId);
Task<ICollection<Subvault>> GetManyByUserIdAsync(Guid userId);

View File

@ -21,6 +21,19 @@ namespace Bit.Core.Repositories.SqlServer
: base(connectionString)
{ }
public async Task<int> GetCountByOrganizationIdAsync(Guid organizationId)
{
using(var connection = new SqlConnection(ConnectionString))
{
var results = await connection.ExecuteScalarAsync<int>(
"[dbo].[OrganizationUser_ReadCountByOrganizationId]",
new { OrganizationId = organizationId },
commandType: CommandType.StoredProcedure);
return results;
}
}
public async Task<int> GetCountByFreeOrganizationAdminUserAsync(Guid userId)
{
using(var connection = new SqlConnection(ConnectionString))

View File

@ -19,6 +19,19 @@ namespace Bit.Core.Repositories.SqlServer
: base(connectionString)
{ }
public async Task<int> GetCountByOrganizationIdAsync(Guid organizationId)
{
using(var connection = new SqlConnection(ConnectionString))
{
var results = await connection.ExecuteScalarAsync<int>(
"[dbo].[Subvault_ReadCountByOrganizationId]",
new { OrganizationId = organizationId },
commandType: CommandType.StoredProcedure);
return results;
}
}
public async Task<ICollection<Subvault>> GetManyByOrganizationIdAsync(Guid organizationId)
{
using(var connection = new SqlConnection(ConnectionString))

View File

@ -76,7 +76,7 @@ namespace Bit.Core.Services
public async Task<Tuple<Organization, OrganizationUser>> SignUpAsync(OrganizationSignup signup)
{
var plan = StaticStore.Plans.FirstOrDefault(p => p.Type == signup.Plan);
var plan = StaticStore.Plans.FirstOrDefault(p => p.Type == signup.Plan && !p.Disabled);
if(plan == null)
{
throw new BadRequestException("Plan not found.");
@ -136,6 +136,7 @@ namespace Bit.Core.Services
BusinessName = signup.BusinessName,
PlanType = plan.Type,
MaxUsers = (short)(plan.BaseUsers + (plan.CanBuyAdditionalUsers ? signup.AdditionalUsers : 0)),
MaxSubvaults = plan.MaxSubvaults,
Plan = plan.ToString(),
StripeCustomerId = customer?.Id,
StripeSubscriptionId = subscription?.Id,
@ -184,6 +185,22 @@ namespace Bit.Core.Services
public async Task<OrganizationUser> InviteUserAsync(Guid organizationId, Guid invitingUserId, string email,
Enums.OrganizationUserType type, IEnumerable<SubvaultUser> subvaults)
{
var organization = await _organizationRepository.GetByIdAsync(organizationId);
if(organization == null)
{
throw new NotFoundException();
}
if(organization.MaxUsers.HasValue)
{
var userCount = await _organizationUserRepository.GetCountByOrganizationIdAsync(organizationId);
if(userCount >= organization.MaxUsers.Value)
{
throw new BadRequestException("You have reached the maximum number of users " +
$"({organization.MaxUsers.Value}) for this organization.");
}
}
// Make sure user is not already invited
var existingOrgUser = await _organizationUserRepository.GetByOrganizationAsync(organizationId, email);
if(existingOrgUser != null)

View File

@ -96,6 +96,7 @@ namespace Bit.Core.Utilities
Type = PlanType.Free,
BaseUsers = 2,
CanBuyAdditionalUsers = false,
MaxSubvaults = 2,
Name = "Free"
},
new Plan

View File

@ -181,5 +181,7 @@
<Build Include="dbo\Stored Procedures\OrganizationUserUserDetails_ReadById.sql" />
<Build Include="dbo\Stored Procedures\OrganizationUserUserDetails_ReadByOrganizationId.sql" />
<Build Include="dbo\User Defined Types\GuidIdArray.sql" />
<Build Include="dbo\Stored Procedures\OrganizationUser_ReadCountByOrganizationId.sql" />
<Build Include="dbo\Stored Procedures\Subvault_ReadCountByOrganizationId.sql" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,13 @@
CREATE PROCEDURE [dbo].[OrganizationUser_ReadCountByOrganizationId]
@OrganizationId UNIQUEIDENTIFIER
AS
BEGIN
SET NOCOUNT ON
SELECT
COUNT(1)
FROM
[dbo].[OrganizationUser]
WHERE
[OrganizationId] = @OrganizationId
END

View File

@ -0,0 +1,13 @@
CREATE PROCEDURE [dbo].[Subvault_ReadCountByOrganizationId]
@OrganizationId UNIQUEIDENTIFIER
AS
BEGIN
SET NOCOUNT ON
SELECT
COUNT(1)
FROM
[dbo].[Subvault]
WHERE
[OrganizationId] = @OrganizationId
END