Browse Source

Restructuring finished.

pull/65/head
Sebastian Stehle 9 years ago
parent
commit
46bcd6c050
  1. 7
      Dockerfile.build
  2. 88
      Squidex.sln
  3. 19
      src/Squidex.Domain.Apps.Core/Identity/SquidexClaimTypes.cs
  4. 21
      src/Squidex.Domain.Apps.Core/Identity/SquidexRoles.cs
  5. 5
      src/Squidex.Domain.Apps.Core/Squidex.Domain.Apps.Core.csproj
  6. 3
      src/Squidex.Domain.Apps.Read.MongoDb/Squidex.Domain.Apps.Read.MongoDb.csproj
  7. 93
      src/Squidex.Domain.Apps.Read.MongoDb/Users/MongoRoleStore.cs
  8. 329
      src/Squidex.Domain.Apps.Read.MongoDb/Users/MongoUserStore.cs
  9. 17
      src/Squidex.Domain.Apps.Read.MongoDb/Users/WrappedIdentityRole.cs
  10. 46
      src/Squidex.Domain.Apps.Read.MongoDb/Users/WrappedIdentityUser.cs
  11. 2
      src/Squidex.Domain.Apps.Read/Squidex.Domain.Apps.Read.csproj
  12. 43
      src/Squidex.Domain.Apps.Read/Users/AssetUserPictureStore.cs
  13. 32
      src/Squidex.Domain.Apps.Read/Users/ExternalLogin.cs
  14. 15
      src/Squidex.Domain.Apps.Read/Users/IRole.cs
  15. 15
      src/Squidex.Domain.Apps.Read/Users/IRoleFactory.cs
  16. 34
      src/Squidex.Domain.Apps.Read/Users/IUser.cs
  17. 15
      src/Squidex.Domain.Apps.Read/Users/IUserFactory.cs
  18. 20
      src/Squidex.Domain.Apps.Read/Users/IUserPictureStore.cs
  19. 17
      src/Squidex.Domain.Apps.Read/Users/IUserResolver.cs
  20. 74
      src/Squidex.Domain.Apps.Read/Users/UserExtensions.cs
  21. 131
      src/Squidex.Domain.Apps.Read/Users/UserManagerExtensions.cs
  22. 2
      src/Squidex.Domain.Apps.Write/Apps/AppCommandHandler.cs
  23. 1
      src/Squidex.Domain.Apps.Write/Squidex.Domain.Apps.Write.csproj
  24. 2
      src/Squidex.Domain.Users.MongoDb/Infrastructure/MongoPersistedGrantStore.cs
  25. 2
      src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj
  26. 2
      src/Squidex/Config/Domain/ReadModule.cs
  27. 7
      src/Squidex/Config/Domain/StoreMongoDbModule.cs
  28. 2
      src/Squidex/Config/Identity/GithubHandler.cs
  29. 2
      src/Squidex/Config/Identity/GoogleHandler.cs
  30. 5
      src/Squidex/Config/Identity/IdentityServices.cs
  31. 5
      src/Squidex/Config/Identity/IdentityUsage.cs
  32. 2
      src/Squidex/Config/Identity/MicrosoftHandler.cs
  33. 12
      src/Squidex/Controllers/Api/Users/UserManagementController.cs
  34. 7
      src/Squidex/Controllers/Api/Users/UsersController.cs
  35. 2
      src/Squidex/Controllers/ContentApi/Generator/SchemasSwaggerGenerator.cs
  36. 5
      src/Squidex/Controllers/UI/Account/AccountController.cs
  37. 3
      src/Squidex/Controllers/UI/Extensions.cs
  38. 3
      src/Squidex/Controllers/UI/Profile/ProfileController.cs
  39. 2
      src/Squidex/Controllers/UI/Profile/ProfileVM.cs
  40. 2
      src/Squidex/Pipeline/AppApiFilter.cs
  41. 2
      src/Squidex/Pipeline/MustBeAdministratorAttribute.cs
  42. 2
      src/Squidex/Pipeline/MustBeAppDeveloperAttribute.cs
  43. 2
      src/Squidex/Pipeline/MustBeAppEditorAttribute.cs
  44. 2
      src/Squidex/Pipeline/MustBeAppOwnerAttribute.cs
  45. 2
      src/Squidex/Pipeline/Swagger/SwaggerHelper.cs
  46. 3
      src/Squidex/Squidex.csproj
  47. 1
      tests/Benchmarks/IBenchmark.cs
  48. 17
      tests/RunCoverage.ps1
  49. 2
      tests/Squidex.Domain.Apps.Write.Tests/Apps/AppCommandHandlerTests.cs
  50. 1
      tests/Squidex.Domain.Apps.Write.Tests/Squidex.Domain.Apps.Write.Tests.csproj
  51. 2
      tests/Squidex.Domain.Users.Tests/AssetUserPictureStoreTests.cs
  52. 28
      tests/Squidex.Domain.Users.Tests/Squidex.Domain.Users.Tests.csproj

7
Dockerfile.build

@ -43,9 +43,10 @@ RUN cp -a /tmp/node_modules /src/Squidex/ \
# Test Backend
RUN dotnet restore \
&& dotnet test tests/Squidex.Infrastructure.Tests/Squidex.Infrastructure.Tests.csproj \
&& dotnet test tests/Squidex.Domain.Apps.Core.Tests/Squidex.Core.Tests.csproj \
&& dotnet test tests/Squidex.Domain.Apps.Read.Tests/Squidex.Read.Tests.csproj \
&& dotnet test tests/Squidex.Domain.Apps.Write.Tests/Squidex.Write.Tests.csproj
&& dotnet test tests/Squidex.Domain.Apps.Core.Tests/Squidex.Domain.Apps.Core.Tests.csproj \
&& dotnet test tests/Squidex.Domain.Apps.Read.Tests/Squidex.Domain.Apps.Read.Tests.csproj \
&& dotnet test tests/Squidex.Domain.Apps.Write.Tests/Squidex.Domain.Apps.Write.Tests.csproj \
&& dotnet test tests/Squidex.Domain.Users.Tests/Squidex.Domain.Users.Tests.csproj
# Publish
RUN dotnet publish src/Squidex/Squidex.csproj --output /out/ --configuration Release

88
Squidex.sln

@ -1,12 +1,12 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26430.14
VisualStudioVersion = 15.0.26430.15
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex", "src\Squidex\Squidex.csproj", "{61F6BBCE-A080-4400-B194-70E2F5D2096E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "squidex_infrastructure", "squidex_infrastructure", "{8CF53B92-5EB1-461D-98F8-70DA9B603FBF}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "infrastructure", "infrastructure", "{8CF53B92-5EB1-461D-98F8-70DA9B603FBF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "squidex_domain", "squidex_domain", "{4C6B06C2-6D77-4E0E-AE32-D7050236433A}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "domain", "domain", "{4C6B06C2-6D77-4E0E-AE32-D7050236433A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Domain.Apps.Core", "src\Squidex.Domain.Apps.Core\Squidex.Domain.Apps.Core.csproj", "{47F3C27E-698B-4EDF-A7E8-D7F4232AFBB0}"
EndProject
@ -44,6 +44,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "migrations", "migrations",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Migrate_01", "tools\Migrate_01\Migrate_01.csproj", "{B51126A8-0D75-4A79-867D-10724EC6AC84}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Shared", "src\Squidex.Shared\Squidex.Shared.csproj", "{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "apps", "apps", "{C9809D59-6665-471E-AD87-5AC624C65892}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "users", "users", "{C0D540F0-9158-4528-BFD8-BEAE6EAE45EA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Domain.Users", "src\Squidex.Domain.Users\Squidex.Domain.Users.csproj", "{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.Domain.Users.MongoDb", "src\Squidex.Domain.Users.MongoDb\Squidex.Domain.Users.MongoDb.csproj", "{27CF800D-890F-4882-BF05-44EC3233537D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Squidex.Domain.Users.Tests", "tests\Squidex.Domain.Users.Tests\Squidex.Domain.Users.Tests.csproj", "{42184546-E3CB-4D4F-9495-43979B9C63B9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -206,26 +218,80 @@ Global
{B51126A8-0D75-4A79-867D-10724EC6AC84}.Release|x64.Build.0 = Release|Any CPU
{B51126A8-0D75-4A79-867D-10724EC6AC84}.Release|x86.ActiveCfg = Release|Any CPU
{B51126A8-0D75-4A79-867D-10724EC6AC84}.Release|x86.Build.0 = Release|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Debug|x64.ActiveCfg = Debug|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Debug|x64.Build.0 = Debug|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Debug|x86.ActiveCfg = Debug|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Debug|x86.Build.0 = Debug|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Release|Any CPU.Build.0 = Release|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Release|x64.ActiveCfg = Release|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Release|x64.Build.0 = Release|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Release|x86.ActiveCfg = Release|Any CPU
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F}.Release|x86.Build.0 = Release|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Debug|x64.ActiveCfg = Debug|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Debug|x64.Build.0 = Debug|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Debug|x86.ActiveCfg = Debug|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Debug|x86.Build.0 = Debug|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Release|Any CPU.Build.0 = Release|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Release|x64.ActiveCfg = Release|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Release|x64.Build.0 = Release|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Release|x86.ActiveCfg = Release|Any CPU
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0}.Release|x86.Build.0 = Release|Any CPU
{27CF800D-890F-4882-BF05-44EC3233537D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{27CF800D-890F-4882-BF05-44EC3233537D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{27CF800D-890F-4882-BF05-44EC3233537D}.Debug|x64.ActiveCfg = Debug|Any CPU
{27CF800D-890F-4882-BF05-44EC3233537D}.Debug|x64.Build.0 = Debug|Any CPU
{27CF800D-890F-4882-BF05-44EC3233537D}.Debug|x86.ActiveCfg = Debug|Any CPU
{27CF800D-890F-4882-BF05-44EC3233537D}.Debug|x86.Build.0 = Debug|Any CPU
{27CF800D-890F-4882-BF05-44EC3233537D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{27CF800D-890F-4882-BF05-44EC3233537D}.Release|Any CPU.Build.0 = Release|Any CPU
{27CF800D-890F-4882-BF05-44EC3233537D}.Release|x64.ActiveCfg = Release|Any CPU
{27CF800D-890F-4882-BF05-44EC3233537D}.Release|x64.Build.0 = Release|Any CPU
{27CF800D-890F-4882-BF05-44EC3233537D}.Release|x86.ActiveCfg = Release|Any CPU
{27CF800D-890F-4882-BF05-44EC3233537D}.Release|x86.Build.0 = Release|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Debug|x64.ActiveCfg = Debug|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Debug|x64.Build.0 = Debug|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Debug|x86.ActiveCfg = Debug|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Debug|x86.Build.0 = Debug|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Release|Any CPU.Build.0 = Release|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Release|x64.ActiveCfg = Release|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Release|x64.Build.0 = Release|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Release|x86.ActiveCfg = Release|Any CPU
{42184546-E3CB-4D4F-9495-43979B9C63B9}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{47F3C27E-698B-4EDF-A7E8-D7F4232AFBB0} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{47F3C27E-698B-4EDF-A7E8-D7F4232AFBB0} = {C9809D59-6665-471E-AD87-5AC624C65892}
{BD1C30A8-8FFA-4A92-A9BD-B67B1CDDD84C} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
{25F66C64-058A-4D44-BC0C-F12A054F9A91} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{A85201C6-6AF8-4B63-8365-08F741050438} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{A92B4734-2587-4F6F-97A3-741BE48709A5} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{28F8E9E2-FE24-41F7-A888-9FC244A9E2DD} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{9A3DEA7E-1681-4D48-AC5C-1F0DE421A203} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{25F66C64-058A-4D44-BC0C-F12A054F9A91} = {C9809D59-6665-471E-AD87-5AC624C65892}
{A85201C6-6AF8-4B63-8365-08F741050438} = {C9809D59-6665-471E-AD87-5AC624C65892}
{A92B4734-2587-4F6F-97A3-741BE48709A5} = {C9809D59-6665-471E-AD87-5AC624C65892}
{28F8E9E2-FE24-41F7-A888-9FC244A9E2DD} = {C9809D59-6665-471E-AD87-5AC624C65892}
{9A3DEA7E-1681-4D48-AC5C-1F0DE421A203} = {C9809D59-6665-471E-AD87-5AC624C65892}
{7FD0A92B-7862-4BB1-932B-B52A9CACB56B} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
{FD0AFD44-7A93-4F9E-B5ED-72582392E435} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{FD0AFD44-7A93-4F9E-B5ED-72582392E435} = {C9809D59-6665-471E-AD87-5AC624C65892}
{6A811927-3C37-430A-90F4-503E37123956} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
{8B074219-F69A-4E41-83C6-12EE1E647779} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{8B074219-F69A-4E41-83C6-12EE1E647779} = {C9809D59-6665-471E-AD87-5AC624C65892}
{D7166C56-178A-4457-B56A-C615C7450DEE} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
{C1E5BBB6-6B6A-4DE5-B19D-0538304DE343} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
{945871B1-77B8-43FB-B53C-27CF385AB756} = {8CF53B92-5EB1-461D-98F8-70DA9B603FBF}
{D48A03DF-BCD3-4667-8747-2F251347E2B6} = {B56EBCEC-9C50-46A7-848C-65502DE69C5C}
{B51126A8-0D75-4A79-867D-10724EC6AC84} = {94207AA6-4923-4183-A558-E0F8196B8CA3}
{5E75AB7D-6F01-4313-AFF1-7F7128FFD71F} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{C9809D59-6665-471E-AD87-5AC624C65892} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{C0D540F0-9158-4528-BFD8-BEAE6EAE45EA} = {4C6B06C2-6D77-4E0E-AE32-D7050236433A}
{F7771E22-47BD-45C4-A133-FD7F1DE27CA0} = {C0D540F0-9158-4528-BFD8-BEAE6EAE45EA}
{27CF800D-890F-4882-BF05-44EC3233537D} = {C0D540F0-9158-4528-BFD8-BEAE6EAE45EA}
{42184546-E3CB-4D4F-9495-43979B9C63B9} = {C0D540F0-9158-4528-BFD8-BEAE6EAE45EA}
EndGlobalSection
EndGlobal

19
src/Squidex.Domain.Apps.Core/Identity/SquidexClaimTypes.cs

@ -1,19 +0,0 @@
// ==========================================================================
// SquidexClaimTypes.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
namespace Squidex.Domain.Apps.Core.Identity
{
public static class SquidexClaimTypes
{
public static readonly string SquidexDisplayName = "urn:squidex:name";
public static readonly string SquidexPictureUrl = "urn:squidex:picture";
public static readonly string Prefix = "urn:squidex:";
}
}

21
src/Squidex.Domain.Apps.Core/Identity/SquidexRoles.cs

@ -1,21 +0,0 @@
// ==========================================================================
// SquidexRoles.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
namespace Squidex.Domain.Apps.Core.Identity
{
public static class SquidexRoles
{
public static readonly string Administrator = "ADMINISTRATOR";
public static readonly string AppOwner = "APP-OWNER";
public static readonly string AppEditor = "APP-EDITOR";
public static readonly string AppDeveloper = "APP-DEVELOPER";
}
}

5
src/Squidex.Domain.Apps.Core/Squidex.Domain.Apps.Core.csproj

@ -11,10 +11,9 @@
<ProjectReference Include="..\Squidex.Infrastructure\Squidex.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="protobuf-net" Version="2.2.1" />
<PackageReference Include="System.Collections.Immutable" Version="1.3.1" />
<PackageReference Include="NodaTime" Version="2.0.3" />
<PackageReference Include="NJsonSchema" Version="9.2.5" />
<PackageReference Include="NodaTime" Version="2.0.3" />
<PackageReference Include="System.Collections.Immutable" Version="1.3.1" />
<PackageReference Include="System.ValueTuple" Version="4.3.1" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.6' ">

3
src/Squidex.Domain.Apps.Read.MongoDb/Squidex.Domain.Apps.Read.MongoDb.csproj

@ -15,9 +15,6 @@
<ProjectReference Include="..\Squidex.Domain.Apps.Read\Squidex.Domain.Apps.Read.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="IdentityServer4" Version="1.5.2" />
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="1.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Identity.MongoDB" Version="1.0.2" />
<PackageReference Include="MongoDB.Driver" Version="2.4.4" />
<PackageReference Include="System.ValueTuple" Version="4.3.1" />
</ItemGroup>

93
src/Squidex.Domain.Apps.Read.MongoDb/Users/MongoRoleStore.cs

@ -1,93 +0,0 @@
// ==========================================================================
// MongoRoleStore.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.MongoDB;
using MongoDB.Driver;
using Squidex.Domain.Apps.Read.Users;
namespace Squidex.Domain.Apps.Read.MongoDb.Users
{
public sealed class MongoRoleStore :
IRoleStore<IRole>,
IRoleFactory
{
private readonly RoleStore<WrappedIdentityRole> innerStore;
public MongoRoleStore(IMongoDatabase database)
{
var rolesCollection = database.GetCollection<WrappedIdentityRole>("Identity_Roles");
IndexChecks.EnsureUniqueIndexOnNormalizedRoleName(rolesCollection);
innerStore = new RoleStore<WrappedIdentityRole>(rolesCollection);
}
public void Dispose()
{
innerStore.Dispose();
}
public IRole Create(string name)
{
return new WrappedIdentityRole { Name = name };
}
public async Task<IRole> FindByIdAsync(string roleId, CancellationToken cancellationToken)
{
return await innerStore.FindByIdAsync(roleId, cancellationToken);
}
public async Task<IRole> FindByNameAsync(string normalizedRoleName, CancellationToken cancellationToken)
{
return await innerStore.FindByNameAsync(normalizedRoleName, cancellationToken);
}
public Task<IdentityResult> CreateAsync(IRole role, CancellationToken cancellationToken)
{
return innerStore.CreateAsync((WrappedIdentityRole)role, cancellationToken);
}
public Task<IdentityResult> UpdateAsync(IRole role, CancellationToken cancellationToken)
{
return innerStore.UpdateAsync((WrappedIdentityRole)role, cancellationToken);
}
public Task<IdentityResult> DeleteAsync(IRole role, CancellationToken cancellationToken)
{
return innerStore.DeleteAsync((WrappedIdentityRole)role, cancellationToken);
}
public Task<string> GetRoleIdAsync(IRole role, CancellationToken cancellationToken)
{
return innerStore.GetRoleIdAsync((WrappedIdentityRole)role, cancellationToken);
}
public Task<string> GetRoleNameAsync(IRole role, CancellationToken cancellationToken)
{
return innerStore.GetRoleNameAsync((WrappedIdentityRole)role, cancellationToken);
}
public Task SetRoleNameAsync(IRole role, string roleName, CancellationToken cancellationToken)
{
return innerStore.SetRoleNameAsync((WrappedIdentityRole)role, roleName, cancellationToken);
}
public Task<string> GetNormalizedRoleNameAsync(IRole role, CancellationToken cancellationToken)
{
return innerStore.GetNormalizedRoleNameAsync((WrappedIdentityRole)role, cancellationToken);
}
public Task SetNormalizedRoleNameAsync(IRole role, string normalizedName, CancellationToken cancellationToken)
{
return innerStore.SetNormalizedRoleNameAsync((WrappedIdentityRole)role, normalizedName, cancellationToken);
}
}
}

329
src/Squidex.Domain.Apps.Read.MongoDb/Users/MongoUserStore.cs

@ -1,329 +0,0 @@
// ==========================================================================
// MongoUserStore.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.MongoDB;
using MongoDB.Driver;
using Squidex.Domain.Apps.Read.Users;
namespace Squidex.Domain.Apps.Read.MongoDb.Users
{
public sealed class MongoUserStore :
IUserPasswordStore<IUser>,
IUserRoleStore<IUser>,
IUserLoginStore<IUser>,
IUserSecurityStampStore<IUser>,
IUserEmailStore<IUser>,
IUserClaimStore<IUser>,
IUserPhoneNumberStore<IUser>,
IUserTwoFactorStore<IUser>,
IUserLockoutStore<IUser>,
IUserAuthenticationTokenStore<IUser>,
IUserFactory,
IUserResolver,
IQueryableUserStore<IUser>
{
private readonly UserStore<WrappedIdentityUser> innerStore;
public MongoUserStore(IMongoDatabase database)
{
var usersCollection = database.GetCollection<WrappedIdentityUser>("Identity_Users");
IndexChecks.EnsureUniqueIndexOnNormalizedEmail(usersCollection);
IndexChecks.EnsureUniqueIndexOnNormalizedUserName(usersCollection);
innerStore = new UserStore<WrappedIdentityUser>(usersCollection);
}
public void Dispose()
{
innerStore.Dispose();
}
public IQueryable<IUser> Users
{
get { return innerStore.Users; }
}
public IUser Create(string email)
{
return new WrappedIdentityUser { Email = email, UserName = email };
}
public async Task<IUser> FindByIdAsync(string userId)
{
return await innerStore.FindByIdAsync(userId, CancellationToken.None);
}
public async Task<IUser> FindByIdAsync(string userId, CancellationToken cancellationToken)
{
return await innerStore.FindByIdAsync(userId, cancellationToken);
}
public async Task<IUser> FindByEmailAsync(string normalizedEmail, CancellationToken cancellationToken)
{
return await innerStore.FindByEmailAsync(normalizedEmail, cancellationToken);
}
public async Task<IUser> FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken)
{
return await innerStore.FindByNameAsync(normalizedUserName, cancellationToken);
}
public async Task<IUser> FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken)
{
return await innerStore.FindByLoginAsync(loginProvider, providerKey, cancellationToken);
}
public async Task<IList<IUser>> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken)
{
return (await innerStore.GetUsersForClaimAsync(claim, cancellationToken)).OfType<IUser>().ToList();
}
public async Task<IList<IUser>> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken)
{
return (await innerStore.GetUsersInRoleAsync(roleName, cancellationToken)).OfType<IUser>().ToList();
}
public Task<IdentityResult> CreateAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.CreateAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task<IdentityResult> UpdateAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.UpdateAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task<IdentityResult> DeleteAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.DeleteAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task<string> GetUserIdAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.GetUserIdAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task<string> GetUserNameAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.GetUserNameAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task SetUserNameAsync(IUser user, string userName, CancellationToken cancellationToken)
{
return innerStore.SetUserNameAsync((WrappedIdentityUser)user, userName, cancellationToken);
}
public Task<string> GetNormalizedUserNameAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.GetNormalizedUserNameAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task SetNormalizedUserNameAsync(IUser user, string normalizedName, CancellationToken cancellationToken)
{
return innerStore.SetNormalizedUserNameAsync((WrappedIdentityUser)user, normalizedName, cancellationToken);
}
public Task<string> GetPasswordHashAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.GetPasswordHashAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task SetPasswordHashAsync(IUser user, string passwordHash, CancellationToken cancellationToken)
{
return innerStore.SetPasswordHashAsync((WrappedIdentityUser)user, passwordHash, cancellationToken);
}
public Task AddToRoleAsync(IUser user, string roleName, CancellationToken cancellationToken)
{
return innerStore.AddToRoleAsync((WrappedIdentityUser)user, roleName, cancellationToken);
}
public Task RemoveFromRoleAsync(IUser user, string roleName, CancellationToken cancellationToken)
{
return innerStore.RemoveFromRoleAsync((WrappedIdentityUser)user, roleName, cancellationToken);
}
public Task<IList<string>> GetRolesAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.GetRolesAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task<bool> IsInRoleAsync(IUser user, string roleName, CancellationToken cancellationToken)
{
return innerStore.IsInRoleAsync((WrappedIdentityUser)user, roleName, cancellationToken);
}
public Task AddLoginAsync(IUser user, UserLoginInfo login, CancellationToken cancellationToken)
{
return innerStore.AddLoginAsync((WrappedIdentityUser)user, login, cancellationToken);
}
public Task RemoveLoginAsync(IUser user, string loginProvider, string providerKey, CancellationToken cancellationToken)
{
return innerStore.RemoveLoginAsync((WrappedIdentityUser)user, loginProvider, providerKey, cancellationToken);
}
public Task<IList<UserLoginInfo>> GetLoginsAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.GetLoginsAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task<string> GetSecurityStampAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.GetSecurityStampAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task SetSecurityStampAsync(IUser user, string stamp, CancellationToken cancellationToken)
{
return innerStore.SetSecurityStampAsync((WrappedIdentityUser)user, stamp, cancellationToken);
}
public Task<string> GetEmailAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.GetEmailAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task SetEmailAsync(IUser user, string email, CancellationToken cancellationToken)
{
return innerStore.SetEmailAsync((WrappedIdentityUser)user, email, cancellationToken);
}
public Task<bool> GetEmailConfirmedAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.GetEmailConfirmedAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task SetEmailConfirmedAsync(IUser user, bool confirmed, CancellationToken cancellationToken)
{
return innerStore.SetEmailConfirmedAsync((WrappedIdentityUser)user, confirmed, cancellationToken);
}
public Task<string> GetNormalizedEmailAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.GetNormalizedEmailAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task SetNormalizedEmailAsync(IUser user, string normalizedEmail, CancellationToken cancellationToken)
{
return innerStore.SetNormalizedEmailAsync((WrappedIdentityUser)user, normalizedEmail, cancellationToken);
}
public Task<IList<Claim>> GetClaimsAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.GetClaimsAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task AddClaimsAsync(IUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken)
{
return innerStore.AddClaimsAsync((WrappedIdentityUser)user, claims, cancellationToken);
}
public Task ReplaceClaimAsync(IUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken)
{
return innerStore.ReplaceClaimAsync((WrappedIdentityUser)user, claim, newClaim, cancellationToken);
}
public Task RemoveClaimsAsync(IUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken)
{
return innerStore.RemoveClaimsAsync((WrappedIdentityUser)user, claims, cancellationToken);
}
public Task<string> GetPhoneNumberAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.GetPhoneNumberAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task SetPhoneNumberAsync(IUser user, string phoneNumber, CancellationToken cancellationToken)
{
return innerStore.SetPhoneNumberAsync((WrappedIdentityUser)user, phoneNumber, cancellationToken);
}
public Task<bool> GetPhoneNumberConfirmedAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.GetPhoneNumberConfirmedAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task SetPhoneNumberConfirmedAsync(IUser user, bool confirmed, CancellationToken cancellationToken)
{
return innerStore.SetPhoneNumberConfirmedAsync((WrappedIdentityUser)user, confirmed, cancellationToken);
}
public Task<bool> GetTwoFactorEnabledAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.GetTwoFactorEnabledAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task SetTwoFactorEnabledAsync(IUser user, bool enabled, CancellationToken cancellationToken)
{
return innerStore.SetTwoFactorEnabledAsync((WrappedIdentityUser)user, enabled, cancellationToken);
}
public Task<DateTimeOffset?> GetLockoutEndDateAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.GetLockoutEndDateAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task SetLockoutEndDateAsync(IUser user, DateTimeOffset? lockoutEnd, CancellationToken cancellationToken)
{
return innerStore.SetLockoutEndDateAsync((WrappedIdentityUser)user, lockoutEnd, cancellationToken);
}
public Task<int> GetAccessFailedCountAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.GetAccessFailedCountAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task<int> IncrementAccessFailedCountAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.IncrementAccessFailedCountAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task ResetAccessFailedCountAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.ResetAccessFailedCountAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task<bool> GetLockoutEnabledAsync(IUser user, CancellationToken cancellationToken)
{
return innerStore.GetLockoutEnabledAsync((WrappedIdentityUser)user, cancellationToken);
}
public Task SetLockoutEnabledAsync(IUser user, bool enabled, CancellationToken cancellationToken)
{
return innerStore.SetLockoutEnabledAsync((WrappedIdentityUser)user, enabled, cancellationToken);
}
public Task SetTokenAsync(IUser user, string loginProvider, string name, string value, CancellationToken cancellationToken)
{
return innerStore.SetTokenAsync((WrappedIdentityUser)user, loginProvider, name, value, cancellationToken);
}
public Task RemoveTokenAsync(IUser user, string loginProvider, string name, CancellationToken cancellationToken)
{
return innerStore.RemoveTokenAsync((WrappedIdentityUser)user, loginProvider, name, cancellationToken);
}
public Task<string> GetTokenAsync(IUser user, string loginProvider, string name, CancellationToken cancellationToken)
{
return innerStore.GetTokenAsync((WrappedIdentityUser)user, loginProvider, name, cancellationToken);
}
public Task<bool> HasPasswordAsync(IUser user, CancellationToken cancellationToken)
{
return Task.FromResult(!string.IsNullOrWhiteSpace(((WrappedIdentityUser)user).PasswordHash));
}
}
}

17
src/Squidex.Domain.Apps.Read.MongoDb/Users/WrappedIdentityRole.cs

@ -1,17 +0,0 @@
// ==========================================================================
// WrappedIdentityRole.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using Microsoft.AspNetCore.Identity.MongoDB;
using Squidex.Domain.Apps.Read.Users;
namespace Squidex.Domain.Apps.Read.MongoDb.Users
{
public sealed class WrappedIdentityRole : IdentityRole, IRole
{
}
}

46
src/Squidex.Domain.Apps.Read.MongoDb/Users/WrappedIdentityUser.cs

@ -1,46 +0,0 @@
// ==========================================================================
// WrappedIdentityUser.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using Microsoft.AspNetCore.Identity.MongoDB;
using Squidex.Domain.Apps.Read.Users;
namespace Squidex.Domain.Apps.Read.MongoDb.Users
{
public sealed class WrappedIdentityUser : IdentityUser, IUser
{
public bool IsLocked
{
get { return LockoutEndDateUtc != null && LockoutEndDateUtc.Value > DateTime.UtcNow; }
}
IReadOnlyList<Claim> IUser.Claims
{
get { return Claims.Select(x => new Claim(x.Type, x.Value)).ToList(); }
}
IReadOnlyList<ExternalLogin> IUser.Logins
{
get { return Logins.Select(x => new ExternalLogin(x.LoginProvider, x.ProviderKey, x.ProviderDisplayName)).ToList(); }
}
public void UpdateEmail(string email)
{
Email = UserName = email;
}
public void SetClaim(string type, string value)
{
Claims.RemoveAll(x => string.Equals(x.Type, type, StringComparison.OrdinalIgnoreCase));
Claims.Add(new IdentityUserClaim { Type = type, Value = value });
}
}
}

2
src/Squidex.Domain.Apps.Read/Squidex.Domain.Apps.Read.csproj

@ -13,10 +13,8 @@
<ProjectReference Include="..\Squidex.Infrastructure\Squidex.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="1.1.2" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="1.1.2" />
<PackageReference Include="NodaTime" Version="2.0.3" />
<PackageReference Include="System.Linq.Queryable" Version="4.3.0" />
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="4.7.0" />
<PackageReference Include="System.ValueTuple" Version="4.3.1" />
</ItemGroup>

43
src/Squidex.Domain.Apps.Read/Users/AssetUserPictureStore.cs

@ -1,43 +0,0 @@
// ==========================================================================
// AssetUserPictureStore.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System.IO;
using System.Threading.Tasks;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Assets;
namespace Squidex.Domain.Apps.Read.Users
{
public sealed class AssetUserPictureStore : IUserPictureStore
{
private readonly IAssetStore assetStore;
public AssetUserPictureStore(IAssetStore assetStore)
{
Guard.NotNull(assetStore, nameof(assetStore));
this.assetStore = assetStore;
}
public Task UploadAsync(string userId, Stream stream)
{
return assetStore.UploadAsync(userId, 0, "picture", stream);
}
public async Task<Stream> DownloadAsync(string userId)
{
var memoryStream = new MemoryStream();
await assetStore.DownloadAsync(userId, 0, "picture", memoryStream);
memoryStream.Position = 0;
return memoryStream;
}
}
}

32
src/Squidex.Domain.Apps.Read/Users/ExternalLogin.cs

@ -1,32 +0,0 @@
// ==========================================================================
// ExternalLogin.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
namespace Squidex.Domain.Apps.Read.Users
{
public sealed class ExternalLogin
{
public string LoginProvider { get; }
public string ProviderKey { get; }
public string ProviderDisplayName { get; }
public ExternalLogin(string loginProvider, string providerKey, string providerDisplayName)
{
LoginProvider = loginProvider;
ProviderKey = providerKey;
ProviderDisplayName = providerDisplayName;
if (string.IsNullOrWhiteSpace(ProviderDisplayName))
{
ProviderDisplayName = loginProvider;
}
}
}
}

15
src/Squidex.Domain.Apps.Read/Users/IRole.cs

@ -1,15 +0,0 @@
// ==========================================================================
// IRole.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
namespace Squidex.Domain.Apps.Read.Users
{
public interface IRole
{
string Name { get; }
}
}

15
src/Squidex.Domain.Apps.Read/Users/IRoleFactory.cs

@ -1,15 +0,0 @@
// ==========================================================================
// IRoleFactory.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
namespace Squidex.Domain.Apps.Read.Users
{
public interface IRoleFactory
{
IRole Create(string name);
}
}

34
src/Squidex.Domain.Apps.Read/Users/IUser.cs

@ -1,34 +0,0 @@
// ==========================================================================
// IUser.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System.Collections.Generic;
using System.Security.Claims;
namespace Squidex.Domain.Apps.Read.Users
{
public interface IUser
{
bool IsLocked { get; }
string Id { get; }
string Email { get; }
string NormalizedEmail { get; }
IReadOnlyList<Claim> Claims { get; }
IReadOnlyList<ExternalLogin> Logins { get; }
void UpdateEmail(string email);
void AddClaim(Claim claim);
void SetClaim(string type, string value);
}
}

15
src/Squidex.Domain.Apps.Read/Users/IUserFactory.cs

@ -1,15 +0,0 @@
// ==========================================================================
// IUserFactory.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
namespace Squidex.Domain.Apps.Read.Users
{
public interface IUserFactory
{
IUser Create(string email);
}
}

20
src/Squidex.Domain.Apps.Read/Users/IUserPictureStore.cs

@ -1,20 +0,0 @@
// ==========================================================================
// IUserPictureStore.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System.IO;
using System.Threading.Tasks;
namespace Squidex.Domain.Apps.Read.Users
{
public interface IUserPictureStore
{
Task UploadAsync(string userId, Stream stream);
Task<Stream> DownloadAsync(string userId);
}
}

17
src/Squidex.Domain.Apps.Read/Users/IUserResolver.cs

@ -1,17 +0,0 @@
// ==========================================================================
// IUserResolver.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System.Threading.Tasks;
namespace Squidex.Domain.Apps.Read.Users
{
public interface IUserResolver
{
Task<IUser> FindByIdAsync(string id);
}
}

74
src/Squidex.Domain.Apps.Read/Users/UserExtensions.cs

@ -1,74 +0,0 @@
// ==========================================================================
// UserExtensions.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System;
using System.Linq;
using Squidex.Domain.Apps.Core.Identity;
using Squidex.Infrastructure;
// ReSharper disable InvertIf
namespace Squidex.Domain.Apps.Read.Users
{
public static class UserExtensions
{
public static void UpdateDisplayName(this IUser user, string displayName)
{
user.SetClaim(SquidexClaimTypes.SquidexDisplayName, displayName);
}
public static void SetPictureUrl(this IUser user, string pictureUrl)
{
user.SetClaim(SquidexClaimTypes.SquidexPictureUrl, pictureUrl);
}
public static void SetPictureUrlToStore(this IUser user)
{
user.SetClaim(SquidexClaimTypes.SquidexPictureUrl, "store");
}
public static void SetPictureUrlFromGravatar(this IUser user, string email)
{
user.SetClaim(SquidexClaimTypes.SquidexPictureUrl, GravatarHelper.CreatePictureUrl(email));
}
public static bool IsPictureUrlStored(this IUser user)
{
return string.Equals(user.Claims.FirstOrDefault(x => x.Type == SquidexClaimTypes.SquidexPictureUrl)?.Value, "store", StringComparison.OrdinalIgnoreCase);
}
public static string PictureUrl(this IUser user)
{
return user.Claims.FirstOrDefault(x => x.Type == SquidexClaimTypes.SquidexPictureUrl)?.Value;
}
public static string DisplayName(this IUser user)
{
return user.Claims.FirstOrDefault(x => x.Type == SquidexClaimTypes.SquidexDisplayName)?.Value;
}
public static string PictureNormalizedUrl(this IUser user)
{
var url = user.Claims.FirstOrDefault(x => x.Type == SquidexClaimTypes.SquidexPictureUrl)?.Value;
if (!string.IsNullOrWhiteSpace(url) && Uri.IsWellFormedUriString(url, UriKind.Absolute) && url.Contains("gravatar"))
{
if (url.Contains("?"))
{
url += "&d=404";
}
else
{
url += "?d=404";
}
}
return url;
}
}
}

131
src/Squidex.Domain.Apps.Read/Users/UserManagerExtensions.cs

@ -1,131 +0,0 @@
// ==========================================================================
// UserManagerExtensions.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Squidex.Infrastructure;
// ReSharper disable ImplicitlyCapturedClosure
// ReSharper disable InvertIf
// ReSharper disable ReturnTypeCanBeEnumerable.Local
namespace Squidex.Domain.Apps.Read.Users
{
public static class UserManagerExtensions
{
public static Task<IReadOnlyList<IUser>> QueryByEmailAsync(this UserManager<IUser> userManager, string email = null, int take = 10, int skip = 0)
{
var users = QueryUsers(userManager, email).Skip(skip).Take(take).ToList();
return Task.FromResult<IReadOnlyList<IUser>>(users);
}
public static Task<long> CountByEmailAsync(this UserManager<IUser> userManager, string email = null)
{
var count = QueryUsers(userManager, email).LongCount();
return Task.FromResult(count);
}
private static IQueryable<IUser> QueryUsers(UserManager<IUser> userManager, string email = null)
{
var result = userManager.Users;
if (!string.IsNullOrWhiteSpace(email))
{
var upperEmail = email.ToUpperInvariant();
result = result.Where(x => x.NormalizedEmail.Contains(upperEmail));
}
return result;
}
public static async Task<IUser> CreateAsync(this UserManager<IUser> userManager, IUserFactory factory, string email, string displayName, string password)
{
var user = factory.Create(email);
user.UpdateDisplayName(displayName);
user.SetPictureUrlFromGravatar(email);
await DoChecked(() => userManager.CreateAsync(user), "Cannot create user.");
if (!string.IsNullOrWhiteSpace(password))
{
await DoChecked(() => userManager.AddPasswordAsync(user, password), "Cannot create user.");
}
return user;
}
public static async Task UpdateAsync(this UserManager<IUser> userManager, string id, string email, string displayName, string password)
{
var user = await userManager.FindByIdAsync(id);
if (user == null)
{
throw new DomainObjectNotFoundException(id, typeof(IUser));
}
if (!string.IsNullOrWhiteSpace(email))
{
user.UpdateEmail(email);
}
if (!string.IsNullOrWhiteSpace(displayName))
{
user.UpdateDisplayName(displayName);
}
await DoChecked(() => userManager.UpdateAsync(user), "Cannot update user.");
if (!string.IsNullOrWhiteSpace(password))
{
await DoChecked(() => userManager.RemovePasswordAsync(user), "Cannot update user.");
await DoChecked(() => userManager.AddPasswordAsync(user, password), "Cannot update user.");
}
}
public static async Task LockAsync(this UserManager<IUser> userManager, string id)
{
var user = await userManager.FindByIdAsync(id);
if (user == null)
{
throw new DomainObjectNotFoundException(id, typeof(IUser));
}
await DoChecked(() => userManager.SetLockoutEndDateAsync(user, DateTimeOffset.UtcNow.AddYears(100)), "Cannot lock user.");
}
public static async Task UnlockAsync(this UserManager<IUser> userManager, string id)
{
var user = await userManager.FindByIdAsync(id);
if (user == null)
{
throw new DomainObjectNotFoundException(id, typeof(IUser));
}
await DoChecked(() => userManager.SetLockoutEndDateAsync(user, null), "Cannot unlock user.");
}
private static async Task DoChecked(Func<Task<IdentityResult>> action, string message)
{
var result = await action();
if (!result.Succeeded)
{
throw new ValidationException(message, result.Errors.Select(x => new ValidationError(x.Description)).ToArray());
}
}
}
}

2
src/Squidex.Domain.Apps.Write/Apps/AppCommandHandler.cs

@ -9,12 +9,12 @@
using System.Threading.Tasks;
using Squidex.Domain.Apps.Read.Apps.Repositories;
using Squidex.Domain.Apps.Read.Apps.Services;
using Squidex.Domain.Apps.Read.Users;
using Squidex.Domain.Apps.Write.Apps.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.CQRS.Commands;
using Squidex.Infrastructure.Dispatching;
using Squidex.Infrastructure.Tasks;
using Squidex.Shared.Users;
// ReSharper disable InvertIf

1
src/Squidex.Domain.Apps.Write/Squidex.Domain.Apps.Write.csproj

@ -12,6 +12,7 @@
<ProjectReference Include="..\Squidex.Domain.Apps.Events\Squidex.Domain.Apps.Events.csproj" />
<ProjectReference Include="..\Squidex.Infrastructure\Squidex.Infrastructure.csproj" />
<ProjectReference Include="..\Squidex.Domain.Apps.Read\Squidex.Domain.Apps.Read.csproj" />
<ProjectReference Include="..\Squidex.Shared\Squidex.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NodaTime" Version="2.0.3" />

2
src/Squidex.Domain.Apps.Read.MongoDb/Infrastructure/MongoPersistedGrantStore.cs → src/Squidex.Domain.Users.MongoDb/Infrastructure/MongoPersistedGrantStore.cs

@ -14,7 +14,7 @@ using MongoDB.Bson.Serialization;
using MongoDB.Driver;
using Squidex.Infrastructure.MongoDb;
namespace Squidex.Domain.Apps.Read.MongoDb.Infrastructure
namespace Squidex.Domain.Users.MongoDb.Infrastructure
{
public class MongoPersistedGrantStore : MongoRepositoryBase<PersistedGrant>, IPersistedGrantStore
{

2
src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj

@ -8,10 +8,12 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Squidex.Domain.Users\Squidex.Domain.Users.csproj" />
<ProjectReference Include="..\Squidex.Infrastructure.MongoDb\Squidex.Infrastructure.MongoDb.csproj" />
<ProjectReference Include="..\Squidex.Infrastructure\Squidex.Infrastructure.csproj" />
<ProjectReference Include="..\Squidex.Shared\Squidex.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="IdentityServer4" Version="1.5.2" />
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="1.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Identity.MongoDB" Version="1.0.2" />
<PackageReference Include="MongoDB.Driver" Version="2.4.4" />

2
src/Squidex/Config/Domain/ReadModule.cs

@ -20,7 +20,7 @@ using Squidex.Domain.Apps.Read.History;
using Squidex.Domain.Apps.Read.Schemas;
using Squidex.Domain.Apps.Read.Schemas.Services;
using Squidex.Domain.Apps.Read.Schemas.Services.Implementations;
using Squidex.Domain.Apps.Read.Users;
using Squidex.Domain.Users;
using Squidex.Infrastructure.CQRS.Events;
// ReSharper disable UnusedAutoPropertyAccessor.Local

7
src/Squidex/Config/Domain/StoreMongoDbModule.cs

@ -21,17 +21,18 @@ using Squidex.Domain.Apps.Read.MongoDb.Apps;
using Squidex.Domain.Apps.Read.MongoDb.Assets;
using Squidex.Domain.Apps.Read.MongoDb.Contents;
using Squidex.Domain.Apps.Read.MongoDb.History;
using Squidex.Domain.Apps.Read.MongoDb.Infrastructure;
using Squidex.Domain.Apps.Read.MongoDb.Schemas;
using Squidex.Domain.Apps.Read.MongoDb.Users;
using Squidex.Domain.Apps.Read.Schemas.Repositories;
using Squidex.Domain.Apps.Read.Schemas.Services.Implementations;
using Squidex.Domain.Apps.Read.Users;
using Squidex.Domain.Users;
using Squidex.Domain.Users.MongoDb;
using Squidex.Domain.Users.MongoDb.Infrastructure;
using Squidex.Infrastructure;
using Squidex.Infrastructure.CQRS.Events;
using Squidex.Infrastructure.MongoDb;
using Squidex.Infrastructure.MongoDb.UsageTracker;
using Squidex.Infrastructure.UsageTracking;
using Squidex.Shared.Users;
namespace Squidex.Config.Domain
{

2
src/Squidex/Config/Identity/GithubHandler.cs

@ -9,7 +9,7 @@
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.OAuth;
using Squidex.Domain.Apps.Core.Identity;
using Squidex.Shared.Identity;
namespace Squidex.Config.Identity
{

2
src/Squidex/Config/Identity/GoogleHandler.cs

@ -10,8 +10,8 @@ using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.OAuth;
using Squidex.Domain.Apps.Core.Identity;
using Squidex.Infrastructure.Tasks;
using Squidex.Shared.Identity;
// ReSharper disable InvertIf

5
src/Squidex/Config/Identity/IdentityServices.cs

@ -17,9 +17,10 @@ using IdentityServer4.Stores;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Squidex.Domain.Apps.Core.Identity;
using Squidex.Domain.Apps.Read.Users;
using Squidex.Domain.Users;
using Squidex.Infrastructure;
using Squidex.Shared.Identity;
using Squidex.Shared.Users;
using StackExchange.Redis;
namespace Squidex.Config.Identity

5
src/Squidex/Config/Identity/IdentityUsage.cs

@ -12,8 +12,9 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Squidex.Domain.Apps.Core.Identity;
using Squidex.Domain.Apps.Read.Users;
using Squidex.Domain.Users;
using Squidex.Shared.Identity;
using Squidex.Shared.Users;
// ReSharper disable InvertIf

2
src/Squidex/Config/Identity/MicrosoftHandler.cs

@ -9,7 +9,7 @@
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.OAuth;
using Squidex.Domain.Apps.Core.Identity;
using Squidex.Shared.Identity;
// ReSharper disable InvertIf

12
src/Squidex/Controllers/Api/Users/UserManagementController.cs

@ -13,11 +13,12 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Squidex.Controllers.Api.Users.Models;
using Squidex.Domain.Apps.Read.Users;
using Squidex.Domain.Users;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Reflection;
using Squidex.Infrastructure.Security;
using Squidex.Pipeline;
using Squidex.Shared.Users;
namespace Squidex.Controllers.Api.Users
{
@ -48,7 +49,7 @@ namespace Squidex.Controllers.Api.Users
var response = new UsersDto
{
Total = taskForCount.Result,
Items = taskForItems.Result.Select(x => SimpleMapper.Map(x, new UserDto { DisplayName = x.DisplayName(), PictureUrl = x.PictureUrl() })).ToArray()
Items = taskForItems.Result.Select(Map).ToArray()
};
return Ok(response);
@ -66,7 +67,7 @@ namespace Squidex.Controllers.Api.Users
return NotFound();
}
var response = SimpleMapper.Map(entity, new UserDto { DisplayName = entity.DisplayName(), PictureUrl = entity.PictureUrl() });
var response = Map(entity);
return Ok(response);
}
@ -123,6 +124,11 @@ namespace Squidex.Controllers.Api.Users
return NoContent();
}
private static UserDto Map(IUser user)
{
return SimpleMapper.Map(user, new UserDto { DisplayName = user.DisplayName(), PictureUrl = user.PictureUrl() });
}
private bool IsSelf(string id)
{
var subject = User.OpenIdSubject();

7
src/Squidex/Controllers/Api/Users/UsersController.cs

@ -16,9 +16,10 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using NSwag.Annotations;
using Squidex.Controllers.Api.Users.Models;
using Squidex.Domain.Apps.Read.Users;
using Squidex.Domain.Users;
using Squidex.Infrastructure.Reflection;
using Squidex.Pipeline;
using Squidex.Shared.Users;
// ReSharper disable InvertIf
@ -144,7 +145,9 @@ namespace Squidex.Controllers.Api.Users
if (response.IsSuccessStatusCode)
{
return new FileStreamResult(await response.Content.ReadAsStreamAsync(), response.Content.Headers.ContentType.ToString());
var contentType = response.Content.Headers.ContentType.ToString();
return new FileStreamResult(await response.Content.ReadAsStreamAsync(), contentType);
}
}
}

2
src/Squidex/Controllers/ContentApi/Generator/SchemasSwaggerGenerator.cs

@ -16,11 +16,11 @@ using NSwag;
using NSwag.AspNetCore;
using NSwag.SwaggerGeneration;
using Squidex.Config;
using Squidex.Domain.Apps.Core.Identity;
using Squidex.Domain.Apps.Read.Apps;
using Squidex.Domain.Apps.Read.Schemas;
using Squidex.Infrastructure;
using Squidex.Pipeline.Swagger;
using Squidex.Shared.Identity;
// ReSharper disable InvertIf
// ReSharper disable SuggestBaseTypeForParameter

5
src/Squidex/Controllers/UI/Account/AccountController.cs

@ -20,11 +20,12 @@ using Microsoft.Extensions.Options;
using NSwag.Annotations;
using Squidex.Config;
using Squidex.Config.Identity;
using Squidex.Domain.Apps.Core.Identity;
using Squidex.Domain.Apps.Read.Users;
using Squidex.Domain.Users;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Tasks;
using Squidex.Shared.Identity;
using Squidex.Shared.Users;
// ReSharper disable InvertIf
// ReSharper disable RedundantIfElseBlock

3
src/Squidex/Controllers/UI/Extensions.cs

@ -9,7 +9,8 @@
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Squidex.Domain.Apps.Read.Users;
using Squidex.Domain.Users;
using Squidex.Shared.Users;
namespace Squidex.Controllers.UI
{

3
src/Squidex/Controllers/UI/Profile/ProfileController.cs

@ -18,9 +18,10 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using NSwag.Annotations;
using Squidex.Config.Identity;
using Squidex.Domain.Apps.Read.Users;
using Squidex.Domain.Users;
using Squidex.Infrastructure.Assets;
using Squidex.Infrastructure.Reflection;
using Squidex.Shared.Users;
namespace Squidex.Controllers.UI.Profile
{

2
src/Squidex/Controllers/UI/Profile/ProfileVM.cs

@ -7,7 +7,7 @@
// ==========================================================================
using System.Collections.Generic;
using Squidex.Domain.Apps.Read.Users;
using Squidex.Shared.Users;
namespace Squidex.Controllers.UI.Profile
{

2
src/Squidex/Pipeline/AppApiFilter.cs

@ -13,11 +13,11 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Identity;
using Squidex.Domain.Apps.Read.Apps;
using Squidex.Domain.Apps.Read.Apps.Services;
using Squidex.Infrastructure.Security;
using Squidex.Infrastructure.UsageTracking;
using Squidex.Shared.Identity;
// ReSharper disable SwitchStatementMissingSomeCases

2
src/Squidex/Pipeline/MustBeAdministratorAttribute.cs

@ -7,7 +7,7 @@
// ==========================================================================
using Microsoft.AspNetCore.Authorization;
using Squidex.Domain.Apps.Core.Identity;
using Squidex.Shared.Identity;
namespace Squidex.Pipeline
{

2
src/Squidex/Pipeline/MustBeAppDeveloperAttribute.cs

@ -7,7 +7,7 @@
// ==========================================================================
using Microsoft.AspNetCore.Authorization;
using Squidex.Domain.Apps.Core.Identity;
using Squidex.Shared.Identity;
namespace Squidex.Pipeline
{

2
src/Squidex/Pipeline/MustBeAppEditorAttribute.cs

@ -7,7 +7,7 @@
// ==========================================================================
using Microsoft.AspNetCore.Authorization;
using Squidex.Domain.Apps.Core.Identity;
using Squidex.Shared.Identity;
namespace Squidex.Pipeline
{

2
src/Squidex/Pipeline/MustBeAppOwnerAttribute.cs

@ -7,7 +7,7 @@
// ==========================================================================
using Microsoft.AspNetCore.Authorization;
using Squidex.Domain.Apps.Core.Identity;
using Squidex.Shared.Identity;
namespace Squidex.Pipeline
{

2
src/Squidex/Pipeline/Swagger/SwaggerHelper.cs

@ -16,7 +16,7 @@ using NSwag;
using NSwag.SwaggerGeneration;
using Squidex.Config;
using Squidex.Controllers.Api;
using Squidex.Domain.Apps.Core.Identity;
using Squidex.Shared.Identity;
namespace Squidex.Pipeline.Swagger
{

3
src/Squidex/Squidex.csproj

@ -28,6 +28,8 @@
<ItemGroup>
<ProjectReference Include="..\Squidex.Domain.Apps.Core\Squidex.Domain.Apps.Core.csproj" />
<ProjectReference Include="..\Squidex.Domain.Apps.Events\Squidex.Domain.Apps.Events.csproj" />
<ProjectReference Include="..\Squidex.Domain.Users.MongoDb\Squidex.Domain.Users.MongoDb.csproj" />
<ProjectReference Include="..\Squidex.Domain.Users\Squidex.Domain.Users.csproj" />
<ProjectReference Include="..\Squidex.Infrastructure.GoogleCloud\Squidex.Infrastructure.GoogleCloud.csproj" />
<ProjectReference Include="..\Squidex.Infrastructure.RabbitMq\Squidex.Infrastructure.RabbitMq.csproj" />
<ProjectReference Include="..\Squidex.Infrastructure\Squidex.Infrastructure.csproj" />
@ -36,6 +38,7 @@
<ProjectReference Include="..\Squidex.Domain.Apps.Read\Squidex.Domain.Apps.Read.csproj" />
<ProjectReference Include="..\Squidex.Domain.Apps.Read.MongoDb\Squidex.Domain.Apps.Read.MongoDb.csproj" />
<ProjectReference Include="..\Squidex.Domain.Apps.Write\Squidex.Domain.Apps.Write.csproj" />
<ProjectReference Include="..\Squidex.Shared\Squidex.Shared.csproj" />
</ItemGroup>
<ItemGroup>

1
tests/Benchmarks/IBenchmark.cs

@ -5,6 +5,7 @@
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
namespace Benchmarks
{
public interface IBenchmark

17
tests/RunCoverage.ps1

@ -26,7 +26,7 @@ New-Item -ItemType directory -Path $reportsFolder
&"$userProfile\.nuget\packages\OpenCover\4.6.519\tools\OpenCover.Console.exe" `
-register:user `
-target:"C:\Program Files\dotnet\dotnet.exe" `
-targetargs:"test $workingFolder\Squidex.Domain.Apps.Core.Tests\Squidex.Core.Tests.csproj" `
-targetargs:"test $workingFolder\Squidex.Domain.Apps.Core.Tests\Squidex.Domain.Apps.Core.Tests.csproj" `
-filter:"+[Squidex*]*" `
-skipautoprops `
-output:"$workingFolder\$reportsFolder\Core.xml" `
@ -35,7 +35,16 @@ New-Item -ItemType directory -Path $reportsFolder
&"$userProfile\.nuget\packages\OpenCover\4.6.519\tools\OpenCover.Console.exe" `
-register:user `
-target:"C:\Program Files\dotnet\dotnet.exe" `
-targetargs:"test $workingFolder\Squidex.Domain.Apps.Write.Tests\Squidex.Write.Tests.csproj" `
-targetargs:"test $workingFolder\Squidex.Domain.Apps.Read.Tests\Squidex.Domain.Apps.Read.Tests.csproj" `
-filter:"+[Squidex*]*" `
-skipautoprops `
-output:"$workingFolder\$reportsFolder\Read.xml" `
-oldStyle
&"$userProfile\.nuget\packages\OpenCover\4.6.519\tools\OpenCover.Console.exe" `
-register:user `
-target:"C:\Program Files\dotnet\dotnet.exe" `
-targetargs:"test $workingFolder\Squidex.Domain.Apps.Write.Tests\Squidex.Domain.Apps.Write.Tests.csproj" `
-filter:"+[Squidex*]*" `
-skipautoprops `
-output:"$workingFolder\$reportsFolder\Write.xml" `
@ -44,10 +53,10 @@ New-Item -ItemType directory -Path $reportsFolder
&"$userProfile\.nuget\packages\OpenCover\4.6.519\tools\OpenCover.Console.exe" `
-register:user `
-target:"C:\Program Files\dotnet\dotnet.exe" `
-targetargs:"test $workingFolder\Squidex.Domain.Apps.Read.Tests\Squidex.Read.Tests.csproj" `
-targetargs:"test $workingFolder\Squidex.Domain.Users.Tests\Squidex.Domain.Users.Tests.csproj" `
-filter:"+[Squidex*]*" `
-skipautoprops `
-output:"$workingFolder\$reportsFolder\Read.xml" `
-output:"$workingFolder\$reportsFolder\Users.xml" `
-oldStyle
&"$userProfile\.nuget\packages\ReportGenerator\2.5.9\tools\ReportGenerator.exe" `

2
tests/Squidex.Domain.Apps.Write.Tests/Apps/AppCommandHandlerTests.cs

@ -13,11 +13,11 @@ using Squidex.Domain.Apps.Read.Apps;
using Squidex.Domain.Apps.Read.Apps.Repositories;
using Squidex.Domain.Apps.Read.Apps.Services;
using Squidex.Domain.Apps.Read.Apps.Services.Implementations;
using Squidex.Domain.Apps.Read.Users;
using Squidex.Domain.Apps.Write.Apps.Commands;
using Squidex.Domain.Apps.Write.TestHelpers;
using Squidex.Infrastructure;
using Squidex.Infrastructure.CQRS.Commands;
using Squidex.Shared.Users;
using Xunit;
// ReSharper disable ImplicitlyCapturedClosure

1
tests/Squidex.Domain.Apps.Write.Tests/Squidex.Domain.Apps.Write.Tests.csproj

@ -13,7 +13,6 @@
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="4.19.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="MongoDB.Driver" Version="2.4.4" />
<PackageReference Include="Moq" Version="4.7.63" />
<PackageReference Include="System.ValueTuple" Version="4.3.1" />
<PackageReference Include="xunit" Version="2.2.0" />

2
tests/Squidex.Domain.Apps.Read.Tests/Users/AssetUserPictureStoreTests.cs → tests/Squidex.Domain.Users.Tests/AssetUserPictureStoreTests.cs

@ -14,7 +14,7 @@ using Squidex.Infrastructure.Assets;
using Squidex.Infrastructure.Tasks;
using Xunit;
namespace Squidex.Domain.Apps.Read.Users
namespace Squidex.Domain.Users
{
public class AssetUserPictureStoreTests
{

28
tests/Squidex.Domain.Users.Tests/Squidex.Domain.Users.Tests.csproj

@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
<PackageTargetFallback>$(PackageTargetFallback);dnxcore50</PackageTargetFallback>
<RootNamespace>Squidex.Domain.Users</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Squidex.Domain.Users.MongoDb\Squidex.Domain.Users.MongoDb.csproj" />
<ProjectReference Include="..\..\src\Squidex.Domain.Users\Squidex.Domain.Users.csproj" />
<ProjectReference Include="..\..\src\Squidex.Infrastructure\Squidex.Infrastructure.csproj" />
<ProjectReference Include="..\..\src\Squidex.Shared\Squidex.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="4.19.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="Moq" Version="4.7.63" />
<PackageReference Include="System.ValueTuple" Version="4.3.1" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.0-msbuild3-final" />
</ItemGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
</Project>
Loading…
Cancel
Save