From 79b4b98b79d96a6436f6be222f90278239293dab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 3 Jan 2018 15:24:29 +0300 Subject: [PATCH] #185 Created entities, dbcontext and a unit test for identityserver module. --- Volo.Abp.sln | 10 ++ .../EntityFrameworkCore/IdentityDbContext.cs | 2 +- ....cs => IdentityDefaultDbContextFactory.cs} | 0 .../Volo.Abp.IdentityServer.Domain.csproj | 7 +- .../AbpIdentityServerDomainModule.cs | 22 ++++ .../IdentityServer/AbpIdentityServerModule.cs | 13 --- .../ApiResources/ApiResource.cs | 33 ++++++ .../ApiResources/ApiResourceClaim.cs | 20 ++++ .../IdentityServer/ApiResources/ApiScope.cs | 35 ++++++ .../ApiResources/ApiScopeClaim.cs | 19 +++ .../IdentityServer/ApiResources/ApiSecret.cs | 20 ++++ .../Volo/Abp/IdentityServer/Clients/Client.cs | 109 ++++++++++++++++++ .../Clients/ClientAutoMapperProfile.cs | 12 ++ .../Abp/IdentityServer/Clients/ClientClaim.cs | 24 ++++ .../Clients/ClientCorsOrigin.cs | 22 ++++ .../IdentityServer/Clients/ClientGrantType.cs | 22 ++++ .../Clients/ClientIdPRestriction.cs | 22 ++++ .../Clients/ClientPostLogoutRedirectUri.cs | 22 ++++ .../IdentityServer/Clients/ClientProperty.cs | 24 ++++ .../Clients/ClientRedirectUri.cs | 22 ++++ .../Abp/IdentityServer/Clients/ClientScope.cs | 22 ++++ .../IdentityServer/Clients/ClientSecret.cs | 20 ++++ .../Abp/IdentityServer/Clients/ClientStore.cs | 25 ++++ .../Clients/IClientRepository.cs | 11 ++ .../IdentityServer/Grants/PersistedGrant.cs | 32 +++++ .../IdentityResources/IdentityClaim.cs | 20 ++++ .../IdentityResources/IdentityResource.cs | 35 ++++++ .../Volo/Abp/IdentityServer/Secret.cs | 29 +++++ .../Volo/Abp/IdentityServer/UserClaim.cs | 22 ++++ ....IdentityServer.EntityFrameworkCore.csproj | 1 + .../Abp/IdentityServer/ClientRepository.cs | 32 +++++ .../AbpIdentityServerModule.cs | 9 ++ .../IdentityServerDbContext.cs | 28 +++++ ...ityServer.EntityFrameworkCore.Tests.csproj | 25 ++++ .../AbpIdentityApplicationTestBase.cs | 12 ++ .../AbpIdentityServerTestDataBuilder.cs | 36 ++++++ ...tityServerTestEntityFrameworkCoreModule.cs | 53 +++++++++ .../Clients/ClientStore_Tests.cs | 37 ++++++ 38 files changed, 889 insertions(+), 20 deletions(-) rename src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/{AbpDeskDefaultDbContextFactory.cs => IdentityDefaultDbContextFactory.cs} (100%) create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs delete mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerModule.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiResource.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiResourceClaim.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiScope.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiScopeClaim.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiSecret.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/Client.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientAutoMapperProfile.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientClaim.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientCorsOrigin.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientGrantType.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientIdPRestriction.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientPostLogoutRedirectUri.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientProperty.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientRedirectUri.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientScope.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientSecret.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientStore.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/IClientRepository.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Grants/PersistedGrant.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IdentityClaim.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IdentityResource.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Secret.cs create mode 100644 src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/UserClaim.cs create mode 100644 src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ClientRepository.cs create mode 100644 src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/EntityFrameworkCore/IdentityServerDbContext.cs create mode 100644 test/Abp.IdentityServer.EntityFrameworkCore.Tests/Abp.IdentityServer.EntityFrameworkCore.Tests.csproj create mode 100644 test/Abp.IdentityServer.EntityFrameworkCore.Tests/Volo/Abp/IdentityServer/AbpIdentityApplicationTestBase.cs create mode 100644 test/Abp.IdentityServer.EntityFrameworkCore.Tests/Volo/Abp/IdentityServer/AbpIdentityServerTestDataBuilder.cs create mode 100644 test/Abp.IdentityServer.EntityFrameworkCore.Tests/Volo/Abp/IdentityServer/AbpIdentityServerTestEntityFrameworkCoreModule.cs create mode 100644 test/Abp.IdentityServer.EntityFrameworkCore.Tests/Volo/Abp/IdentityServer/Clients/ClientStore_Tests.cs diff --git a/Volo.Abp.sln b/Volo.Abp.sln index f1c1588f55..fb09f7a89e 100644 --- a/Volo.Abp.sln +++ b/Volo.Abp.sln @@ -208,6 +208,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.IdentityServer.Dom EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.IdentityServer.EntityFrameworkCore", "src\Volo.Abp.IdentityServer.EntityFrameworkCore\Volo.Abp.IdentityServer.EntityFrameworkCore.csproj", "{8D891D68-7859-477D-BE78-99258B8B1E86}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Abp.IdentityServer", "Abp.IdentityServer", "{3DF5C4E8-51E7-4931-B4F4-EA390AB8FCC9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Abp.IdentityServer.EntityFrameworkCore.Tests", "test\Abp.IdentityServer.EntityFrameworkCore.Tests\Abp.IdentityServer.EntityFrameworkCore.Tests.csproj", "{0C73A439-7CD2-4105-8B70-30B896C15C72}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -554,6 +558,10 @@ Global {8D891D68-7859-477D-BE78-99258B8B1E86}.Debug|Any CPU.Build.0 = Debug|Any CPU {8D891D68-7859-477D-BE78-99258B8B1E86}.Release|Any CPU.ActiveCfg = Release|Any CPU {8D891D68-7859-477D-BE78-99258B8B1E86}.Release|Any CPU.Build.0 = Release|Any CPU + {0C73A439-7CD2-4105-8B70-30B896C15C72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0C73A439-7CD2-4105-8B70-30B896C15C72}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0C73A439-7CD2-4105-8B70-30B896C15C72}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0C73A439-7CD2-4105-8B70-30B896C15C72}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -654,6 +662,8 @@ Global {324B920F-5BBA-46D8-BDC6-E1FA5EFE3733} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {210B1A21-CBC8-423D-9C69-3E63569F2C43} = {324B920F-5BBA-46D8-BDC6-E1FA5EFE3733} {8D891D68-7859-477D-BE78-99258B8B1E86} = {324B920F-5BBA-46D8-BDC6-E1FA5EFE3733} + {3DF5C4E8-51E7-4931-B4F4-EA390AB8FCC9} = {447C8A77-E5F0-4538-8687-7383196D04EA} + {0C73A439-7CD2-4105-8B70-30B896C15C72} = {3DF5C4E8-51E7-4931-B4F4-EA390AB8FCC9} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5} diff --git a/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContext.cs b/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContext.cs index 5e4b9c272f..b4f1bd649b 100644 --- a/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContext.cs +++ b/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContext.cs @@ -63,7 +63,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore { base.OnModelCreating(builder); - //Split configuration to dedicated classes + //TODO: Split configuration to dedicated classes (probably a resuable extension method) builder.Entity(b => { diff --git a/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpDeskDefaultDbContextFactory.cs b/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDefaultDbContextFactory.cs similarity index 100% rename from src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpDeskDefaultDbContextFactory.cs rename to src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDefaultDbContextFactory.cs diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo.Abp.IdentityServer.Domain.csproj b/src/Volo.Abp.IdentityServer.Domain/Volo.Abp.IdentityServer.Domain.csproj index 969f8bb710..42d252e295 100644 --- a/src/Volo.Abp.IdentityServer.Domain/Volo.Abp.IdentityServer.Domain.csproj +++ b/src/Volo.Abp.IdentityServer.Domain/Volo.Abp.IdentityServer.Domain.csproj @@ -14,6 +14,7 @@ + @@ -21,10 +22,4 @@ - - - - - - diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs new file mode 100644 index 0000000000..16b6caf2ba --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AutoMapper; +using Volo.Abp.IdentityServer.Clients; +using Volo.Abp.Modularity; + +namespace Volo.Abp.IdentityServer +{ + [DependsOn(typeof(AbpAutoMapperModule))] + [DependsOn(typeof(AbpDddModule))] + public class AbpIdentityServerDomainModule : AbpModule + { + public override void ConfigureServices(IServiceCollection services) + { + services.Configure(options => + { + options.AddProfile(/*TODO: validate: true*/); + }); + + services.AddAssemblyOf(); + } + } +} diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerModule.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerModule.cs deleted file mode 100644 index 8eb91ab176..0000000000 --- a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerModule.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Modularity; - -namespace Volo.Abp.IdentityServer -{ - public class AbpIdentityServerModule : AbpModule - { - public override void ConfigureServices(IServiceCollection services) - { - services.AddAssemblyOf(); - } - } -} diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiResource.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiResource.cs new file mode 100644 index 0000000000..72ab3cb7c1 --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiResource.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.IdentityServer.ApiResources +{ + public class ApiResource : AggregateRoot + { + public virtual bool Enabled { get; set; } = true; + + public virtual string Name { get; set; } + + public virtual string DisplayName { get; set; } + + public virtual string Description { get; set; } + + public virtual List Secrets { get; set; } + + public virtual List Scopes { get; set; } + + public virtual List UserClaims { get; set; } + + protected ApiResource() + { + + } + + public ApiResource(Guid id) + { + Id = id; + } + } +} diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiResourceClaim.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiResourceClaim.cs new file mode 100644 index 0000000000..b764302409 --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiResourceClaim.cs @@ -0,0 +1,20 @@ +using System; + +namespace Volo.Abp.IdentityServer.ApiResources +{ + public class ApiResourceClaim : UserClaim + { + public virtual Guid ApiResourceId { get; set; } + + protected ApiResourceClaim() + { + + } + + public ApiResourceClaim(Guid id) + : base(id) + { + + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiScope.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiScope.cs new file mode 100644 index 0000000000..ab4056d657 --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiScope.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.IdentityServer.ApiResources +{ + public class ApiScope : Entity + { + public virtual string Name { get; set; } + + public virtual string DisplayName { get; set; } + + public virtual string Description { get; set; } + + public virtual bool Required { get; set; } + + public virtual bool Emphasize { get; set; } + + public virtual bool ShowInDiscoveryDocument { get; set; } = true; + + public virtual List UserClaims { get; set; } + + public virtual Guid ApiResourceId { get; set; } + + protected ApiScope() + { + + } + + public ApiScope(Guid id) + { + Id = id; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiScopeClaim.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiScopeClaim.cs new file mode 100644 index 0000000000..85ac26a6ef --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiScopeClaim.cs @@ -0,0 +1,19 @@ +using System; + +namespace Volo.Abp.IdentityServer.ApiResources +{ + public class ApiScopeClaim : UserClaim + { + public virtual Guid ApiScopeId { get; set; } + + protected ApiScopeClaim() + { + + } + + protected ApiScopeClaim(Guid id) + : base(id) + { + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiSecret.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiSecret.cs new file mode 100644 index 0000000000..c18fe95372 --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/ApiResources/ApiSecret.cs @@ -0,0 +1,20 @@ +using System; + +namespace Volo.Abp.IdentityServer.ApiResources +{ + public class ApiSecret : Secret + { + public virtual string ApiResourceId { get; set; } + + protected ApiSecret() + { + + } + + public ApiSecret(Guid id) + : base(id) + { + + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/Client.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/Client.cs new file mode 100644 index 0000000000..c8809c32fb --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/Client.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using IdentityServer4; +using IdentityServer4.Models; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.IdentityServer.Clients +{ + //TODO: Move property initializations to ctor. + + public class Client : AggregateRoot + { + public virtual string ClientId { get; set; } + + public virtual string ClientName { get; set; } + + public virtual string Description { get; set; } + + public virtual string ClientUri { get; set; } + + public virtual string LogoUri { get; set; } + + public virtual bool Enabled { get; set; } = true; + + public virtual string ProtocolType { get; set; } = IdentityServerConstants.ProtocolTypes.OpenIdConnect; + + public virtual List ClientSecrets { get; set; } + + public virtual bool RequireClientSecret { get; set; } = true; + + public virtual bool RequireConsent { get; set; } = true; + + public virtual bool AllowRememberConsent { get; set; } = true; + + public virtual bool AlwaysIncludeUserClaimsInIdToken { get; set; } + + public virtual List AllowedGrantTypes { get; set; } + + public virtual bool RequirePkce { get; set; } + + public virtual bool AllowPlainTextPkce { get; set; } + + public virtual bool AllowAccessTokensViaBrowser { get; set; } + + public virtual List RedirectUris { get; set; } + + public virtual List PostLogoutRedirectUris { get; set; } + + public virtual string FrontChannelLogoutUri { get; set; } + + public virtual bool FrontChannelLogoutSessionRequired { get; set; } = true; + + public virtual string BackChannelLogoutUri { get; set; } + + public virtual bool BackChannelLogoutSessionRequired { get; set; } = true; + + public virtual bool AllowOfflineAccess { get; set; } + + public virtual List AllowedScopes { get; set; } + + public virtual int IdentityTokenLifetime { get; set; } = 300; + + public virtual int AccessTokenLifetime { get; set; } = 3600; + + public virtual int AuthorizationCodeLifetime { get; set; } = 300; + + public virtual int? ConsentLifetime { get; set; } = null; + + public virtual int AbsoluteRefreshTokenLifetime { get; set; } = 2592000; + + public virtual int SlidingRefreshTokenLifetime { get; set; } = 1296000; + + public virtual int RefreshTokenUsage { get; set; } = (int)TokenUsage.OneTimeOnly; + + public virtual bool UpdateAccessTokenClaimsOnRefresh { get; set; } + + public virtual int RefreshTokenExpiration { get; set; } = (int)TokenExpiration.Absolute; + + public virtual int AccessTokenType { get; set; } = (int)0; // AccessTokenType.Jwt; + + public virtual bool EnableLocalLogin { get; set; } = true; + + public virtual List IdentityProviderRestrictions { get; set; } + + public virtual bool IncludeJwtId { get; set; } + + public virtual List Claims { get; set; } + + public virtual bool AlwaysSendClientClaims { get; set; } + + public virtual string ClientClaimsPrefix { get; set; } = "client_"; + + public virtual string PairWiseSubjectSalt { get; set; } + + public virtual List AllowedCorsOrigins { get; set; } + + public virtual List Properties { get; set; } + + protected Client() + { + + } + + public Client(Guid id) + { + Id = id; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientAutoMapperProfile.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientAutoMapperProfile.cs new file mode 100644 index 0000000000..ccd551b294 --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientAutoMapperProfile.cs @@ -0,0 +1,12 @@ +using AutoMapper; + +namespace Volo.Abp.IdentityServer.Clients +{ + public class ClientAutoMapperProfile : Profile + { + public ClientAutoMapperProfile() + { + CreateMap(); + } + } +} diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientClaim.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientClaim.cs new file mode 100644 index 0000000000..bb0cb7e0f5 --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientClaim.cs @@ -0,0 +1,24 @@ +using System; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.IdentityServer.Clients +{ + public class ClientClaim : Entity + { + public virtual string Type { get; set; } + + public virtual string Value { get; set; } + + public virtual Guid ClientId { get; set; } + + protected ClientClaim() + { + + } + + public ClientClaim(Guid id) + { + Id = id; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientCorsOrigin.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientCorsOrigin.cs new file mode 100644 index 0000000000..4decc3132e --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientCorsOrigin.cs @@ -0,0 +1,22 @@ +using System; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.IdentityServer.Clients +{ + public class ClientCorsOrigin : Entity + { + public virtual string Origin { get; set; } + + public virtual Guid ClientId { get; set; } + + protected ClientCorsOrigin() + { + + } + + public ClientCorsOrigin(Guid id) + { + Id = id; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientGrantType.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientGrantType.cs new file mode 100644 index 0000000000..8b577193ad --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientGrantType.cs @@ -0,0 +1,22 @@ +using System; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.IdentityServer.Clients +{ + public class ClientGrantType : Entity + { + public virtual string GrantType { get; set; } + + public virtual Guid ClientId { get; set; } + + protected ClientGrantType() + { + + } + + public ClientGrantType(Guid id) + { + Id = id; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientIdPRestriction.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientIdPRestriction.cs new file mode 100644 index 0000000000..936dc71042 --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientIdPRestriction.cs @@ -0,0 +1,22 @@ +using System; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.IdentityServer.Clients +{ + public class ClientIdPRestriction : Entity + { + public virtual string Provider { get; set; } + + public virtual Guid ClientId { get; set; } + + protected ClientIdPRestriction() + { + + } + + public ClientIdPRestriction(Guid id) + { + Id = id; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientPostLogoutRedirectUri.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientPostLogoutRedirectUri.cs new file mode 100644 index 0000000000..fa30e00819 --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientPostLogoutRedirectUri.cs @@ -0,0 +1,22 @@ +using System; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.IdentityServer.Clients +{ + public class ClientPostLogoutRedirectUri : Entity + { + public virtual string PostLogoutRedirectUri { get; set; } + + public virtual Guid ClientId { get; set; } + + protected ClientPostLogoutRedirectUri() + { + + } + + public ClientPostLogoutRedirectUri(Guid id) + { + Id = id; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientProperty.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientProperty.cs new file mode 100644 index 0000000000..843884cf3b --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientProperty.cs @@ -0,0 +1,24 @@ +using System; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.IdentityServer.Clients +{ + public class ClientProperty : Entity + { + public virtual string Key { get; set; } + + public virtual string Value { get; set; } + + public virtual Guid ClientId { get; set; } + + protected ClientProperty() + { + + } + + public ClientProperty(Guid id) + { + Id = id; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientRedirectUri.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientRedirectUri.cs new file mode 100644 index 0000000000..689d15a681 --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientRedirectUri.cs @@ -0,0 +1,22 @@ +using System; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.IdentityServer.Clients +{ + public class ClientRedirectUri : Entity + { + public virtual string RedirectUri { get; set; } + + public virtual Guid ClientId { get; set; } + + protected ClientRedirectUri() + { + + } + + public ClientRedirectUri(Guid id) + { + Id = id; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientScope.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientScope.cs new file mode 100644 index 0000000000..b7740dd78b --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientScope.cs @@ -0,0 +1,22 @@ +using System; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.IdentityServer.Clients +{ + public class ClientScope : Entity + { + public virtual string Scope { get; set; } + + public virtual Guid ClientId { get; set; } + + protected ClientScope() + { + + } + + public ClientScope(Guid id) + { + Id = id; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientSecret.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientSecret.cs new file mode 100644 index 0000000000..a0de719658 --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientSecret.cs @@ -0,0 +1,20 @@ +using System; + +namespace Volo.Abp.IdentityServer.Clients +{ + public class ClientSecret : Secret + { + public virtual Guid ClientId { get; set; } + + protected ClientSecret() + { + + } + + public ClientSecret(Guid id) + : base(id) + { + Id = id; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientStore.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientStore.cs new file mode 100644 index 0000000000..28583b78ee --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/ClientStore.cs @@ -0,0 +1,25 @@ +using System.Threading.Tasks; +using IdentityServer4.Stores; +using Volo.Abp.DependencyInjection; +using Volo.Abp.ObjectMapping; + +namespace Volo.Abp.IdentityServer.Clients +{ + public class ClientStore : IClientStore, ITransientDependency + { + private readonly IClientRepository _clientRepository; + private readonly IObjectMapper _objectMapper; + + public ClientStore(IClientRepository clientRepository, IObjectMapper objectMapper) + { + _clientRepository = clientRepository; + _objectMapper = objectMapper; + } + + public virtual async Task FindClientByIdAsync(string clientId) + { + var client = await _clientRepository.FindByCliendIdIncludingAllAsync(clientId); + return _objectMapper.Map(client); + } + } +} diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/IClientRepository.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/IClientRepository.cs new file mode 100644 index 0000000000..c8cd46af63 --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Clients/IClientRepository.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; +using JetBrains.Annotations; +using Volo.Abp.Domain.Repositories; + +namespace Volo.Abp.IdentityServer.Clients +{ + public interface IClientRepository : IRepository + { + Task FindByCliendIdIncludingAllAsync([NotNull] string clientId); + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Grants/PersistedGrant.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Grants/PersistedGrant.cs new file mode 100644 index 0000000000..e47401d607 --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Grants/PersistedGrant.cs @@ -0,0 +1,32 @@ +using System; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.IdentityServer.Grants +{ + public class PersistedGrant : AggregateRoot + { + public virtual string Key { get; set; } + + public virtual string Type { get; set; } + + public virtual string SubjectId { get; set; } + + public virtual string ClientId { get; set; } + + public virtual DateTime CreationTime { get; set; } + + public virtual DateTime? Expiration { get; set; } + + public virtual string Data { get; set; } + + protected PersistedGrant() + { + + } + + public PersistedGrant(Guid id) + { + Id = id; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IdentityClaim.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IdentityClaim.cs new file mode 100644 index 0000000000..253e0388b2 --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IdentityClaim.cs @@ -0,0 +1,20 @@ +using System; + +namespace Volo.Abp.IdentityServer.IdentityResources +{ + public class IdentityClaim : UserClaim + { + public virtual Guid IdentityResourceId { get; set; } + + protected IdentityClaim() + { + + } + + public IdentityClaim(Guid id) + : base(id) + { + + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IdentityResource.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IdentityResource.cs new file mode 100644 index 0000000000..9251862c96 --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityResources/IdentityResource.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.IdentityServer.IdentityResources +{ + public class IdentityResource : AggregateRoot + { + public virtual bool Enabled { get; set; } = true; + + public virtual string Name { get; set; } + + public virtual string DisplayName { get; set; } + + public virtual string Description { get; set; } + + public virtual bool Required { get; set; } + + public virtual bool Emphasize { get; set; } + + public virtual bool ShowInDiscoveryDocument { get; set; } = true; + + public virtual List UserClaims { get; set; } //TODO: Rename to Claims..? + + protected IdentityResource() + { + + } + + public IdentityResource(Guid id) + { + Id = id; + } + } +} diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Secret.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Secret.cs new file mode 100644 index 0000000000..bf0b83d444 --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/Secret.cs @@ -0,0 +1,29 @@ +using System; +using IdentityServer4; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.IdentityServer +{ + //TODO: Eleminate Secret class for simplicity. + + public abstract class Secret : Entity + { + public virtual string Description { get; set; } + + public virtual string Value { get; set; } + + public virtual DateTime? Expiration { get; set; } + + public virtual string Type { get; set; } = IdentityServerConstants.SecretTypes.SharedSecret; + + protected Secret() + { + + } + + protected Secret(Guid id) + { + Id = id; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/UserClaim.cs b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/UserClaim.cs new file mode 100644 index 0000000000..9529a42ed1 --- /dev/null +++ b/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/UserClaim.cs @@ -0,0 +1,22 @@ +using System; +using Volo.Abp.Domain.Entities; + +namespace Volo.Abp.IdentityServer +{ + //TODO: Eleminate UserClaim class for simplicity. + + public abstract class UserClaim : Entity + { + public virtual string Type { get; set; } + + protected UserClaim() + { + + } + + protected UserClaim(Guid id) + { + Id = id; + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo.Abp.IdentityServer.EntityFrameworkCore.csproj b/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo.Abp.IdentityServer.EntityFrameworkCore.csproj index 70e0258eb7..19c847d9a1 100644 --- a/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo.Abp.IdentityServer.EntityFrameworkCore.csproj +++ b/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo.Abp.IdentityServer.EntityFrameworkCore.csproj @@ -14,6 +14,7 @@ + diff --git a/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ClientRepository.cs b/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ClientRepository.cs new file mode 100644 index 0000000000..e0d44d2183 --- /dev/null +++ b/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ClientRepository.cs @@ -0,0 +1,32 @@ +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Volo.Abp.Domain.Repositories.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.IdentityServer.Clients; +using Volo.Abp.IdentityServer.EntityFrameworkCore; + +namespace Volo.Abp.IdentityServer +{ + public class ClientRepository : EfCoreRepository, IClientRepository + { + public ClientRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) + { + + } + + public Task FindByCliendIdIncludingAllAsync(string clientId) + { + return DbSet + .Include(x => x.AllowedGrantTypes) + .Include(x => x.RedirectUris) + .Include(x => x.PostLogoutRedirectUris) + .Include(x => x.AllowedScopes) + .Include(x => x.ClientSecrets) + .Include(x => x.Claims) + .Include(x => x.IdentityProviderRestrictions) + .Include(x => x.AllowedCorsOrigins) + .Include(x => x.Properties) + .FirstOrDefaultAsync(x => x.ClientId == clientId); + } + } +} diff --git a/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/EntityFrameworkCore/AbpIdentityServerModule.cs b/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/EntityFrameworkCore/AbpIdentityServerModule.cs index 30e8f68ff2..2b38a9f56a 100644 --- a/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/EntityFrameworkCore/AbpIdentityServerModule.cs +++ b/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/EntityFrameworkCore/AbpIdentityServerModule.cs @@ -1,12 +1,21 @@ using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.EntityFrameworkCore; using Volo.Abp.Modularity; namespace Volo.Abp.IdentityServer.EntityFrameworkCore { + [DependsOn(typeof(AbpIdentityServerDomainModule))] + [DependsOn(typeof(AbpEntityFrameworkCoreModule))] public class AbpIdentityServerEntityFrameworkCoreModule : AbpModule { public override void ConfigureServices(IServiceCollection services) { + services.AddAbpDbContext(options => + { + options.WithDefaultRepositories(); + //options.WithCustomRepository(); + }); + services.AddAssemblyOf(); } } diff --git a/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/EntityFrameworkCore/IdentityServerDbContext.cs b/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/EntityFrameworkCore/IdentityServerDbContext.cs new file mode 100644 index 0000000000..3c4bc19fc4 --- /dev/null +++ b/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/EntityFrameworkCore/IdentityServerDbContext.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.IdentityServer.ApiResources; +using Volo.Abp.IdentityServer.Clients; +using Volo.Abp.IdentityServer.Grants; +using Volo.Abp.IdentityServer.IdentityResources; + +namespace Volo.Abp.IdentityServer.EntityFrameworkCore +{ + public class IdentityServerDbContext : AbpDbContext + { + public DbSet Clients { get; set; } + + public DbSet PersistedGrants { get; set; } + + public DbSet ApiResources { get; set; } + + public DbSet IdentityResources { get; set; } + + //TODO: Add child entity types too... + + public IdentityServerDbContext(DbContextOptions options) + : base(options) + { + + } + } +} diff --git a/test/Abp.IdentityServer.EntityFrameworkCore.Tests/Abp.IdentityServer.EntityFrameworkCore.Tests.csproj b/test/Abp.IdentityServer.EntityFrameworkCore.Tests/Abp.IdentityServer.EntityFrameworkCore.Tests.csproj new file mode 100644 index 0000000000..48ac770ec5 --- /dev/null +++ b/test/Abp.IdentityServer.EntityFrameworkCore.Tests/Abp.IdentityServer.EntityFrameworkCore.Tests.csproj @@ -0,0 +1,25 @@ + + + + netcoreapp2.0 + Abp.IdentityServer.EntityFrameworkCore.Tests + Abp.IdentityServer.EntityFrameworkCore.Tests + true + false + false + false + + + + + + + + + + + + + + + diff --git a/test/Abp.IdentityServer.EntityFrameworkCore.Tests/Volo/Abp/IdentityServer/AbpIdentityApplicationTestBase.cs b/test/Abp.IdentityServer.EntityFrameworkCore.Tests/Volo/Abp/IdentityServer/AbpIdentityApplicationTestBase.cs new file mode 100644 index 0000000000..2897897ab2 --- /dev/null +++ b/test/Abp.IdentityServer.EntityFrameworkCore.Tests/Volo/Abp/IdentityServer/AbpIdentityApplicationTestBase.cs @@ -0,0 +1,12 @@ +using Volo.Abp.TestBase; + +namespace Volo.Abp.IdentityServer +{ + public class AbpIdentityServerTestBase : AbpIntegratedTest + { + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + } +} diff --git a/test/Abp.IdentityServer.EntityFrameworkCore.Tests/Volo/Abp/IdentityServer/AbpIdentityServerTestDataBuilder.cs b/test/Abp.IdentityServer.EntityFrameworkCore.Tests/Volo/Abp/IdentityServer/AbpIdentityServerTestDataBuilder.cs new file mode 100644 index 0000000000..952838c79f --- /dev/null +++ b/test/Abp.IdentityServer.EntityFrameworkCore.Tests/Volo/Abp/IdentityServer/AbpIdentityServerTestDataBuilder.cs @@ -0,0 +1,36 @@ +using Volo.Abp.DependencyInjection; +using Volo.Abp.Guids; +using Volo.Abp.IdentityServer.Clients; + +namespace Volo.Abp.IdentityServer +{ + public class AbpIdentityServerTestDataBuilder : ITransientDependency + { + private readonly IClientRepository _clientRepository; + private readonly IGuidGenerator _guidGenerator; + + public AbpIdentityServerTestDataBuilder( + IClientRepository clientRepository, + IGuidGenerator guidGenerator) + { + _clientRepository = clientRepository; + _guidGenerator = guidGenerator; + } + + public void Build() + { + AddClients(); + } + + private void AddClients() + { + var client42 = new Client(_guidGenerator.Create()) + { + ClientId = "42", + ProtocolType = "TestProtocol-42" + }; + + _clientRepository.Insert(client42); + } + } +} diff --git a/test/Abp.IdentityServer.EntityFrameworkCore.Tests/Volo/Abp/IdentityServer/AbpIdentityServerTestEntityFrameworkCoreModule.cs b/test/Abp.IdentityServer.EntityFrameworkCore.Tests/Volo/Abp/IdentityServer/AbpIdentityServerTestEntityFrameworkCoreModule.cs new file mode 100644 index 0000000000..f5a3efe323 --- /dev/null +++ b/test/Abp.IdentityServer.EntityFrameworkCore.Tests/Volo/Abp/IdentityServer/AbpIdentityServerTestEntityFrameworkCoreModule.cs @@ -0,0 +1,53 @@ +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Autofac; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.IdentityServer.EntityFrameworkCore; +using Volo.Abp.Modularity; +using Volo.Abp.Uow; + +namespace Volo.Abp.IdentityServer +{ + [DependsOn(typeof(AbpAutofacModule))] + [DependsOn(typeof(AbpIdentityServerEntityFrameworkCoreModule))] + public class AbpIdentityServerTestEntityFrameworkCoreModule : AbpModule + { + public override void ConfigureServices(IServiceCollection services) + { + services.AddAssemblyOf(); + + services.AddEntityFrameworkInMemoryDatabase(); + + var databaseName = Guid.NewGuid().ToString(); + + services.Configure(options => + { + options.Configure(context => + { + context.DbContextOptions.UseInMemoryDatabase(databaseName); + }); + }); + + services.Configure(options => + { + options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; //EF in-memory database does not support transactions + }); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + SeedTestData(context); + } + + private static void SeedTestData(ApplicationInitializationContext context) + { + using (var scope = context.ServiceProvider.CreateScope()) + { + scope.ServiceProvider + .GetRequiredService() + .Build(); + } + } + } +} \ No newline at end of file diff --git a/test/Abp.IdentityServer.EntityFrameworkCore.Tests/Volo/Abp/IdentityServer/Clients/ClientStore_Tests.cs b/test/Abp.IdentityServer.EntityFrameworkCore.Tests/Volo/Abp/IdentityServer/Clients/ClientStore_Tests.cs new file mode 100644 index 0000000000..32c5669635 --- /dev/null +++ b/test/Abp.IdentityServer.EntityFrameworkCore.Tests/Volo/Abp/IdentityServer/Clients/ClientStore_Tests.cs @@ -0,0 +1,37 @@ +using System.Threading.Tasks; +using IdentityServer4.Stores; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Xunit; + +namespace Volo.Abp.IdentityServer.Clients +{ + public class ClientStore_Tests : AbpIdentityServerTestBase + { + private readonly IClientStore _clientStore; + + public ClientStore_Tests() + { + _clientStore = ServiceProvider.GetRequiredService(); + } + + [Fact] + public async Task FindClientByIdAsync_Should_Return_Null_If_Not_Found() + { + var client = await _clientStore.FindClientByIdAsync("non-existing-id"); + client.ShouldBeNull(); + } + + [Fact] + public async Task FindClientByIdAsync_Should_Return_The_Client_If_Found() + { + //Act + var client = await _clientStore.FindClientByIdAsync("42"); + + //Assert + client.ShouldNotBeNull(); + client.ClientId.ShouldBe("42"); + client.ProtocolType.ShouldBe("TestProtocol-42"); + } + } +}