Browse Source

Replace `AutoMapper` with `Mapperly` in `IdentityServer`

pull/23520/head
Muhammed Ali ÖZKAYA 6 months ago
parent
commit
17478d6ca6
  1. 6
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo.Abp.IdentityServer.Domain.abppkg.analyze.json
  2. 2
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo.Abp.IdentityServer.Domain.csproj
  3. 11
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs
  4. 40
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AllowedSigningAlgorithmsConverter.cs
  5. 155
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityServerAutoMapperProfile.cs
  6. 238
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityServerMapperlyMappers.cs

6
modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo.Abp.IdentityServer.Domain.abppkg.analyze.json

@ -11,9 +11,9 @@
"name": "AbpIdentityServerDomainSharedModule"
},
{
"declaringAssemblyName": "Volo.Abp.AutoMapper",
"namespace": "Volo.Abp.AutoMapper",
"name": "AbpAutoMapperModule"
"declaringAssemblyName": "Volo.Abp.Mapperly",
"namespace": "Volo.Abp.Mapperly",
"name": "AbpMapperlyModule"
},
{
"declaringAssemblyName": "Volo.Abp.Identity.Domain",

2
modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo.Abp.IdentityServer.Domain.csproj

@ -17,7 +17,7 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.IdentityServer.Domain.Shared\Volo.Abp.IdentityServer.Domain.Shared.csproj" />
<ProjectReference Include="..\..\..\..\modules\identity\src\Volo.Abp.Identity.Domain\Volo.Abp.Identity.Domain.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.AutoMapper\Volo.Abp.AutoMapper.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Mapperly\Volo.Abp.Mapperly.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Security\Volo.Abp.Security.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Caching\Volo.Abp.Caching.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Validation\Volo.Abp.Validation.csproj" />

11
modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs

@ -5,7 +5,7 @@ using IdentityServer4.Stores;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using Volo.Abp.AutoMapper;
using Volo.Abp.Mapperly;
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.Caching;
using Volo.Abp.Domain.Entities.Events.Distributed;
@ -28,7 +28,7 @@ namespace Volo.Abp.IdentityServer;
[DependsOn(
typeof(AbpIdentityServerDomainSharedModule),
typeof(AbpAutoMapperModule),
typeof(AbpMapperlyModule),
typeof(AbpIdentityDomainModule),
typeof(AbpSecurityModule),
typeof(AbpCachingModule),
@ -41,12 +41,7 @@ public class AbpIdentityServerDomainModule : AbpModule
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAutoMapperObjectMapper<AbpIdentityServerDomainModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<IdentityServerAutoMapperProfile>(validate: true);
});
context.Services.AddMapperlyObjectMapper<AbpIdentityServerDomainModule>();
Configure<AbpDistributedEntityEventOptions>(options =>
{

40
modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AllowedSigningAlgorithmsConverter.cs

@ -1,36 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
namespace Volo.Abp.IdentityServer;
public class AllowedSigningAlgorithmsConverter :
IValueConverter<ICollection<string>, string>,
IValueConverter<string, ICollection<string>>
public static class AllowedSigningAlgorithmsConverter
{
public static AllowedSigningAlgorithmsConverter Converter = new AllowedSigningAlgorithmsConverter();
public string Convert(ICollection<string> sourceMember, ResolutionContext context)
{
if (sourceMember == null || !sourceMember.Any())
{
return null;
}
return sourceMember.Aggregate((x, y) => $"{x},{y}");
}
public ICollection<string> Convert(string sourceMember, ResolutionContext context)
private const char Separator = ',';
public static string[] SplitToArray(string algorithms)
{
var list = new HashSet<string>();
if (!String.IsNullOrWhiteSpace(sourceMember))
if (string.IsNullOrWhiteSpace(algorithms))
{
sourceMember = sourceMember.Trim();
foreach (var item in sourceMember.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Distinct())
{
list.Add(item);
}
return [];
}
return list;
return algorithms
.Split([Separator], StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Trim())
.Where(x => !string.IsNullOrEmpty(x))
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToArray();
}
}
}

155
modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityServerAutoMapperProfile.cs

@ -1,155 +0,0 @@
using System.Collections.Generic;
using System.Security.Claims;
using AutoMapper;
using Volo.Abp.IdentityServer.ApiResources;
using Volo.Abp.IdentityServer.ApiScopes;
using Volo.Abp.IdentityServer.Clients;
using Volo.Abp.IdentityServer.Devices;
using Volo.Abp.IdentityServer.Grants;
using Volo.Abp.IdentityServer.IdentityResources;
namespace Volo.Abp.IdentityServer;
public class IdentityServerAutoMapperProfile : Profile
{
/// <summary>
/// TODO: Reverse maps will not used probably. Remove those will not used
/// </summary>
public IdentityServerAutoMapperProfile()
{
CreateMap<UserClaim, string>()
.ConstructUsing(src => src.Type)
.ReverseMap()
.ForMember(dest => dest.Type, opt => opt.MapFrom(src => src));
CreateClientMap();
CreateApiResourceMap();
CreateApiScopeMap();
CreateIdentityResourceMap();
CreatePersistedGrantMap();
CreateDeviceFlowCodesMap();
}
private void CreateClientMap()
{
CreateMap<ClientCorsOrigin, string>()
.ConstructUsing(src => src.Origin)
.ReverseMap()
.ForMember(dest => dest.Origin, opt => opt.MapFrom(src => src));
CreateMap<ClientProperty, KeyValuePair<string, string>>()
.ReverseMap();
CreateMap<Client, IdentityServer4.Models.Client>()
.ForMember(dest => dest.ProtocolType, opt => opt.Condition(srs => srs != null))
.ForMember(x => x.AllowedIdentityTokenSigningAlgorithms, opts => opts.ConvertUsing(AllowedSigningAlgorithmsConverter.Converter, x => x.AllowedIdentityTokenSigningAlgorithms))
.ReverseMap()
.ForMember(x => x.AllowedIdentityTokenSigningAlgorithms, opts => opts.ConvertUsing(AllowedSigningAlgorithmsConverter.Converter, x => x.AllowedIdentityTokenSigningAlgorithms));
CreateMap<ClientCorsOrigin, string>()
.ConstructUsing(src => src.Origin)
.ReverseMap()
.ForMember(dest => dest.Origin, opt => opt.MapFrom(src => src));
CreateMap<ClientIdPRestriction, string>()
.ConstructUsing(src => src.Provider)
.ReverseMap()
.ForMember(dest => dest.Provider, opt => opt.MapFrom(src => src));
CreateMap<ClientClaim, Claim>(MemberList.None)
.ConstructUsing(src => new Claim(src.Type, src.Value))
.ReverseMap();
CreateMap<ClientClaim, IdentityServer4.Models.ClientClaim>(MemberList.None)
.ConstructUsing(src => new IdentityServer4.Models.ClientClaim(src.Type, src.Value, ClaimValueTypes.String))
.ReverseMap();
CreateMap<ClientScope, string>()
.ConstructUsing(src => src.Scope)
.ReverseMap()
.ForMember(dest => dest.Scope, opt => opt.MapFrom(src => src));
CreateMap<ClientPostLogoutRedirectUri, string>()
.ConstructUsing(src => src.PostLogoutRedirectUri)
.ReverseMap()
.ForMember(dest => dest.PostLogoutRedirectUri, opt => opt.MapFrom(src => src));
CreateMap<ClientRedirectUri, string>()
.ConstructUsing(src => src.RedirectUri)
.ReverseMap()
.ForMember(dest => dest.RedirectUri, opt => opt.MapFrom(src => src));
CreateMap<ClientGrantType, string>()
.ConstructUsing(src => src.GrantType)
.ReverseMap()
.ForMember(dest => dest.GrantType, opt => opt.MapFrom(src => src));
CreateMap<ClientSecret, IdentityServer4.Models.Secret>(MemberList.Destination)
.ForMember(dest => dest.Type, opt => opt.Condition(srs => srs != null))
.ReverseMap();
CreateMap<Client, ClientEto>();
}
private void CreateApiResourceMap()
{
CreateMap<ApiResource, IdentityServer4.Models.ApiResource>()
.ForMember(dest => dest.ApiSecrets, opt => opt.MapFrom(src => src.Secrets))
.ForMember(x => x.AllowedAccessTokenSigningAlgorithms, opts => opts.ConvertUsing(AllowedSigningAlgorithmsConverter.Converter, x => x.AllowedAccessTokenSigningAlgorithms));
CreateMap<ApiResourceSecret, IdentityServer4.Models.Secret>();
CreateMap<ApiResourceScope, string>()
.ConstructUsing(x => x.Scope)
.ReverseMap()
.ForMember(dest => dest.Scope, opt => opt.MapFrom(src => src));
CreateMap<ApiResourceProperty, KeyValuePair<string, string>>()
.ReverseMap();
CreateMap<ApiResource, ApiResourceEto>();
}
private void CreateApiScopeMap()
{
CreateMap<ApiScopeProperty, KeyValuePair<string, string>>()
.ReverseMap();
CreateMap<ApiScopeClaim, string>()
.ConstructUsing(x => x.Type)
.ReverseMap()
.ForMember(dest => dest.Type, opt => opt.MapFrom(src => src));
CreateMap<ApiScope, IdentityServer4.Models.ApiScope>(MemberList.Destination)
.ConstructUsing(src => new IdentityServer4.Models.ApiScope())
.ReverseMap();
}
private void CreateIdentityResourceMap()
{
CreateMap<IdentityResource, IdentityServer4.Models.IdentityResource>()
.ConstructUsing(src => new IdentityServer4.Models.IdentityResource());
CreateMap<IdentityResourceClaim, string>()
.ConstructUsing(x => x.Type)
.ReverseMap()
.ForMember(dest => dest.Type, opt => opt.MapFrom(src => src));
CreateMap<IdentityResourceProperty, KeyValuePair<string, string>>()
.ReverseMap();
CreateMap<IdentityResource, IdentityResourceEto>();
}
private void CreatePersistedGrantMap()
{
//TODO: Why PersistedGrant mapping is in this profile?
CreateMap<PersistedGrant, IdentityServer4.Models.PersistedGrant>().ReverseMap();
CreateMap<PersistedGrant, PersistedGrantEto>();
}
private void CreateDeviceFlowCodesMap()
{
CreateMap<DeviceFlowCodes, DeviceFlowCodesEto>();
}
}

238
modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/IdentityServerMapperlyMappers.cs

@ -0,0 +1,238 @@
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using Riok.Mapperly.Abstractions;
using Volo.Abp.Mapperly;
using Volo.Abp.IdentityServer.ApiResources;
using Volo.Abp.IdentityServer.ApiScopes;
using Volo.Abp.IdentityServer.Clients;
using Volo.Abp.IdentityServer.Devices;
using Volo.Abp.IdentityServer.Grants;
using Volo.Abp.IdentityServer.IdentityResources;
namespace Volo.Abp.IdentityServer;
[Mapper]
public partial class ClientToISClientMapper : MapperBase<Client, IdentityServer4.Models.Client>
{
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.AllowedIdentityTokenSigningAlgorithms))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.Claims))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.ClientSecrets))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.AllowedGrantTypes))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.AllowedScopes))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.AllowedCorsOrigins))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.RedirectUris))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.PostLogoutRedirectUris))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.IdentityProviderRestrictions))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.Properties))]
public override partial IdentityServer4.Models.Client Map(Client source);
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.AllowedIdentityTokenSigningAlgorithms))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.Claims))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.ClientSecrets))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.AllowedGrantTypes))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.AllowedScopes))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.AllowedCorsOrigins))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.RedirectUris))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.PostLogoutRedirectUris))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.IdentityProviderRestrictions))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.Client.Properties))]
public override partial void Map(Client source, IdentityServer4.Models.Client destination);
public override void AfterMap(Client source, IdentityServer4.Models.Client destination)
{
destination.AllowedIdentityTokenSigningAlgorithms = AllowedSigningAlgorithmsConverter.SplitToArray(source.AllowedIdentityTokenSigningAlgorithms);
if (source.Properties != null)
{
destination.Properties = source.Properties.ToDictionary(x => x.Key, x => x.Value);
}
if (source.Claims != null)
{
destination.Claims = source.Claims.Select(x => new IdentityServer4.Models.ClientClaim(x.Type, x.Value, ClaimValueTypes.String)).ToList();
}
if (source.ClientSecrets != null)
{
destination.ClientSecrets = source.ClientSecrets.Select(x => new IdentityServer4.Models.Secret(x.Value, x.Expiration) { Type = x.Type, Description = x.Description }).ToList();
}
if (source.AllowedGrantTypes != null)
{
destination.AllowedGrantTypes = source.AllowedGrantTypes.Select(x => x.GrantType).ToList();
}
if (source.AllowedScopes != null)
{
destination.AllowedScopes = source.AllowedScopes.Select(x => x.Scope).ToList();
}
if (source.AllowedCorsOrigins != null)
{
destination.AllowedCorsOrigins = source.AllowedCorsOrigins.Select(x => x.Origin).ToList();
}
if (source.RedirectUris != null)
{
destination.RedirectUris = source.RedirectUris.Select(x => x.RedirectUri).ToList();
}
if (source.PostLogoutRedirectUris != null)
{
destination.PostLogoutRedirectUris = source.PostLogoutRedirectUris.Select(x => x.PostLogoutRedirectUri).ToList();
}
if (source.IdentityProviderRestrictions != null)
{
destination.IdentityProviderRestrictions = source.IdentityProviderRestrictions.Select(x => x.Provider).ToList();
}
}
}
[Mapper]
public partial class ApiResourceToISApiResourceMapper : MapperBase<ApiResource, IdentityServer4.Models.ApiResource>
{
[MapperIgnoreTarget(nameof(IdentityServer4.Models.ApiResource.AllowedAccessTokenSigningAlgorithms))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.ApiResource.ApiSecrets))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.ApiResource.Properties))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.ApiResource.Scopes))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.ApiResource.UserClaims))]
public override partial IdentityServer4.Models.ApiResource Map(ApiResource source);
[MapperIgnoreTarget(nameof(IdentityServer4.Models.ApiResource.AllowedAccessTokenSigningAlgorithms))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.ApiResource.ApiSecrets))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.ApiResource.Properties))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.ApiResource.Scopes))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.ApiResource.UserClaims))]
public override partial void Map(ApiResource source, IdentityServer4.Models.ApiResource destination);
public override void AfterMap(ApiResource source, IdentityServer4.Models.ApiResource destination)
{
destination.AllowedAccessTokenSigningAlgorithms = AllowedSigningAlgorithmsConverter.SplitToArray(source.AllowedAccessTokenSigningAlgorithms);
if (source.Properties != null)
{
destination.Properties = source.Properties.ToDictionary(x => x.Key, x => x.Value);
}
if (source.Secrets != null)
{
destination.ApiSecrets = source.Secrets.Select(x => new IdentityServer4.Models.Secret(x.Value, x.Expiration) { Type = x.Type, Description = x.Description }).ToList();
}
if (source.UserClaims != null)
{
destination.UserClaims = source.UserClaims.Select(x => x.Type).ToList();
}
if (source.Scopes != null)
{
destination.Scopes = source.Scopes.Select(x => x.Scope).ToList();
}
}
}
[Mapper]
public partial class ApiScopeToISApiScopeMapper : MapperBase<ApiScope, IdentityServer4.Models.ApiScope>
{
[MapperIgnoreTarget(nameof(IdentityServer4.Models.ApiScope.UserClaims))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.ApiScope.Properties))]
public override partial IdentityServer4.Models.ApiScope Map(ApiScope source);
[MapperIgnoreTarget(nameof(IdentityServer4.Models.ApiScope.UserClaims))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.ApiScope.Properties))]
public override partial void Map(ApiScope source, IdentityServer4.Models.ApiScope destination);
public override void AfterMap(ApiScope source, IdentityServer4.Models.ApiScope destination)
{
if (source.Properties != null)
{
destination.Properties = source.Properties.ToDictionary(x => x.Key, x => x.Value);
}
if (source.UserClaims != null)
{
destination.UserClaims = source.UserClaims.Select(x => x.Type).ToList();
}
}
}
[Mapper]
public partial class IdentityResourceToISIdentityResourceMapper : MapperBase<IdentityResource, IdentityServer4.Models.IdentityResource>
{
[MapperIgnoreTarget(nameof(IdentityServer4.Models.IdentityResource.UserClaims))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.IdentityResource.Properties))]
public override partial IdentityServer4.Models.IdentityResource Map(IdentityResource source);
[MapperIgnoreTarget(nameof(IdentityServer4.Models.IdentityResource.UserClaims))]
[MapperIgnoreTarget(nameof(IdentityServer4.Models.IdentityResource.Properties))]
public override partial void Map(IdentityResource source, IdentityServer4.Models.IdentityResource destination);
public override void AfterMap(IdentityResource source, IdentityServer4.Models.IdentityResource destination)
{
if (source.Properties != null)
{
destination.Properties = source.Properties.ToDictionary(x => x.Key, x => x.Value);
}
if (source.UserClaims != null)
{
destination.UserClaims = source.UserClaims.Select(x => x.Type).ToList();
}
}
}
[Mapper]
public partial class ClientToClientEtoMapper : MapperBase<Client, ClientEto>
{
public override partial ClientEto Map(Client source);
public override partial void Map(Client source, ClientEto destination);
}
[Mapper]
public partial class IdentityResourceToIdentityResourceEtoMapper : MapperBase<IdentityResource, IdentityResourceEto>
{
public override partial IdentityResourceEto Map(IdentityResource source);
public override partial void Map(IdentityResource source, IdentityResourceEto destination);
}
[Mapper]
public partial class PersistedGrantToISPersistedGrantMapper : TwoWayMapperBase<PersistedGrant, IdentityServer4.Models.PersistedGrant>
{
public override partial IdentityServer4.Models.PersistedGrant Map(PersistedGrant source);
public override partial void Map(PersistedGrant source, IdentityServer4.Models.PersistedGrant destination);
public override PersistedGrant ReverseMap(IdentityServer4.Models.PersistedGrant source)
{
var entity = new PersistedGrant(System.Guid.Empty)
{
Key = source.Key,
Type = source.Type,
SubjectId = source.SubjectId,
SessionId = source.SessionId,
ClientId = source.ClientId,
Description = source.Description,
CreationTime = source.CreationTime,
Expiration = source.Expiration,
ConsumedTime = source.ConsumedTime,
Data = source.Data
};
return entity;
}
public override void ReverseMap(IdentityServer4.Models.PersistedGrant source, PersistedGrant destination)
{
destination.Key = source.Key;
destination.Type = source.Type;
destination.SubjectId = source.SubjectId;
destination.SessionId = source.SessionId;
destination.ClientId = source.ClientId;
destination.Description = source.Description;
destination.CreationTime = source.CreationTime;
destination.Expiration = source.Expiration;
destination.ConsumedTime = source.ConsumedTime;
destination.Data = source.Data;
}
}
[Mapper]
public partial class PersistedGrantToPersistedGrantEtoMapper : MapperBase<PersistedGrant, PersistedGrantEto>
{
public override partial PersistedGrantEto Map(PersistedGrant source);
public override partial void Map(PersistedGrant source, PersistedGrantEto destination);
}
[Mapper]
public partial class DeviceFlowCodesToDeviceFlowCodesEtoMapper : MapperBase<DeviceFlowCodes, DeviceFlowCodesEto>
{
public override partial DeviceFlowCodesEto Map(DeviceFlowCodes source);
public override partial void Map(DeviceFlowCodes source, DeviceFlowCodesEto destination);
}
Loading…
Cancel
Save