mirror of https://github.com/abpframework/abp.git
71 changed files with 3152 additions and 200 deletions
@ -0,0 +1,49 @@ |
|||||
|
using System; |
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Tracing; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Tracing |
||||
|
{ |
||||
|
[Dependency(ReplaceServices = true)] |
||||
|
public class AspNetCoreCorrelationIdProvider : ICorrelationIdProvider, ITransientDependency |
||||
|
{ |
||||
|
protected IHttpContextAccessor HttpContextAccessor { get; } |
||||
|
protected CorrelationIdOptions Options { get; } |
||||
|
|
||||
|
public AspNetCoreCorrelationIdProvider( |
||||
|
IHttpContextAccessor httpContextAccessor, |
||||
|
IOptions<CorrelationIdOptions> options) |
||||
|
{ |
||||
|
HttpContextAccessor = httpContextAccessor; |
||||
|
Options = options.Value; |
||||
|
} |
||||
|
|
||||
|
public virtual string Get() |
||||
|
{ |
||||
|
if (HttpContextAccessor.HttpContext?.Request?.Headers == null) |
||||
|
{ |
||||
|
return CreateNewCorrelationId(); |
||||
|
} |
||||
|
|
||||
|
lock (HttpContextAccessor.HttpContext.Request.Headers) |
||||
|
{ |
||||
|
string correlationId = HttpContextAccessor.HttpContext.Request.Headers[Options.HttpHeaderName]; |
||||
|
|
||||
|
if (correlationId.IsNullOrEmpty()) |
||||
|
{ |
||||
|
correlationId = CreateNewCorrelationId(); |
||||
|
HttpContextAccessor.HttpContext.Request.Headers[Options.HttpHeaderName] = correlationId; |
||||
|
} |
||||
|
|
||||
|
return correlationId; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected virtual string CreateNewCorrelationId() |
||||
|
{ |
||||
|
return Guid.NewGuid().ToString("N"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Security.Claims; |
||||
|
|
||||
|
namespace Volo.Abp.Authorization.Permissions |
||||
|
{ |
||||
|
public class ClientPermissionValueProvider : PermissionValueProvider |
||||
|
{ |
||||
|
public const string ProviderName = "Client"; |
||||
|
|
||||
|
public override string Name => ProviderName; |
||||
|
|
||||
|
public ClientPermissionValueProvider(IPermissionStore permissionStore) |
||||
|
: base(permissionStore) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public override async Task<PermissionValueProviderGrantInfo> CheckAsync(PermissionValueCheckContext context) |
||||
|
{ |
||||
|
var clientId = context.Principal?.FindFirst(AbpClaimTypes.ClientId)?.Value; |
||||
|
|
||||
|
if (clientId == null) |
||||
|
{ |
||||
|
return PermissionValueProviderGrantInfo.NonGranted; |
||||
|
} |
||||
|
|
||||
|
if (await PermissionStore.IsGrantedAsync(context.Permission.Name, Name, clientId)) |
||||
|
{ |
||||
|
return new PermissionValueProviderGrantInfo(true, clientId); |
||||
|
} |
||||
|
|
||||
|
return PermissionValueProviderGrantInfo.NonGranted; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
namespace Volo.Abp.Tracing |
||||
|
{ |
||||
|
public class CorrelationIdOptions |
||||
|
{ |
||||
|
public string HttpHeaderName { get; set; } = "X-Correlation-Id"; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
using System; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.Tracing |
||||
|
{ |
||||
|
public class DefaultCorrelationIdProvider : ICorrelationIdProvider, ISingletonDependency |
||||
|
{ |
||||
|
public string Get() |
||||
|
{ |
||||
|
return CreateNewCorrelationId(); |
||||
|
} |
||||
|
|
||||
|
protected virtual string CreateNewCorrelationId() |
||||
|
{ |
||||
|
return Guid.NewGuid().ToString("N"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace Volo.Abp.Tracing |
||||
|
{ |
||||
|
public interface ICorrelationIdProvider |
||||
|
{ |
||||
|
[NotNull] |
||||
|
string Get(); |
||||
|
} |
||||
|
} |
||||
@ -1,98 +1,61 @@ |
|||||
using System; |
using System.Collections.Generic; |
||||
using System.Linq; |
using System.Linq; |
||||
using System.Reflection; |
|
||||
|
|
||||
namespace Volo.Abp.Domain.Values |
namespace Volo.Abp.Domain.Values |
||||
{ |
{ |
||||
//Inspired from https://blogs.msdn.microsoft.com/cesardelatorre/2011/06/06/implementing-a-value-object-base-class-supertype-patternddd-patterns-related/
|
//Inspired from https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/microservice-ddd-cqrs-patterns/implement-value-objects
|
||||
|
|
||||
/// <summary>
|
public abstract class ValueObject |
||||
/// Base class for value objects.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TValueObject">The type of the value object.</typeparam>
|
|
||||
public abstract class ValueObject<TValueObject> : IEquatable<TValueObject> |
|
||||
where TValueObject : ValueObject<TValueObject> |
|
||||
{ |
{ |
||||
public bool Equals(TValueObject other) |
protected static bool EqualOperator(ValueObject left, ValueObject right) |
||||
{ |
{ |
||||
if ((object)other == null) |
if (ReferenceEquals(left, null) ^ ReferenceEquals(right, null)) |
||||
{ |
{ |
||||
return false; |
return false; |
||||
} |
} |
||||
|
return ReferenceEquals(left, null) || left.Equals(right); |
||||
|
} |
||||
|
|
||||
var publicProperties = GetType().GetTypeInfo().GetProperties(); |
protected static bool NotEqualOperator(ValueObject left, ValueObject right) |
||||
if (!publicProperties.Any()) |
{ |
||||
{ |
return !(EqualOperator(left, right)); |
||||
return true; |
|
||||
} |
|
||||
|
|
||||
return publicProperties.All(property => Equals(property.GetValue(this, null), property.GetValue(other, null))); |
|
||||
} |
} |
||||
|
|
||||
|
protected abstract IEnumerable<object> GetAtomicValues(); |
||||
|
|
||||
public override bool Equals(object obj) |
public override bool Equals(object obj) |
||||
{ |
{ |
||||
if (obj == null) |
if (obj == null || obj.GetType() != GetType()) |
||||
{ |
{ |
||||
return false; |
return false; |
||||
} |
} |
||||
|
|
||||
var item = obj as ValueObject<TValueObject>; |
ValueObject other = (ValueObject)obj; |
||||
return (object)item != null && Equals((TValueObject)item); |
IEnumerator<object> thisValues = GetAtomicValues().GetEnumerator(); |
||||
} |
IEnumerator<object> otherValues = other.GetAtomicValues().GetEnumerator(); |
||||
|
while (thisValues.MoveNext() && otherValues.MoveNext()) |
||||
public override int GetHashCode() |
|
||||
{ |
|
||||
//TODO: Can we cache the hash value assuming value objects are always immutable? We can make a Reset-like method to reset it's mutated.
|
|
||||
|
|
||||
const int index = 1; |
|
||||
const int initialHasCode = 31; |
|
||||
|
|
||||
var publicProperties = GetType().GetTypeInfo().GetProperties(); |
|
||||
|
|
||||
if (!publicProperties.Any()) |
|
||||
{ |
{ |
||||
return initialHasCode; |
if (ReferenceEquals(thisValues.Current, null) ^ |
||||
} |
ReferenceEquals(otherValues.Current, null)) |
||||
|
|
||||
var hashCode = initialHasCode; |
|
||||
var changeMultiplier = false; |
|
||||
|
|
||||
foreach (var property in publicProperties) |
|
||||
{ |
|
||||
var value = property.GetValue(this, null); |
|
||||
|
|
||||
if (value == null) |
|
||||
{ |
{ |
||||
//support {"a",null,null,"a"} != {null,"a","a",null}
|
return false; |
||||
hashCode = hashCode ^ (index * 13); |
|
||||
continue; |
|
||||
} |
} |
||||
|
|
||||
hashCode = hashCode * (changeMultiplier ? 59 : 114) + value.GetHashCode(); |
if (thisValues.Current != null && |
||||
changeMultiplier = !changeMultiplier; |
!thisValues.Current.Equals(otherValues.Current)) |
||||
} |
{ |
||||
|
return false; |
||||
return hashCode; |
} |
||||
} |
|
||||
|
|
||||
public static bool operator ==(ValueObject<TValueObject> x, ValueObject<TValueObject> y) |
|
||||
{ |
|
||||
if (ReferenceEquals(x, y)) |
|
||||
{ |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
if (((object)x == null) || ((object)y == null)) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
} |
||||
|
return !thisValues.MoveNext() && !otherValues.MoveNext(); |
||||
return x.Equals(y); |
|
||||
} |
} |
||||
|
|
||||
public static bool operator !=(ValueObject<TValueObject> x, ValueObject<TValueObject> y) |
public override int GetHashCode() |
||||
{ |
{ |
||||
return !(x == y); |
return GetAtomicValues() |
||||
|
.Select(x => x != null ? x.GetHashCode() : 0) |
||||
|
.Aggregate((x, y) => x ^ y); |
||||
} |
} |
||||
|
// Other utilility methods
|
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,20 @@ |
|||||
|
using System.Security.Principal; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Security.Claims; |
||||
|
|
||||
|
namespace Volo.Abp.Clients |
||||
|
{ |
||||
|
public class CurrentClient : ICurrentClient, ITransientDependency |
||||
|
{ |
||||
|
public virtual string Id => _principalAccessor.Principal?.FindClientId(); |
||||
|
|
||||
|
public virtual bool IsAuthenticated => Id != null; |
||||
|
|
||||
|
private readonly ICurrentPrincipalAccessor _principalAccessor; |
||||
|
|
||||
|
public CurrentClient(ICurrentPrincipalAccessor principalAccessor) |
||||
|
{ |
||||
|
_principalAccessor = principalAccessor; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
namespace Volo.Abp.Clients |
||||
|
{ |
||||
|
public interface ICurrentClient |
||||
|
{ |
||||
|
string Id { get; } |
||||
|
|
||||
|
bool IsAuthenticated { get; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
using Volo.Blogging.Posts; |
||||
|
using System.Linq; |
||||
|
using Microsoft.EntityFrameworkCore; |
||||
|
|
||||
|
namespace Volo.Blogging |
||||
|
{ |
||||
|
public static class BloggingEntityFrameworkCoreQueryableExtensions |
||||
|
{ |
||||
|
public static IQueryable<Post> IncludeDetails(this IQueryable<Post> queryable, bool include = true) |
||||
|
{ |
||||
|
if (!include) |
||||
|
{ |
||||
|
return queryable; |
||||
|
} |
||||
|
|
||||
|
return queryable |
||||
|
.Include(x => x.Tags); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Application.Services; |
||||
|
using Volo.Abp.Users; |
||||
|
|
||||
|
namespace Volo.Abp.Identity |
||||
|
{ |
||||
|
public interface IIdentityUserLookupAppService : IApplicationService |
||||
|
{ |
||||
|
Task<UserData> FindByIdAsync(Guid id); |
||||
|
|
||||
|
Task<UserData> FindByUserNameAsync(string userName); |
||||
|
} |
||||
|
} |
||||
@ -1,12 +1,12 @@ |
|||||
{ |
{ |
||||
"culture": "pt-BR", |
"culture": "pt-BR", |
||||
"texts": { |
"texts": { |
||||
"Permission:IdentityManagement": "Gerenciamento de Acessos", |
"Permission:IdentityManagement": "Acessos", |
||||
"Permission:RoleManagement": "Gerenciamento de Perfis", |
"Permission:RoleManagement": "Perfis", |
||||
"Permission:Create": "Criar", |
"Permission:Create": "Criar", |
||||
"Permission:Edit": "Editar", |
"Permission:Edit": "Editar", |
||||
"Permission:Delete": "Excluir", |
"Permission:Delete": "Excluir", |
||||
"Permission:ChangePermissions": "Alterar Permissões", |
"Permission:ChangePermissions": "Alterar Permissões", |
||||
"Permission:UserManagement": "Gerenciamento de Usuários" |
"Permission:UserManagement": "Usuários" |
||||
} |
} |
||||
} |
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Authorization; |
||||
|
using Volo.Abp.Users; |
||||
|
|
||||
|
namespace Volo.Abp.Identity |
||||
|
{ |
||||
|
[Authorize(IdentityPermissions.UserLookup.Default)] |
||||
|
public class IdentityUserLookupAppService : IdentityAppServiceBase, IIdentityUserLookupAppService |
||||
|
{ |
||||
|
protected IdentityUserRepositoryExternalUserLookupServiceProvider UserLookupServiceProvider { get; } |
||||
|
|
||||
|
public IdentityUserLookupAppService( |
||||
|
IdentityUserRepositoryExternalUserLookupServiceProvider userLookupServiceProvider) |
||||
|
{ |
||||
|
UserLookupServiceProvider = userLookupServiceProvider; |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<UserData> FindByIdAsync(Guid id) |
||||
|
{ |
||||
|
var userData = await UserLookupServiceProvider.FindByIdAsync(id); |
||||
|
if (userData == null) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return new UserData(userData); |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<UserData> FindByUserNameAsync(string userName) |
||||
|
{ |
||||
|
var userData = await UserLookupServiceProvider.FindByUserNameAsync(userName); |
||||
|
if (userData == null) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return new UserData(userData); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,36 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Volo.Abp.AspNetCore.Mvc; |
||||
|
using Volo.Abp.Users; |
||||
|
|
||||
|
namespace Volo.Abp.Identity |
||||
|
{ |
||||
|
[RemoteService] |
||||
|
[Area("identity")] |
||||
|
[ControllerName("UserLookup")] |
||||
|
[Route("api/identity/user-lookup")] |
||||
|
public class IdentityUserLookupController : AbpController, IIdentityUserLookupAppService |
||||
|
{ |
||||
|
protected IIdentityUserLookupAppService LookupAppService { get; } |
||||
|
|
||||
|
public IdentityUserLookupController(IIdentityUserLookupAppService lookupAppService) |
||||
|
{ |
||||
|
LookupAppService = lookupAppService; |
||||
|
} |
||||
|
|
||||
|
[HttpGet] |
||||
|
[Route("{id}")] |
||||
|
public Task<UserData> FindByIdAsync(Guid id) |
||||
|
{ |
||||
|
return LookupAppService.FindByIdAsync(id); |
||||
|
} |
||||
|
|
||||
|
[HttpGet] |
||||
|
[Route("by-username/{userName}")] |
||||
|
public Task<UserData> FindByUserNameAsync(string userName) |
||||
|
{ |
||||
|
return LookupAppService.FindByUserNameAsync(userName); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.0</TargetFramework> |
||||
|
<AssemblyName>Volo.Abp.PermissionManagement.Domain.IdentityServer</AssemblyName> |
||||
|
<PackageId>Volo.Abp.PermissionManagement.Domain.IdentityServer</PackageId> |
||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
||||
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
||||
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
||||
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.IdentityServer.Domain.Shared\Volo.Abp.IdentityServer.Domain.Shared.csproj" /> |
||||
|
<ProjectReference Include="..\..\..\permission-management\src\Volo.Abp.PermissionManagement.Domain\Volo.Abp.PermissionManagement.Domain.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,18 @@ |
|||||
|
using Volo.Abp.Authorization.Permissions; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.PermissionManagement.IdentityServer |
||||
|
{ |
||||
|
public class AbpPermissionManagementDomainIdentityServerModule : AbpModule |
||||
|
{ |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
Configure<PermissionManagementOptions>(options => |
||||
|
{ |
||||
|
options.ManagementProviders.Add<ClientPermissionManagementProvider>(); |
||||
|
|
||||
|
options.ProviderPolicies[ClientPermissionValueProvider.ProviderName] = "IdentityServer.Client.ManagePermissions"; |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
using Volo.Abp.Authorization.Permissions; |
||||
|
using Volo.Abp.Guids; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
|
||||
|
namespace Volo.Abp.PermissionManagement.IdentityServer |
||||
|
{ |
||||
|
public class ClientPermissionManagementProvider : PermissionManagementProvider |
||||
|
{ |
||||
|
public override string Name => ClientPermissionValueProvider.ProviderName; |
||||
|
|
||||
|
public ClientPermissionManagementProvider( |
||||
|
IPermissionGrantRepository permissionGrantRepository, |
||||
|
IGuidGenerator guidGenerator, |
||||
|
ICurrentTenant currentTenant) |
||||
|
: base( |
||||
|
permissionGrantRepository, |
||||
|
guidGenerator, |
||||
|
currentTenant) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
File diff suppressed because it is too large
@ -0,0 +1,72 @@ |
|||||
|
using System.Reflection.Metadata; |
||||
|
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
|
||||
|
namespace AuthServer.Host.Migrations |
||||
|
{ |
||||
|
public partial class Added_ClientId_And_CorrelationId_To_AuditLogs : Migration |
||||
|
{ |
||||
|
protected override void Up(MigrationBuilder migrationBuilder) |
||||
|
{ |
||||
|
migrationBuilder.DropPrimaryKey( |
||||
|
"PK_IdentityServerClientPostLogoutRedirectUris", |
||||
|
"IdentityServerClientPostLogoutRedirectUris" |
||||
|
); |
||||
|
|
||||
|
migrationBuilder.AlterColumn<string>( |
||||
|
name: "PostLogoutRedirectUri", |
||||
|
table: "IdentityServerClientPostLogoutRedirectUris", |
||||
|
maxLength: 200, |
||||
|
nullable: false, |
||||
|
oldClrType: typeof(string), |
||||
|
oldMaxLength: 2000); |
||||
|
|
||||
|
migrationBuilder.AddPrimaryKey( |
||||
|
"PK_IdentityServerClientPostLogoutRedirectUris", |
||||
|
"IdentityServerClientPostLogoutRedirectUris", |
||||
|
new[] {"ClientId", "PostLogoutRedirectUri"} |
||||
|
); |
||||
|
|
||||
|
migrationBuilder.AddColumn<string>( |
||||
|
name: "ClientId", |
||||
|
table: "AbpAuditLogs", |
||||
|
maxLength: 64, |
||||
|
nullable: true); |
||||
|
|
||||
|
migrationBuilder.AddColumn<string>( |
||||
|
name: "CorrelationId", |
||||
|
table: "AbpAuditLogs", |
||||
|
maxLength: 64, |
||||
|
nullable: true); |
||||
|
} |
||||
|
|
||||
|
protected override void Down(MigrationBuilder migrationBuilder) |
||||
|
{ |
||||
|
migrationBuilder.DropColumn( |
||||
|
name: "ClientId", |
||||
|
table: "AbpAuditLogs"); |
||||
|
|
||||
|
migrationBuilder.DropColumn( |
||||
|
name: "CorrelationId", |
||||
|
table: "AbpAuditLogs"); |
||||
|
|
||||
|
migrationBuilder.DropPrimaryKey( |
||||
|
"PK_IdentityServerClientPostLogoutRedirectUris", |
||||
|
"IdentityServerClientPostLogoutRedirectUris" |
||||
|
); |
||||
|
|
||||
|
migrationBuilder.AlterColumn<string>( |
||||
|
name: "PostLogoutRedirectUri", |
||||
|
table: "IdentityServerClientPostLogoutRedirectUris", |
||||
|
maxLength: 2000, |
||||
|
nullable: false, |
||||
|
oldClrType: typeof(string), |
||||
|
oldMaxLength: 200); |
||||
|
|
||||
|
migrationBuilder.AddPrimaryKey( |
||||
|
"PK_IdentityServerClientPostLogoutRedirectUris", |
||||
|
"IdentityServerClientPostLogoutRedirectUris", |
||||
|
new[] { "ClientId", "PostLogoutRedirectUri" } |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
File diff suppressed because it is too large
@ -0,0 +1,23 @@ |
|||||
|
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
|
||||
|
namespace AuthServer.Host.Migrations |
||||
|
{ |
||||
|
public partial class Added_ApplicationName_To_AuditLogs : Migration |
||||
|
{ |
||||
|
protected override void Up(MigrationBuilder migrationBuilder) |
||||
|
{ |
||||
|
migrationBuilder.AddColumn<string>( |
||||
|
name: "ApplicationName", |
||||
|
table: "AbpAuditLogs", |
||||
|
maxLength: 96, |
||||
|
nullable: true); |
||||
|
} |
||||
|
|
||||
|
protected override void Down(MigrationBuilder migrationBuilder) |
||||
|
{ |
||||
|
migrationBuilder.DropColumn( |
||||
|
name: "ApplicationName", |
||||
|
table: "AbpAuditLogs"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Binary file not shown.
Loading…
Reference in new issue