diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpIdentityEntityFrameworkCoreModule.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpIdentityEntityFrameworkCoreModule.cs index f7211df12f..b3ff5c368b 100644 --- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpIdentityEntityFrameworkCoreModule.cs +++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/AbpIdentityEntityFrameworkCoreModule.cs @@ -15,6 +15,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore { options.AddRepository(); options.AddRepository(); + options.AddRepository(); }); } } diff --git a/modules/identityserver/Volo.Abp.IdentityServer.sln b/modules/identityserver/Volo.Abp.IdentityServer.sln index fcdc057cf3..97d6b0b97a 100644 --- a/modules/identityserver/Volo.Abp.IdentityServer.sln +++ b/modules/identityserver/Volo.Abp.IdentityServer.sln @@ -15,6 +15,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{2C792EC1-B EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.IdentityServer.EntityFrameworkCore.Tests", "test\Volo.Abp.IdentityServer.EntityFrameworkCore.Tests\Volo.Abp.IdentityServer.EntityFrameworkCore.Tests.csproj", "{8B8FBA95-4FA2-4438-A387-7C5EC7A89E82}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.IdentityServer.MongoDB", "src\Volo.Abp.IdentityServer.MongoDB\Volo.Abp.IdentityServer.MongoDB.csproj", "{FC6CC65A-27B9-43D4-8F20-D941B4987B2C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -37,6 +39,10 @@ Global {8B8FBA95-4FA2-4438-A387-7C5EC7A89E82}.Debug|Any CPU.Build.0 = Debug|Any CPU {8B8FBA95-4FA2-4438-A387-7C5EC7A89E82}.Release|Any CPU.ActiveCfg = Release|Any CPU {8B8FBA95-4FA2-4438-A387-7C5EC7A89E82}.Release|Any CPU.Build.0 = Release|Any CPU + {FC6CC65A-27B9-43D4-8F20-D941B4987B2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FC6CC65A-27B9-43D4-8F20-D941B4987B2C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FC6CC65A-27B9-43D4-8F20-D941B4987B2C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FC6CC65A-27B9-43D4-8F20-D941B4987B2C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -46,6 +52,7 @@ Global {FC035412-78AD-424C-BECE-B19D04C7B5A6} = {59A0FC0F-EA6D-477B-84A7-3B1E41B4C858} {F352D620-1CBF-4658-953F-70BA73B458F1} = {59A0FC0F-EA6D-477B-84A7-3B1E41B4C858} {8B8FBA95-4FA2-4438-A387-7C5EC7A89E82} = {2C792EC1-BA27-44ED-B7CC-D0939553F1B2} + {FC6CC65A-27B9-43D4-8F20-D941B4987B2C} = {59A0FC0F-EA6D-477B-84A7-3B1E41B4C858} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {45562023-C330-4060-A583-2BA10F472D3D} diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo.Abp.IdentityServer.MongoDB.csproj b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo.Abp.IdentityServer.MongoDB.csproj new file mode 100644 index 0000000000..72179c1d3c --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo.Abp.IdentityServer.MongoDB.csproj @@ -0,0 +1,22 @@ + + + + + + netstandard2.0 + Volo.Abp.IdentityServer.MongoDB + Volo.Abp.IdentityServer.MongoDB + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + false + false + false + + + + + + + + + + diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/AbpIdentityServerBsonClassMap.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/AbpIdentityServerBsonClassMap.cs new file mode 100644 index 0000000000..28cde387cf --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/AbpIdentityServerBsonClassMap.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Text; +using IdentityServer4.Models; +using MongoDB.Bson.Serialization; +using Volo.Abp.Threading; + +namespace Volo.Abp.IdentityServer.MongoDB +{ + public class AbpIdentityServerBsonClassMap + { + private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); + + public static void Configure() + { + OneTimeRunner.Run(() => + { + BsonClassMap.RegisterClassMap(map => + { + map.AutoMap(); + }); + BsonClassMap.RegisterClassMap(map => + { + map.AutoMap(); + }); + BsonClassMap.RegisterClassMap(map => + { + map.AutoMap(); + }); + BsonClassMap.RegisterClassMap(map => + { + map.AutoMap(); + }); + }); + } + } +} diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/AbpIdentityServerMongoDbContext.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/AbpIdentityServerMongoDbContext.cs new file mode 100644 index 0000000000..2803b91f8c --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/AbpIdentityServerMongoDbContext.cs @@ -0,0 +1,34 @@ +using MongoDB.Driver; +using Volo.Abp.Data; +using Volo.Abp.IdentityServer.ApiResources; +using Volo.Abp.IdentityServer.Clients; +using Volo.Abp.IdentityServer.Grants; +using Volo.Abp.MongoDB; +using IdentityResource = Volo.Abp.IdentityServer.IdentityResources.IdentityResource; + +namespace Volo.Abp.IdentityServer.MongoDB +{ + [ConnectionStringName("AbpIdentityServer")] + public class AbpIdentityServerMongoDbContext : AbpMongoDbContext, IAbpIdentityServerMongoDbContext + { + public static string CollectionPrefix { get; set; } = AbpIdentityServerConsts.DefaultDbTablePrefix; + + public IMongoCollection ApiResources => Collection(); + + public IMongoCollection Clients => Collection(); + + public IMongoCollection IdentityResources => Collection(); + + public IMongoCollection PersistedGrants => Collection(); + + protected override void CreateModel(IMongoModelBuilder modelBuilder) + { + base.CreateModel(modelBuilder); + + modelBuilder.ConfigureIdentityServer(options => + { + options.CollectionPrefix = CollectionPrefix; + }); + } + } +} diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/AbpIdentityServerMongoDbContextExtensions.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/AbpIdentityServerMongoDbContextExtensions.cs new file mode 100644 index 0000000000..ed9bfc7422 --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/AbpIdentityServerMongoDbContextExtensions.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Text; +using IdentityServer4.Models; +using Volo.Abp.MongoDB; + +namespace Volo.Abp.IdentityServer.MongoDB +{ + public static class AbpIdentityServerMongoDbContextExtensions + { + public static void ConfigureIdentityServer( + this IMongoModelBuilder builder, + Action optionsAction = null) + { + Check.NotNull(builder, nameof(builder)); + + var options = new IdentityServerMongoModelBuilderConfigurationOptions(); + + optionsAction?.Invoke(options); + + builder.Entity(b => + { + b.CollectionName = options.CollectionPrefix + "ApiResources"; + }); + + builder.Entity(b => + { + b.CollectionName = options.CollectionPrefix + "Clients"; + }); + + builder.Entity(b => + { + b.CollectionName = options.CollectionPrefix + "IdentityResources"; + }); + + builder.Entity(b => + { + b.CollectionName = options.CollectionPrefix + "PersistedGrants"; + }); + } + } +} diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/AbpIdentityServerMongoDbModule.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/AbpIdentityServerMongoDbModule.cs new file mode 100644 index 0000000000..6e42bc347d --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/AbpIdentityServerMongoDbModule.cs @@ -0,0 +1,30 @@ +using IdentityServer4.Models; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; +using Volo.Abp.MongoDB; +using ApiResource = Volo.Abp.IdentityServer.ApiResources.ApiResource; +using Client = Volo.Abp.IdentityServer.Clients.Client; +using IdentityResource = Volo.Abp.IdentityServer.IdentityResources.IdentityResource; + +namespace Volo.Abp.IdentityServer.MongoDB +{ + [DependsOn( + typeof(AbpIdentityServerDomainModule), + typeof(AbpMongoDbModule) + )] + public class AbpIdentityServerMongoDbModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + AbpIdentityServerBsonClassMap.Configure(); + + context.Services.AddMongoDbContext(options => + { + options.AddRepository(); + options.AddRepository(); + options.AddRepository(); + options.AddRepository(); + }); + } + } +} diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/IAbpIdentityServerMongoDbContext.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/IAbpIdentityServerMongoDbContext.cs new file mode 100644 index 0000000000..cbe1cf867f --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/IAbpIdentityServerMongoDbContext.cs @@ -0,0 +1,22 @@ +using MongoDB.Driver; +using Volo.Abp.Data; +using Volo.Abp.IdentityServer.Clients; +using Volo.Abp.IdentityServer.Grants; +using Volo.Abp.IdentityServer.IdentityResources; +using Volo.Abp.MongoDB; +using ApiResource = Volo.Abp.IdentityServer.ApiResources.ApiResource; + +namespace Volo.Abp.IdentityServer.MongoDB +{ + [ConnectionStringName("AbpIdentityServer")] + public interface IAbpIdentityServerMongoDbContext : IAbpMongoDbContext + { + IMongoCollection ApiResources { get; } + + IMongoCollection Clients { get; } + + IMongoCollection IdentityResources { get; } + + IMongoCollection PersistedGrants { get; } + } +} diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/IdentityServerMongoModelBuilderConfigurationOptions.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/IdentityServerMongoModelBuilderConfigurationOptions.cs new file mode 100644 index 0000000000..49b9f80f47 --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/IdentityServerMongoModelBuilderConfigurationOptions.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Volo.Abp.MongoDB; + +namespace Volo.Abp.IdentityServer.MongoDB +{ + public class IdentityServerMongoModelBuilderConfigurationOptions : MongoModelBuilderConfigurationOptions + { + public IdentityServerMongoModelBuilderConfigurationOptions() + : base(AbpIdentityServerConsts.DefaultDbTablePrefix) + { + } + } +} diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoApiResourceRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoApiResourceRepository.cs new file mode 100644 index 0000000000..26ab375882 --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoApiResourceRepository.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using MongoDB.Driver; +using MongoDB.Driver.Linq; +using Volo.Abp.Domain.Repositories.MongoDB; +using Volo.Abp.IdentityServer.ApiResources; +using Volo.Abp.MongoDB; + +namespace Volo.Abp.IdentityServer.MongoDB +{ + public class MongoApiResourceRepository : MongoDbRepository, IApiResourceRepository + { + public MongoApiResourceRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } + + public virtual async Task FindByNameAsync(string name, bool includeDetails = true, CancellationToken cancellationToken = default) + { + return await GetMongoQueryable() + .Where(ar=>ar.Name == name) + .FirstOrDefaultAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task> GetListByScopesAsync(string[] scopeNames, bool includeDetails = false, + CancellationToken cancellationToken = default) + { + return await GetMongoQueryable() + .Where(ar=>ar.Scopes.Any(x=> scopeNames.Contains(x.Name))) + .ToListAsync(GetCancellationToken(cancellationToken)); + } + } +} diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoClientRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoClientRepository.cs new file mode 100644 index 0000000000..f3ebe4bb62 --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoClientRepository.cs @@ -0,0 +1,22 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using MongoDB.Driver.Linq; +using Volo.Abp.Domain.Repositories.MongoDB; +using Volo.Abp.IdentityServer.Clients; +using Volo.Abp.MongoDB; + +namespace Volo.Abp.IdentityServer.MongoDB +{ + public class MongoClientRepository : MongoDbRepository, IClientRepository + { + public MongoClientRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } + + public async Task FindByCliendIdAsync(string clientId, bool includeDetails = true, CancellationToken cancellationToken = default) + { + return await GetMongoQueryable().FirstOrDefaultAsync(x => x.ClientId == clientId, GetCancellationToken(cancellationToken)); + } + } +} diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoIdentityResourceRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoIdentityResourceRepository.cs new file mode 100644 index 0000000000..ac2a1b4978 --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoIdentityResourceRepository.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using MongoDB.Driver; +using MongoDB.Driver.Linq; +using Volo.Abp.Domain.Repositories.MongoDB; +using Volo.Abp.IdentityServer.IdentityResources; +using Volo.Abp.MongoDB; + +namespace Volo.Abp.IdentityServer.MongoDB +{ + public class MongoIdentityResourceRepository : MongoDbRepository, IIdentityResourceRepository + { + public MongoIdentityResourceRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } + + public async Task> GetListByScopesAsync(string[] scopeNames, bool includeDetails = false, + CancellationToken cancellationToken = default) + { + return await GetMongoQueryable() + .Where(ar => scopeNames.Any(s=>s == ar.Name)) + .ToListAsync(GetCancellationToken(cancellationToken)); + } + } +} diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoPersistedGrantRepository.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoPersistedGrantRepository.cs new file mode 100644 index 0000000000..b85d3d3e06 --- /dev/null +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.MongoDB/Volo/Abp/IdentityServer/MongoDB/MongoPersistedGrantRepository.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using MongoDB.Driver; +using MongoDB.Driver.Linq; +using Volo.Abp.Domain.Repositories.MongoDB; +using Volo.Abp.IdentityServer.Grants; +using Volo.Abp.MongoDB; + +namespace Volo.Abp.IdentityServer.MongoDB +{ + public class MongoPersistedGrantRepository : MongoDbRepository, IPersistentGrantRepository + { + public MongoPersistedGrantRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } + + public async Task FindByKeyAsync(string key, CancellationToken cancellationToken = default) + { + + return await GetMongoQueryable() + .FirstOrDefaultAsync(x => x.Key == key, GetCancellationToken(cancellationToken)); + } + + public async Task> GetListBySubjectIdAsync(string subjectId, CancellationToken cancellationToken = default) + { + return await GetMongoQueryable() + .Where(x => x.SubjectId == subjectId) + .ToListAsync(GetCancellationToken(cancellationToken)); + } + + public async Task DeleteAsync(string subjectId, string clientId, CancellationToken cancellationToken = default) + { + await DeleteAsync( + x => x.SubjectId == subjectId && x.ClientId == clientId, + cancellationToken: GetCancellationToken(cancellationToken) + ); + } + + public async Task DeleteAsync(string subjectId, string clientId, string type, CancellationToken cancellationToken = default) + { + await DeleteAsync( + x => x.SubjectId == subjectId && x.ClientId == clientId && x.Type == type, + cancellationToken: GetCancellationToken(cancellationToken) + ); + } + } +}