mirror of
https://github.com/bitwarden/server.git
synced 2024-12-23 17:07:42 +01:00
Additional 2FA tests (#1860)
* Add 2FA tests for organization * Move user tests to be in same directory * Fixed some names and namespace qualifications * Add GetTwoFactorProviders tests * Add tests to ensure we can read from name as well
This commit is contained in:
parent
8d6c49f656
commit
6f12a9e621
@ -61,7 +61,7 @@ namespace Bit.Core.Test.AutoFixture.CollectionFixtures
|
|||||||
|
|
||||||
internal class CollectionAutoDataAttribute : CustomAutoDataAttribute
|
internal class CollectionAutoDataAttribute : CustomAutoDataAttribute
|
||||||
{
|
{
|
||||||
public CollectionAutoDataAttribute() : base(new SutProviderCustomization(), new Bit.Core.Test.AutoFixture.OrganizationFixtures.Organization())
|
public CollectionAutoDataAttribute() : base(new SutProviderCustomization(), new OrganizationCustomization())
|
||||||
{ }
|
{ }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,21 +8,20 @@ using Bit.Core.Test.AutoFixture.Relays;
|
|||||||
using Bit.Infrastructure.EntityFramework.Repositories;
|
using Bit.Infrastructure.EntityFramework.Repositories;
|
||||||
using Bit.Test.Common.AutoFixture;
|
using Bit.Test.Common.AutoFixture;
|
||||||
using Bit.Test.Common.AutoFixture.Attributes;
|
using Bit.Test.Common.AutoFixture.Attributes;
|
||||||
using Fixtures = Bit.Core.Test.AutoFixture.OrganizationFixtures;
|
|
||||||
|
|
||||||
namespace Bit.Core.Test.AutoFixture.GroupFixtures
|
namespace Bit.Core.Test.AutoFixture.GroupFixtures
|
||||||
{
|
{
|
||||||
internal class GroupOrganizationAutoDataAttribute : CustomAutoDataAttribute
|
internal class GroupOrganizationAutoDataAttribute : CustomAutoDataAttribute
|
||||||
{
|
{
|
||||||
public GroupOrganizationAutoDataAttribute() : base(
|
public GroupOrganizationAutoDataAttribute() : base(
|
||||||
new SutProviderCustomization(), new Fixtures.Organization { UseGroups = true })
|
new SutProviderCustomization(), new OrganizationCustomization { UseGroups = true })
|
||||||
{ }
|
{ }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class GroupOrganizationNotUseGroupsAutoDataAttribute : CustomAutoDataAttribute
|
internal class GroupOrganizationNotUseGroupsAutoDataAttribute : CustomAutoDataAttribute
|
||||||
{
|
{
|
||||||
public GroupOrganizationNotUseGroupsAutoDataAttribute() : base(
|
public GroupOrganizationNotUseGroupsAutoDataAttribute() : base(
|
||||||
new SutProviderCustomization(), new Bit.Core.Test.AutoFixture.OrganizationFixtures.Organization { UseGroups = false })
|
new SutProviderCustomization(), new OrganizationCustomization { UseGroups = false })
|
||||||
{ }
|
{ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ using Bit.Test.Common.AutoFixture.Attributes;
|
|||||||
|
|
||||||
namespace Bit.Core.Test.AutoFixture.OrganizationFixtures
|
namespace Bit.Core.Test.AutoFixture.OrganizationFixtures
|
||||||
{
|
{
|
||||||
public class Organization : ICustomization
|
public class OrganizationCustomization : ICustomization
|
||||||
{
|
{
|
||||||
public bool UseGroups { get; set; }
|
public bool UseGroups { get; set; }
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ namespace Bit.Core.Test.AutoFixture.OrganizationFixtures
|
|||||||
var organizationId = Guid.NewGuid();
|
var organizationId = Guid.NewGuid();
|
||||||
var maxConnections = (short)new Random().Next(10, short.MaxValue);
|
var maxConnections = (short)new Random().Next(10, short.MaxValue);
|
||||||
|
|
||||||
fixture.Customize<Entities.Organization>(composer => composer
|
fixture.Customize<Organization>(composer => composer
|
||||||
.With(o => o.Id, organizationId)
|
.With(o => o.Id, organizationId)
|
||||||
.With(o => o.MaxCollections, maxConnections)
|
.With(o => o.MaxCollections, maxConnections)
|
||||||
.With(o => o.UseGroups, UseGroups));
|
.With(o => o.UseGroups, UseGroups));
|
||||||
@ -51,14 +51,14 @@ namespace Bit.Core.Test.AutoFixture.OrganizationFixtures
|
|||||||
}
|
}
|
||||||
|
|
||||||
var type = request as Type;
|
var type = request as Type;
|
||||||
if (type == null || type != typeof(Entities.Organization))
|
if (type == null || type != typeof(Organization))
|
||||||
{
|
{
|
||||||
return new NoSpecimen();
|
return new NoSpecimen();
|
||||||
}
|
}
|
||||||
|
|
||||||
var fixture = new Fixture();
|
var fixture = new Fixture();
|
||||||
var providers = fixture.Create<Dictionary<TwoFactorProviderType, TwoFactorProvider>>();
|
var providers = fixture.Create<Dictionary<TwoFactorProviderType, TwoFactorProvider>>();
|
||||||
var organization = new Fixture().WithAutoNSubstitutions().Create<Entities.Organization>();
|
var organization = new Fixture().WithAutoNSubstitutions().Create<Organization>();
|
||||||
organization.SetTwoFactorProviders(providers);
|
organization.SetTwoFactorProviders(providers);
|
||||||
return organization;
|
return organization;
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ namespace Bit.Core.Test.AutoFixture.OrganizationFixtures
|
|||||||
var lowestActivePaidPlan = validUpgradePlans.First();
|
var lowestActivePaidPlan = validUpgradePlans.First();
|
||||||
CheckedPlanType = CheckedPlanType.Equals(PlanType.Free) ? lowestActivePaidPlan : CheckedPlanType;
|
CheckedPlanType = CheckedPlanType.Equals(PlanType.Free) ? lowestActivePaidPlan : CheckedPlanType;
|
||||||
validUpgradePlans.Remove(lowestActivePaidPlan);
|
validUpgradePlans.Remove(lowestActivePaidPlan);
|
||||||
fixture.Customize<Entities.Organization>(composer => composer
|
fixture.Customize<Organization>(composer => composer
|
||||||
.With(o => o.PlanType, CheckedPlanType));
|
.With(o => o.PlanType, CheckedPlanType));
|
||||||
fixture.Customize<OrganizationUpgrade>(composer => composer
|
fixture.Customize<OrganizationUpgrade>(composer => composer
|
||||||
.With(ou => ou.Plan, validUpgradePlans.First()));
|
.With(ou => ou.Plan, validUpgradePlans.First()));
|
||||||
@ -84,7 +84,7 @@ namespace Bit.Core.Test.AutoFixture.OrganizationFixtures
|
|||||||
{
|
{
|
||||||
public void Customize(IFixture fixture)
|
public void Customize(IFixture fixture)
|
||||||
{
|
{
|
||||||
fixture.Customize<Entities.Organization>(composer => composer
|
fixture.Customize<Organization>(composer => composer
|
||||||
.With(o => o.PlanType, PlanType.Free));
|
.With(o => o.PlanType, PlanType.Free));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,7 +93,7 @@ namespace Bit.Core.Test.AutoFixture.OrganizationFixtures
|
|||||||
{
|
{
|
||||||
public void Customize(IFixture fixture)
|
public void Customize(IFixture fixture)
|
||||||
{
|
{
|
||||||
fixture.Customize<Entities.Organization>(composer => composer
|
fixture.Customize<Organization>(composer => composer
|
||||||
.With(o => o.PlanType, PlanType.Free));
|
.With(o => o.PlanType, PlanType.Free));
|
||||||
|
|
||||||
var plansToIgnore = new List<PlanType> { PlanType.Free, PlanType.Custom };
|
var plansToIgnore = new List<PlanType> { PlanType.Free, PlanType.Custom };
|
||||||
@ -102,7 +102,7 @@ namespace Bit.Core.Test.AutoFixture.OrganizationFixtures
|
|||||||
fixture.Customize<OrganizationUpgrade>(composer => composer
|
fixture.Customize<OrganizationUpgrade>(composer => composer
|
||||||
.With(ou => ou.Plan, selectedPlan.Type)
|
.With(ou => ou.Plan, selectedPlan.Type)
|
||||||
.With(ou => ou.PremiumAccessAddon, selectedPlan.HasPremiumAccessOption));
|
.With(ou => ou.PremiumAccessAddon, selectedPlan.HasPremiumAccessOption));
|
||||||
fixture.Customize<Entities.Organization>(composer => composer
|
fixture.Customize<Organization>(composer => composer
|
||||||
.Without(o => o.GatewaySubscriptionId));
|
.Without(o => o.GatewaySubscriptionId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,7 +119,7 @@ namespace Bit.Core.Test.AutoFixture.OrganizationFixtures
|
|||||||
{
|
{
|
||||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||||
});
|
});
|
||||||
fixture.Customize<Entities.Organization>(composer => composer
|
fixture.Customize<Organization>(composer => composer
|
||||||
.With(o => o.Id, organizationId)
|
.With(o => o.Id, organizationId)
|
||||||
.With(o => o.Seats, (short)100));
|
.With(o => o.Seats, (short)100));
|
||||||
fixture.Customize<OrganizationUser>(composer => composer
|
fixture.Customize<OrganizationUser>(composer => composer
|
||||||
|
@ -5,6 +5,7 @@ using System.Text.Json;
|
|||||||
using AutoFixture;
|
using AutoFixture;
|
||||||
using AutoFixture.Kernel;
|
using AutoFixture.Kernel;
|
||||||
using AutoFixture.Xunit2;
|
using AutoFixture.Xunit2;
|
||||||
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Models;
|
using Bit.Core.Models;
|
||||||
using Bit.Core.Models.Data;
|
using Bit.Core.Models.Data;
|
||||||
@ -27,10 +28,10 @@ namespace Bit.Core.Test.AutoFixture.OrganizationUserFixtures
|
|||||||
}
|
}
|
||||||
|
|
||||||
var type = request as Type;
|
var type = request as Type;
|
||||||
if (type == typeof(OrganizationUser))
|
if (type == typeof(OrganizationUserCustomization))
|
||||||
{
|
{
|
||||||
var fixture = new Fixture();
|
var fixture = new Fixture();
|
||||||
var orgUser = fixture.WithAutoNSubstitutions().Create<Entities.OrganizationUser>();
|
var orgUser = fixture.WithAutoNSubstitutions().Create<OrganizationUser>();
|
||||||
var orgUserPermissions = fixture.WithAutoNSubstitutions().Create<Permissions>();
|
var orgUserPermissions = fixture.WithAutoNSubstitutions().Create<Permissions>();
|
||||||
orgUser.Permissions = JsonSerializer.Serialize(orgUserPermissions, new JsonSerializerOptions()
|
orgUser.Permissions = JsonSerializer.Serialize(orgUserPermissions, new JsonSerializerOptions()
|
||||||
{
|
{
|
||||||
@ -38,10 +39,10 @@ namespace Bit.Core.Test.AutoFixture.OrganizationUserFixtures
|
|||||||
});
|
});
|
||||||
return orgUser;
|
return orgUser;
|
||||||
}
|
}
|
||||||
else if (type == typeof(List<OrganizationUser>))
|
else if (type == typeof(List<OrganizationUserCustomization>))
|
||||||
{
|
{
|
||||||
var fixture = new Fixture();
|
var fixture = new Fixture();
|
||||||
var orgUsers = fixture.WithAutoNSubstitutions().CreateMany<Entities.OrganizationUser>(2);
|
var orgUsers = fixture.WithAutoNSubstitutions().CreateMany<OrganizationUser>(2);
|
||||||
foreach (var orgUser in orgUsers)
|
foreach (var orgUser in orgUsers)
|
||||||
{
|
{
|
||||||
var providers = fixture.Create<Dictionary<TwoFactorProviderType, TwoFactorProvider>>();
|
var providers = fixture.Create<Dictionary<TwoFactorProviderType, TwoFactorProvider>>();
|
||||||
@ -57,12 +58,12 @@ namespace Bit.Core.Test.AutoFixture.OrganizationUserFixtures
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class OrganizationUser : ICustomization
|
internal class OrganizationUserCustomization : ICustomization
|
||||||
{
|
{
|
||||||
public OrganizationUserStatusType Status { get; set; }
|
public OrganizationUserStatusType Status { get; set; }
|
||||||
public OrganizationUserType Type { get; set; }
|
public OrganizationUserType Type { get; set; }
|
||||||
|
|
||||||
public OrganizationUser(OrganizationUserStatusType status, OrganizationUserType type)
|
public OrganizationUserCustomization(OrganizationUserStatusType status, OrganizationUserType type)
|
||||||
{
|
{
|
||||||
Status = status;
|
Status = status;
|
||||||
Type = type;
|
Type = type;
|
||||||
@ -70,7 +71,7 @@ namespace Bit.Core.Test.AutoFixture.OrganizationUserFixtures
|
|||||||
|
|
||||||
public void Customize(IFixture fixture)
|
public void Customize(IFixture fixture)
|
||||||
{
|
{
|
||||||
fixture.Customize<Entities.OrganizationUser>(composer => composer
|
fixture.Customize<OrganizationUser>(composer => composer
|
||||||
.With(o => o.Type, Type)
|
.With(o => o.Type, Type)
|
||||||
.With(o => o.Status, Status));
|
.With(o => o.Status, Status));
|
||||||
}
|
}
|
||||||
@ -91,7 +92,7 @@ namespace Bit.Core.Test.AutoFixture.OrganizationUserFixtures
|
|||||||
|
|
||||||
public override ICustomization GetCustomization(ParameterInfo parameter)
|
public override ICustomization GetCustomization(ParameterInfo parameter)
|
||||||
{
|
{
|
||||||
return new OrganizationUser(_status, _type);
|
return new OrganizationUserCustomization(_status, _type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ using System.Reflection;
|
|||||||
using AutoFixture;
|
using AutoFixture;
|
||||||
using AutoFixture.Kernel;
|
using AutoFixture.Kernel;
|
||||||
using AutoFixture.Xunit2;
|
using AutoFixture.Xunit2;
|
||||||
|
using Bit.Core.Entities;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
using Bit.Core.Test.AutoFixture.EntityFrameworkRepositoryFixtures;
|
using Bit.Core.Test.AutoFixture.EntityFrameworkRepositoryFixtures;
|
||||||
using Bit.Core.Test.AutoFixture.OrganizationFixtures;
|
using Bit.Core.Test.AutoFixture.OrganizationFixtures;
|
||||||
@ -12,18 +13,18 @@ using Bit.Test.Common.AutoFixture.Attributes;
|
|||||||
|
|
||||||
namespace Bit.Core.Test.AutoFixture.PolicyFixtures
|
namespace Bit.Core.Test.AutoFixture.PolicyFixtures
|
||||||
{
|
{
|
||||||
internal class Policy : ICustomization
|
internal class PolicyCustomization : ICustomization
|
||||||
{
|
{
|
||||||
public PolicyType Type { get; set; }
|
public PolicyType Type { get; set; }
|
||||||
|
|
||||||
public Policy(PolicyType type)
|
public PolicyCustomization(PolicyType type)
|
||||||
{
|
{
|
||||||
Type = type;
|
Type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Customize(IFixture fixture)
|
public void Customize(IFixture fixture)
|
||||||
{
|
{
|
||||||
fixture.Customize<Entities.Policy>(composer => composer
|
fixture.Customize<Policy>(composer => composer
|
||||||
.With(o => o.OrganizationId, Guid.NewGuid())
|
.With(o => o.OrganizationId, Guid.NewGuid())
|
||||||
.With(o => o.Type, Type)
|
.With(o => o.Type, Type)
|
||||||
.With(o => o.Enabled, true));
|
.With(o => o.Enabled, true));
|
||||||
@ -41,7 +42,7 @@ namespace Bit.Core.Test.AutoFixture.PolicyFixtures
|
|||||||
|
|
||||||
public override ICustomization GetCustomization(ParameterInfo parameter)
|
public override ICustomization GetCustomization(ParameterInfo parameter)
|
||||||
{
|
{
|
||||||
return new Policy(_type);
|
return new PolicyCustomization(_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,13 +56,13 @@ namespace Bit.Core.Test.AutoFixture.PolicyFixtures
|
|||||||
}
|
}
|
||||||
|
|
||||||
var type = request as Type;
|
var type = request as Type;
|
||||||
if (type == null || type != typeof(Entities.Policy))
|
if (type == null || type != typeof(Policy))
|
||||||
{
|
{
|
||||||
return new NoSpecimen();
|
return new NoSpecimen();
|
||||||
}
|
}
|
||||||
|
|
||||||
var fixture = new Fixture();
|
var fixture = new Fixture();
|
||||||
var obj = fixture.WithAutoNSubstitutions().Create<Entities.Policy>();
|
var obj = fixture.WithAutoNSubstitutions().Create<Policy>();
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ namespace Bit.Core.Test.AutoFixture.TransactionFixtures
|
|||||||
}
|
}
|
||||||
|
|
||||||
var type = request as Type;
|
var type = request as Type;
|
||||||
if (type == null || type != typeof(Entities.Transaction))
|
if (type == null || type != typeof(Transaction))
|
||||||
{
|
{
|
||||||
return new NoSpecimen();
|
return new NoSpecimen();
|
||||||
}
|
}
|
||||||
@ -35,7 +35,7 @@ namespace Bit.Core.Test.AutoFixture.TransactionFixtures
|
|||||||
.Without(c => c.OrganizationId));
|
.Without(c => c.OrganizationId));
|
||||||
}
|
}
|
||||||
fixture.Customizations.Add(new MaxLengthStringRelay());
|
fixture.Customizations.Add(new MaxLengthStringRelay());
|
||||||
var obj = fixture.WithAutoNSubstitutions().Create<Entities.Transaction>();
|
var obj = fixture.WithAutoNSubstitutions().Create<Transaction>();
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,4 +71,3 @@ namespace Bit.Core.Test.AutoFixture.TransactionFixtures
|
|||||||
{ }
|
{ }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
101
test/Core.Test/Entities/OrganizationTests.cs
Normal file
101
test/Core.Test/Entities/OrganizationTests.cs
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.Json;
|
||||||
|
using Bit.Core.Entities;
|
||||||
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.Models;
|
||||||
|
using Bit.Test.Common.Helpers;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Bit.Core.Test.Entities
|
||||||
|
{
|
||||||
|
public class OrganizationTests
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<TwoFactorProviderType, TwoFactorProvider> _testConfig = new Dictionary<TwoFactorProviderType, TwoFactorProvider>()
|
||||||
|
{
|
||||||
|
[TwoFactorProviderType.OrganizationDuo] = new TwoFactorProvider
|
||||||
|
{
|
||||||
|
Enabled = true,
|
||||||
|
MetaData = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["IKey"] = "IKey_value",
|
||||||
|
["SKey"] = "SKey_value",
|
||||||
|
["Host"] = "Host_value",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SetTwoFactorProviders_Success()
|
||||||
|
{
|
||||||
|
var organization = new Organization();
|
||||||
|
organization.SetTwoFactorProviders(_testConfig);
|
||||||
|
|
||||||
|
using var jsonDocument = JsonDocument.Parse(organization.TwoFactorProviders);
|
||||||
|
var root = jsonDocument.RootElement;
|
||||||
|
|
||||||
|
var duo = AssertHelper.AssertJsonProperty(root, "6", JsonValueKind.Object);
|
||||||
|
AssertHelper.AssertJsonProperty(duo, "Enabled", JsonValueKind.True);
|
||||||
|
var duoMetaData = AssertHelper.AssertJsonProperty(duo, "MetaData", JsonValueKind.Object);
|
||||||
|
var iKey = AssertHelper.AssertJsonProperty(duoMetaData, "IKey", JsonValueKind.String).GetString();
|
||||||
|
Assert.Equal("IKey_value", iKey);
|
||||||
|
var sKey = AssertHelper.AssertJsonProperty(duoMetaData, "SKey", JsonValueKind.String).GetString();
|
||||||
|
Assert.Equal("SKey_value", sKey);
|
||||||
|
var host = AssertHelper.AssertJsonProperty(duoMetaData, "Host", JsonValueKind.String).GetString();
|
||||||
|
Assert.Equal("Host_value", host);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetTwoFactorProviders_Success()
|
||||||
|
{
|
||||||
|
// This is to get rid of the cached dictionary the SetTwoFactorProviders keeps so we can fully test the JSON reading
|
||||||
|
// It intent is to mimic a storing of the entity in the database and it being read later
|
||||||
|
var tempOrganization = new Organization();
|
||||||
|
tempOrganization.SetTwoFactorProviders(_testConfig);
|
||||||
|
var organization = new Organization
|
||||||
|
{
|
||||||
|
TwoFactorProviders = tempOrganization.TwoFactorProviders,
|
||||||
|
};
|
||||||
|
|
||||||
|
var twoFactorProviders = organization.GetTwoFactorProviders();
|
||||||
|
|
||||||
|
var duo = Assert.Contains(TwoFactorProviderType.OrganizationDuo, (IDictionary<TwoFactorProviderType, TwoFactorProvider>)twoFactorProviders);
|
||||||
|
Assert.True(duo.Enabled);
|
||||||
|
Assert.NotNull(duo.MetaData);
|
||||||
|
var iKey = Assert.Contains("IKey", (IDictionary<string, object>)duo.MetaData);
|
||||||
|
Assert.Equal("IKey_value", iKey);
|
||||||
|
var sKey = Assert.Contains("SKey", (IDictionary<string, object>)duo.MetaData);
|
||||||
|
Assert.Equal("SKey_value", sKey);
|
||||||
|
var host = Assert.Contains("Host", (IDictionary<string, object>)duo.MetaData);
|
||||||
|
Assert.Equal("Host_value", host);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetTwoFactorProviders_SavedWithName_Success()
|
||||||
|
{
|
||||||
|
var organization = new Organization();
|
||||||
|
// This should save items with the string name of the enum and we will validate that we can read
|
||||||
|
// from that just incase some organizations have it saved that way.
|
||||||
|
organization.TwoFactorProviders = JsonSerializer.Serialize(_testConfig);
|
||||||
|
|
||||||
|
// Preliminary Asserts to make sure we are testing what we want to be testing
|
||||||
|
using var jsonDocument = JsonDocument.Parse(organization.TwoFactorProviders);
|
||||||
|
var root = jsonDocument.RootElement;
|
||||||
|
// This means it saved the enum as its string name
|
||||||
|
AssertHelper.AssertJsonProperty(root, "OrganizationDuo", JsonValueKind.Object);
|
||||||
|
|
||||||
|
// Actual checks
|
||||||
|
var twoFactorProviders = organization.GetTwoFactorProviders();
|
||||||
|
|
||||||
|
var duo = Assert.Contains(TwoFactorProviderType.OrganizationDuo, (IDictionary<TwoFactorProviderType, TwoFactorProvider>)twoFactorProviders);
|
||||||
|
Assert.True(duo.Enabled);
|
||||||
|
Assert.NotNull(duo.MetaData);
|
||||||
|
var iKey = Assert.Contains("IKey", (IDictionary<string, object>)duo.MetaData);
|
||||||
|
Assert.Equal("IKey_value", iKey);
|
||||||
|
var sKey = Assert.Contains("SKey", (IDictionary<string, object>)duo.MetaData);
|
||||||
|
Assert.Equal("SKey_value", sKey);
|
||||||
|
var host = Assert.Contains("Host", (IDictionary<string, object>)duo.MetaData);
|
||||||
|
Assert.Equal("Host_value", host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
146
test/Core.Test/Entities/UserTests.cs
Normal file
146
test/Core.Test/Entities/UserTests.cs
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.Json;
|
||||||
|
using Bit.Core.Entities;
|
||||||
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.Models;
|
||||||
|
using Bit.Test.Common.Helpers;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Bit.Core.Test.Entities
|
||||||
|
{
|
||||||
|
public class UserTests
|
||||||
|
{
|
||||||
|
// KB MB GB
|
||||||
|
public const long Multiplier = 1024 * 1024 * 1024;
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void StorageBytesRemaining_HasMax_DoesNotHaveStorage_ReturnsMaxAsBytes()
|
||||||
|
{
|
||||||
|
short maxStorageGb = 1;
|
||||||
|
|
||||||
|
var user = new User
|
||||||
|
{
|
||||||
|
MaxStorageGb = maxStorageGb,
|
||||||
|
Storage = null,
|
||||||
|
};
|
||||||
|
|
||||||
|
var bytesRemaining = user.StorageBytesRemaining();
|
||||||
|
|
||||||
|
Assert.Equal(bytesRemaining, maxStorageGb * Multiplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(2, 1 * Multiplier, 1 * Multiplier)]
|
||||||
|
|
||||||
|
public void StorageBytesRemaining_HasMax_HasStorage_ReturnRemainingStorage(short maxStorageGb, long storageBytes, long expectedRemainingBytes)
|
||||||
|
{
|
||||||
|
var user = new User
|
||||||
|
{
|
||||||
|
MaxStorageGb = maxStorageGb,
|
||||||
|
Storage = storageBytes,
|
||||||
|
};
|
||||||
|
|
||||||
|
var bytesRemaining = user.StorageBytesRemaining();
|
||||||
|
|
||||||
|
Assert.Equal(expectedRemainingBytes, bytesRemaining);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Dictionary<TwoFactorProviderType, TwoFactorProvider> _testTwoFactorConfig = new Dictionary<TwoFactorProviderType, TwoFactorProvider>
|
||||||
|
{
|
||||||
|
[TwoFactorProviderType.WebAuthn] = new TwoFactorProvider
|
||||||
|
{
|
||||||
|
Enabled = true,
|
||||||
|
MetaData = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["Item"] = "thing",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[TwoFactorProviderType.Email] = new TwoFactorProvider
|
||||||
|
{
|
||||||
|
Enabled = false,
|
||||||
|
MetaData = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["Email"] = "test@email.com",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SetTwoFactorProviders_Success()
|
||||||
|
{
|
||||||
|
var user = new User();
|
||||||
|
user.SetTwoFactorProviders(_testTwoFactorConfig);
|
||||||
|
|
||||||
|
using var jsonDocument = JsonDocument.Parse(user.TwoFactorProviders);
|
||||||
|
var root = jsonDocument.RootElement;
|
||||||
|
|
||||||
|
var webAuthn = AssertHelper.AssertJsonProperty(root, "7", JsonValueKind.Object);
|
||||||
|
AssertHelper.AssertJsonProperty(webAuthn, "Enabled", JsonValueKind.True);
|
||||||
|
var webMetaData = AssertHelper.AssertJsonProperty(webAuthn, "MetaData", JsonValueKind.Object);
|
||||||
|
AssertHelper.AssertJsonProperty(webMetaData, "Item", JsonValueKind.String);
|
||||||
|
|
||||||
|
var email = AssertHelper.AssertJsonProperty(root, "1", JsonValueKind.Object);
|
||||||
|
AssertHelper.AssertJsonProperty(email, "Enabled", JsonValueKind.False);
|
||||||
|
var emailMetaData = AssertHelper.AssertJsonProperty(email, "MetaData", JsonValueKind.Object);
|
||||||
|
AssertHelper.AssertJsonProperty(emailMetaData, "Email", JsonValueKind.String);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetTwoFactorProviders_Success()
|
||||||
|
{
|
||||||
|
// This is to get rid of the cached dictionary the SetTwoFactorProviders keeps so we can fully test the JSON reading
|
||||||
|
// It intent is to mimic a storing of the entity in the database and it being read later
|
||||||
|
var tempUser = new User();
|
||||||
|
tempUser.SetTwoFactorProviders(_testTwoFactorConfig);
|
||||||
|
var user = new User
|
||||||
|
{
|
||||||
|
TwoFactorProviders = tempUser.TwoFactorProviders,
|
||||||
|
};
|
||||||
|
|
||||||
|
var twoFactorProviders = user.GetTwoFactorProviders();
|
||||||
|
|
||||||
|
var webAuthn = Assert.Contains(TwoFactorProviderType.WebAuthn, (IDictionary<TwoFactorProviderType, TwoFactorProvider>)twoFactorProviders);
|
||||||
|
Assert.True(webAuthn.Enabled);
|
||||||
|
Assert.NotNull(webAuthn.MetaData);
|
||||||
|
var webAuthnMetaDataItem = Assert.Contains("Item", (IDictionary<string, object>)webAuthn.MetaData);
|
||||||
|
Assert.Equal("thing", webAuthnMetaDataItem);
|
||||||
|
|
||||||
|
var email = Assert.Contains(TwoFactorProviderType.Email, (IDictionary<TwoFactorProviderType, TwoFactorProvider>)twoFactorProviders);
|
||||||
|
Assert.False(email.Enabled);
|
||||||
|
Assert.NotNull(email.MetaData);
|
||||||
|
var emailMetaDataEmail = Assert.Contains("Email", (IDictionary<string, object>)email.MetaData);
|
||||||
|
Assert.Equal("test@email.com", emailMetaDataEmail);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetTwoFactorProviders_SavedWithName_Success()
|
||||||
|
{
|
||||||
|
var user = new User();
|
||||||
|
// This should save items with the string name of the enum and we will validate that we can read
|
||||||
|
// from that just incase some users have it saved that way.
|
||||||
|
user.TwoFactorProviders = JsonSerializer.Serialize(_testTwoFactorConfig);
|
||||||
|
|
||||||
|
// Preliminary Asserts to make sure we are testing what we want to be testing
|
||||||
|
using var jsonDocument = JsonDocument.Parse(user.TwoFactorProviders);
|
||||||
|
var root = jsonDocument.RootElement;
|
||||||
|
// This means it saved the enum as its string name
|
||||||
|
AssertHelper.AssertJsonProperty(root, "WebAuthn", JsonValueKind.Object);
|
||||||
|
AssertHelper.AssertJsonProperty(root, "Email", JsonValueKind.Object);
|
||||||
|
|
||||||
|
// Actual checks
|
||||||
|
var twoFactorProviders = user.GetTwoFactorProviders();
|
||||||
|
|
||||||
|
var webAuthn = Assert.Contains(TwoFactorProviderType.WebAuthn, (IDictionary<TwoFactorProviderType, TwoFactorProvider>)twoFactorProviders);
|
||||||
|
Assert.True(webAuthn.Enabled);
|
||||||
|
Assert.NotNull(webAuthn.MetaData);
|
||||||
|
var webAuthnMetaDataItem = Assert.Contains("Item", (IDictionary<string, object>)webAuthn.MetaData);
|
||||||
|
Assert.Equal("thing", webAuthnMetaDataItem);
|
||||||
|
|
||||||
|
var email = Assert.Contains(TwoFactorProviderType.Email, (IDictionary<TwoFactorProviderType, TwoFactorProvider>)twoFactorProviders);
|
||||||
|
Assert.False(email.Enabled);
|
||||||
|
Assert.NotNull(email.MetaData);
|
||||||
|
var emailMetaDataEmail = Assert.Contains("Email", (IDictionary<string, object>)email.MetaData);
|
||||||
|
Assert.Equal("test@email.com", emailMetaDataEmail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,86 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Text.Json;
|
|
||||||
using Bit.Core.Entities;
|
|
||||||
using Bit.Core.Enums;
|
|
||||||
using Bit.Core.Models;
|
|
||||||
using Bit.Test.Common.Helpers;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Bit.Core.Test.Models.Tables
|
|
||||||
{
|
|
||||||
public class UserTests
|
|
||||||
{
|
|
||||||
// KB MB GB
|
|
||||||
public const long Multiplier = 1024 * 1024 * 1024;
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void StorageBytesRemaining_HasMax_DoesNotHaveStorage_ReturnsMaxAsBytes()
|
|
||||||
{
|
|
||||||
short maxStorageGb = 1;
|
|
||||||
|
|
||||||
var user = new User
|
|
||||||
{
|
|
||||||
MaxStorageGb = maxStorageGb,
|
|
||||||
Storage = null,
|
|
||||||
};
|
|
||||||
|
|
||||||
var bytesRemaining = user.StorageBytesRemaining();
|
|
||||||
|
|
||||||
Assert.Equal(bytesRemaining, maxStorageGb * Multiplier);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(2, 1 * Multiplier, 1 * Multiplier)]
|
|
||||||
|
|
||||||
public void StorageBytesRemaining_HasMax_HasStorage_ReturnRemainingStorage(short maxStorageGb, long storageBytes, long expectedRemainingBytes)
|
|
||||||
{
|
|
||||||
var user = new User
|
|
||||||
{
|
|
||||||
MaxStorageGb = maxStorageGb,
|
|
||||||
Storage = storageBytes,
|
|
||||||
};
|
|
||||||
|
|
||||||
var bytesRemaining = user.StorageBytesRemaining();
|
|
||||||
|
|
||||||
Assert.Equal(expectedRemainingBytes, bytesRemaining);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void SetTwoFactorProviders()
|
|
||||||
{
|
|
||||||
var user = new User();
|
|
||||||
user.SetTwoFactorProviders(new Dictionary<TwoFactorProviderType, TwoFactorProvider>
|
|
||||||
{
|
|
||||||
[TwoFactorProviderType.WebAuthn] = new TwoFactorProvider
|
|
||||||
{
|
|
||||||
Enabled = true,
|
|
||||||
MetaData = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
["Item"] = "thing",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[TwoFactorProviderType.Email] = new TwoFactorProvider
|
|
||||||
{
|
|
||||||
Enabled = false,
|
|
||||||
MetaData = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
["Email"] = "test@email.com",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
using var jsonDocument = JsonDocument.Parse(user.TwoFactorProviders);
|
|
||||||
var root = jsonDocument.RootElement;
|
|
||||||
|
|
||||||
var webAuthn = AssertHelper.AssertJsonProperty(root, "7", JsonValueKind.Object);
|
|
||||||
AssertHelper.AssertJsonProperty(webAuthn, "Enabled", JsonValueKind.True);
|
|
||||||
var webMetaData = AssertHelper.AssertJsonProperty(webAuthn, "MetaData", JsonValueKind.Object);
|
|
||||||
AssertHelper.AssertJsonProperty(webMetaData, "Item", JsonValueKind.String);
|
|
||||||
|
|
||||||
var email = AssertHelper.AssertJsonProperty(root, "1", JsonValueKind.Object);
|
|
||||||
AssertHelper.AssertJsonProperty(email, "Enabled", JsonValueKind.False);
|
|
||||||
var emailMetaData = AssertHelper.AssertJsonProperty(email, "MetaData", JsonValueKind.Object);
|
|
||||||
AssertHelper.AssertJsonProperty(emailMetaData, "Email", JsonValueKind.String);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,6 +10,7 @@ using Bit.Core.Models.Data;
|
|||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Core.Services;
|
using Bit.Core.Services;
|
||||||
using Bit.Core.Test.AutoFixture.SendFixtures;
|
using Bit.Core.Test.AutoFixture.SendFixtures;
|
||||||
|
using Bit.Core.Test.Entities;
|
||||||
using Bit.Test.Common.AutoFixture;
|
using Bit.Test.Common.AutoFixture;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using NSubstitute;
|
using NSubstitute;
|
||||||
@ -254,7 +255,7 @@ namespace Bit.Core.Test.Services
|
|||||||
EmailVerified = true,
|
EmailVerified = true,
|
||||||
Premium = true,
|
Premium = true,
|
||||||
MaxStorageGb = 2,
|
MaxStorageGb = 2,
|
||||||
Storage = 2 * Models.Tables.UserTests.Multiplier,
|
Storage = 2 * UserTests.Multiplier,
|
||||||
};
|
};
|
||||||
|
|
||||||
send.UserId = user.Id;
|
send.UserId = user.Id;
|
||||||
@ -302,7 +303,7 @@ namespace Bit.Core.Test.Services
|
|||||||
.SelfHosted = true;
|
.SelfHosted = true;
|
||||||
|
|
||||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||||
sutProvider.Sut.SaveFileSendAsync(send, null, 11000 * Models.Tables.UserTests.Multiplier)
|
sutProvider.Sut.SaveFileSendAsync(send, null, 11000 * UserTests.Multiplier)
|
||||||
);
|
);
|
||||||
|
|
||||||
Assert.Contains("not enough storage", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
Assert.Contains("not enough storage", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
||||||
@ -335,7 +336,7 @@ namespace Bit.Core.Test.Services
|
|||||||
.SelfHosted = false;
|
.SelfHosted = false;
|
||||||
|
|
||||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||||
sutProvider.Sut.SaveFileSendAsync(send, null, 2 * Models.Tables.UserTests.Multiplier)
|
sutProvider.Sut.SaveFileSendAsync(send, null, 2 * UserTests.Multiplier)
|
||||||
);
|
);
|
||||||
|
|
||||||
Assert.Contains("not enough storage", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
Assert.Contains("not enough storage", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
||||||
@ -413,7 +414,7 @@ namespace Bit.Core.Test.Services
|
|||||||
.Returns(org);
|
.Returns(org);
|
||||||
|
|
||||||
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
var badRequest = await Assert.ThrowsAsync<BadRequestException>(() =>
|
||||||
sutProvider.Sut.SaveFileSendAsync(send, null, 2 * Models.Tables.UserTests.Multiplier)
|
sutProvider.Sut.SaveFileSendAsync(send, null, 2 * UserTests.Multiplier)
|
||||||
);
|
);
|
||||||
|
|
||||||
Assert.Contains("not enough storage", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
Assert.Contains("not enough storage", badRequest.Message, StringComparison.InvariantCultureIgnoreCase);
|
||||||
@ -455,7 +456,7 @@ namespace Bit.Core.Test.Services
|
|||||||
|
|
||||||
var utcNow = DateTime.UtcNow;
|
var utcNow = DateTime.UtcNow;
|
||||||
|
|
||||||
var url = await sutProvider.Sut.SaveFileSendAsync(send, data, 1 * Models.Tables.UserTests.Multiplier);
|
var url = await sutProvider.Sut.SaveFileSendAsync(send, data, 1 * UserTests.Multiplier);
|
||||||
|
|
||||||
Assert.Equal(testUrl, url);
|
Assert.Equal(testUrl, url);
|
||||||
Assert.True(send.RevisionDate - utcNow < TimeSpan.FromSeconds(1));
|
Assert.True(send.RevisionDate - utcNow < TimeSpan.FromSeconds(1));
|
||||||
@ -510,7 +511,7 @@ namespace Bit.Core.Test.Services
|
|||||||
var utcNow = DateTime.UtcNow;
|
var utcNow = DateTime.UtcNow;
|
||||||
|
|
||||||
var exception = await Assert.ThrowsAsync<Exception>(() =>
|
var exception = await Assert.ThrowsAsync<Exception>(() =>
|
||||||
sutProvider.Sut.SaveFileSendAsync(send, data, 1 * Models.Tables.UserTests.Multiplier)
|
sutProvider.Sut.SaveFileSendAsync(send, data, 1 * UserTests.Multiplier)
|
||||||
);
|
);
|
||||||
|
|
||||||
Assert.True(send.RevisionDate - utcNow < TimeSpan.FromSeconds(1));
|
Assert.True(send.RevisionDate - utcNow < TimeSpan.FromSeconds(1));
|
||||||
|
Loading…
Reference in New Issue
Block a user