Browse Source

Merge pull request #4675 from abpframework/maliming/UserSecurityLog

Introduce security log.
pull/4797/head
Halil İbrahim Kalkan 6 years ago
committed by GitHub
parent
commit
cce16101ad
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 24
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AspNetCoreAuditLogContributor.cs
  2. 73
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/SecurityLog/AspNetCoreSecurityLogManager.cs
  3. 43
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/WebClientInfo/HttpContextWebClientInfoProvider.cs
  4. 9
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/WebClientInfo/IWebClientInfoProvider.cs
  5. 21
      framework/src/Volo.Abp.Security/Volo/Abp/SecurityLog/AbpSecurityLogOptions.cs
  6. 42
      framework/src/Volo.Abp.Security/Volo/Abp/SecurityLog/DefaultSecurityLogManager.cs
  7. 10
      framework/src/Volo.Abp.Security/Volo/Abp/SecurityLog/ISecurityLogManager.cs
  8. 9
      framework/src/Volo.Abp.Security/Volo/Abp/SecurityLog/ISecurityLogStore.cs
  9. 45
      framework/src/Volo.Abp.Security/Volo/Abp/SecurityLog/SecurityLogInfo.cs
  10. 30
      framework/src/Volo.Abp.Security/Volo/Abp/SecurityLog/SimpleSecurityLogStore.cs
  11. 9
      framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/AbpSecurityTestModule.cs
  12. 45
      framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/SecurityLog/SecurityLogManager_Tests.cs
  13. 10
      modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Account/IdentityServerSupportedLoginModel.cs
  14. 7
      modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Account/IdentityServerSupportedLogoutModel.cs
  15. 33
      modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/AccountController.cs
  16. 3
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/AccountPageModel.cs
  17. 27
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs
  18. 7
      modules/account/src/Volo.Abp.Account.Web/Pages/Account/Logout.cshtml.cs
  19. 37
      modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/SignInResultExtensions.cs
  20. 33
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySecurityLogActionConsts.cs
  21. 52
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySecurityLogConsts.cs
  22. 11
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySecurityLogIdentityConsts.cs
  23. 12
      modules/identity/src/Volo.Abp.Identity.Domain/Microsoft/AspNetCore/Identity/AbpIdentityResultExtensions.cs
  24. 45
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentitySecurityLogRepository.cs
  25. 64
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySecurityLog.cs
  26. 33
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySecurityLogEvent.cs
  27. 86
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySecurityLogHandler.cs
  28. 49
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySecurityLogStore.cs
  29. 109
      modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EFCoreIdentitySecurityLogRepository.cs
  30. 3
      modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IIdentityDbContext.cs
  31. 4
      modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContext.cs
  32. 28
      modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs
  33. 4
      modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContext.cs
  34. 7
      modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContextExtensions.cs
  35. 1
      modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbModule.cs
  36. 4
      modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/IAbpIdentityMongoDbContext.cs
  37. 117
      modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs
  38. 7
      modules/identity/test/Volo.Abp.Identity.EntityFrameworkCore.Tests/Volo/Abp/Identity/EntityFrameworkCore/IdentitySecurityLogRepository_Tests.cs
  39. 10
      modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/IdentitySecurityLogRepository_Tests.cs
  40. 36
      modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/AbpIdentityTestDataBuilder.cs
  41. 36
      modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/IdentitySecurityLogRepository_Tests.cs
  42. 168
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/Migrations/20200710064926_Initial.Designer.cs
  43. 100
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/Migrations/20200710064926_Initial.cs
  44. 75
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/Migrations/MyProjectNameMigrationsDbContextModelSnapshot.cs
  45. 168
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Migrations/20200710065039_Initial.Designer.cs
  46. 100
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Migrations/20200710065039_Initial.cs
  47. 75
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Migrations/IdentityServerHostMigrationsDbContextModelSnapshot.cs
  48. 77
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20200710065052_Initial.Designer.cs
  49. 48
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20200710065052_Initial.cs
  50. 75
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs

24
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Auditing/AspNetCoreAuditLogContributor.cs

@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.AspNetCore.WebClientInfo;
using Volo.Abp.Auditing;
using Volo.Abp.DependencyInjection;
@ -35,14 +36,15 @@ namespace Volo.Abp.AspNetCore.Auditing
context.AuditInfo.Url = BuildUrl(httpContext);
}
var clientInfoProvider = context.ServiceProvider.GetRequiredService<IWebClientInfoProvider>();
if (context.AuditInfo.ClientIpAddress == null)
{
context.AuditInfo.ClientIpAddress = GetClientIpAddress(httpContext);
context.AuditInfo.ClientIpAddress = clientInfoProvider.ClientIpAddress;
}
if (context.AuditInfo.BrowserInfo == null)
{
context.AuditInfo.BrowserInfo = GetBrowserInfo(httpContext);
context.AuditInfo.BrowserInfo = clientInfoProvider.BrowserInfo;
}
//TODO: context.AuditInfo.ClientName
@ -62,24 +64,6 @@ namespace Volo.Abp.AspNetCore.Auditing
}
}
protected virtual string GetBrowserInfo(HttpContext httpContext)
{
return httpContext.Request?.Headers?["User-Agent"];
}
protected virtual string GetClientIpAddress(HttpContext httpContext)
{
try
{
return httpContext.Connection?.RemoteIpAddress?.ToString();
}
catch (Exception ex)
{
Logger.LogException(ex, LogLevel.Warning);
return null;
}
}
protected virtual string BuildUrl(HttpContext httpContext)
{
//TODO: Add options to include/exclude query, schema and host

73
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/SecurityLog/AspNetCoreSecurityLogManager.cs

@ -0,0 +1,73 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.WebClientInfo;
using Volo.Abp.Clients;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
using Volo.Abp.SecurityLog;
using Volo.Abp.Timing;
using Volo.Abp.Tracing;
using Volo.Abp.Users;
namespace Volo.Abp.AspNetCore.SecurityLog
{
[Dependency(ReplaceServices = true)]
public class AspNetCoreSecurityLogManager : DefaultSecurityLogManager
{
protected ILogger<AspNetCoreSecurityLogManager> Logger { get; }
protected IClock Clock { get; }
protected ICurrentUser CurrentUser { get; }
protected ICurrentTenant CurrentTenant { get; }
protected ICurrentClient CurrentClient { get; }
protected IHttpContextAccessor HttpContextAccessor { get; }
protected ICorrelationIdProvider CorrelationIdProvider { get; }
protected IWebClientInfoProvider WebClientInfoProvider { get; }
public AspNetCoreSecurityLogManager(
IOptions<AbpSecurityLogOptions> securityLogOptions,
ISecurityLogStore securityLogStore,
ILogger<AspNetCoreSecurityLogManager> logger,
IClock clock,
ICurrentUser currentUser,
ICurrentTenant currentTenant,
ICurrentClient currentClient,
IHttpContextAccessor httpContextAccessor,
ICorrelationIdProvider correlationIdProvider,
IWebClientInfoProvider webClientInfoProvider)
: base(securityLogOptions, securityLogStore)
{
Logger = logger;
Clock = clock;
CurrentUser = currentUser;
CurrentTenant = currentTenant;
CurrentClient = currentClient;
HttpContextAccessor = httpContextAccessor;
CorrelationIdProvider = correlationIdProvider;
WebClientInfoProvider = webClientInfoProvider;
}
protected override async Task<SecurityLogInfo> CreateAsync()
{
var securityLogInfo = await base.CreateAsync();
securityLogInfo.CreationTime = Clock.Now;
securityLogInfo.TenantId = CurrentTenant.Id;
securityLogInfo.TenantName = CurrentTenant.Name;
securityLogInfo.UserId = CurrentUser.Id;
securityLogInfo.UserName = CurrentUser.UserName;
securityLogInfo.ClientId = CurrentClient.Id;
securityLogInfo.CorrelationId = CorrelationIdProvider.Get();
securityLogInfo.ClientIpAddress = WebClientInfoProvider.ClientIpAddress;
securityLogInfo.BrowserInfo = WebClientInfoProvider.BrowserInfo;
return securityLogInfo;
}
}
}

43
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/WebClientInfo/HttpContextWebClientInfoProvider.cs

@ -0,0 +1,43 @@
using System;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.WebClientInfo
{
public class HttpContextWebClientInfoProvider : IWebClientInfoProvider, ITransientDependency
{
protected ILogger<HttpContextWebClientInfoProvider> Logger { get; }
protected IHttpContextAccessor HttpContextAccessor { get; }
public HttpContextWebClientInfoProvider(
ILogger<HttpContextWebClientInfoProvider> logger,
IHttpContextAccessor httpContextAccessor)
{
Logger = logger;
HttpContextAccessor = httpContextAccessor;
}
public string BrowserInfo => GetBrowserInfo();
public string ClientIpAddress => GetClientIpAddress();
protected virtual string GetBrowserInfo()
{
return HttpContextAccessor.HttpContext?.Request?.Headers?["User-Agent"];
}
protected virtual string GetClientIpAddress()
{
try
{
return HttpContextAccessor.HttpContext?.Connection?.RemoteIpAddress?.ToString();
}
catch (Exception ex)
{
Logger.LogException(ex, LogLevel.Warning);
return null;
}
}
}
}

9
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/WebClientInfo/IWebClientInfoProvider.cs

@ -0,0 +1,9 @@
namespace Volo.Abp.AspNetCore.WebClientInfo
{
public interface IWebClientInfoProvider
{
string BrowserInfo { get; }
string ClientIpAddress { get; }
}
}

21
framework/src/Volo.Abp.Security/Volo/Abp/SecurityLog/AbpSecurityLogOptions.cs

@ -0,0 +1,21 @@
namespace Volo.Abp.SecurityLog
{
public class AbpSecurityLogOptions
{
/// <summary>
/// Default: true.
/// </summary>
public bool IsEnabled { get; set; }
/// <summary>
/// The name of the application or service writing security log.
/// Default: null.
/// </summary>
public string ApplicationName { get; set; }
public AbpSecurityLogOptions()
{
IsEnabled = true;
}
}
}

42
framework/src/Volo.Abp.Security/Volo/Abp/SecurityLog/DefaultSecurityLogManager.cs

@ -0,0 +1,42 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.SecurityLog
{
public class DefaultSecurityLogManager : ISecurityLogManager, ITransientDependency
{
protected AbpSecurityLogOptions SecurityLogOptions { get; }
protected ISecurityLogStore SecurityLogStore { get; }
public DefaultSecurityLogManager(
IOptions<AbpSecurityLogOptions> securityLogOptions,
ISecurityLogStore securityLogStore)
{
SecurityLogStore = securityLogStore;
SecurityLogOptions = securityLogOptions.Value;
}
public async Task SaveAsync(Action<SecurityLogInfo> saveAction = null)
{
if (!SecurityLogOptions.IsEnabled)
{
return;
}
var securityLogInfo = await CreateAsync();
saveAction?.Invoke(securityLogInfo);
await SecurityLogStore.SaveAsync(securityLogInfo);
}
protected virtual Task<SecurityLogInfo> CreateAsync()
{
return Task.FromResult(new SecurityLogInfo
{
ApplicationName = SecurityLogOptions.ApplicationName
});
}
}
}

10
framework/src/Volo.Abp.Security/Volo/Abp/SecurityLog/ISecurityLogManager.cs

@ -0,0 +1,10 @@
using System;
using System.Threading.Tasks;
namespace Volo.Abp.SecurityLog
{
public interface ISecurityLogManager
{
Task SaveAsync(Action<SecurityLogInfo> saveAction = null);
}
}

9
framework/src/Volo.Abp.Security/Volo/Abp/SecurityLog/ISecurityLogStore.cs

@ -0,0 +1,9 @@
using System.Threading.Tasks;
namespace Volo.Abp.SecurityLog
{
public interface ISecurityLogStore
{
Task SaveAsync(SecurityLogInfo securityLogInfo);
}
}

45
framework/src/Volo.Abp.Security/Volo/Abp/SecurityLog/SecurityLogInfo.cs

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
namespace Volo.Abp.SecurityLog
{
[Serializable]
public class SecurityLogInfo
{
public string ApplicationName { get; set; }
public string Identity { get; set; }
public string Action { get; set; }
public Dictionary<string, object> ExtraProperties { get; }
public Guid? UserId { get; set; }
public string UserName { get; set; }
public Guid? TenantId { get; set; }
public string TenantName { get; set; }
public string ClientId { get; set; }
public string CorrelationId { get; set; }
public string ClientIpAddress { get; set; }
public string BrowserInfo { get; set; }
public DateTime CreationTime { get; set; }
public SecurityLogInfo()
{
ExtraProperties = new Dictionary<string, object>();
}
public override string ToString()
{
return $"SECURITY LOG: [{ApplicationName} - {Identity} - {Action}]";
}
}
}

30
framework/src/Volo.Abp.Security/Volo/Abp/SecurityLog/SimpleSecurityLogStore.cs

@ -0,0 +1,30 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.SecurityLog
{
public class SimpleSecurityLogStore : ISecurityLogStore, ITransientDependency
{
public ILogger<SimpleSecurityLogStore> Logger { get; set; }
protected AbpSecurityLogOptions SecurityLogOptions { get; }
public SimpleSecurityLogStore(ILogger<SimpleSecurityLogStore> logger, IOptions<AbpSecurityLogOptions> securityLogOptions)
{
Logger = logger;
SecurityLogOptions = securityLogOptions.Value;
}
public Task SaveAsync(SecurityLogInfo securityLogInfo)
{
if (!SecurityLogOptions.IsEnabled)
{
return Task.CompletedTask;
}
Logger.LogInformation(securityLogInfo.ToString());
return Task.CompletedTask;
}
}
}

9
framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/AbpSecurityTestModule.cs

@ -1,4 +1,5 @@
using Volo.Abp.Modularity;
using Volo.Abp.SecurityLog;
namespace Volo.Abp.Security
{
@ -8,6 +9,12 @@ namespace Volo.Abp.Security
)]
public class AbpSecurityTestModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpSecurityLogOptions>(x =>
{
x.ApplicationName = "AbpSecurityTest";
});
}
}
}

45
framework/test/Volo.Abp.Security.Tests/Volo/Abp/Security/SecurityLog/SecurityLogManager_Tests.cs

@ -0,0 +1,45 @@
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
using Volo.Abp.SecurityLog;
using Volo.Abp.Testing;
using Xunit;
namespace Volo.Abp.Security.SecurityLog
{
public class SecurityLogManager_Tests : AbpIntegratedTest<AbpSecurityTestModule>
{
private readonly ISecurityLogManager _securityLogManager;
private ISecurityLogStore _auditingStore;
public SecurityLogManager_Tests()
{
_securityLogManager = GetRequiredService<ISecurityLogManager>();
}
protected override void AfterAddApplication(IServiceCollection services)
{
_auditingStore = Substitute.For<ISecurityLogStore>();
services.AddSingleton(_auditingStore);
}
[Fact]
public async Task SaveAsync()
{
await _securityLogManager.SaveAsync(securityLog =>
{
securityLog.Identity = "Test";
securityLog.Action = "Test-Action";
securityLog.UserName = "Test-User";
});
await _auditingStore.Received().SaveAsync(Arg.Is<SecurityLogInfo>(log =>
log.ApplicationName == "AbpSecurityTest" &&
log.Identity == "Test" &&
log.Action == "Test-Action" &&
log.UserName == "Test-User"));
}
}
}

10
modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Account/IdentityServerSupportedLoginModel.cs

@ -14,7 +14,10 @@ using System.Security.Principal;
using System.Threading.Tasks;
using Volo.Abp.Account.Settings;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
using Volo.Abp.Identity.AspNetCore;
using Volo.Abp.MultiTenancy;
using Volo.Abp.SecurityLog;
using Volo.Abp.Settings;
using Volo.Abp.Uow;
@ -129,6 +132,13 @@ namespace Volo.Abp.Account.Web.Pages.Account
true
);
await LocalEventBus.PublishAsync(new IdentitySecurityLogEvent
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = result.ToIdentitySecurityLogAction(),
UserName = LoginInput.UserNameOrEmailAddress
});
if (result.RequiresTwoFactor)
{
return RedirectToPage("./SendSecurityCode", new

7
modules/account/src/Volo.Abp.Account.Web.IdentityServer/Pages/Account/IdentityServerSupportedLogoutModel.cs

@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
namespace Volo.Abp.Account.Web.Pages.Account
{
@ -19,6 +20,12 @@ namespace Volo.Abp.Account.Web.Pages.Account
public override async Task<IActionResult> OnGetAsync()
{
await LocalEventBus.PublishAsync(new IdentitySecurityLogEvent
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.Logout
});
await SignInManager.SignOutAsync();
var logoutId = Request.Query["logoutId"].ToString();

33
modules/account/src/Volo.Abp.Account.Web/Areas/Account/Controllers/AccountController.cs

@ -6,7 +6,10 @@ using Volo.Abp.Account.Localization;
using Volo.Abp.Account.Settings;
using Volo.Abp.Account.Web.Areas.Account.Controllers.Models;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.EventBus.Local;
using Volo.Abp.Identity;
using Volo.Abp.Identity.AspNetCore;
using Volo.Abp.SecurityLog;
using Volo.Abp.Settings;
using Volo.Abp.Validation;
using SignInResult = Microsoft.AspNetCore.Identity.SignInResult;
@ -26,13 +29,21 @@ namespace Volo.Abp.Account.Web.Areas.Account.Controllers
protected IdentityUserManager UserManager { get; }
protected ISettingProvider SettingProvider { get; }
public AccountController(SignInManager<IdentityUser> signInManager, IdentityUserManager userManager, ISettingProvider settingProvider)
protected ILocalEventBus LocalEventBus { get; }
public AccountController(
SignInManager<IdentityUser> signInManager,
IdentityUserManager userManager,
ISettingProvider settingProvider,
ISecurityLogManager securityLogManager,
ILocalEventBus localEventBus)
{
LocalizationResource = typeof(AccountResource);
SignInManager = signInManager;
UserManager = userManager;
SettingProvider = settingProvider;
LocalEventBus = localEventBus;
}
[HttpPost]
@ -44,19 +55,33 @@ namespace Volo.Abp.Account.Web.Areas.Account.Controllers
ValidateLoginInfo(login);
await ReplaceEmailToUsernameOfInputIfNeeds(login);
return GetAbpLoginResult(await SignInManager.PasswordSignInAsync(
var signInResult = await SignInManager.PasswordSignInAsync(
login.UserNameOrEmailAddress,
login.Password,
login.RememberMe,
true
));
);
await LocalEventBus.PublishAsync(new IdentitySecurityLogEvent
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = signInResult.ToIdentitySecurityLogAction(),
UserName = login.UserNameOrEmailAddress
});
return GetAbpLoginResult(signInResult);
}
[HttpGet]
[Route("logout")]
public virtual async Task Logout()
{
await LocalEventBus.PublishAsync(new IdentitySecurityLogEvent
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.Logout
});
await SignInManager.SignOutAsync();
}

3
modules/account/src/Volo.Abp.Account.Web/Pages/Account/AccountPageModel.cs

@ -1,11 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Account.Localization;
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
using Volo.Abp.EventBus.Local;
using Volo.Abp.Identity;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
@ -15,6 +15,7 @@ namespace Volo.Abp.Account.Web.Pages.Account
{
public SignInManager<IdentityUser> SignInManager { get; set; }
public IdentityUserManager UserManager { get; set; }
public ILocalEventBus LocalEventBus { get; set; }
protected AccountPageModel()
{

27
modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml.cs

@ -13,11 +13,12 @@ using System.Threading.Tasks;
using Volo.Abp.Account.Settings;
using Volo.Abp.Auditing;
using Volo.Abp.Identity;
using Volo.Abp.Identity.AspNetCore;
using Volo.Abp.Security.Claims;
using Volo.Abp.Settings;
using Volo.Abp.Uow;
using Volo.Abp.Validation;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
using SignInResult = Microsoft.AspNetCore.Identity.SignInResult;
namespace Volo.Abp.Account.Web.Pages.Account
{
@ -97,6 +98,13 @@ namespace Volo.Abp.Account.Web.Pages.Account
true
);
await LocalEventBus.PublishAsync(new IdentitySecurityLogEvent
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = result.ToIdentitySecurityLogAction(),
UserName = LoginInput.UserNameOrEmailAddress
});
if (result.RequiresTwoFactor)
{
return RedirectToPage("./SendSecurityCode", new
@ -184,6 +192,15 @@ namespace Volo.Abp.Account.Web.Pages.Account
bypassTwoFactor: true
);
if (!result.Succeeded)
{
await LocalEventBus.PublishAsync(new IdentitySecurityLogEvent
{
Identity = IdentitySecurityLogIdentityConsts.IdentityExternal,
Action = "Login" + result
});
}
if (result.IsLockedOut)
{
throw new UserFriendlyException("Cannot proceed because user is locked out!");
@ -206,6 +223,14 @@ namespace Volo.Abp.Account.Web.Pages.Account
var user = await CreateExternalUserAsync(info);
await SignInManager.SignInAsync(user, false);
await LocalEventBus.PublishAsync(new IdentitySecurityLogEvent
{
Identity = IdentitySecurityLogIdentityConsts.IdentityExternal,
Action = result.ToIdentitySecurityLogAction(),
UserName = user.Name
});
return RedirectSafely(returnUrl, returnUrlHash);
}

7
modules/account/src/Volo.Abp.Account.Web/Pages/Account/Logout.cshtml.cs

@ -1,5 +1,6 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Identity;
namespace Volo.Abp.Account.Web.Pages.Account
{
@ -15,6 +16,12 @@ namespace Volo.Abp.Account.Web.Pages.Account
public virtual async Task<IActionResult> OnGetAsync()
{
await LocalEventBus.PublishAsync(new IdentitySecurityLogEvent
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = IdentitySecurityLogActionConsts.Logout
});
await SignInManager.SignOutAsync();
if (ReturnUrl != null)
{

37
modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/SignInResultExtensions.cs

@ -0,0 +1,37 @@
using Microsoft.AspNetCore.Identity;
namespace Volo.Abp.Identity.AspNetCore
{
public static class SignInResultExtensions
{
public static string ToIdentitySecurityLogAction(this SignInResult result)
{
if (result.Succeeded)
{
return IdentitySecurityLogActionConsts.LoginSucceeded;
}
if (result.IsLockedOut)
{
return IdentitySecurityLogActionConsts.LoginLockedout;
}
if (result.RequiresTwoFactor)
{
return IdentitySecurityLogActionConsts.LoginRequiresTwoFactor;
}
if (result.IsNotAllowed)
{
return IdentitySecurityLogActionConsts.LoginNotAllowed;
}
if (!result.Succeeded)
{
return IdentitySecurityLogActionConsts.LoginFailed;
}
return IdentitySecurityLogActionConsts.LoginFailed;
}
}
}

33
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySecurityLogActionConsts.cs

@ -0,0 +1,33 @@
namespace Volo.Abp.Identity
{
public class IdentitySecurityLogActionConsts
{
public static string LoginSucceeded { get; set; } = "LoginSucceeded";
public static string LoginLockedout { get; set; } = "LoginLockedout";
public static string LoginNotAllowed { get; set; } = "LoginNotAllowed";
public static string LoginRequiresTwoFactor { get; set; } = "LoginRequiresTwoFactor";
public static string LoginFailed { get; set; } = "LoginFailed";
public static string LoginInvalidUserName { get; set; } = "LoginInvalidUserName";
public static string LoginInvalidUserNameOrPassword { get; set; } = "LoginInvalidUserNameOrPassword";
public static string Logout { get; set; } = "Logout";
public static string ChangeUserName { get; set; } = "ChangeUserName";
public static string ChangeEmail { get; set; } = "ChangeEmail";
public static string ChangePhoneNumber { get; set; } = "ChangePhoneNumber";
public static string ChangePassword { get; set; } = "ChangePassword";
public static string TwoFactorEnabled { get; set; } = "TwoFactorEnabled";
public static string TwoFactorDisabled { get; set; } = "TwoFactorDisabled";
}
}

52
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySecurityLogConsts.cs

@ -0,0 +1,52 @@
namespace Volo.Abp.Identity
{
public class IdentitySecurityLogConsts
{
/// <summary>
/// Default value: 96
/// </summary>
public static int MaxApplicationNameLength { get; set; } = 96;
/// <summary>
/// Default value: 96
/// </summary>
public static int MaxIdentityLength { get; set; } = 96;
/// <summary>
/// Default value: 96
/// </summary>
public static int MaxActionLength { get; set; } = 96;
/// <summary>
/// Default value: 256
/// </summary>
public static int MaxUserNameLength { get; set; } = 256;
/// <summary>
/// Default value: 64
/// </summary>
public static int MaxTenantNameLength { get; set; } = 64;
/// <summary>
/// Default value: 64
/// </summary>
public static int MaxClientIpAddressLength { get; set; } = 64;
/// <summary>
/// Default value: 64
/// </summary>
public static int MaxClientIdLength { get; set; } = 64;
/// <summary>
/// Default value: 64
/// </summary>
public static int MaxCorrelationIdLength { get; set; } = 64;
/// <summary>
/// Default value: 512
/// </summary>
public static int MaxBrowserInfoLength { get; set; } = 512;
}
}

11
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentitySecurityLogIdentityConsts.cs

@ -0,0 +1,11 @@
namespace Volo.Abp.Identity
{
public static class IdentitySecurityLogIdentityConsts
{
public static string Identity { get; set; } = "Identity";
public static string IdentityExternal { get; set; } = "IdentityExternal";
public static string IdentityTwoFactor { get; set; } = "IdentityTwoFactor";
}
}

12
modules/identity/src/Volo.Abp.Identity.Domain/Microsoft/AspNetCore/Identity/AbpIdentityResultExtensions.cs

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Globalization;
using Microsoft.Extensions.Localization;
using Volo.Abp.Identity;
using Volo.Abp.Localization;
using Volo.Abp.Text.Formatting;
namespace Microsoft.AspNetCore.Identity
@ -48,12 +49,15 @@ namespace Microsoft.AspNetCore.Identity
if (!localizedString.ResourceNotFound)
{
var englishLocalizedString = localizer.WithCulture(CultureInfo.GetCultureInfo("en"))[key];
if (!englishLocalizedString.ResourceNotFound)
using (CultureHelper.Use(CultureInfo.GetCultureInfo("en")))
{
if (FormattedStringValueExtracter.IsMatch(error.Description, englishLocalizedString.Value, out var values))
var englishLocalizedString = localizer[key];
if (!englishLocalizedString.ResourceNotFound)
{
return string.Format(localizedString.Value, values.Cast<object>().ToArray());
if (FormattedStringValueExtracter.IsMatch(error.Description, englishLocalizedString.Value, out var values))
{
return string.Format(localizedString.Value, values.Cast<object>().ToArray());
}
}
}
}

45
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentitySecurityLogRepository.cs

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace Volo.Abp.Identity
{
public interface IIdentitySecurityLogRepository : IBasicRepository<IdentitySecurityLog, Guid>
{
Task<List<IdentitySecurityLog>> GetListAsync(
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string correlationId = null,
bool includeDetails = false,
CancellationToken cancellationToken = default);
Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string correlationId = null,
CancellationToken cancellationToken = default);
Task<IdentitySecurityLog> GetByUserIdAsync(
Guid id,
Guid userId,
bool includeDetails = false,
CancellationToken cancellationToken = default);
}
}

64
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySecurityLog.cs

@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;
using Volo.Abp.SecurityLog;
namespace Volo.Abp.Identity
{
public class IdentitySecurityLog : AggregateRoot<Guid>, IMultiTenant
{
public Guid? TenantId { get; protected set; }
public string ApplicationName { get; protected set; }
public string Identity { get; protected set; }
public string Action { get; protected set; }
public Guid? UserId { get; protected set; }
public string UserName { get; protected set; }
public string TenantName { get; protected set; }
public string ClientId { get; protected set; }
public string CorrelationId { get; protected set; }
public string ClientIpAddress { get; protected set; }
public string BrowserInfo { get; protected set; }
public DateTime CreationTime { get; protected set; }
protected IdentitySecurityLog()
{
ExtraProperties = new Dictionary<string, object>();
}
public IdentitySecurityLog(IGuidGenerator guidGenerator, SecurityLogInfo securityLogInfo)
{
Id = guidGenerator.Create();
TenantId = securityLogInfo.TenantId;
TenantName = securityLogInfo.TenantName.Truncate(IdentitySecurityLogConsts.MaxTenantNameLength);
ApplicationName = securityLogInfo.ApplicationName.Truncate(IdentitySecurityLogConsts.MaxApplicationNameLength);
Identity = securityLogInfo.Identity.Truncate(IdentitySecurityLogConsts.MaxIdentityLength);
Action = securityLogInfo.Action.Truncate(IdentitySecurityLogConsts.MaxActionLength);
UserId = securityLogInfo.UserId;
UserName = securityLogInfo.UserName.Truncate(IdentitySecurityLogConsts.MaxUserNameLength);
CreationTime = securityLogInfo.CreationTime;
ClientIpAddress = securityLogInfo.ClientIpAddress.Truncate(IdentitySecurityLogConsts.MaxClientIpAddressLength);
ClientId = securityLogInfo.ClientId.Truncate(IdentitySecurityLogConsts.MaxClientIdLength);
CorrelationId = securityLogInfo.CorrelationId.Truncate(IdentitySecurityLogConsts.MaxCorrelationIdLength);
BrowserInfo = securityLogInfo.BrowserInfo.Truncate(IdentitySecurityLogConsts.MaxBrowserInfoLength);
ExtraProperties = securityLogInfo.ExtraProperties;
}
}
}

33
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySecurityLogEvent.cs

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Identity
{
public class IdentitySecurityLogEvent : IMultiTenant
{
public Guid? TenantId { get; set; }
public string Identity { get; set; }
public string Action { get; set; }
public string UserName { get; set; }
public string ClientId { get; set; }
public Dictionary<string, object> ExtraProperties { get; }
public IdentitySecurityLogEvent()
{
ExtraProperties = new Dictionary<string, object>();
}
public virtual IdentitySecurityLogEvent WithProperty(string key, object value)
{
ExtraProperties[key] = value;
return this;
}
}
}

86
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySecurityLogHandler.cs

@ -0,0 +1,86 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus;
using Volo.Abp.Security.Claims;
using Volo.Abp.SecurityLog;
using Volo.Abp.Uow;
using Volo.Abp.Users;
namespace Volo.Abp.Identity
{
public class IdentitySecurityLogHandler : ILocalEventHandler<IdentitySecurityLogEvent>, ITransientDependency
{
protected ISecurityLogManager SecurityLogManager { get; }
protected IdentityUserManager UserManager { get; }
protected ICurrentPrincipalAccessor CurrentPrincipalAccessor { get; }
protected IUserClaimsPrincipalFactory<IdentityUser> UserClaimsPrincipalFactory { get; }
protected ICurrentUser CurrentUser { get; }
public IdentitySecurityLogHandler(
ISecurityLogManager securityLogManager,
IdentityUserManager userManager,
ICurrentPrincipalAccessor currentPrincipalAccessor,
IUserClaimsPrincipalFactory<IdentityUser> userClaimsPrincipalFactory,
ICurrentUser currentUser)
{
SecurityLogManager = securityLogManager;
UserManager = userManager;
CurrentPrincipalAccessor = currentPrincipalAccessor;
UserClaimsPrincipalFactory = userClaimsPrincipalFactory;
CurrentUser = currentUser;
}
public async Task HandleEventAsync(IdentitySecurityLogEvent eventData)
{
Action<SecurityLogInfo> securityLogAction = securityLog =>
{
securityLog.Identity = eventData.Identity;
securityLog.Action = eventData.Action;
if (securityLog.UserName.IsNullOrWhiteSpace())
{
securityLog.UserName = eventData.UserName;
}
if (securityLog.ClientId.IsNullOrWhiteSpace())
{
securityLog.ClientId = eventData.ClientId;
}
foreach (var property in eventData.ExtraProperties)
{
securityLog.ExtraProperties[property.Key] = property.Value;
}
};
if (CurrentUser.IsAuthenticated)
{
await SecurityLogManager.SaveAsync(securityLogAction);
}
else
{
if (eventData.UserName.IsNullOrWhiteSpace())
{
await SecurityLogManager.SaveAsync(securityLogAction);
}
else
{
var user = await UserManager.FindByNameAsync(eventData.UserName);
if (user != null)
{
using (CurrentPrincipalAccessor.Change(await UserClaimsPrincipalFactory.CreateAsync(user)))
{
await SecurityLogManager.SaveAsync(securityLogAction);
}
}
else
{
await SecurityLogManager.SaveAsync(securityLogAction);
}
}
}
}
}
}

49
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentitySecurityLogStore.cs

@ -0,0 +1,49 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.SecurityLog;
using Volo.Abp.Uow;
namespace Volo.Abp.Identity
{
[Dependency(ReplaceServices = true)]
public class IdentitySecurityLogStore : ISecurityLogStore, ITransientDependency
{
public ILogger<IdentitySecurityLogStore> Logger { get; set; }
protected AbpSecurityLogOptions SecurityLogOptions { get; }
protected IIdentitySecurityLogRepository IdentitySecurityLogRepository { get; }
protected IGuidGenerator GuidGenerator { get; }
protected IUnitOfWorkManager UnitOfWorkManager { get; }
public IdentitySecurityLogStore(
ILogger<IdentitySecurityLogStore> logger,
IOptions<AbpSecurityLogOptions> securityLogOptions,
IIdentitySecurityLogRepository identitySecurityLogRepository,
IGuidGenerator guidGenerator,
IUnitOfWorkManager unitOfWorkManager)
{
Logger = logger;
SecurityLogOptions = securityLogOptions.Value;
IdentitySecurityLogRepository = identitySecurityLogRepository;
GuidGenerator = guidGenerator;
UnitOfWorkManager = unitOfWorkManager;
}
public async Task SaveAsync(SecurityLogInfo securityLogInfo)
{
if (!SecurityLogOptions.IsEnabled)
{
return;
}
using (var uow = UnitOfWorkManager.Begin(requiresNew: true))
{
await IdentitySecurityLogRepository.InsertAsync(new IdentitySecurityLog(GuidGenerator, securityLogInfo));
await uow.CompleteAsync();
}
}
}
}

109
modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EFCoreIdentitySecurityLogRepository.cs

@ -0,0 +1,109 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace Volo.Abp.Identity.EntityFrameworkCore
{
public class EFCoreIdentitySecurityLogRepository : EfCoreRepository<IIdentityDbContext, IdentitySecurityLog, Guid>, IIdentitySecurityLogRepository
{
public EFCoreIdentitySecurityLogRepository(IDbContextProvider<IIdentityDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public async Task<List<IdentitySecurityLog>> GetListAsync(
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string correlationId = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = GetListQuery(
startTime,
endTime,
applicationName,
identity,
action,
userId,
userName,
clientId,
correlationId
);
return await query.OrderBy(sorting ?? nameof(IdentitySecurityLog.CreationTime) + " desc")
.PageBy(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string correlationId = null,
CancellationToken cancellationToken = default)
{
var query = GetListQuery(
startTime,
endTime,
applicationName,
identity,
action,
userId,
userName,
clientId,
correlationId
);
return await query.LongCountAsync(GetCancellationToken(cancellationToken));
}
public async Task<IdentitySecurityLog> GetByUserIdAsync(Guid id, Guid userId, bool includeDetails = false, CancellationToken cancellationToken = default)
{
return await DbSet.FirstOrDefaultAsync(x => x.Id == id && x.UserId == userId, GetCancellationToken(cancellationToken));
}
protected virtual IQueryable<IdentitySecurityLog> GetListQuery(
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string correlationId = null)
{
return DbSet.AsNoTracking()
.WhereIf(startTime.HasValue, securityLog => securityLog.CreationTime >= startTime)
.WhereIf(endTime.HasValue, securityLog => securityLog.CreationTime >= endTime)
.WhereIf(!applicationName.IsNullOrWhiteSpace(), securityLog => securityLog.ApplicationName == applicationName)
.WhereIf(!identity.IsNullOrWhiteSpace(), securityLog => securityLog.Identity == identity)
.WhereIf(!action.IsNullOrWhiteSpace(), securityLog => securityLog.Action == action)
.WhereIf(userId.HasValue, securityLog => securityLog.UserId == userId)
.WhereIf(!userName.IsNullOrWhiteSpace(), securityLog => securityLog.UserName == userName)
.WhereIf(!clientId.IsNullOrWhiteSpace(), securityLog => securityLog.ClientId == clientId)
.WhereIf(!correlationId.IsNullOrWhiteSpace(), securityLog => securityLog.CorrelationId == correlationId);
}
}
}

3
modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IIdentityDbContext.cs

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.SecurityLog;
namespace Volo.Abp.Identity.EntityFrameworkCore
{
@ -14,5 +15,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
DbSet<IdentityClaimType> ClaimTypes { get; set; }
DbSet<OrganizationUnit> OrganizationUnits { get; set; }
DbSet<IdentitySecurityLog> IdentitySecurityLogs { get; set; }
}
}

4
modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContext.cs

@ -18,6 +18,8 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
public DbSet<OrganizationUnit> OrganizationUnits { get; set; }
public DbSet<IdentitySecurityLog> IdentitySecurityLogs { get; set; }
public IdentityDbContext(DbContextOptions<IdentityDbContext> options)
: base(options)
{
@ -31,4 +33,4 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
builder.ConfigureIdentity();
}
}
}
}

28
modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs

@ -204,6 +204,32 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
b.HasIndex(ou => new {ou.UserId, ou.OrganizationUnitId});
});
builder.Entity<IdentitySecurityLog>(b =>
{
b.ToTable(options.TablePrefix + "SecurityLogs", options.Schema);
b.ConfigureByConvention();
b.Property(x => x.TenantName).HasMaxLength(IdentitySecurityLogConsts.MaxTenantNameLength);
b.Property(x => x.ApplicationName).HasMaxLength(IdentitySecurityLogConsts.MaxApplicationNameLength);
b.Property(x => x.Identity).HasMaxLength(IdentitySecurityLogConsts.MaxIdentityLength);
b.Property(x => x.Action).HasMaxLength(IdentitySecurityLogConsts.MaxActionLength);
b.Property(x => x.UserName).HasMaxLength(IdentitySecurityLogConsts.MaxUserNameLength);
b.Property(x => x.ClientIpAddress).HasMaxLength(IdentitySecurityLogConsts.MaxClientIpAddressLength);
b.Property(x => x.ClientId).HasMaxLength(IdentitySecurityLogConsts.MaxClientIdLength);
b.Property(x => x.CorrelationId).HasMaxLength(IdentitySecurityLogConsts.MaxCorrelationIdLength);
b.Property(x => x.BrowserInfo).HasMaxLength(IdentitySecurityLogConsts.MaxBrowserInfoLength);
b.HasIndex(x => new { x.TenantId, x.ApplicationName });
b.HasIndex(x => new { x.TenantId, x.Identity });
b.HasIndex(x => new { x.TenantId, x.Action });
b.HasIndex(x => new { x.TenantId, x.UserId });
});
}
}
}
}

4
modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContext.cs

@ -15,6 +15,8 @@ namespace Volo.Abp.Identity.MongoDB
public IMongoCollection<OrganizationUnit> OrganizationUnits => Collection<OrganizationUnit>();
public IMongoCollection<IdentitySecurityLog> IdentitySecurityLogs => Collection<IdentitySecurityLog>();
protected override void CreateModel(IMongoModelBuilder modelBuilder)
{
base.CreateModel(modelBuilder);
@ -22,4 +24,4 @@ namespace Volo.Abp.Identity.MongoDB
modelBuilder.ConfigureIdentity();
}
}
}
}

7
modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbContextExtensions.cs

@ -36,6 +36,11 @@ namespace Volo.Abp.Identity.MongoDB
{
b.CollectionName = options.CollectionPrefix + "OrganizationUnits";
});
builder.Entity<IdentitySecurityLog>(b =>
{
b.CollectionName = options.CollectionPrefix + "SecurityLogs";
});
}
}
}
}

1
modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/AbpIdentityMongoDbModule.cs

@ -18,6 +18,7 @@ namespace Volo.Abp.Identity.MongoDB
options.AddRepository<IdentityRole, MongoIdentityRoleRepository>();
options.AddRepository<IdentityClaimType, MongoIdentityRoleRepository>();
options.AddRepository<OrganizationUnit, MongoIdentityRoleRepository>();
options.AddRepository<IdentitySecurityLog, MongoIdentitySecurityLogRepository>();
});
}
}

4
modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/IAbpIdentityMongoDbContext.cs

@ -14,5 +14,7 @@ namespace Volo.Abp.Identity.MongoDB
IMongoCollection<IdentityClaimType> ClaimTypes { get; }
IMongoCollection<OrganizationUnit> OrganizationUnits { get; }
IMongoCollection<IdentitySecurityLog> IdentitySecurityLogs { get; }
}
}
}

117
modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs

@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading;
using System.Threading.Tasks;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using Volo.Abp.Domain.Repositories.MongoDB;
using Volo.Abp.MongoDB;
namespace Volo.Abp.Identity.MongoDB
{
public class MongoIdentitySecurityLogRepository :
MongoDbRepository<IAbpIdentityMongoDbContext, IdentitySecurityLog, Guid>, IIdentitySecurityLogRepository
{
public MongoIdentitySecurityLogRepository(IMongoDbContextProvider<IAbpIdentityMongoDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public async Task<List<IdentitySecurityLog>> GetListAsync(
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string correlationId = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = GetListQuery(
startTime,
endTime,
applicationName,
identity,
action,
userId,
userName,
clientId,
correlationId
);
return await query.OrderBy(sorting ?? nameof(IdentitySecurityLog.CreationTime) + " desc")
.As<IMongoQueryable<IdentitySecurityLog>>()
.PageBy<IdentitySecurityLog, IMongoQueryable<IdentitySecurityLog>>(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string correlationId = null,
CancellationToken cancellationToken = default)
{
var query = GetListQuery(
startTime,
endTime,
applicationName,
identity,
action,
userId,
userName,
clientId,
correlationId
);
return await query.As<IMongoQueryable<IdentitySecurityLog>>()
.LongCountAsync(GetCancellationToken(cancellationToken));
}
public async Task<IdentitySecurityLog> GetByUserIdAsync(Guid id, Guid userId, bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable().FirstOrDefaultAsync(x => x.Id == id && x.UserId == userId,
GetCancellationToken(cancellationToken));
}
protected virtual IQueryable<IdentitySecurityLog> GetListQuery(
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string correlationId = null)
{
return GetMongoQueryable()
.WhereIf(startTime.HasValue, securityLog => securityLog.CreationTime >= startTime)
.WhereIf(endTime.HasValue, securityLog => securityLog.CreationTime >= endTime)
.WhereIf(!applicationName.IsNullOrWhiteSpace(),
securityLog => securityLog.ApplicationName == applicationName)
.WhereIf(!identity.IsNullOrWhiteSpace(), securityLog => securityLog.Identity == identity)
.WhereIf(!action.IsNullOrWhiteSpace(), securityLog => securityLog.Action == action)
.WhereIf(userId.HasValue, securityLog => securityLog.UserId == userId)
.WhereIf(!userName.IsNullOrWhiteSpace(), securityLog => securityLog.UserName == userName)
.WhereIf(!clientId.IsNullOrWhiteSpace(), securityLog => securityLog.ClientId == clientId)
.WhereIf(!correlationId.IsNullOrWhiteSpace(),
securityLog => securityLog.CorrelationId == correlationId);
}
}
}

7
modules/identity/test/Volo.Abp.Identity.EntityFrameworkCore.Tests/Volo/Abp/Identity/EntityFrameworkCore/IdentitySecurityLogRepository_Tests.cs

@ -0,0 +1,7 @@
namespace Volo.Abp.Identity.EntityFrameworkCore
{
public class IdentitySecurityLogRepository_Tests : IdentitySecurityLogRepository_Tests<AbpIdentityEntityFrameworkCoreTestModule>
{
}
}

10
modules/identity/test/Volo.Abp.Identity.MongoDB.Tests/Volo/Abp/Identity/MongoDB/IdentitySecurityLogRepository_Tests.cs

@ -0,0 +1,10 @@
using Xunit;
namespace Volo.Abp.Identity.MongoDB
{
[Collection(MongoTestCollection.Name)]
public class IdentitySecurityLogRepository_Tests : IdentitySecurityLogRepository_Tests<AbpIdentityMongoDbTestModule>
{
}
}

36
modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/AbpIdentityTestDataBuilder.cs

@ -1,9 +1,10 @@
using System;
using System;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.SecurityLog;
namespace Volo.Abp.Identity
{
@ -14,6 +15,7 @@ namespace Volo.Abp.Identity
private readonly IIdentityClaimTypeRepository _identityClaimTypeRepository;
private readonly IIdentityRoleRepository _roleRepository;
private readonly IOrganizationUnitRepository _organizationUnitRepository;
private readonly IIdentitySecurityLogRepository _identitySecurityLogRepository;
private readonly ILookupNormalizer _lookupNormalizer;
private readonly IdentityTestData _testData;
private readonly OrganizationUnitManager _organizationUnitManager;
@ -31,6 +33,7 @@ namespace Volo.Abp.Identity
IIdentityClaimTypeRepository identityClaimTypeRepository,
IIdentityRoleRepository roleRepository,
IOrganizationUnitRepository organizationUnitRepository,
IIdentitySecurityLogRepository identitySecurityLogRepository,
ILookupNormalizer lookupNormalizer,
IdentityTestData testData,
OrganizationUnitManager organizationUnitManager)
@ -43,6 +46,7 @@ namespace Volo.Abp.Identity
_testData = testData;
_organizationUnitRepository = organizationUnitRepository;
_organizationUnitManager = organizationUnitManager;
_identitySecurityLogRepository = identitySecurityLogRepository;
}
public async Task Build()
@ -51,6 +55,7 @@ namespace Volo.Abp.Identity
await AddOrganizationUnits();
await AddUsers();
await AddClaimTypes();
await AddSecurityLogs();
}
private async Task AddRoles()
@ -69,7 +74,7 @@ namespace Volo.Abp.Identity
}
/* Creates OU tree as shown below:
*
*
* - OU1
* - OU11
* - OU111
@ -138,5 +143,30 @@ namespace Volo.Abp.Identity
var ou = await _organizationUnitRepository.InsertAsync(new OrganizationUnit(_guidGenerator.Create(), displayName, parentId) { Code = code });
return ou;
}
private async Task AddSecurityLogs()
{
await _identitySecurityLogRepository.InsertAsync(new IdentitySecurityLog(_guidGenerator, new SecurityLogInfo
{
ApplicationName = "Test-ApplicationName",
Identity = "Test-Identity",
Action = "Test-Action",
UserId = _testData.UserJohnId,
UserName = "john.nash",
CreationTime = new DateTime(2020, 01, 01, 10, 0, 0)
}));
await _identitySecurityLogRepository.InsertAsync(new IdentitySecurityLog(_guidGenerator, new SecurityLogInfo
{
ApplicationName = "Test-ApplicationName",
Identity = "Test-Identity",
Action = "Test-Action",
UserId = _testData.UserDavidId,
UserName = "david",
CreationTime = new DateTime(2020, 01, 02, 10, 0, 0)
}));
}
}
}
}

36
modules/identity/test/Volo.Abp.Identity.TestBase/Volo/Abp/Identity/IdentitySecurityLogRepository_Tests.cs

@ -0,0 +1,36 @@
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Modularity;
using Xunit;
namespace Volo.Abp.Identity
{
public abstract class IdentitySecurityLogRepository_Tests<TStartupModule> : AbpIdentityTestBase<TStartupModule>
where TStartupModule : IAbpModule
{
protected IIdentitySecurityLogRepository RoleRepository { get; }
protected IdentityTestData TestData { get; }
protected IdentitySecurityLogRepository_Tests()
{
RoleRepository = GetRequiredService<IIdentitySecurityLogRepository>();
TestData = GetRequiredService<IdentityTestData>();
}
[Fact]
public async Task GetListAsync()
{
var logs = await RoleRepository.GetListAsync();
logs.ShouldNotBeEmpty();
logs.ShouldContain(x => x.ApplicationName == "Test-ApplicationName" && x.UserId == TestData.UserJohnId);
logs.ShouldContain(x => x.ApplicationName == "Test-ApplicationName" && x.UserId == TestData.UserDavidId);
}
[Fact]
public async Task GetCountAsync()
{
var count = await RoleRepository.GetCountAsync();
count.ShouldBe(2);
}
}
}

168
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Migrations/20200624023331_Initial.Designer.cs → templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/Migrations/20200710064926_Initial.Designer.cs

@ -10,8 +10,8 @@ using Volo.Abp.EntityFrameworkCore;
namespace MyCompanyName.MyProjectName.Migrations
{
[DbContext(typeof(IdentityServerHostMigrationsDbContext))]
[Migration("20200624023331_Initial")]
[DbContext(typeof(MyProjectNameMigrationsDbContext))]
[Migration("20200710064926_Initial")]
partial class Initial
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -275,6 +275,95 @@ namespace MyCompanyName.MyProjectName.Migrations
b.ToTable("AbpEntityPropertyChanges");
});
modelBuilder.Entity("Volo.Abp.BackgroundJobs.BackgroundJobRecord", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime2");
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsAbandoned")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<string>("JobArgs")
.IsRequired()
.HasColumnType("nvarchar(max)")
.HasMaxLength(1048576);
b.Property<string>("JobName")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<DateTime?>("LastTryTime")
.HasColumnType("datetime2");
b.Property<DateTime>("NextTryTime")
.HasColumnType("datetime2");
b.Property<byte>("Priority")
.ValueGeneratedOnAdd()
.HasColumnType("tinyint")
.HasDefaultValue((byte)15);
b.Property<short>("TryCount")
.ValueGeneratedOnAdd()
.HasColumnType("smallint")
.HasDefaultValue((short)0);
b.HasKey("Id");
b.HasIndex("IsAbandoned", "NextTryTime");
b.ToTable("AbpBackgroundJobs");
});
modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("ProviderKey")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ProviderName")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("Value")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.HasKey("Id");
b.HasIndex("Name", "ProviderName", "ProviderKey");
b.ToTable("AbpFeatureValues");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b =>
{
b.Property<Guid>("Id")
@ -399,6 +488,81 @@ namespace MyCompanyName.MyProjectName.Migrations
b.ToTable("AbpRoleClaims");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Action")
.HasColumnType("nvarchar(96)")
.HasMaxLength(96);
b.Property<string>("ApplicationName")
.HasColumnType("nvarchar(96)")
.HasMaxLength(96);
b.Property<string>("BrowserInfo")
.HasColumnType("nvarchar(512)")
.HasMaxLength(512);
b.Property<string>("ClientId")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ClientIpAddress")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<string>("CorrelationId")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2");
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<string>("Identity")
.HasColumnType("nvarchar(96)")
.HasMaxLength(96);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("uniqueidentifier");
b.Property<string>("TenantName")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<Guid?>("UserId")
.HasColumnType("uniqueidentifier");
b.Property<string>("UserName")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("TenantId", "Action");
b.HasIndex("TenantId", "ApplicationName");
b.HasIndex("TenantId", "Identity");
b.HasIndex("TenantId", "UserId");
b.ToTable("AbpSecurityLogs");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property<Guid>("Id")

100
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Migrations/20200624023331_Initial.cs → templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/Migrations/20200710064926_Initial.cs

@ -39,6 +39,27 @@ namespace MyCompanyName.MyProjectName.Migrations
table.PrimaryKey("PK_AbpAuditLogs", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpBackgroundJobs",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
ExtraProperties = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(maxLength: 40, nullable: true),
JobName = table.Column<string>(maxLength: 128, nullable: false),
JobArgs = table.Column<string>(maxLength: 1048576, nullable: false),
TryCount = table.Column<short>(nullable: false, defaultValue: (short)0),
CreationTime = table.Column<DateTime>(nullable: false),
NextTryTime = table.Column<DateTime>(nullable: false),
LastTryTime = table.Column<DateTime>(nullable: true),
IsAbandoned = table.Column<bool>(nullable: false, defaultValue: false),
Priority = table.Column<byte>(nullable: false, defaultValue: (byte)15)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpBackgroundJobs", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpClaimTypes",
columns: table => new
@ -59,6 +80,21 @@ namespace MyCompanyName.MyProjectName.Migrations
table.PrimaryKey("PK_AbpClaimTypes", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpFeatureValues",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
Name = table.Column<string>(maxLength: 128, nullable: false),
Value = table.Column<string>(maxLength: 128, nullable: false),
ProviderName = table.Column<string>(maxLength: 64, nullable: true),
ProviderKey = table.Column<string>(maxLength: 64, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpFeatureValues", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpOrganizationUnits",
columns: table => new
@ -123,6 +159,31 @@ namespace MyCompanyName.MyProjectName.Migrations
table.PrimaryKey("PK_AbpRoles", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpSecurityLogs",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
ExtraProperties = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(maxLength: 40, nullable: true),
TenantId = table.Column<Guid>(nullable: true),
ApplicationName = table.Column<string>(maxLength: 96, nullable: true),
Identity = table.Column<string>(maxLength: 96, nullable: true),
Action = table.Column<string>(maxLength: 96, nullable: true),
UserId = table.Column<Guid>(nullable: true),
UserName = table.Column<string>(maxLength: 256, nullable: true),
TenantName = table.Column<string>(maxLength: 64, nullable: true),
ClientId = table.Column<string>(maxLength: 64, nullable: true),
CorrelationId = table.Column<string>(maxLength: 64, nullable: true),
ClientIpAddress = table.Column<string>(maxLength: 64, nullable: true),
BrowserInfo = table.Column<string>(maxLength: 512, nullable: true),
CreationTime = table.Column<DateTime>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpSettings",
columns: table => new
@ -887,6 +948,11 @@ namespace MyCompanyName.MyProjectName.Migrations
table: "AbpAuditLogs",
columns: new[] { "TenantId", "UserId", "ExecutionTime" });
migrationBuilder.CreateIndex(
name: "IX_AbpBackgroundJobs_IsAbandoned_NextTryTime",
table: "AbpBackgroundJobs",
columns: new[] { "IsAbandoned", "NextTryTime" });
migrationBuilder.CreateIndex(
name: "IX_AbpEntityChanges_AuditLogId",
table: "AbpEntityChanges",
@ -902,6 +968,11 @@ namespace MyCompanyName.MyProjectName.Migrations
table: "AbpEntityPropertyChanges",
column: "EntityChangeId");
migrationBuilder.CreateIndex(
name: "IX_AbpFeatureValues_Name_ProviderName_ProviderKey",
table: "AbpFeatureValues",
columns: new[] { "Name", "ProviderName", "ProviderKey" });
migrationBuilder.CreateIndex(
name: "IX_AbpOrganizationUnitRoles_RoleId_OrganizationUnitId",
table: "AbpOrganizationUnitRoles",
@ -932,6 +1003,26 @@ namespace MyCompanyName.MyProjectName.Migrations
table: "AbpRoles",
column: "NormalizedName");
migrationBuilder.CreateIndex(
name: "IX_AbpSecurityLogs_TenantId_Action",
table: "AbpSecurityLogs",
columns: new[] { "TenantId", "Action" });
migrationBuilder.CreateIndex(
name: "IX_AbpSecurityLogs_TenantId_ApplicationName",
table: "AbpSecurityLogs",
columns: new[] { "TenantId", "ApplicationName" });
migrationBuilder.CreateIndex(
name: "IX_AbpSecurityLogs_TenantId_Identity",
table: "AbpSecurityLogs",
columns: new[] { "TenantId", "Identity" });
migrationBuilder.CreateIndex(
name: "IX_AbpSecurityLogs_TenantId_UserId",
table: "AbpSecurityLogs",
columns: new[] { "TenantId", "UserId" });
migrationBuilder.CreateIndex(
name: "IX_AbpSettings_Name_ProviderName_ProviderKey",
table: "AbpSettings",
@ -1020,12 +1111,18 @@ namespace MyCompanyName.MyProjectName.Migrations
migrationBuilder.DropTable(
name: "AbpAuditLogActions");
migrationBuilder.DropTable(
name: "AbpBackgroundJobs");
migrationBuilder.DropTable(
name: "AbpClaimTypes");
migrationBuilder.DropTable(
name: "AbpEntityPropertyChanges");
migrationBuilder.DropTable(
name: "AbpFeatureValues");
migrationBuilder.DropTable(
name: "AbpOrganizationUnitRoles");
@ -1035,6 +1132,9 @@ namespace MyCompanyName.MyProjectName.Migrations
migrationBuilder.DropTable(
name: "AbpRoleClaims");
migrationBuilder.DropTable(
name: "AbpSecurityLogs");
migrationBuilder.DropTable(
name: "AbpSettings");

75
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/Migrations/MyProjectNameMigrationsDbContextModelSnapshot.cs

@ -486,6 +486,81 @@ namespace MyCompanyName.MyProjectName.Migrations
b.ToTable("AbpRoleClaims");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Action")
.HasColumnType("nvarchar(96)")
.HasMaxLength(96);
b.Property<string>("ApplicationName")
.HasColumnType("nvarchar(96)")
.HasMaxLength(96);
b.Property<string>("BrowserInfo")
.HasColumnType("nvarchar(512)")
.HasMaxLength(512);
b.Property<string>("ClientId")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ClientIpAddress")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<string>("CorrelationId")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2");
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<string>("Identity")
.HasColumnType("nvarchar(96)")
.HasMaxLength(96);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("uniqueidentifier");
b.Property<string>("TenantName")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<Guid?>("UserId")
.HasColumnType("uniqueidentifier");
b.Property<string>("UserName")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("TenantId", "Action");
b.HasIndex("TenantId", "ApplicationName");
b.HasIndex("TenantId", "Identity");
b.HasIndex("TenantId", "UserId");
b.ToTable("AbpSecurityLogs");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property<Guid>("Id")

168
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/Migrations/20200624023152_Initial.Designer.cs → templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Migrations/20200710065039_Initial.Designer.cs

@ -10,8 +10,8 @@ using Volo.Abp.EntityFrameworkCore;
namespace MyCompanyName.MyProjectName.Migrations
{
[DbContext(typeof(MyProjectNameMigrationsDbContext))]
[Migration("20200624023152_Initial")]
[DbContext(typeof(IdentityServerHostMigrationsDbContext))]
[Migration("20200710065039_Initial")]
partial class Initial
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -275,95 +275,6 @@ namespace MyCompanyName.MyProjectName.Migrations
b.ToTable("AbpEntityPropertyChanges");
});
modelBuilder.Entity("Volo.Abp.BackgroundJobs.BackgroundJobRecord", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime2");
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsAbandoned")
.ValueGeneratedOnAdd()
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<string>("JobArgs")
.IsRequired()
.HasColumnType("nvarchar(max)")
.HasMaxLength(1048576);
b.Property<string>("JobName")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<DateTime?>("LastTryTime")
.HasColumnType("datetime2");
b.Property<DateTime>("NextTryTime")
.HasColumnType("datetime2");
b.Property<byte>("Priority")
.ValueGeneratedOnAdd()
.HasColumnType("tinyint")
.HasDefaultValue((byte)15);
b.Property<short>("TryCount")
.ValueGeneratedOnAdd()
.HasColumnType("smallint")
.HasDefaultValue((short)0);
b.HasKey("Id");
b.HasIndex("IsAbandoned", "NextTryTime");
b.ToTable("AbpBackgroundJobs");
});
modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("ProviderKey")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ProviderName")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("Value")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.HasKey("Id");
b.HasIndex("Name", "ProviderName", "ProviderKey");
b.ToTable("AbpFeatureValues");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b =>
{
b.Property<Guid>("Id")
@ -488,6 +399,81 @@ namespace MyCompanyName.MyProjectName.Migrations
b.ToTable("AbpRoleClaims");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Action")
.HasColumnType("nvarchar(96)")
.HasMaxLength(96);
b.Property<string>("ApplicationName")
.HasColumnType("nvarchar(96)")
.HasMaxLength(96);
b.Property<string>("BrowserInfo")
.HasColumnType("nvarchar(512)")
.HasMaxLength(512);
b.Property<string>("ClientId")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ClientIpAddress")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<string>("CorrelationId")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2");
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<string>("Identity")
.HasColumnType("nvarchar(96)")
.HasMaxLength(96);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("uniqueidentifier");
b.Property<string>("TenantName")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<Guid?>("UserId")
.HasColumnType("uniqueidentifier");
b.Property<string>("UserName")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("TenantId", "Action");
b.HasIndex("TenantId", "ApplicationName");
b.HasIndex("TenantId", "Identity");
b.HasIndex("TenantId", "UserId");
b.ToTable("AbpSecurityLogs");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property<Guid>("Id")

100
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/Migrations/20200624023152_Initial.cs → templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Migrations/20200710065039_Initial.cs

@ -39,27 +39,6 @@ namespace MyCompanyName.MyProjectName.Migrations
table.PrimaryKey("PK_AbpAuditLogs", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpBackgroundJobs",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
ExtraProperties = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(maxLength: 40, nullable: true),
JobName = table.Column<string>(maxLength: 128, nullable: false),
JobArgs = table.Column<string>(maxLength: 1048576, nullable: false),
TryCount = table.Column<short>(nullable: false, defaultValue: (short)0),
CreationTime = table.Column<DateTime>(nullable: false),
NextTryTime = table.Column<DateTime>(nullable: false),
LastTryTime = table.Column<DateTime>(nullable: true),
IsAbandoned = table.Column<bool>(nullable: false, defaultValue: false),
Priority = table.Column<byte>(nullable: false, defaultValue: (byte)15)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpBackgroundJobs", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpClaimTypes",
columns: table => new
@ -80,21 +59,6 @@ namespace MyCompanyName.MyProjectName.Migrations
table.PrimaryKey("PK_AbpClaimTypes", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpFeatureValues",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
Name = table.Column<string>(maxLength: 128, nullable: false),
Value = table.Column<string>(maxLength: 128, nullable: false),
ProviderName = table.Column<string>(maxLength: 64, nullable: true),
ProviderKey = table.Column<string>(maxLength: 64, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpFeatureValues", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpOrganizationUnits",
columns: table => new
@ -159,6 +123,31 @@ namespace MyCompanyName.MyProjectName.Migrations
table.PrimaryKey("PK_AbpRoles", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpSecurityLogs",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
ExtraProperties = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(maxLength: 40, nullable: true),
TenantId = table.Column<Guid>(nullable: true),
ApplicationName = table.Column<string>(maxLength: 96, nullable: true),
Identity = table.Column<string>(maxLength: 96, nullable: true),
Action = table.Column<string>(maxLength: 96, nullable: true),
UserId = table.Column<Guid>(nullable: true),
UserName = table.Column<string>(maxLength: 256, nullable: true),
TenantName = table.Column<string>(maxLength: 64, nullable: true),
ClientId = table.Column<string>(maxLength: 64, nullable: true),
CorrelationId = table.Column<string>(maxLength: 64, nullable: true),
ClientIpAddress = table.Column<string>(maxLength: 64, nullable: true),
BrowserInfo = table.Column<string>(maxLength: 512, nullable: true),
CreationTime = table.Column<DateTime>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpSettings",
columns: table => new
@ -923,11 +912,6 @@ namespace MyCompanyName.MyProjectName.Migrations
table: "AbpAuditLogs",
columns: new[] { "TenantId", "UserId", "ExecutionTime" });
migrationBuilder.CreateIndex(
name: "IX_AbpBackgroundJobs_IsAbandoned_NextTryTime",
table: "AbpBackgroundJobs",
columns: new[] { "IsAbandoned", "NextTryTime" });
migrationBuilder.CreateIndex(
name: "IX_AbpEntityChanges_AuditLogId",
table: "AbpEntityChanges",
@ -943,11 +927,6 @@ namespace MyCompanyName.MyProjectName.Migrations
table: "AbpEntityPropertyChanges",
column: "EntityChangeId");
migrationBuilder.CreateIndex(
name: "IX_AbpFeatureValues_Name_ProviderName_ProviderKey",
table: "AbpFeatureValues",
columns: new[] { "Name", "ProviderName", "ProviderKey" });
migrationBuilder.CreateIndex(
name: "IX_AbpOrganizationUnitRoles_RoleId_OrganizationUnitId",
table: "AbpOrganizationUnitRoles",
@ -978,6 +957,26 @@ namespace MyCompanyName.MyProjectName.Migrations
table: "AbpRoles",
column: "NormalizedName");
migrationBuilder.CreateIndex(
name: "IX_AbpSecurityLogs_TenantId_Action",
table: "AbpSecurityLogs",
columns: new[] { "TenantId", "Action" });
migrationBuilder.CreateIndex(
name: "IX_AbpSecurityLogs_TenantId_ApplicationName",
table: "AbpSecurityLogs",
columns: new[] { "TenantId", "ApplicationName" });
migrationBuilder.CreateIndex(
name: "IX_AbpSecurityLogs_TenantId_Identity",
table: "AbpSecurityLogs",
columns: new[] { "TenantId", "Identity" });
migrationBuilder.CreateIndex(
name: "IX_AbpSecurityLogs_TenantId_UserId",
table: "AbpSecurityLogs",
columns: new[] { "TenantId", "UserId" });
migrationBuilder.CreateIndex(
name: "IX_AbpSettings_Name_ProviderName_ProviderKey",
table: "AbpSettings",
@ -1066,18 +1065,12 @@ namespace MyCompanyName.MyProjectName.Migrations
migrationBuilder.DropTable(
name: "AbpAuditLogActions");
migrationBuilder.DropTable(
name: "AbpBackgroundJobs");
migrationBuilder.DropTable(
name: "AbpClaimTypes");
migrationBuilder.DropTable(
name: "AbpEntityPropertyChanges");
migrationBuilder.DropTable(
name: "AbpFeatureValues");
migrationBuilder.DropTable(
name: "AbpOrganizationUnitRoles");
@ -1087,6 +1080,9 @@ namespace MyCompanyName.MyProjectName.Migrations
migrationBuilder.DropTable(
name: "AbpRoleClaims");
migrationBuilder.DropTable(
name: "AbpSecurityLogs");
migrationBuilder.DropTable(
name: "AbpSettings");

75
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/Migrations/IdentityServerHostMigrationsDbContextModelSnapshot.cs

@ -397,6 +397,81 @@ namespace MyCompanyName.MyProjectName.Migrations
b.ToTable("AbpRoleClaims");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Action")
.HasColumnType("nvarchar(96)")
.HasMaxLength(96);
b.Property<string>("ApplicationName")
.HasColumnType("nvarchar(96)")
.HasMaxLength(96);
b.Property<string>("BrowserInfo")
.HasColumnType("nvarchar(512)")
.HasMaxLength(512);
b.Property<string>("ClientId")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ClientIpAddress")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<string>("CorrelationId")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2");
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<string>("Identity")
.HasColumnType("nvarchar(96)")
.HasMaxLength(96);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("uniqueidentifier");
b.Property<string>("TenantName")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<Guid?>("UserId")
.HasColumnType("uniqueidentifier");
b.Property<string>("UserName")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("TenantId", "Action");
b.HasIndex("TenantId", "ApplicationName");
b.HasIndex("TenantId", "Identity");
b.HasIndex("TenantId", "UserId");
b.ToTable("AbpSecurityLogs");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property<Guid>("Id")

77
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20200624023340_Initial.Designer.cs → templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20200710065052_Initial.Designer.cs

@ -11,7 +11,7 @@ using Volo.Abp.EntityFrameworkCore;
namespace MyCompanyName.MyProjectName.Migrations
{
[DbContext(typeof(UnifiedDbContext))]
[Migration("20200624023340_Initial")]
[Migration("20200710065052_Initial")]
partial class Initial
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -399,6 +399,81 @@ namespace MyCompanyName.MyProjectName.Migrations
b.ToTable("AbpRoleClaims");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Action")
.HasColumnType("nvarchar(96)")
.HasMaxLength(96);
b.Property<string>("ApplicationName")
.HasColumnType("nvarchar(96)")
.HasMaxLength(96);
b.Property<string>("BrowserInfo")
.HasColumnType("nvarchar(512)")
.HasMaxLength(512);
b.Property<string>("ClientId")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ClientIpAddress")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<string>("CorrelationId")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2");
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<string>("Identity")
.HasColumnType("nvarchar(96)")
.HasMaxLength(96);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("uniqueidentifier");
b.Property<string>("TenantName")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<Guid?>("UserId")
.HasColumnType("uniqueidentifier");
b.Property<string>("UserName")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("TenantId", "Action");
b.HasIndex("TenantId", "ApplicationName");
b.HasIndex("TenantId", "Identity");
b.HasIndex("TenantId", "UserId");
b.ToTable("AbpSecurityLogs");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property<Guid>("Id")

48
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20200624023340_Initial.cs → templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/20200710065052_Initial.cs

@ -123,6 +123,31 @@ namespace MyCompanyName.MyProjectName.Migrations
table.PrimaryKey("PK_AbpRoles", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpSecurityLogs",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
ExtraProperties = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(maxLength: 40, nullable: true),
TenantId = table.Column<Guid>(nullable: true),
ApplicationName = table.Column<string>(maxLength: 96, nullable: true),
Identity = table.Column<string>(maxLength: 96, nullable: true),
Action = table.Column<string>(maxLength: 96, nullable: true),
UserId = table.Column<Guid>(nullable: true),
UserName = table.Column<string>(maxLength: 256, nullable: true),
TenantName = table.Column<string>(maxLength: 64, nullable: true),
ClientId = table.Column<string>(maxLength: 64, nullable: true),
CorrelationId = table.Column<string>(maxLength: 64, nullable: true),
ClientIpAddress = table.Column<string>(maxLength: 64, nullable: true),
BrowserInfo = table.Column<string>(maxLength: 512, nullable: true),
CreationTime = table.Column<DateTime>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AbpSecurityLogs", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AbpSettings",
columns: table => new
@ -515,6 +540,26 @@ namespace MyCompanyName.MyProjectName.Migrations
table: "AbpRoles",
column: "NormalizedName");
migrationBuilder.CreateIndex(
name: "IX_AbpSecurityLogs_TenantId_Action",
table: "AbpSecurityLogs",
columns: new[] { "TenantId", "Action" });
migrationBuilder.CreateIndex(
name: "IX_AbpSecurityLogs_TenantId_ApplicationName",
table: "AbpSecurityLogs",
columns: new[] { "TenantId", "ApplicationName" });
migrationBuilder.CreateIndex(
name: "IX_AbpSecurityLogs_TenantId_Identity",
table: "AbpSecurityLogs",
columns: new[] { "TenantId", "Identity" });
migrationBuilder.CreateIndex(
name: "IX_AbpSecurityLogs_TenantId_UserId",
table: "AbpSecurityLogs",
columns: new[] { "TenantId", "UserId" });
migrationBuilder.CreateIndex(
name: "IX_AbpSettings_Name_ProviderName_ProviderKey",
table: "AbpSettings",
@ -586,6 +631,9 @@ namespace MyCompanyName.MyProjectName.Migrations
migrationBuilder.DropTable(
name: "AbpRoleClaims");
migrationBuilder.DropTable(
name: "AbpSecurityLogs");
migrationBuilder.DropTable(
name: "AbpSettings");

75
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs

@ -397,6 +397,81 @@ namespace MyCompanyName.MyProjectName.Migrations
b.ToTable("AbpRoleClaims");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Action")
.HasColumnType("nvarchar(96)")
.HasMaxLength(96);
b.Property<string>("ApplicationName")
.HasColumnType("nvarchar(96)")
.HasMaxLength(96);
b.Property<string>("BrowserInfo")
.HasColumnType("nvarchar(512)")
.HasMaxLength(512);
b.Property<string>("ClientId")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ClientIpAddress")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(40)")
.HasMaxLength(40);
b.Property<string>("CorrelationId")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime2");
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<string>("Identity")
.HasColumnType("nvarchar(96)")
.HasMaxLength(96);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("uniqueidentifier");
b.Property<string>("TenantName")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<Guid?>("UserId")
.HasColumnType("uniqueidentifier");
b.Property<string>("UserName")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("TenantId", "Action");
b.HasIndex("TenantId", "ApplicationName");
b.HasIndex("TenantId", "Identity");
b.HasIndex("TenantId", "UserId");
b.ToTable("AbpSecurityLogs");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property<Guid>("Id")

Loading…
Cancel
Save