@BrandingProvider.AppName
diff --git a/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests/EntityFrameworkCore/BlobStoringDatabaseEntityFrameworkCoreTestModule.cs b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests/EntityFrameworkCore/BlobStoringDatabaseEntityFrameworkCoreTestModule.cs
index 038ca5874d..beae51969a 100644
--- a/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests/EntityFrameworkCore/BlobStoringDatabaseEntityFrameworkCoreTestModule.cs
+++ b/modules/blob-storing-database/test/Volo.Abp.BlobStoring.Database.EntityFrameworkCore.Tests/EntityFrameworkCore/BlobStoringDatabaseEntityFrameworkCoreTestModule.cs
@@ -15,6 +15,11 @@ namespace Volo.Abp.BlobStoring.Database.EntityFrameworkCore;
)]
public class BlobStoringDatabaseEntityFrameworkCoreTestModule : AbpModule
{
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ PreConfigure
(x => x.BusyTimeout = null);
+ }
+
public override void ConfigureServices(ServiceConfigurationContext context)
{
var sqliteConnection = CreateDatabaseAndGetConnection();
diff --git a/modules/blogging/test/Volo.Blogging.EntityFrameworkCore.Tests/Volo/Blogging/EntityFrameworkCore/BloggingEntityFrameworkCoreTestModule.cs b/modules/blogging/test/Volo.Blogging.EntityFrameworkCore.Tests/Volo/Blogging/EntityFrameworkCore/BloggingEntityFrameworkCoreTestModule.cs
index 498e8e7ab6..2d40880875 100644
--- a/modules/blogging/test/Volo.Blogging.EntityFrameworkCore.Tests/Volo/Blogging/EntityFrameworkCore/BloggingEntityFrameworkCoreTestModule.cs
+++ b/modules/blogging/test/Volo.Blogging.EntityFrameworkCore.Tests/Volo/Blogging/EntityFrameworkCore/BloggingEntityFrameworkCoreTestModule.cs
@@ -18,6 +18,11 @@ namespace Volo.Blogging.EntityFrameworkCore
{
private SqliteConnection _sqliteConnection;
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ PreConfigure(x => x.BusyTimeout = null);
+ }
+
public override void ConfigureServices(ServiceConfigurationContext context)
{
_sqliteConnection = CreateDatabaseAndGetConnection();
diff --git a/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/CmsKitEntityFrameworkCoreTestModule.cs b/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/CmsKitEntityFrameworkCoreTestModule.cs
index 3c28251536..659fa551b2 100644
--- a/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/CmsKitEntityFrameworkCoreTestModule.cs
+++ b/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/CmsKitEntityFrameworkCoreTestModule.cs
@@ -20,6 +20,7 @@ public class CmsKitEntityFrameworkCoreTestModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
+ PreConfigure(x => x.BusyTimeout = null);
context.Services.AddDataMigrationEnvironment();
}
diff --git a/modules/docs/test/Volo.Docs.EntityFrameworkCore.Tests/Volo/Docs/EntityFrameworkCore/DocsEntityFrameworkCoreTestModule.cs b/modules/docs/test/Volo.Docs.EntityFrameworkCore.Tests/Volo/Docs/EntityFrameworkCore/DocsEntityFrameworkCoreTestModule.cs
index fe3e32291f..b61b8368d6 100644
--- a/modules/docs/test/Volo.Docs.EntityFrameworkCore.Tests/Volo/Docs/EntityFrameworkCore/DocsEntityFrameworkCoreTestModule.cs
+++ b/modules/docs/test/Volo.Docs.EntityFrameworkCore.Tests/Volo/Docs/EntityFrameworkCore/DocsEntityFrameworkCoreTestModule.cs
@@ -15,6 +15,11 @@ namespace Volo.Docs.EntityFrameworkCore
)]
public class DocsEntityFrameworkCoreTestModule : AbpModule
{
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ PreConfigure(x => x.BusyTimeout = null);
+ }
+
public override void ConfigureServices(ServiceConfigurationContext context)
{
var sqliteConnection = CreateDatabaseAndGetConnection();
diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/AbpFeatureManagementEntityFrameworkCoreTestModule.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/AbpFeatureManagementEntityFrameworkCoreTestModule.cs
index 242cf75233..c370e5f558 100644
--- a/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/AbpFeatureManagementEntityFrameworkCoreTestModule.cs
+++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/AbpFeatureManagementEntityFrameworkCoreTestModule.cs
@@ -19,6 +19,11 @@ namespace Volo.Abp.FeatureManagement.EntityFrameworkCore;
)]
public class AbpFeatureManagementEntityFrameworkCoreTestModule : AbpModule
{
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ PreConfigure(x => x.BusyTimeout = null);
+ }
+
public override void ConfigureServices(ServiceConfigurationContext context)
{
var sqliteConnection = CreateDatabaseAndGetConnection();
diff --git a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/Integration/IIdentityUserIntegrationService.cs b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/Integration/IIdentityUserIntegrationService.cs
index 815c1c48c9..3a61407ddf 100644
--- a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/Integration/IIdentityUserIntegrationService.cs
+++ b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/Integration/IIdentityUserIntegrationService.cs
@@ -10,12 +10,20 @@ namespace Volo.Abp.Identity.Integration;
public interface IIdentityUserIntegrationService : IApplicationService
{
Task GetRoleNamesAsync(Guid id);
-
+
Task FindByIdAsync(Guid id);
Task FindByUserNameAsync(string userName);
Task> SearchAsync(UserLookupSearchInputDto input);
+ Task> SearchByIdsAsync(Guid[] ids);
+
Task GetCountAsync(UserLookupCountInputDto input);
-}
\ No newline at end of file
+
+ Task> SearchRoleAsync(RoleLookupSearchInputDto input);
+
+ Task> SearchRoleByNamesAsync(string[] ids);
+
+ Task GetRoleCountAsync(RoleLookupCountInputDto input);
+}
diff --git a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/RoleLookupCountInputDto.cs b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/RoleLookupCountInputDto.cs
new file mode 100644
index 0000000000..875d350f1c
--- /dev/null
+++ b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/RoleLookupCountInputDto.cs
@@ -0,0 +1,6 @@
+namespace Volo.Abp.Identity;
+
+public class RoleLookupCountInputDto
+{
+ public string Filter { get; set; }
+}
diff --git a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/RoleLookupSearchInputDto.cs b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/RoleLookupSearchInputDto.cs
new file mode 100644
index 0000000000..ebc1707055
--- /dev/null
+++ b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/RoleLookupSearchInputDto.cs
@@ -0,0 +1,8 @@
+using Volo.Abp.Application.Dtos;
+
+namespace Volo.Abp.Identity;
+
+public class RoleLookupSearchInputDto : ExtensiblePagedAndSortedResultRequestDto
+{
+ public string Filter { get; set; }
+}
diff --git a/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/Integration/IdentityUserIntegrationService.cs b/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/Integration/IdentityUserIntegrationService.cs
index 37446ce1f3..4019cd9031 100644
--- a/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/Integration/IdentityUserIntegrationService.cs
+++ b/modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/Integration/IdentityUserIntegrationService.cs
@@ -2,6 +2,7 @@
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
+using Volo.Abp.Domain.Repositories;
using Volo.Abp.Users;
namespace Volo.Abp.Identity.Integration;
@@ -10,13 +11,19 @@ public class IdentityUserIntegrationService : IdentityAppServiceBase, IIdentityU
{
protected IUserRoleFinder UserRoleFinder { get; }
protected IdentityUserRepositoryExternalUserLookupServiceProvider UserLookupServiceProvider { get; }
+ protected IIdentityUserRepository UserRepository { get; }
+ protected IIdentityRoleRepository RoleRepository { get; }
public IdentityUserIntegrationService(
IUserRoleFinder userRoleFinder,
- IdentityUserRepositoryExternalUserLookupServiceProvider userLookupServiceProvider)
+ IdentityUserRepositoryExternalUserLookupServiceProvider userLookupServiceProvider,
+ IIdentityUserRepository userRepository,
+ IIdentityRoleRepository roleRepository)
{
UserRoleFinder = userRoleFinder;
UserLookupServiceProvider = userLookupServiceProvider;
+ UserRepository = userRepository;
+ RoleRepository = roleRepository;
}
public virtual async Task GetRoleNamesAsync(Guid id)
@@ -62,8 +69,53 @@ public class IdentityUserIntegrationService : IdentityAppServiceBase, IIdentityU
);
}
+ public virtual async Task> SearchByIdsAsync(Guid[] ids)
+ {
+ var users = await UserRepository.GetListByIdsAsync(ids);
+
+ return new ListResultDto(
+ users
+ .Select(u => new UserData(
+ u.Id,
+ u.UserName,
+ u.Email,
+ u.Name,
+ u.Surname,
+ u.EmailConfirmed,
+ u.PhoneNumber,
+ u.PhoneNumberConfirmed,
+ u.TenantId,
+ u.IsActive,
+ u.ExtraProperties))
+ .ToList()
+ );
+ }
+
public virtual async Task GetCountAsync(UserLookupCountInputDto input)
{
return await UserLookupServiceProvider.GetCountAsync(input.Filter);
}
+
+ public virtual async Task> SearchRoleAsync(RoleLookupSearchInputDto input)
+ {
+ using (RoleRepository.DisableTracking())
+ {
+ var roles = await RoleRepository.GetListAsync(input.Filter);
+ return new ListResultDto(roles.Select(r => new RoleData(r.Id, r.Name, r.IsDefault, r.IsStatic, r.IsPublic, r.TenantId, r.ExtraProperties)).ToList());
+ }
+ }
+
+ public virtual async Task> SearchRoleByNamesAsync(string[] names)
+ {
+ using (RoleRepository.DisableTracking())
+ {
+ var roles = await RoleRepository.GetListAsync(names);
+ return new ListResultDto(roles.Select(r => new RoleData(r.Id, r.Name, r.IsDefault, r.IsStatic, r.IsPublic, r.TenantId, r.ExtraProperties)).ToList());
+ }
+ }
+
+ public virtual async Task GetRoleCountAsync(RoleLookupCountInputDto input)
+ {
+ return await RoleRepository.GetCountAsync(input.Filter);
+ }
}
diff --git a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs
index f4b4a2d35a..09f3e4bf24 100644
--- a/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs
+++ b/modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpSignInManager.cs
@@ -5,9 +5,7 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
-using Volo.Abp.Identity.Settings;
using Volo.Abp.Settings;
-using Volo.Abp.Timing;
namespace Volo.Abp.Identity.AspNetCore;
@@ -42,7 +40,7 @@ public class AbpSignInManager : SignInManager
_identityUserManager = userManager;
}
- public async override Task PasswordSignInAsync(
+ public override async Task PasswordSignInAsync(
string userName,
string password,
bool isPersistent,
@@ -86,7 +84,17 @@ public class AbpSignInManager : SignInManager
return await base.PasswordSignInAsync(userName, password, isPersistent, lockoutOnFailure);
}
- protected async override Task PreSignInCheck(IdentityUser user)
+ ///
+ /// This is to call the protection method PreSignInCheck
+ ///
+ /// The user
+ /// Null if the user should be allowed to sign in, otherwise the SignInResult why they should be denied.
+ public virtual async Task CallPreSignInCheckAsync(IdentityUser user)
+ {
+ return await PreSignInCheck(user);
+ }
+
+ protected override async Task PreSignInCheck(IdentityUser user)
{
if (!user.IsActive)
{
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IUserRoleFinder.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IUserRoleFinder.cs
index 1835f38952..75261b2cc4 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IUserRoleFinder.cs
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IUserRoleFinder.cs
@@ -1,4 +1,6 @@
using System;
+using System.Collections.Generic;
+using System.Threading;
using System.Threading.Tasks;
namespace Volo.Abp.Identity;
@@ -7,6 +9,14 @@ public interface IUserRoleFinder
{
[Obsolete("Use GetRoleNamesAsync instead.")]
Task GetRolesAsync(Guid userId);
-
+
Task GetRoleNamesAsync(Guid userId);
+
+ Task> SearchUserAsync(string filter, int page = 1);
+
+ Task> SearchRoleAsync(string filter, int page = 1);
+
+ Task> SearchUserByIdsAsync(Guid[] ids);
+
+ Task> SearchRoleByNamesAsync(string[] names);
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserPasskeyConsts.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserPasskeyConsts.cs
new file mode 100644
index 0000000000..8f0971d315
--- /dev/null
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/IdentityUserPasskeyConsts.cs
@@ -0,0 +1,14 @@
+namespace Volo.Abp.Identity;
+
+public static class IdentityUserPasskeyConsts
+{
+ ///
+ /// Default value: 256
+ ///
+ public static int MaxPassKeyNameLength { get; set; } = 256;
+
+ ///
+ /// Default value: 1024
+ ///
+ public static int MaxCredentialIdLength { get; set; } = 1024;
+}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json
index 49b22071cd..71b858f834 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json
@@ -135,6 +135,8 @@
"ModificationTime": "وقت التعديل",
"PasswordUpdateTime": "وقت تحديث كلمة المرور",
"LockoutEndTime": "وقت انتهاء القفل",
- "FailedAccessCount": "فشل عدد الوصول"
+ "FailedAccessCount": "فشل عدد الوصول",
+ "UserResourcePermissionProviderKeyLookupService": "المستخدم",
+ "RoleResourcePermissionProviderKeyLookupService": "الدور"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json
index 8f0456c601..e84320059e 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json
@@ -135,6 +135,8 @@
"ModificationTime": "Doba úpravy",
"PasswordUpdateTime": "Čas aktualizace hesla",
"LockoutEndTime": "Čas konce uzamčení",
- "FailedAccessCount": "Počet neúspěšných přístupů"
+ "FailedAccessCount": "Počet neúspěšných přístupů",
+ "UserResourcePermissionProviderKeyLookupService": "Uživatel",
+ "RoleResourcePermissionProviderKeyLookupService": "Role"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json
index 19daf4d440..4064866f00 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json
@@ -135,6 +135,8 @@
"LockoutEndTime": "Endzeit der Sperrung",
"FailedAccessCount": "Anzahl der fehlgeschlagenen Zugriffe",
"DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "E-Mail-Verifizierung für die Registrierung erzwingen",
- "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Benutzerkonten werden nicht erstellt, es sei denn, sie verifizieren ihre E-Mail-Adressen."
+ "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Benutzerkonten werden nicht erstellt, es sei denn, sie verifizieren ihre E-Mail-Adressen.",
+ "UserResourcePermissionProviderKeyLookupService": "Benutzer",
+ "RoleResourcePermissionProviderKeyLookupService": "Rolle"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json
index 1e2c8a23ce..ba610a993a 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json
@@ -128,6 +128,8 @@
"Description:Abp.Identity.User.IsEmailUpdateEnabled": "Εάν το email μπορεί να ενημερωθεί από τον χρήστη.",
"DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Επιβολή επαλήθευσης email για εγγραφή",
"Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Οι λογαριασμοί χρηστών δεν θα δημιουργηθούν εκτός αν επαληθεύσουν τις διευθύνσεις email τους.",
- "Details": "Λεπτομέρειες"
+ "Details": "Λεπτομέρειες",
+ "UserResourcePermissionProviderKeyLookupService": "Χρήστης",
+ "RoleResourcePermissionProviderKeyLookupService": "Ρόλος"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json
index 45f25bc864..9f10e1f188 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json
@@ -137,6 +137,8 @@
"Description:Abp.Identity.UsersCanChange": "Allow users to change their Two Factor.",
"DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Enforce email verification to register",
"Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "User accounts will not be created unless they verify their email addresses.",
- "Details": "Details"
+ "Details": "Details",
+ "UserResourcePermissionProviderKeyLookupService": "User",
+ "RoleResourcePermissionProviderKeyLookupService": "Role"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json
index f2cc74cef0..0deb6a4b56 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json
@@ -135,6 +135,8 @@
"ModificationTime": "Modification time",
"PasswordUpdateTime": "Password update time",
"LockoutEndTime": "Lockout end time",
- "FailedAccessCount": "Failed access count"
+ "FailedAccessCount": "Failed access count",
+ "UserResourcePermissionProviderKeyLookupService": "User",
+ "RoleResourcePermissionProviderKeyLookupService": "Role"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json
index ff4d4302f8..a2a9414214 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json
@@ -135,6 +135,8 @@
"ModificationTime": "tiempo de modificación",
"PasswordUpdateTime": "Hora de actualización de contraseña",
"LockoutEndTime": "Hora de finalización del bloqueo",
- "FailedAccessCount": "Recuento de acceso fallido"
+ "FailedAccessCount": "Recuento de acceso fallido",
+ "UserResourcePermissionProviderKeyLookupService": "Usuario",
+ "RoleResourcePermissionProviderKeyLookupService": "Rol"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json
index 024b443fec..e9a1911b52 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json
@@ -139,6 +139,8 @@
"Description:Abp.Identity.SignIn.RequireConfirmedEmail": "کاربران میتوانند حساب ایجاد کنند اما تا زمانی که آدرس ایمیل خود را تایید نکنند نمیتوانند وارد شوند.",
"Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "کاربران میتوانند حساب ایجاد کنند اما تا زمانی که شماره تلفن خود را تایید نکنند نمیتوانند وارد شوند.",
"DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "اجباری کردن تایید ایمیل برای ثبتنام",
- "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "حسابهای کاربری ایجاد نخواهند شد مگر اینکه آدرس ایمیل خود را تایید کنند."
+ "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "حسابهای کاربری ایجاد نخواهند شد مگر اینکه آدرس ایمیل خود را تایید کنند.",
+ "UserResourcePermissionProviderKeyLookupService": "کاربر",
+ "RoleResourcePermissionProviderKeyLookupService": "نقش"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json
index 71cfe15712..2a37974cbb 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json
@@ -135,6 +135,8 @@
"ModificationTime": "Muutosaika",
"PasswordUpdateTime": "Salasanan päivityksen aika",
"LockoutEndTime": "Lukituksen päättymisaika",
- "FailedAccessCount": "Epäonnistuneet käyttöoikeudet"
+ "FailedAccessCount": "Epäonnistuneet käyttöoikeudet",
+ "UserResourcePermissionProviderKeyLookupService": "Käyttäjä",
+ "RoleResourcePermissionProviderKeyLookupService": "Rooli"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json
index 61bc1dea98..323bb5927a 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json
@@ -135,6 +135,8 @@
"LockoutEndTime": "Heure de fin du verrouillage",
"FailedAccessCount": "Nombre d'accès ayant échoué",
"DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Exiger la vérification de l'e-mail pour s'inscrire",
- "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Les comptes d’utilisateurs ne seront pas créés à moins qu’ils ne vérifient leurs adresses e-mail."
+ "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Les comptes d’utilisateurs ne seront pas créés à moins qu’ils ne vérifient leurs adresses e-mail.",
+ "UserResourcePermissionProviderKeyLookupService": "Utilisateur",
+ "RoleResourcePermissionProviderKeyLookupService": "Rôle"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json
index 464426cf34..0d5fca3dde 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json
@@ -135,6 +135,8 @@
"ModificationTime": "संशोधन का समय",
"PasswordUpdateTime": "पासवर्ड अद्यतन समय",
"LockoutEndTime": "तालाबंदी समाप्ति समय",
- "FailedAccessCount": "विफल पहुंच गणना"
+ "FailedAccessCount": "विफल पहुंच गणना",
+ "UserResourcePermissionProviderKeyLookupService": "उपयोगकर्ता",
+ "RoleResourcePermissionProviderKeyLookupService": "भूमिका"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json
index e8af421629..0e73aa5f1e 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json
@@ -135,6 +135,8 @@
"ModificationTime": "Vrijeme izmjene",
"PasswordUpdateTime": "Vrijeme ažuriranja lozinke",
"LockoutEndTime": "Vrijeme završetka zaključavanja",
- "FailedAccessCount": "Broj neuspjelih pristupa"
+ "FailedAccessCount": "Broj neuspjelih pristupa",
+ "UserResourcePermissionProviderKeyLookupService": "Korisnik",
+ "RoleResourcePermissionProviderKeyLookupService": "Uloga"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json
index 935a59e2f5..730a831d23 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json
@@ -135,6 +135,8 @@
"ModificationTime": "Módosítási idő",
"PasswordUpdateTime": "A jelszó frissítési ideje",
"LockoutEndTime": "A zárolás befejezési ideje",
- "FailedAccessCount": "Sikertelen hozzáférések száma"
+ "FailedAccessCount": "Sikertelen hozzáférések száma",
+ "UserResourcePermissionProviderKeyLookupService": "Felhasználó",
+ "RoleResourcePermissionProviderKeyLookupService": "Szerep"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json
index ebf43ceab3..da53a10657 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json
@@ -135,6 +135,8 @@
"ModificationTime": "Breytingartími",
"PasswordUpdateTime": "Uppfærslutími lykilorðs",
"LockoutEndTime": "Lokatími lokunar",
- "FailedAccessCount": "Misheppnuð fjöldi aðgangs"
+ "FailedAccessCount": "Misheppnuð fjöldi aðgangs",
+ "UserResourcePermissionProviderKeyLookupService": "Notandi",
+ "RoleResourcePermissionProviderKeyLookupService": "Hlutverk"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json
index 1d1d9771fd..163ff98754 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json
@@ -135,6 +135,8 @@
"LockoutEndTime": "Ora di fine del blocco",
"FailedAccessCount": "Conteggio accessi non riusciti",
"DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Richiedi verifica email per la registrazione",
- "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Gli account utente non verranno creati a meno che non verifichino i loro indirizzi email."
+ "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Gli account utente non verranno creati a meno che non verifichino i loro indirizzi email.",
+ "UserResourcePermissionProviderKeyLookupService": "Utente",
+ "RoleResourcePermissionProviderKeyLookupService": "Ruolo"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json
index 2b405697ae..9836137c80 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json
@@ -135,6 +135,8 @@
"LockoutEndTime": "Eindtijd uitsluiting",
"FailedAccessCount": "Aantal mislukte toegangen",
"DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "E-mailverificatie vereisen voor registratie",
- "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Gebruikersaccounts worden niet aangemaakt tenzij ze hun e-mailadressen verifiëren."
+ "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Gebruikersaccounts worden niet aangemaakt tenzij ze hun e-mailadressen verifiëren.",
+ "UserResourcePermissionProviderKeyLookupService": "Gebruiker",
+ "RoleResourcePermissionProviderKeyLookupService": "Rol"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json
index c3c8053556..18f33d89c1 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json
@@ -135,6 +135,8 @@
"LockoutEndTime": "Czas zakończenia blokady",
"FailedAccessCount": "Liczba nieudanych dostępów",
"DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Wymagaj weryfikacji e-mail do rejestracji",
- "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Konta użytkowników nie zostaną utworzone, dopóki nie zweryfikują swoich adresów e-mail."
+ "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Konta użytkowników nie zostaną utworzone, dopóki nie zweryfikują swoich adresów e-mail.",
+ "UserResourcePermissionProviderKeyLookupService": "Użytkownik",
+ "RoleResourcePermissionProviderKeyLookupService": "Rola"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json
index 40ef80556f..cd796edbde 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json
@@ -135,6 +135,8 @@
"ModificationTime": "Hora da modificação",
"PasswordUpdateTime": "Hora de atualização da senha",
"LockoutEndTime": "Hora de término do bloqueio",
- "FailedAccessCount": "Contagem de acessos com falha"
+ "FailedAccessCount": "Contagem de acessos com falha",
+ "UserResourcePermissionProviderKeyLookupService": "Usuário",
+ "RoleResourcePermissionProviderKeyLookupService": "Perfil"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json
index efe0c53541..3ebc98d179 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json
@@ -135,6 +135,8 @@
"ModificationTime": "Timp de modificare",
"PasswordUpdateTime": "Ora actualizării parolei",
"LockoutEndTime": "Ora de încheiere a blocării",
- "FailedAccessCount": "Număr de acces eșuat"
+ "FailedAccessCount": "Număr de acces eșuat",
+ "UserResourcePermissionProviderKeyLookupService": "Utilizator",
+ "RoleResourcePermissionProviderKeyLookupService": "Rol"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json
index 6afaf14b1a..f9ddb814d4 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json
@@ -135,6 +135,8 @@
"LockoutEndTime": "Время окончания блокировки",
"FailedAccessCount": "Количество неудачных попыток доступа",
"DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Требовать подтверждение электронной почты для регистрации",
- "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Учетные записи пользователей не будут созданы, пока они не подтвердят свои адреса электронной почты."
+ "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Учетные записи пользователей не будут созданы, пока они не подтвердят свои адреса электронной почты.",
+ "UserResourcePermissionProviderKeyLookupService": "Пользователь",
+ "RoleResourcePermissionProviderKeyLookupService": "Роль"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json
index e529910a5e..26486aa6ab 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json
@@ -135,6 +135,8 @@
"ModificationTime": "Čas úpravy",
"PasswordUpdateTime": "Čas aktualizácie hesla",
"LockoutEndTime": "Čas ukončenia uzamknutia",
- "FailedAccessCount": "Počet neúspešných prístupov"
+ "FailedAccessCount": "Počet neúspešných prístupov",
+ "UserResourcePermissionProviderKeyLookupService": "Používateľ",
+ "RoleResourcePermissionProviderKeyLookupService": "Rola"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json
index c02577c385..8ae2a2f81b 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json
@@ -135,6 +135,8 @@
"ModificationTime": "Čas spreminjanja",
"PasswordUpdateTime": "Čas posodobitve gesla",
"LockoutEndTime": "Končni čas zaklepanja",
- "FailedAccessCount": "Število neuspešnih dostopov"
+ "FailedAccessCount": "Število neuspešnih dostopov",
+ "UserResourcePermissionProviderKeyLookupService": "Uporabnik",
+ "RoleResourcePermissionProviderKeyLookupService": "Vloga"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sv.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sv.json
index 166f32a10a..aef65e2b11 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sv.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sv.json
@@ -135,6 +135,8 @@
"ModificationTime": "Tid för modifiering",
"PasswordUpdateTime": "Uppdateringstid för lösenord",
"LockoutEndTime": "Sluttid för låsning",
- "FailedAccessCount": "Antal misslyckade åtkomster"
+ "FailedAccessCount": "Antal misslyckade åtkomster",
+ "UserResourcePermissionProviderKeyLookupService": "Användare",
+ "RoleResourcePermissionProviderKeyLookupService": "Roll"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json
index 2da62b0355..0a6e4d393c 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json
@@ -135,6 +135,8 @@
"LockoutEndTime": "Kilitlenme bitiş zamanı",
"FailedAccessCount": "Başarısız giriş denemesi sayısı",
"DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Kayıt için e-posta doğrulaması zorunlu kıl",
- "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Kullanıcı hesapları, e-posta adreslerini doğrulamadıkça oluşturulmayacaktır."
+ "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Kullanıcı hesapları, e-posta adreslerini doğrulamadıkça oluşturulmayacaktır.",
+ "UserResourcePermissionProviderKeyLookupService": "Kullanıcı",
+ "RoleResourcePermissionProviderKeyLookupService": "Rol"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json
index a98baf6566..32c1dfe008 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json
@@ -135,6 +135,8 @@
"LockoutEndTime": "Thời gian kết thúc khóa",
"FailedAccessCount": "Số lượt truy cập không thành công",
"DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Yêu cầu xác minh email để đăng ký",
- "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Tài khoản người dùng sẽ không được tạo ra trừ khi họ xác minh địa chỉ email của mình."
+ "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "Tài khoản người dùng sẽ không được tạo ra trừ khi họ xác minh địa chỉ email của mình.",
+ "UserResourcePermissionProviderKeyLookupService": "Người dùng",
+ "RoleResourcePermissionProviderKeyLookupService": "Vai trò"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json
index 0cfc117cf6..3a1239ddc7 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json
@@ -135,6 +135,8 @@
"ModificationTime": "修改时间",
"PasswordUpdateTime": "密码更新时间",
"LockoutEndTime": "锁定结束时间",
- "FailedAccessCount": "访问失败次数"
+ "FailedAccessCount": "访问失败次数",
+ "UserResourcePermissionProviderKeyLookupService": "用户",
+ "RoleResourcePermissionProviderKeyLookupService": "角色"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json
index 39f6fe5267..a28cc6c7d4 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json
@@ -135,6 +135,8 @@
"LockoutEndTime": "鎖定結束時間",
"FailedAccessCount": "訪問失敗次數",
"DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "強制要求驗證電子郵件才能註冊",
- "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "除非驗證他們的電子郵件地址,否則不會創建用戶帳戶。"
+ "Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "除非驗證他們的電子郵件地址,否則不會創建用戶帳戶。",
+ "UserResourcePermissionProviderKeyLookupService": "使用者",
+ "RoleResourcePermissionProviderKeyLookupService": "角色"
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/RoleFinderResult.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/RoleFinderResult.cs
new file mode 100644
index 0000000000..8fe118f13d
--- /dev/null
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/RoleFinderResult.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace Volo.Abp.Identity;
+
+public class RoleFinderResult
+{
+ public Guid Id { get; set; }
+
+ public string RoleName { get; set; }
+}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/UserFinderResult.cs b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/UserFinderResult.cs
new file mode 100644
index 0000000000..48ba5ace7a
--- /dev/null
+++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/UserFinderResult.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace Volo.Abp.Identity;
+
+public class UserFinderResult
+{
+ public Guid Id { get; set; }
+
+ public string UserName { get; set; }
+}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs
index a9eefe019e..26bd8624b9 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs
+++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityRoleRepository.cs
@@ -31,11 +31,17 @@ public interface IIdentityRoleRepository : IBasicRepository
bool includeDetails = false,
CancellationToken cancellationToken = default
);
+
Task> GetListAsync(
IEnumerable ids,
CancellationToken cancellationToken = default
);
+ Task> GetListAsync(
+ IEnumerable names,
+ CancellationToken cancellationToken = default
+ );
+
Task> GetDefaultOnesAsync(
bool includeDetails = false,
CancellationToken cancellationToken = default
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserRepository.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserRepository.cs
index 8da3237f83..33ec2eab95 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserRepository.cs
+++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IIdentityUserRepository.cs
@@ -160,4 +160,9 @@ public interface IIdentityUserRepository : IBasicRepository
Task> GetRoleNamesAsync(
IEnumerable userIds,
CancellationToken cancellationToken = default);
+
+ Task FindByPasskeyIdAsync(
+ byte[] credentialId,
+ bool includeDetails = true,
+ CancellationToken cancellationToken = default);
}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityPasskeyData.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityPasskeyData.cs
new file mode 100644
index 0000000000..8c26227741
--- /dev/null
+++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityPasskeyData.cs
@@ -0,0 +1,68 @@
+using System;
+
+namespace Volo.Abp.Identity;
+
+///
+/// Represents data associated with a passkey.
+///
+public class IdentityPasskeyData
+{
+ ///
+ /// Gets or sets the public key associated with this passkey.
+ ///
+ public virtual byte[] PublicKey { get; set; }
+
+ ///
+ /// Gets or sets the friendly name for this passkey.
+ ///
+ public virtual string? Name { get; set; }
+
+ ///
+ /// Gets or sets the time this passkey was created.
+ ///
+ public virtual DateTimeOffset CreatedAt { get; set; }
+
+ ///
+ /// Gets or sets the signature counter for this passkey.
+ ///
+ public virtual uint SignCount { get; set; }
+
+ ///
+ /// Gets or sets the transports supported by this passkey.
+ ///
+ ///
+ /// See .
+ ///
+ public virtual string[] Transports { get; set; }
+
+ ///
+ /// Gets or sets whether the passkey has a verified user.
+ ///
+ public virtual bool IsUserVerified { get; set; }
+
+ ///
+ /// Gets or sets whether the passkey is eligible for backup.
+ ///
+ public virtual bool IsBackupEligible { get; set; }
+
+ ///
+ /// Gets or sets whether the passkey is currently backed up.
+ ///
+ public virtual bool IsBackedUp { get; set; }
+
+ ///
+ /// Gets or sets the attestation object associated with this passkey.
+ ///
+ ///
+ /// See .
+ ///
+ public virtual byte[] AttestationObject { get; set; }
+
+ ///
+ /// Gets or sets the collected client data JSON associated with this passkey.
+ ///
+ ///
+ /// See .
+ ///
+ public virtual byte[] ClientDataJson { get; set; }
+}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUser.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUser.cs
index be9ccfe8bb..3f4a91117c 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUser.cs
+++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUser.cs
@@ -127,6 +127,11 @@ public class IdentityUser : FullAuditedAggregateRoot, IUser, IHasEntityVer
///
public virtual DateTimeOffset? LastPasswordChangeTime { get; protected set; }
+ ///
+ /// Gets or sets the last sign-in time for the user.
+ ///
+ public virtual DateTimeOffset? LastSignInTime { get; protected set; }
+
//TODO: Can we make collections readonly collection, which will provide encapsulation. But... can work for all ORMs?
///
@@ -159,6 +164,11 @@ public class IdentityUser : FullAuditedAggregateRoot, IUser, IHasEntityVer
///
public virtual ICollection PasswordHistories { get; protected set; }
+ ///
+ /// Navigation property for this users passkeys.
+ ///
+ public virtual ICollection Passkeys { get; protected set; }
+
protected IdentityUser()
{
}
@@ -188,6 +198,7 @@ public class IdentityUser : FullAuditedAggregateRoot, IUser, IHasEntityVer
Tokens = new Collection();
OrganizationUnits = new Collection();
PasswordHistories = new Collection();
+ Passkeys = new Collection();
}
public virtual void AddRole(Guid roleId)
@@ -403,6 +414,27 @@ public class IdentityUser : FullAuditedAggregateRoot, IUser, IHasEntityVer
LastPasswordChangeTime = lastPasswordChangeTime;
}
+ public virtual void SetLastSignInTime(DateTimeOffset? lastSignInTime)
+ {
+ LastSignInTime = lastSignInTime;
+ }
+
+ [CanBeNull]
+ public virtual IdentityUserPasskey FindPasskey(byte[] credentialId)
+ {
+ return Passkeys.FirstOrDefault(x => x.UserId == Id && x.CredentialId.SequenceEqual(credentialId));
+ }
+
+ public virtual void AddPasskey(byte[] credentialId, IdentityPasskeyData passkeyData)
+ {
+ Passkeys.Add(new IdentityUserPasskey(Id, credentialId, passkeyData, TenantId));
+ }
+
+ public virtual void RemovePasskey(byte[] credentialId)
+ {
+ Passkeys.RemoveAll(x => x.CredentialId.SequenceEqual(credentialId));
+ }
+
public override string ToString()
{
return $"{base.ToString()}, UserName = {UserName}";
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserPasskey.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserPasskey.cs
new file mode 100644
index 0000000000..59aad98ea6
--- /dev/null
+++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserPasskey.cs
@@ -0,0 +1,53 @@
+using System;
+using Volo.Abp.Domain.Entities;
+using Volo.Abp.MultiTenancy;
+
+namespace Volo.Abp.Identity;
+
+///
+/// Represents a passkey credential for a user in the identity system.
+///
+///
+/// See .
+///
+public class IdentityUserPasskey : Entity, IMultiTenant
+{
+ public virtual Guid? TenantId { get; protected set; }
+
+ ///
+ /// Gets or sets the primary key of the user that owns this passkey.
+ ///
+ public virtual Guid UserId { get; protected set; }
+
+ ///
+ /// Gets or sets the credential ID for this passkey.
+ ///
+ public virtual byte[] CredentialId { get; set; }
+
+ ///
+ /// Gets or sets additional data associated with this passkey.
+ ///
+ public virtual IdentityPasskeyData Data { get; set; }
+
+ protected IdentityUserPasskey()
+ {
+
+ }
+
+ public IdentityUserPasskey(
+ Guid userId,
+ byte[] credentialId,
+ IdentityPasskeyData data,
+ Guid? tenantId)
+ {
+ UserId = userId;
+ CredentialId = credentialId;
+ Data = data;
+ TenantId = tenantId;
+ }
+
+ public override object[] GetKeys()
+ {
+ return new object[] { UserId, CredentialId };
+ }
+}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserPasskeyExtensions.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserPasskeyExtensions.cs
new file mode 100644
index 0000000000..fd1bd3fbf5
--- /dev/null
+++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserPasskeyExtensions.cs
@@ -0,0 +1,32 @@
+using Microsoft.AspNetCore.Identity;
+
+namespace Volo.Abp.Identity;
+
+public static class IdentityUserPasskeyExtensions
+{
+ public static void UpdateFromUserPasskeyInfo(this IdentityUserPasskey passkey, UserPasskeyInfo passkeyInfo)
+ {
+ passkey.Data.Name = passkeyInfo.Name;
+ passkey.Data.SignCount = passkeyInfo.SignCount;
+ passkey.Data.IsBackedUp = passkeyInfo.IsBackedUp;
+ passkey.Data.IsUserVerified = passkeyInfo.IsUserVerified;
+ }
+
+ public static UserPasskeyInfo ToUserPasskeyInfo(this IdentityUserPasskey passkey)
+ {
+ return new UserPasskeyInfo(
+ passkey.CredentialId,
+ passkey.Data.PublicKey,
+ passkey.Data.CreatedAt,
+ passkey.Data.SignCount,
+ passkey.Data.Transports,
+ passkey.Data.IsUserVerified,
+ passkey.Data.IsBackupEligible,
+ passkey.Data.IsBackedUp,
+ passkey.Data.AttestationObject,
+ passkey.Data.ClientDataJson)
+ {
+ Name = passkey.Data.Name
+ };
+ }
+}
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs
index 83fe745677..f407e6c977 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs
+++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserStore.cs
@@ -32,6 +32,7 @@ public class IdentityUserStore :
IUserAuthenticationTokenStore,
IUserAuthenticatorKeyStore,
IUserTwoFactorRecoveryCodeStore,
+ IUserPasskeyStore,
ITransientDependency
{
private const string InternalLoginProvider = "[AspNetUserStore]";
@@ -1123,6 +1124,110 @@ public class IdentityUserStore :
return Task.FromResult(RecoveryCodeTokenName);
}
+ ///
+ /// Creates a new passkey credential in the store for the specified ,
+ /// or updates an existing passkey.
+ ///
+ /// The user to create the passkey credential for.
+ ///
+ /// The used to propagate notifications that the operation should be canceled.
+ /// The that represents the asynchronous operation.
+ public virtual async Task AddOrUpdatePasskeyAsync(IdentityUser user, UserPasskeyInfo passkey, CancellationToken cancellationToken)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ await UserRepository.EnsureCollectionLoadedAsync(user, u => u.Passkeys, cancellationToken);
+
+ var userPasskey = user.FindPasskey(passkey.CredentialId);
+ if (userPasskey != null)
+ {
+ userPasskey.UpdateFromUserPasskeyInfo(passkey);
+ }
+ else
+ {
+ user.AddPasskey(passkey.CredentialId, new IdentityPasskeyData()
+ {
+ PublicKey = passkey.PublicKey,
+ Name = passkey.Name,
+ CreatedAt = passkey.CreatedAt,
+ Transports = passkey.Transports,
+ SignCount = passkey.SignCount,
+ IsUserVerified = passkey.IsUserVerified,
+ IsBackupEligible = passkey.IsBackupEligible,
+ IsBackedUp = passkey.IsBackedUp,
+ AttestationObject = passkey.AttestationObject,
+ ClientDataJson = passkey.ClientDataJson,
+ });
+ }
+ }
+
+ ///
+ /// Gets the passkey credentials for the specified .
+ ///
+ /// The user whose passkeys should be retrieved.
+ /// The used to propagate notifications that the operation should be canceled.
+ /// The that represents the asynchronous operation, containing a list of the user's passkeys.
+ public virtual async Task> GetPasskeysAsync(IdentityUser user, CancellationToken cancellationToken)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ Check.NotNull(user, nameof(user));
+
+ await UserRepository.EnsureCollectionLoadedAsync(user, u => u.Passkeys, cancellationToken);
+
+ return user.Passkeys.Select(p => p.ToUserPasskeyInfo()).ToList();
+ }
+
+ ///
+ /// Finds and returns a user, if any, associated with the specified passkey credential identifier.
+ ///
+ /// The passkey credential id to search for.
+ /// The used to propagate notifications that the operation should be canceled.
+ ///
+ /// The that represents the asynchronous operation, containing the user, if any, associated with the specified passkey credential id.
+ ///
+ public virtual async Task FindByPasskeyIdAsync(byte[] credentialId, CancellationToken cancellationToken)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+ return await UserRepository.FindByPasskeyIdAsync(credentialId, cancellationToken: cancellationToken);
+ }
+
+ ///
+ /// Finds a passkey for the specified user with the specified credential id.
+ ///
+ /// The user whose passkey should be retrieved.
+ /// The credential id to search for.
+ /// The used to propagate notifications that the operation should be canceled.
+ /// The that represents the asynchronous operation, containing the user's passkey information.
+ public virtual async Task FindPasskeyAsync(IdentityUser user, byte[] credentialId, CancellationToken cancellationToken)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ Check.NotNull(user, nameof(user));
+ Check.NotNull(credentialId, nameof(credentialId));
+
+ await UserRepository.EnsureCollectionLoadedAsync(user, u => u.Passkeys, cancellationToken);
+ return user.FindPasskey(credentialId)?.ToUserPasskeyInfo();
+ }
+
+ ///
+ /// Removes a passkey credential from the specified .
+ ///
+ /// The user to remove the passkey credential from.
+ /// The credential id of the passkey to remove.
+ /// The used to propagate notifications that the operation should be canceled.
+ /// The that represents the asynchronous operation.
+ public virtual async Task RemovePasskeyAsync(IdentityUser user, byte[] credentialId, CancellationToken cancellationToken)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ Check.NotNull(user, nameof(user));
+ Check.NotNull(credentialId, nameof(credentialId));
+
+ await UserRepository.EnsureCollectionLoadedAsync(user, u => u.Passkeys, cancellationToken);
+ user.RemovePasskey(credentialId);
+ }
+
public virtual void Dispose()
{
diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/UserRoleFinder.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/UserRoleFinder.cs
index 3ec1b2fbb1..48d8b01a73 100644
--- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/UserRoleFinder.cs
+++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/UserRoleFinder.cs
@@ -1,16 +1,21 @@
using System;
+using System.Collections.Generic;
+using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
+using Volo.Abp.Domain.Repositories;
namespace Volo.Abp.Identity;
public class UserRoleFinder : IUserRoleFinder, ITransientDependency
{
protected IIdentityUserRepository IdentityUserRepository { get; }
+ protected IIdentityRoleRepository IdentityRoleRepository { get; }
- public UserRoleFinder(IIdentityUserRepository identityUserRepository)
+ public UserRoleFinder(IIdentityUserRepository identityUserRepository, IIdentityRoleRepository identityRoleRepository)
{
IdentityUserRepository = identityUserRepository;
+ IdentityRoleRepository = identityRoleRepository;
}
[Obsolete("Use GetRoleNamesAsync instead.")]
@@ -19,8 +24,62 @@ public class UserRoleFinder : IUserRoleFinder, ITransientDependency
return (await IdentityUserRepository.GetRoleNamesAsync(userId)).ToArray();
}
- public async Task GetRoleNamesAsync(Guid userId)
+ public virtual async Task GetRoleNamesAsync(Guid userId)
{
return (await IdentityUserRepository.GetRoleNamesAsync(userId)).ToArray();
}
+
+ public virtual async Task> SearchUserAsync(string filter, int page = 1)
+ {
+ using (IdentityUserRepository.DisableTracking())
+ {
+ page = page < 1 ? 1 : page;
+ var users = await IdentityUserRepository.GetListAsync(filter: filter, skipCount: (page - 1) * 10, maxResultCount: 10);
+ return users.Select(user => new UserFinderResult
+ {
+ Id = user.Id,
+ UserName = user.UserName
+ }).ToList();
+ }
+ }
+
+ public virtual async Task> SearchRoleAsync(string filter, int page = 1)
+ {
+ using (IdentityUserRepository.DisableTracking())
+ {
+ page = page < 1 ? 1 : page;
+ var roles = await IdentityRoleRepository.GetListAsync(filter: filter, skipCount: (page - 1) * 10, maxResultCount: 10);
+ return roles.Select(user => new RoleFinderResult
+ {
+ Id = user.Id,
+ RoleName = user.Name
+ }).ToList();
+ }
+ }
+
+ public virtual async Task> SearchUserByIdsAsync(Guid[] ids)
+ {
+ using (IdentityUserRepository.DisableTracking())
+ {
+ var users = await IdentityUserRepository.GetListByIdsAsync(ids);
+ return users.Select(user => new UserFinderResult
+ {
+ Id = user.Id,
+ UserName = user.UserName
+ }).ToList();
+ }
+ }
+
+ public virtual async Task> SearchRoleByNamesAsync(string[] names)
+ {
+ using (IdentityUserRepository.DisableTracking())
+ {
+ var roles = await IdentityRoleRepository.GetListAsync(names);
+ return roles.Select(user => new RoleFinderResult
+ {
+ Id = user.Id,
+ RoleName = user.Name
+ }).ToList();
+ }
+ }
}
diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs
index ca6dc42d6f..1da7758f19 100644
--- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs
+++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs
@@ -72,6 +72,13 @@ public class EfCoreIdentityRoleRepository : EfCoreRepository> GetListAsync(IEnumerable names, CancellationToken cancellationToken = default)
+ {
+ return await (await GetDbSetAsync())
+ .Where(t => names.Contains(t.Name))
+ .ToListAsync(GetCancellationToken(cancellationToken));
+ }
+
public virtual async Task> GetDefaultOnesAsync(
bool includeDetails = false, CancellationToken cancellationToken = default)
{
diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs
index 25646ac90a..68c05738db 100644
--- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs
+++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs
@@ -94,6 +94,15 @@ public class EfCoreIdentityUserRepository : EfCoreRepository x.Id).Select(x => new IdentityUserIdWithRoleNames { Id = x.Key, RoleNames = x.SelectMany(y => y.RoleNames).Distinct().ToArray() }).ToList();
}
+ public virtual async Task FindByPasskeyIdAsync(byte[] credentialId, bool includeDetails = true, CancellationToken cancellationToken = default)
+ {
+ return await (await GetDbSetAsync())
+ .IncludeDetails(includeDetails)
+ .Where(u => u.Passkeys.Any(x => x.CredentialId.SequenceEqual(credentialId)))
+ .OrderBy(x => x.Id)
+ .FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
+ }
+
public virtual async Task> GetRoleNamesInOrganizationUnitAsync(
Guid id,
CancellationToken cancellationToken = default)
@@ -468,11 +477,11 @@ public class EfCoreIdentityUserRepository : EfCoreRepository x.Id == id);
- }
+ }
if (roleId.HasValue)
{
diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs
index 1b396754a8..2b302e4cf8 100644
--- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs
+++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityDbContextModelBuilderExtensions.cs
@@ -47,6 +47,7 @@ public static class IdentityDbContextModelBuilderExtensions
b.HasMany(u => u.Tokens).WithOne().HasForeignKey(ur => ur.UserId).IsRequired();
b.HasMany(u => u.OrganizationUnits).WithOne().HasForeignKey(ur => ur.UserId).IsRequired();
b.HasMany(u => u.PasswordHistories).WithOne().HasForeignKey(ur => ur.UserId).IsRequired();
+ b.HasMany(u => u.Passkeys).WithOne().HasForeignKey(ur => ur.UserId).IsRequired();
b.HasIndex(u => u.NormalizedUserName);
b.HasIndex(u => u.NormalizedEmail);
@@ -176,6 +177,20 @@ public static class IdentityDbContextModelBuilderExtensions
});
}
+ builder.Entity(b =>
+ {
+ b.ToTable(AbpIdentityDbProperties.DbTablePrefix + "UserPasskeys", AbpIdentityDbProperties.DbSchema);
+
+ b.ConfigureByConvention();
+
+ b.HasKey(p => p.CredentialId);
+
+ b.Property(p => p.CredentialId).HasMaxLength(IdentityUserPasskeyConsts.MaxCredentialIdLength); // Defined in WebAuthn spec to be no longer than 1023 bytes
+ b.OwnsOne(p => p.Data).ToJson();
+
+ b.ApplyObjectExtensionMappings();
+ });
+
builder.Entity(b =>
{
b.ToTable(AbpIdentityDbProperties.DbTablePrefix + "OrganizationUnits", AbpIdentityDbProperties.DbSchema);
diff --git a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityEfCoreQueryableExtensions.cs b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityEfCoreQueryableExtensions.cs
index 0d51910e97..b5ce878a4f 100644
--- a/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityEfCoreQueryableExtensions.cs
+++ b/modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/IdentityEfCoreQueryableExtensions.cs
@@ -18,7 +18,8 @@ public static class IdentityEfCoreQueryableExtensions
.Include(x => x.Claims)
.Include(x => x.Tokens)
.Include(x => x.OrganizationUnits)
- .Include(x => x.PasswordHistories);
+ .Include(x => x.PasswordHistories)
+ .Include(x => x.Passkeys);
}
public static IQueryable IncludeDetails(this IQueryable queryable, bool include = true)
diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/Integration/IdentityUserIntegrationClientProxy.Generated.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/Integration/IdentityUserIntegrationClientProxy.Generated.cs
index 1c2f1b61cb..ddbb2cfc55 100644
--- a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/Integration/IdentityUserIntegrationClientProxy.Generated.cs
+++ b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/Volo/Abp/Identity/Integration/IdentityUserIntegrationClientProxy.Generated.cs
@@ -52,6 +52,14 @@ public partial class IdentityUserIntegrationClientProxy : ClientProxyBase> SearchByIdsAsync(Guid[] ids)
+ {
+ return await RequestAsync>(nameof(SearchByIdsAsync), new ClientProxyRequestTypeValue
+ {
+ { typeof(Guid[]), ids }
+ });
+ }
+
public virtual async Task GetCountAsync(UserLookupCountInputDto input)
{
return await RequestAsync(nameof(GetCountAsync), new ClientProxyRequestTypeValue
@@ -59,4 +67,28 @@ public partial class IdentityUserIntegrationClientProxy : ClientProxyBase> SearchRoleAsync(RoleLookupSearchInputDto input)
+ {
+ return await RequestAsync>(nameof(SearchRoleAsync), new ClientProxyRequestTypeValue
+ {
+ { typeof(RoleLookupSearchInputDto), input }
+ });
+ }
+
+ public virtual async Task> SearchRoleByNamesAsync(String[] names)
+ {
+ return await RequestAsync>(nameof(SearchRoleByNamesAsync), new ClientProxyRequestTypeValue
+ {
+ { typeof(String[]), names }
+ });
+ }
+
+ public virtual async Task GetRoleCountAsync(RoleLookupCountInputDto input)
+ {
+ return await RequestAsync(nameof(GetRoleCountAsync), new ClientProxyRequestTypeValue
+ {
+ { typeof(RoleLookupCountInputDto), input }
+ });
+ }
}
diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/identity-generate-proxy.json b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/identity-generate-proxy.json
index 33efd0a6e7..3937d99aa9 100644
--- a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/identity-generate-proxy.json
+++ b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/ClientProxies/identity-generate-proxy.json
@@ -200,6 +200,18 @@
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
+ },
+ {
+ "nameOnMethod": "input",
+ "name": "ExtraProperties",
+ "jsonName": null,
+ "type": "Volo.Abp.Data.ExtraPropertyDictionary",
+ "typeSimple": "{string:object}",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": null,
+ "bindingSourceId": "ModelBinding",
+ "descriptorName": "input"
}
],
"returnValue": {
@@ -673,6 +685,18 @@
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
+ },
+ {
+ "nameOnMethod": "input",
+ "name": "ExtraProperties",
+ "jsonName": null,
+ "type": "Volo.Abp.Data.ExtraPropertyDictionary",
+ "typeSimple": "{string:object}",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": null,
+ "bindingSourceId": "ModelBinding",
+ "descriptorName": "input"
}
],
"returnValue": {
@@ -1220,6 +1244,18 @@
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
+ },
+ {
+ "nameOnMethod": "input",
+ "name": "ExtraProperties",
+ "jsonName": null,
+ "type": "Volo.Abp.Data.ExtraPropertyDictionary",
+ "typeSimple": "{string:object}",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": null,
+ "bindingSourceId": "ModelBinding",
+ "descriptorName": "input"
}
],
"returnValue": {
@@ -1348,6 +1384,23 @@
"typeSimple": "Volo.Abp.Application.Dtos.ListResultDto"
}
},
+ {
+ "name": "SearchByIdsAsync",
+ "parametersOnMethod": [
+ {
+ "name": "ids",
+ "typeAsString": "System.Guid[], System.Private.CoreLib",
+ "type": "System.Guid[]",
+ "typeSimple": "[string]",
+ "isOptional": false,
+ "defaultValue": null
+ }
+ ],
+ "returnValue": {
+ "type": "Volo.Abp.Application.Dtos.ListResultDto",
+ "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto"
+ }
+ },
{
"name": "GetCountAsync",
"parametersOnMethod": [
@@ -1364,6 +1417,57 @@
"type": "System.Int64",
"typeSimple": "number"
}
+ },
+ {
+ "name": "SearchRoleAsync",
+ "parametersOnMethod": [
+ {
+ "name": "input",
+ "typeAsString": "Volo.Abp.Identity.RoleLookupSearchInputDto, Volo.Abp.Identity.Application.Contracts",
+ "type": "Volo.Abp.Identity.RoleLookupSearchInputDto",
+ "typeSimple": "Volo.Abp.Identity.RoleLookupSearchInputDto",
+ "isOptional": false,
+ "defaultValue": null
+ }
+ ],
+ "returnValue": {
+ "type": "Volo.Abp.Application.Dtos.ListResultDto",
+ "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto"
+ }
+ },
+ {
+ "name": "SearchRoleByNamesAsync",
+ "parametersOnMethod": [
+ {
+ "name": "ids",
+ "typeAsString": "System.String[], System.Private.CoreLib",
+ "type": "System.String[]",
+ "typeSimple": "[string]",
+ "isOptional": false,
+ "defaultValue": null
+ }
+ ],
+ "returnValue": {
+ "type": "Volo.Abp.Application.Dtos.ListResultDto",
+ "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto"
+ }
+ },
+ {
+ "name": "GetRoleCountAsync",
+ "parametersOnMethod": [
+ {
+ "name": "input",
+ "typeAsString": "Volo.Abp.Identity.RoleLookupCountInputDto, Volo.Abp.Identity.Application.Contracts",
+ "type": "Volo.Abp.Identity.RoleLookupCountInputDto",
+ "typeSimple": "Volo.Abp.Identity.RoleLookupCountInputDto",
+ "isOptional": false,
+ "defaultValue": null
+ }
+ ],
+ "returnValue": {
+ "type": "System.Int64",
+ "typeSimple": "number"
+ }
}
]
}
@@ -1544,6 +1648,55 @@
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
+ },
+ {
+ "nameOnMethod": "input",
+ "name": "ExtraProperties",
+ "jsonName": null,
+ "type": "Volo.Abp.Data.ExtraPropertyDictionary",
+ "typeSimple": "{string:object}",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": null,
+ "bindingSourceId": "ModelBinding",
+ "descriptorName": "input"
+ }
+ ],
+ "returnValue": {
+ "type": "Volo.Abp.Application.Dtos.ListResultDto",
+ "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto"
+ },
+ "allowAnonymous": null,
+ "implementFrom": "Volo.Abp.Identity.Integration.IIdentityUserIntegrationService"
+ },
+ "SearchByIdsAsyncByIds": {
+ "uniqueName": "SearchByIdsAsyncByIds",
+ "name": "SearchByIdsAsync",
+ "httpMethod": "GET",
+ "url": "integration-api/identity/users/search/by-ids",
+ "supportedVersions": [],
+ "parametersOnMethod": [
+ {
+ "name": "ids",
+ "typeAsString": "System.Guid[], System.Private.CoreLib",
+ "type": "System.Guid[]",
+ "typeSimple": "[string]",
+ "isOptional": false,
+ "defaultValue": null
+ }
+ ],
+ "parameters": [
+ {
+ "nameOnMethod": "ids",
+ "name": "ids",
+ "jsonName": null,
+ "type": "System.Guid[]",
+ "typeSimple": "[string]",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": null,
+ "bindingSourceId": "ModelBinding",
+ "descriptorName": ""
}
],
"returnValue": {
@@ -1589,6 +1742,165 @@
},
"allowAnonymous": null,
"implementFrom": "Volo.Abp.Identity.Integration.IIdentityUserIntegrationService"
+ },
+ "SearchRoleAsyncByInput": {
+ "uniqueName": "SearchRoleAsyncByInput",
+ "name": "SearchRoleAsync",
+ "httpMethod": "GET",
+ "url": "integration-api/identity/users/search/roles",
+ "supportedVersions": [],
+ "parametersOnMethod": [
+ {
+ "name": "input",
+ "typeAsString": "Volo.Abp.Identity.RoleLookupSearchInputDto, Volo.Abp.Identity.Application.Contracts",
+ "type": "Volo.Abp.Identity.RoleLookupSearchInputDto",
+ "typeSimple": "Volo.Abp.Identity.RoleLookupSearchInputDto",
+ "isOptional": false,
+ "defaultValue": null
+ }
+ ],
+ "parameters": [
+ {
+ "nameOnMethod": "input",
+ "name": "Filter",
+ "jsonName": null,
+ "type": "System.String",
+ "typeSimple": "string",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": null,
+ "bindingSourceId": "ModelBinding",
+ "descriptorName": "input"
+ },
+ {
+ "nameOnMethod": "input",
+ "name": "Sorting",
+ "jsonName": null,
+ "type": "System.String",
+ "typeSimple": "string",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": null,
+ "bindingSourceId": "ModelBinding",
+ "descriptorName": "input"
+ },
+ {
+ "nameOnMethod": "input",
+ "name": "SkipCount",
+ "jsonName": null,
+ "type": "System.Int32",
+ "typeSimple": "number",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": null,
+ "bindingSourceId": "ModelBinding",
+ "descriptorName": "input"
+ },
+ {
+ "nameOnMethod": "input",
+ "name": "MaxResultCount",
+ "jsonName": null,
+ "type": "System.Int32",
+ "typeSimple": "number",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": null,
+ "bindingSourceId": "ModelBinding",
+ "descriptorName": "input"
+ },
+ {
+ "nameOnMethod": "input",
+ "name": "ExtraProperties",
+ "jsonName": null,
+ "type": "Volo.Abp.Data.ExtraPropertyDictionary",
+ "typeSimple": "{string:object}",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": null,
+ "bindingSourceId": "ModelBinding",
+ "descriptorName": "input"
+ }
+ ],
+ "returnValue": {
+ "type": "Volo.Abp.Application.Dtos.ListResultDto",
+ "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto"
+ },
+ "allowAnonymous": null,
+ "implementFrom": "Volo.Abp.Identity.Integration.IIdentityUserIntegrationService"
+ },
+ "SearchRoleByNamesAsyncByNames": {
+ "uniqueName": "SearchRoleByNamesAsyncByNames",
+ "name": "SearchRoleByNamesAsync",
+ "httpMethod": "GET",
+ "url": "integration-api/identity/users/search/roles/by-names",
+ "supportedVersions": [],
+ "parametersOnMethod": [
+ {
+ "name": "names",
+ "typeAsString": "System.String[], System.Private.CoreLib",
+ "type": "System.String[]",
+ "typeSimple": "[string]",
+ "isOptional": false,
+ "defaultValue": null
+ }
+ ],
+ "parameters": [
+ {
+ "nameOnMethod": "names",
+ "name": "names",
+ "jsonName": null,
+ "type": "System.String[]",
+ "typeSimple": "[string]",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": null,
+ "bindingSourceId": "ModelBinding",
+ "descriptorName": ""
+ }
+ ],
+ "returnValue": {
+ "type": "Volo.Abp.Application.Dtos.ListResultDto",
+ "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto"
+ },
+ "allowAnonymous": null,
+ "implementFrom": "Volo.Abp.Identity.Integration.IIdentityUserIntegrationService"
+ },
+ "GetRoleCountAsyncByInput": {
+ "uniqueName": "GetRoleCountAsyncByInput",
+ "name": "GetRoleCountAsync",
+ "httpMethod": "GET",
+ "url": "integration-api/identity/users/count/roles",
+ "supportedVersions": [],
+ "parametersOnMethod": [
+ {
+ "name": "input",
+ "typeAsString": "Volo.Abp.Identity.RoleLookupCountInputDto, Volo.Abp.Identity.Application.Contracts",
+ "type": "Volo.Abp.Identity.RoleLookupCountInputDto",
+ "typeSimple": "Volo.Abp.Identity.RoleLookupCountInputDto",
+ "isOptional": false,
+ "defaultValue": null
+ }
+ ],
+ "parameters": [
+ {
+ "nameOnMethod": "input",
+ "name": "Filter",
+ "jsonName": null,
+ "type": "System.String",
+ "typeSimple": "string",
+ "isOptional": false,
+ "defaultValue": null,
+ "constraintTypes": null,
+ "bindingSourceId": "ModelBinding",
+ "descriptorName": "input"
+ }
+ ],
+ "returnValue": {
+ "type": "System.Int64",
+ "typeSimple": "number"
+ },
+ "allowAnonymous": null,
+ "implementFrom": "Volo.Abp.Identity.Integration.IIdentityUserIntegrationService"
}
}
}
diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/Volo/Abp/Identity/HttpClientUserRoleFinder.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/Volo/Abp/Identity/HttpClientUserRoleFinder.cs
index 201c9f3eb0..ed7f0f5382 100644
--- a/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/Volo/Abp/Identity/HttpClientUserRoleFinder.cs
+++ b/modules/identity/src/Volo.Abp.Identity.HttpApi.Client/Volo/Abp/Identity/HttpClientUserRoleFinder.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
@@ -25,8 +26,59 @@ public class HttpClientUserRoleFinder : IUserRoleFinder, ITransientDependency
return output.Items.Select(r => r.Name).ToArray();
}
- public async Task GetRoleNamesAsync(Guid userId)
+ public virtual async Task GetRoleNamesAsync(Guid userId)
{
return await _userIntegrationService.GetRoleNamesAsync(userId);
}
+
+ public virtual async Task> SearchUserAsync(string filter, int page = 1)
+ {
+ page = page < 1 ? 1 : page;
+ var users = await _userIntegrationService.SearchAsync(new UserLookupSearchInputDto()
+ {
+ Filter = filter,
+ SkipCount = (page - 1) * 10
+ });
+ return users.Items.Select(u => new UserFinderResult
+ {
+ Id = u.Id,
+ UserName = u.UserName
+ }).ToList();
+ }
+
+ public virtual async Task> SearchRoleAsync(string filter, int page = 1)
+ {
+ page = page < 1 ? 1 : page;
+ var roles = await _userIntegrationService.SearchRoleAsync(new RoleLookupSearchInputDto()
+ {
+ Filter = filter,
+ SkipCount = (page - 1) * 10
+ });
+
+ return roles.Items.Select(r => new RoleFinderResult
+ {
+ Id = r.Id,
+ RoleName = r.Name
+ }).ToList();
+ }
+
+ public virtual async Task> SearchUserByIdsAsync(Guid[] ids)
+ {
+ var users = await _userIntegrationService.SearchByIdsAsync(ids);
+ return users.Items.Select(u => new UserFinderResult
+ {
+ Id = u.Id,
+ UserName = u.UserName
+ }).ToList();
+ }
+
+ public virtual async Task> SearchRoleByNamesAsync(string[] names)
+ {
+ var roles = await _userIntegrationService.SearchRoleByNamesAsync(names);
+ return roles.Items.Select(r => new RoleFinderResult
+ {
+ Id = r.Id,
+ RoleName = r.Name
+ }).ToList();
+ }
}
diff --git a/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/Integration/IdentityUserIntegrationController.cs b/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/Integration/IdentityUserIntegrationController.cs
index 2a84385e48..a30b73d5cd 100644
--- a/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/Integration/IdentityUserIntegrationController.cs
+++ b/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/Integration/IdentityUserIntegrationController.cs
@@ -20,7 +20,7 @@ public class IdentityUserIntegrationController : AbpControllerBase, IIdentityUse
{
UserIntegrationService = userIntegrationService;
}
-
+
[HttpGet]
[Route("{id}/role-names")]
public virtual Task GetRoleNamesAsync(Guid id)
@@ -49,10 +49,38 @@ public class IdentityUserIntegrationController : AbpControllerBase, IIdentityUse
return UserIntegrationService.SearchAsync(input);
}
+ [HttpGet]
+ [Route("search/by-ids")]
+ public virtual Task> SearchByIdsAsync(Guid[] ids)
+ {
+ return UserIntegrationService.SearchByIdsAsync(ids);
+ }
+
[HttpGet]
[Route("count")]
public Task GetCountAsync(UserLookupCountInputDto input)
{
return UserIntegrationService.GetCountAsync(input);
}
-}
\ No newline at end of file
+
+ [HttpGet]
+ [Route("search/roles")]
+ public virtual Task> SearchRoleAsync(RoleLookupSearchInputDto input)
+ {
+ return UserIntegrationService.SearchRoleAsync(input);
+ }
+
+ [HttpGet]
+ [Route("search/roles/by-names")]
+ public virtual Task> SearchRoleByNamesAsync(string[] names)
+ {
+ return UserIntegrationService.SearchRoleByNamesAsync(names);
+ }
+
+ [HttpGet]
+ [Route("count/roles")]
+ public virtual Task GetRoleCountAsync(RoleLookupCountInputDto input)
+ {
+ return UserIntegrationService.GetRoleCountAsync(input);
+ }
+}
diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs
index 7deee94160..f613a3ee88 100644
--- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs
+++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs
@@ -78,6 +78,13 @@ public class MongoIdentityRoleRepository : MongoDbRepository> GetListAsync(IEnumerable names, CancellationToken cancellationToken = default)
+ {
+ return await (await GetQueryableAsync(cancellationToken))
+ .Where(x => names.Contains(x.Name))
+ .ToListAsync(GetCancellationToken(cancellationToken));
+ }
+
public virtual async Task> GetDefaultOnesAsync(
bool includeDetails = false,
CancellationToken cancellationToken = default)
diff --git a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs
index 29b9817e05..2a8654cd3b 100644
--- a/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs
+++ b/modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs
@@ -443,6 +443,14 @@ public class MongoIdentityUserRepository : MongoDbRepository FindByPasskeyIdAsync(byte[] credentialId, bool includeDetails = true, CancellationToken cancellationToken = default)
+ {
+ return await (await GetQueryableAsync(cancellationToken))
+ .Where(u => u.Passkeys.Any(x => x.CredentialId == credentialId))
+ .OrderBy(x => x.Id)
+ .FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
+ }
+
protected virtual async Task> GetFilteredQueryableAsync(
string filter = null,
Guid? roleId = null,
diff --git a/modules/identity/src/Volo.Abp.Identity.Web/wwwroot/client-proxies/identity-proxy.js b/modules/identity/src/Volo.Abp.Identity.Web/wwwroot/client-proxies/identity-proxy.js
index 250abbc47b..6de3aeb8d5 100644
--- a/modules/identity/src/Volo.Abp.Identity.Web/wwwroot/client-proxies/identity-proxy.js
+++ b/modules/identity/src/Volo.Abp.Identity.Web/wwwroot/client-proxies/identity-proxy.js
@@ -20,7 +20,7 @@
volo.abp.identity.identityRole.getList = function(input, ajaxParams) {
return abp.ajax($.extend(true, {
- url: abp.appPath + 'api/identity/roles' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }]) + '',
+ url: abp.appPath + 'api/identity/roles' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }, { name: 'extraProperties', value: input.extraProperties }]) + '',
type: 'GET'
}, ajaxParams));
};
@@ -73,7 +73,7 @@
volo.abp.identity.identityUser.getList = function(input, ajaxParams) {
return abp.ajax($.extend(true, {
- url: abp.appPath + 'api/identity/users' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }]) + '',
+ url: abp.appPath + 'api/identity/users' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }, { name: 'extraProperties', value: input.extraProperties }]) + '',
type: 'GET'
}, ajaxParams));
};
@@ -163,7 +163,7 @@
volo.abp.identity.identityUserLookup.search = function(input, ajaxParams) {
return abp.ajax($.extend(true, {
- url: abp.appPath + 'api/identity/users/lookup/search' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }]) + '',
+ url: abp.appPath + 'api/identity/users/lookup/search' + abp.utils.buildQueryString([{ name: 'filter', value: input.filter }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }, { name: 'extraProperties', value: input.extraProperties }]) + '',
type: 'GET'
}, ajaxParams));
};
diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/AbpPermissionManagementDomainIdentityModule.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/AbpPermissionManagementDomainIdentityModule.cs
index 973577ccff..43399a134d 100644
--- a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/AbpPermissionManagementDomainIdentityModule.cs
+++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/AbpPermissionManagementDomainIdentityModule.cs
@@ -1,4 +1,5 @@
using Volo.Abp.Authorization.Permissions;
+using Volo.Abp.Authorization.Permissions.Resources;
using Volo.Abp.Identity;
using Volo.Abp.Modularity;
using Volo.Abp.Users;
@@ -22,6 +23,12 @@ public class AbpPermissionManagementDomainIdentityModule : AbpModule
//TODO: Can we prevent duplication of permission names without breaking the design and making the system complicated
options.ProviderPolicies[UserPermissionValueProvider.ProviderName] = "AbpIdentity.Users.ManagePermissions";
options.ProviderPolicies[RolePermissionValueProvider.ProviderName] = "AbpIdentity.Roles.ManagePermissions";
+
+ options.ResourceManagementProviders.Add();
+ options.ResourceManagementProviders.Add();
+
+ options.ResourcePermissionProviderKeyLookupServices.Add();
+ options.ResourcePermissionProviderKeyLookupServices.Add();
});
}
}
diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleDeletedEventHandler.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleDeletedEventHandler.cs
index cb63b2681a..82200f763f 100644
--- a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleDeletedEventHandler.cs
+++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleDeletedEventHandler.cs
@@ -1,5 +1,6 @@
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
+using Volo.Abp.Authorization.Permissions.Resources;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.EventBus;
@@ -14,15 +15,18 @@ public class RoleDeletedEventHandler :
ITransientDependency
{
protected IPermissionManager PermissionManager { get; }
+ protected IResourcePermissionManager ResourcePermissionManager { get; }
- public RoleDeletedEventHandler(IPermissionManager permissionManager)
+ public RoleDeletedEventHandler(IPermissionManager permissionManager, IResourcePermissionManager resourcePermissionManager)
{
PermissionManager = permissionManager;
+ ResourcePermissionManager = resourcePermissionManager;
}
[UnitOfWork]
public virtual async Task HandleEventAsync(EntityDeletedEto eventData)
{
await PermissionManager.DeleteAsync(RolePermissionValueProvider.ProviderName, eventData.Entity.Name);
+ await ResourcePermissionManager.DeleteAsync(RoleResourcePermissionValueProvider.ProviderName, eventData.Entity.Name);
}
}
diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RolePermissionManagementProvider.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RolePermissionManagementProvider.cs
index e97d524cd7..5cd2dda193 100644
--- a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RolePermissionManagementProvider.cs
+++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RolePermissionManagementProvider.cs
@@ -49,9 +49,8 @@ public class RolePermissionManagementProvider : PermissionManagementProvider
}
- if (providerName == UserPermissionValueProvider.ProviderName)
+ if (providerName == UserPermissionValueProvider.ProviderName && Guid.TryParse(providerKey, out var userId))
{
- var userId = Guid.Parse(providerKey);
var roleNames = await UserRoleFinder.GetRoleNamesAsync(userId);
foreach (var roleName in roleNames)
diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleResourcePermissionManagementProvider.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleResourcePermissionManagementProvider.cs
new file mode 100644
index 0000000000..bce070130c
--- /dev/null
+++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleResourcePermissionManagementProvider.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp.Authorization.Permissions.Resources;
+using Volo.Abp.Domain.Repositories;
+using Volo.Abp.Guids;
+using Volo.Abp.Identity;
+using Volo.Abp.MultiTenancy;
+
+namespace Volo.Abp.PermissionManagement.Identity;
+
+public class RoleResourcePermissionManagementProvider : ResourcePermissionManagementProvider
+{
+ public override string Name => RoleResourcePermissionValueProvider.ProviderName;
+
+ protected IUserRoleFinder UserRoleFinder { get; }
+
+ public RoleResourcePermissionManagementProvider(
+ IResourcePermissionGrantRepository resourcepPrmissionGrantRepository,
+ IGuidGenerator guidGenerator,
+ ICurrentTenant currentTenant,
+ IUserRoleFinder userRoleFinder)
+ : base(
+ resourcepPrmissionGrantRepository,
+ guidGenerator,
+ currentTenant)
+ {
+ UserRoleFinder = userRoleFinder;
+ }
+
+ public override async Task CheckAsync(string name, string resourceName, string resourceKey, string providerName, string providerKey)
+ {
+ var multipleGrantInfo = await CheckAsync(new[] { name }, resourceName, resourceKey, providerName, providerKey);
+
+ return multipleGrantInfo.Result.Values.First();
+ }
+
+ public override async Task CheckAsync(string[] names, string resourceName, string resourceKey, string providerName, string providerKey)
+ {
+ using (ResourcePermissionGrantRepository.DisableTracking())
+ {
+ var multiplePermissionValueProviderGrantInfo = new MultipleResourcePermissionValueProviderGrantInfo(names);
+ var resourcePermissionGrants = new List();
+
+ if (providerName == Name)
+ {
+ resourcePermissionGrants.AddRange(await ResourcePermissionGrantRepository.GetListAsync(names, resourceName, resourceKey, providerName, providerKey));
+ }
+
+ if (providerName == UserResourcePermissionValueProvider.ProviderName && Guid.TryParse(providerKey, out var userId))
+ {
+ var roleNames = await UserRoleFinder.GetRoleNamesAsync(userId);
+
+ foreach (var roleName in roleNames)
+ {
+ resourcePermissionGrants.AddRange(await ResourcePermissionGrantRepository.GetListAsync(names, resourceName, resourceKey, Name, roleName));
+ }
+ }
+
+ resourcePermissionGrants = resourcePermissionGrants.Distinct().ToList();
+ if (!resourcePermissionGrants.Any())
+ {
+ return multiplePermissionValueProviderGrantInfo;
+ }
+
+ foreach (var permissionName in names)
+ {
+ var resourcePermissionGrant = resourcePermissionGrants.FirstOrDefault(x => x.Name == permissionName);
+ if (resourcePermissionGrant != null)
+ {
+ multiplePermissionValueProviderGrantInfo.Result[permissionName] = new ResourcePermissionValueProviderGrantInfo(true, resourcePermissionGrant.ProviderKey);
+ }
+ }
+
+ return multiplePermissionValueProviderGrantInfo;
+ }
+ }
+}
diff --git a/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleResourcePermissionProviderKeyLookupService.cs b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleResourcePermissionProviderKeyLookupService.cs
new file mode 100644
index 0000000000..fa9fc31f79
--- /dev/null
+++ b/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleResourcePermissionProviderKeyLookupService.cs
@@ -0,0 +1,38 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Volo.Abp.Authorization.Permissions.Resources;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Identity;
+using Volo.Abp.Identity.Localization;
+using Volo.Abp.Localization;
+
+namespace Volo.Abp.PermissionManagement.Identity;
+
+public class RoleResourcePermissionProviderKeyLookupService : IResourcePermissionProviderKeyLookupService, ITransientDependency
+{
+ public string Name => RoleResourcePermissionValueProvider.ProviderName;
+
+ public ILocalizableString DisplayName { get; }
+
+ protected IUserRoleFinder UserRoleFinder { get; }
+
+ public RoleResourcePermissionProviderKeyLookupService(IUserRoleFinder userRoleFinder)
+ {
+ UserRoleFinder = userRoleFinder;
+ DisplayName = LocalizableString.Create(nameof(RoleResourcePermissionProviderKeyLookupService));
+ }
+
+ public virtual async Task