Browse Source

Merge pull request #17257 from abpframework/auto-merge/rel-7-3/2100

pull/17260/head
maliming 3 years ago
committed by GitHub
parent
commit
ee01afdce8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 27
      docs/en/Modules/Tenant-Management.md
  2. 8
      framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/IAbpMauiAccessTokenProvider.cs
  3. 14
      framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiBlazorAbpAccessTokenProvider.cs
  4. 24
      framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiIBlazorIdentityModelRemoteServiceHttpClientAuthenticator.cs
  5. 13
      framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/NullAbpMauiAccessTokenProvider.cs
  6. 8
      framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/AbpHttpClientIdentityModelWebModule.cs
  7. 29
      framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextAbpAccessTokenProvider.cs
  8. 23
      framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextIdentityModelRemoteServiceHttpClientAuthenticator.cs
  9. 34
      framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs
  10. 34
      framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/WebAssemblyAbpAccessTokenProvider.cs
  11. 8
      framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IAbpAccessTokenProvider.cs
  12. 12
      framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/NullAbpAccessTokenProvider.cs
  13. 3
      modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs
  14. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json
  15. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json
  16. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json
  17. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json
  18. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json
  19. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json
  20. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json
  21. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json
  22. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json
  23. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json
  24. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json
  25. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json
  26. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json
  27. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json
  28. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json
  29. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json
  30. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json
  31. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json
  32. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json
  33. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json
  34. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json
  35. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json
  36. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json
  37. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json
  38. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json
  39. 1
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json
  40. 48
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs
  41. 36
      modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs

27
docs/en/Modules/Tenant-Management.md

@ -48,6 +48,33 @@ The Features action opens a modal to enable/disable/set [features](../Features.m
*Manage Host features* button is used to set features for the host side, if you use the features of your application also in the host side.
## Distributed Events
This module defines the following ETOs (Event Transfer Objects) to allow you to subscribe to changes on the entities of the module;
- `TenantEto` is published on changes done on an `Tenant` entity.
**Example: Get notified when a new tenant has been created**
```
public class MyHandler :
IDistributedEventHandler<EntityCreatedEto<TenantEto>>,
ITransientDependency
{
public async Task HandleEventAsync(EntityCreatedEto<TenantEto> eventData)
{
TenantEto tenant = eventData.Entity;
// TODO: ...
}
}
```
`TenantEto` is configured to automatically publish the events. You should configure yourself for the others. See the [Distributed Event Bus document](https://github.com/abpframework/abp/blob/rel-7.3/docs/en/Distributed-Event-Bus.md) to learn details of the pre-defined events.
> Subscribing to the distributed events is especially useful for distributed scenarios (like microservice architecture). If you are building a monolithic application, or listening events in the same process that runs the Tenant Management Module, then subscribing to the [local events](https://github.com/abpframework/abp/blob/rel-7.3/docs/en/Local-Event-Bus.md) can be more efficient and easier.
## Internals
This section can be used as a reference if you want to [customize](../Customizing-Application-Modules-Guide.md) this module without changing [its source code](https://github.com/abpframework/abp/tree/dev/modules/tenant-management).

8
framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/IAbpMauiAccessTokenProvider.cs

@ -1,8 +0,0 @@
using System.Threading.Tasks;
namespace Volo.Abp.Http.Client.IdentityModel.MauiBlazor;
public interface IAbpMauiAccessTokenProvider
{
Task<string> GetAccessTokenAsync();
}

14
framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiBlazorAbpAccessTokenProvider.cs

@ -0,0 +1,14 @@
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client.Authentication;
namespace Volo.Abp.Http.Client.IdentityModel.MauiBlazor;
[Dependency(ReplaceServices = true)]
public class MauiBlazorAbpAccessTokenProvider : IAbpAccessTokenProvider, ITransientDependency
{
public virtual Task<string> GetTokenAsync()
{
return Task.FromResult(null as string);
}
}

24
framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/MauiIBlazorIdentityModelRemoteServiceHttpClientAuthenticator.cs

@ -1,8 +1,5 @@
using System;
using System.Threading.Tasks;
using System.Threading.Tasks;
using IdentityModel.Client;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client.Authentication;
using Volo.Abp.IdentityModel;
@ -12,22 +9,21 @@ namespace Volo.Abp.Http.Client.IdentityModel.MauiBlazor;
[Dependency(ReplaceServices = true)]
public class MauiBlazorIdentityModelRemoteServiceHttpClientAuthenticator : IdentityModelRemoteServiceHttpClientAuthenticator
{
[CanBeNull]
protected IAbpMauiAccessTokenProvider AbpMauiAccessTokenProvider { get; }
protected IAbpAccessTokenProvider AccessTokenProvider { get; }
public MauiBlazorIdentityModelRemoteServiceHttpClientAuthenticator(
IIdentityModelAuthenticationService identityModelAuthenticationService,
IServiceProvider serviceProvider)
IAbpAccessTokenProvider abpAccessTokenProvider)
: base(identityModelAuthenticationService)
{
AbpMauiAccessTokenProvider = serviceProvider.GetService<IAbpMauiAccessTokenProvider>();
AccessTokenProvider = abpAccessTokenProvider;
}
public async override Task Authenticate(RemoteServiceHttpClientAuthenticateContext context)
{
if (context.RemoteService.GetUseCurrentAccessToken() != false)
{
var accessToken = await GetAccessTokenFromAccessTokenProviderOrNullAsync();
var accessToken = await AccessTokenProvider.GetTokenAsync();
if (accessToken != null)
{
context.Request.SetBearerToken(accessToken);
@ -37,14 +33,4 @@ public class MauiBlazorIdentityModelRemoteServiceHttpClientAuthenticator : Ident
await base.Authenticate(context);
}
protected virtual async Task<string> GetAccessTokenFromAccessTokenProviderOrNullAsync()
{
if (AbpMauiAccessTokenProvider == null)
{
return null;
}
return await AbpMauiAccessTokenProvider.GetAccessTokenAsync();
}
}

13
framework/src/Volo.Abp.Http.Client.IdentityModel.MauiBlazor/Volo/Abp/Http/Client/IdentityModel/MauiBlazor/NullAbpMauiAccessTokenProvider.cs

@ -1,13 +0,0 @@
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Http.Client.IdentityModel.MauiBlazor;
[Dependency(TryRegister = true)]
public class NullAbpMauiAccessTokenProvider : IAbpMauiAccessTokenProvider
{
public Task<string> GetAccessTokenAsync()
{
return Task.FromResult(null as string);
}
}

8
framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/AbpHttpClientIdentityModelWebModule.cs

@ -1,4 +1,5 @@
using Volo.Abp.Modularity;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
namespace Volo.Abp.Http.Client.IdentityModel.Web;
@ -7,5 +8,8 @@ namespace Volo.Abp.Http.Client.IdentityModel.Web;
)]
public class AbpHttpClientIdentityModelWebModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddHttpContextAccessor();
}
}

29
framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextAbpAccessTokenProvider.cs

@ -0,0 +1,29 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client.Authentication;
namespace Volo.Abp.Http.Client.IdentityModel.Web;
[Dependency(ReplaceServices = true)]
public class HttpContextAbpAccessTokenProvider : IAbpAccessTokenProvider, ITransientDependency
{
protected IHttpContextAccessor HttpContextAccessor { get; }
public HttpContextAbpAccessTokenProvider(IHttpContextAccessor httpContextAccessor)
{
HttpContextAccessor = httpContextAccessor;
}
public virtual async Task<string> GetTokenAsync()
{
var httpContext = HttpContextAccessor?.HttpContext;
if (httpContext == null)
{
return null;
}
return await httpContext.GetTokenAsync("access_token");
}
}

23
framework/src/Volo.Abp.Http.Client.IdentityModel.Web/Volo/Abp/Http/Client/IdentityModel/Web/HttpContextIdentityModelRemoteServiceHttpClientAuthenticator.cs

@ -1,7 +1,5 @@
using System.Threading.Tasks;
using IdentityModel.Client;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client.Authentication;
using Volo.Abp.IdentityModel;
@ -11,19 +9,21 @@ namespace Volo.Abp.Http.Client.IdentityModel.Web;
[Dependency(ReplaceServices = true)]
public class HttpContextIdentityModelRemoteServiceHttpClientAuthenticator : IdentityModelRemoteServiceHttpClientAuthenticator
{
public IHttpContextAccessor HttpContextAccessor { get; set; }
protected IAbpAccessTokenProvider AccessTokenProvider { get; }
public HttpContextIdentityModelRemoteServiceHttpClientAuthenticator(
IIdentityModelAuthenticationService identityModelAuthenticationService)
IIdentityModelAuthenticationService identityModelAuthenticationService,
IAbpAccessTokenProvider accessTokenProvider)
: base(identityModelAuthenticationService)
{
AccessTokenProvider = accessTokenProvider;
}
public override async Task Authenticate(RemoteServiceHttpClientAuthenticateContext context)
public async override Task Authenticate(RemoteServiceHttpClientAuthenticateContext context)
{
if (context.RemoteService.GetUseCurrentAccessToken() != false)
{
var accessToken = await GetAccessTokenFromHttpContextOrNullAsync();
var accessToken = await AccessTokenProvider.GetTokenAsync();
if (accessToken != null)
{
context.Request.SetBearerToken(accessToken);
@ -33,15 +33,4 @@ public class HttpContextIdentityModelRemoteServiceHttpClientAuthenticator : Iden
await base.Authenticate(context);
}
protected virtual async Task<string> GetAccessTokenFromHttpContextOrNullAsync()
{
var httpContext = HttpContextAccessor?.HttpContext;
if (httpContext == null)
{
return null;
}
return await httpContext.GetTokenAsync("access_token");
}
}

34
framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator.cs

@ -1,9 +1,5 @@
using System;
using System.Threading.Tasks;
using System.Threading.Tasks;
using IdentityModel.Client;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client.Authentication;
using Volo.Abp.IdentityModel;
@ -14,22 +10,21 @@ namespace Volo.Abp.Http.Client.IdentityModel.WebAssembly;
public class AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator
: IdentityModelRemoteServiceHttpClientAuthenticator
{
[CanBeNull]
protected IAccessTokenProvider AccessTokenProvider { get; }
protected IAbpAccessTokenProvider AccessTokenProvider { get; }
public AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticator(
IIdentityModelAuthenticationService identityModelAuthenticationService,
IServiceProvider serviceProvider)
IAbpAccessTokenProvider accessTokenProvider)
: base(identityModelAuthenticationService)
{
AccessTokenProvider = serviceProvider.GetService<IAccessTokenProvider>();
AccessTokenProvider = accessTokenProvider;
}
public override async Task Authenticate(RemoteServiceHttpClientAuthenticateContext context)
public async override Task Authenticate(RemoteServiceHttpClientAuthenticateContext context)
{
if (context.RemoteService.GetUseCurrentAccessToken() != false)
{
var accessToken = await GetAccessTokenFromAccessTokenProviderOrNullAsync();
var accessToken = await AccessTokenProvider.GetTokenAsync();
if (accessToken != null)
{
context.Request.SetBearerToken(accessToken);
@ -39,21 +34,4 @@ public class AccessTokenProviderIdentityModelRemoteServiceHttpClientAuthenticato
await base.Authenticate(context);
}
protected virtual async Task<string> GetAccessTokenFromAccessTokenProviderOrNullAsync()
{
if (AccessTokenProvider == null)
{
return null;
}
var result = await AccessTokenProvider.RequestAccessToken();
if (result.Status != AccessTokenResultStatus.Success)
{
return null;
}
result.TryGetToken(out var token);
return token.Value;
}
}

34
framework/src/Volo.Abp.Http.Client.IdentityModel.WebAssembly/Volo/Abp/Http/Client/IdentityModel/WebAssembly/WebAssemblyAbpAccessTokenProvider.cs

@ -0,0 +1,34 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client.Authentication;
namespace Volo.Abp.Http.Client.IdentityModel.WebAssembly;
[Dependency(ReplaceServices = true)]
public class WebAssemblyAbpAccessTokenProvider : IAbpAccessTokenProvider, ITransientDependency
{
protected IAccessTokenProvider AccessTokenProvider { get; }
public WebAssemblyAbpAccessTokenProvider(IAccessTokenProvider accessTokenProvider)
{
AccessTokenProvider = accessTokenProvider;
}
public virtual async Task<string> GetTokenAsync()
{
if (AccessTokenProvider == null)
{
return null;
}
var result = await AccessTokenProvider.RequestAccessToken();
if (result.Status != AccessTokenResultStatus.Success)
{
return null;
}
result.TryGetToken(out var token);
return token.Value;
}
}

8
framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/IAbpAccessTokenProvider.cs

@ -0,0 +1,8 @@
using System.Threading.Tasks;
namespace Volo.Abp.Http.Client.Authentication;
public interface IAbpAccessTokenProvider
{
Task<string> GetTokenAsync();
}

12
framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/Authentication/NullAbpAccessTokenProvider.cs

@ -0,0 +1,12 @@
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Http.Client.Authentication;
public class NullAbpAccessTokenProvider : IAbpAccessTokenProvider, ITransientDependency
{
public Task<string> GetTokenAsync()
{
return Task.FromResult(null as string);
}
}

3
modules/identity/src/Volo.Abp.Identity.AspNetCore/Volo/Abp/Identity/AspNetCore/AbpIdentityAspNetCoreModule.cs

@ -16,7 +16,8 @@ public class AbpIdentityAspNetCoreModule : AbpModule
builder
.AddDefaultTokenProviders()
.AddTokenProvider<LinkUserTokenProvider>(LinkUserTokenProviderConsts.LinkUserTokenProviderName)
.AddSignInManager<AbpSignInManager>();
.AddSignInManager<AbpSignInManager>()
.AddUserValidator<AbpIdentityUserValidator>();
});
}

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ar.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "اسم الدور '{0}' غير صالح.",
"Volo.Abp.Identity:InvalidToken": "غير صالح token.",
"Volo.Abp.Identity:InvalidUserName": "اسم المستخدم '{0}' غير صالح ، يمكن أن يحتوي على أحرف أو أرقام فقط.",
"InvalidUserName": "لااسم المستخدم '{0}' غير صالح .",
"Volo.Abp.Identity:LoginAlreadyAssociated": "يوجد مستخدم لديه معلومات تسجيل الدخول هذه بالفعل.",
"Volo.Abp.Identity:PasswordMismatch": "كلمة مرور غير صحيحة.",
"Volo.Abp.Identity:PasswordRequiresDigit": "يجب أن تحتوي كلمات المرور على رقم واحد على الأقل ('0' - '9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/cs.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "Role '{0}' je neplatná.",
"Volo.Abp.Identity:InvalidToken": "Neplatný token.",
"Volo.Abp.Identity:InvalidUserName": "Uživatelské jméno '{0}' je neplatné, může obsahovat pouze písmena a číslice.",
"InvalidUserName": "Uživatelské jméno '{0}' je neplatné.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Uživatel s tímto přihlášením již existuje.",
"Volo.Abp.Identity:PasswordMismatch": "Chybné heslo.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Hesla musí obsahovat alespoň jednu číslici ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/de.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "Der Rollenname '{0}' ist ungültig.",
"Volo.Abp.Identity:InvalidToken": "Ungültiger Token.",
"Volo.Abp.Identity:InvalidUserName": "Der Benutzername '{0}' ist ungültig und darf nur Buchstaben oder Ziffern enthalten.",
"InvalidUserName": "Der Benutzername '{0}' ist ungültig.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Ein Benutzer mit diesem Login existiert bereits.",
"Volo.Abp.Identity:PasswordMismatch": "Falsches Passwort.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Passwörter müssen mindestens eine Ziffer haben ('0' - '9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/el.json

@ -47,6 +47,7 @@
"Volo.Abp.Identity:InvalidRoleName": "Το όνομα ρόλου '{0}' δεν είναι έγκυρο.",
"Volo.Abp.Identity:InvalidToken": "Μη έγκυρο διακριτικό.",
"Volo.Abp.Identity:InvalidUserName": "Το όνομα χρήστη '{0}' δεν είναι έγκυρο, μπορεί να περιέχει μόνο γράμματα ή ψηφία.",
"InvalidUserName": "Το όνομα χρήστη '{0}' δεν είναι έγκυρο.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Ένας χρήστης με αυτήν τη σύνδεση υπάρχει ήδη.",
"Volo.Abp.Identity:PasswordMismatch": "Λάθος κωδικός.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Οι κωδικοί πρόσβασης πρέπει να έχουν τουλάχιστον ένα ψηφίο ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en-GB.json

@ -47,6 +47,7 @@
"Volo.Abp.Identity:InvalidRoleName": "Role name '{0}' is invalid.",
"Volo.Abp.Identity:InvalidToken": "Invalid token.",
"Volo.Abp.Identity:InvalidUserName": "Username '{0}' is invalid, it should only contain letters or digits.",
"InvalidUserName": "Username '{0}' is invalid.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "A user with this login already exists.",
"Volo.Abp.Identity:PasswordMismatch": "Incorrect password.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Passwords must have at least one digit ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "Role name '{0}' is invalid.",
"Volo.Abp.Identity:InvalidToken": "Invalid token.",
"Volo.Abp.Identity:InvalidUserName": "Username '{0}' is invalid, can only contain letters or digits.",
"InvalidUserName": "Username '{0}' is invalid.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "A user with this login already exists.",
"Volo.Abp.Identity:PasswordMismatch": "Incorrect password.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Passwords must have at least one digit ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/es.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "El nombre de rol '{0}' no es válido.",
"Volo.Abp.Identity:InvalidToken": "token no válido",
"Volo.Abp.Identity:InvalidUserName": "Nombre de usuario '{0}' no es válido. Sólo puede contener letras o dígitos",
"InvalidUserName": "Nombre de usuario '{0}' no es válido.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Usuario con este inicio de sesión en uso.",
"Volo.Abp.Identity:PasswordMismatch": "Contraseña incorrecta.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Contraseñas deben tener al menos un dígito ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fa.json

@ -47,6 +47,7 @@
"Volo.Abp.Identity:InvalidRoleName": "عنوان نقش/وظیفه {0} نامعتبر است.",
"Volo.Abp.Identity:InvalidToken": "گذرواژه وارد شده معتبر نیست.",
"Volo.Abp.Identity:InvalidUserName": "نام کاربری '{0}' نامعتبر است، نام کاربری فقط می تواند شامل حروف یا ارقام باشد.",
"InvalidUserName": "ام کاربری '{0}' نامعتبر است",
"Volo.Abp.Identity:LoginAlreadyAssociated": "یک کاربر با این نام کاربری از قبل موجود می باشد.",
"Volo.Abp.Identity:PasswordMismatch": "گذرواژه اشتباه است.",
"Volo.Abp.Identity:PasswordRequiresDigit": "گذرواژه ها باید حداقل یک رقم داشته باشند ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fi.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "Roolin nimi {0} on virheellinen.",
"Volo.Abp.Identity:InvalidToken": "Virheellinen tunnus.",
"Volo.Abp.Identity:InvalidUserName": "Käyttäjätunnus {0} on virheellinen, voi sisältää vain kirjaimia tai numeroita.",
"InvalidUserName": "Käyttäjätunnus {0} on virheellinen.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Käyttäjä, jolla on tämä sisäänkirjautuminen, on jo olemassa.",
"Volo.Abp.Identity:PasswordMismatch": "Väärä salasana.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Salasanoissa on oltava vähintään yksi numero ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/fr.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "Le nom de rôle '{0}' n’est pas valide.",
"Volo.Abp.Identity:InvalidToken": "Jeton non valide.",
"Volo.Abp.Identity:InvalidUserName": "Le nom d’utilisateur '{0}' n’est pas valide, ne peut contenir que des lettres ou des chiffres.",
"InvalidUserName": "Le nom d’utilisateur '{0}' n’est pas valide.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Un utilisateur avec cette connexion existe déjà.",
"Volo.Abp.Identity:PasswordMismatch": "Mot de passe incorrect.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Les mots de passe doivent avoir au moins un chiffre ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hi.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "भूमिका नाम '{0}' अमान्य है।",
"Volo.Abp.Identity:InvalidToken": "अमान्य टोकन।",
"Volo.Abp.Identity:InvalidUserName": "उपयोगकर्ता नाम '{0}' अमान्य है, इसमें केवल अक्षर या अंक हो सकते हैं।",
"InvalidUserName": "उपयोगकर्ता नाम '{0}' अमान्य है",
"Volo.Abp.Identity:LoginAlreadyAssociated": "इस लॉगिन वाला उपयोगकर्ता पहले से मौजूद है।",
"Volo.Abp.Identity:PasswordMismatch": "गलत पासवर्ड।",
"Volo.Abp.Identity:PasswordRequiresDigit": "पासवर्ड में कम से कम एक अंक ('0'-'9') होना चाहिए।",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hr.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "Naziv uloge '{0}' nije valjan.",
"Volo.Abp.Identity:InvalidToken": "Pogrešan token.",
"Volo.Abp.Identity:InvalidUserName": "Korisničko ime '{0}' nije važeće, može sadržavati samo slova ili znamenke.",
"InvalidUserName": "Korisničko ime '{0}' nije važeće.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Korisnik s ovom prijavom već postoji.",
"Volo.Abp.Identity:PasswordMismatch": "Netočna lozinka.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Lozinke moraju imati najmanje jednu znamenku ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/hu.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "'{0}' szerepkör név érvénytelen.",
"Volo.Abp.Identity:InvalidToken": "Érvénytelen token.",
"Volo.Abp.Identity:InvalidUserName": "'{0}' felhasználónév érvénytelen, csak betűket és számokat tartalmazhat.",
"InvalidUserName": "'{0}' felhasználónév érvénytelen.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Az ilyen bejelentkezéssel rendelkező felhasználó már létezik.",
"Volo.Abp.Identity:PasswordMismatch": "Érvénytelen jelszó.",
"Volo.Abp.Identity:PasswordRequiresDigit": "A jelszavaknak legalább egy számjegyet kell rendelkezniük ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/is.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "Hlutverkanafnið '{0}' er ógilt.",
"Volo.Abp.Identity:InvalidToken": "Ógilt token.",
"Volo.Abp.Identity:InvalidUserName": "Notandanafnið '{0}' er ógilt, getur aðeins innihaldið bókstafi eða tölustafi.",
"InvalidUserName": "Notandanafnið '{0}' er ógilt.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Notandi með þessa innskráningu er þegar til.",
"Volo.Abp.Identity:PasswordMismatch": "Rangt lykilorð.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Lykilorð verða að hafa að minnsta kosti einn staf ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/it.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "Il nome del ruolo '{0}' non è valido.",
"Volo.Abp.Identity:InvalidToken": "Token non valido.",
"Volo.Abp.Identity:InvalidUserName": "Il nome utente '{0}' non è valido, può contenere solo lettere o cifre.",
"InvalidUserName": "Il nome utente '{0}' non è valido.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Esiste già un utente con questo account.",
"Volo.Abp.Identity:PasswordMismatch": "Password errata.",
"Volo.Abp.Identity:PasswordRequiresDigit": "La password deve contenere almeno una cifra ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/nl.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "Rol naam '{0}' is ongeldig.",
"Volo.Abp.Identity:InvalidToken": "Ongeldig token.",
"Volo.Abp.Identity:InvalidUserName": "Gebruikersnaam '{0}' is ongeldig, mag alleen letters of cijfers bevatten.",
"InvalidUserName": "Gebruikersnaam '{0}' is ongeldig.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Er bestaat al een gebruiker met deze login.",
"Volo.Abp.Identity:PasswordMismatch": "Incorrect wachtwoord.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Wachtwoorden moeten minimaal één cijfer bevatten ('0' - '9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pl-PL.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "Rola '{0}' jest niepoprawna.",
"Volo.Abp.Identity:InvalidToken": "Niepoprawny token.",
"Volo.Abp.Identity:InvalidUserName": "Nazwa użytkownika '{0}' jest niepoprawna, może zawierać tylko litery i cyfry.",
"InvalidUserName": "Nazwa użytkownika '{0}' jest niepoprawna.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Użytkownik o tym loginie już istnieje.",
"Volo.Abp.Identity:PasswordMismatch": "Niepoprawne hasło.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Hasło musi zawierać przynajmniej jedną cyfrę ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/pt-BR.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "Perfil '{0}' inválido.",
"Volo.Abp.Identity:InvalidToken": "Token inválido.",
"Volo.Abp.Identity:InvalidUserName": "Usuário '{0}' é inválido, somente pode conter letras ou números.",
"InvalidUserName": "Usuário '{0}' é inválido.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Um usuário com este login já existe.",
"Volo.Abp.Identity:PasswordMismatch": "Senha incorreta.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Senhas devem possuir pelo menos um dígito ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ro-RO.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "Numele de rol '{0}' este invalid.",
"Volo.Abp.Identity:InvalidToken": "Invalid token.",
"Volo.Abp.Identity:InvalidUserName": "Numele de utilizator '{0}' este invalid, poate conţine doar litere şi cifre.",
"InvalidUserName": "Numele de utilizator '{0}' este invalid.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Un utilizator cu această autentificare există deja.",
"Volo.Abp.Identity:PasswordMismatch": "Parolă incorectă.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Parolele trebuie să conţină cel puţin o cifră ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/ru.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "Имя роли '{0}' недопустимо.",
"Volo.Abp.Identity:InvalidToken": "Недопустимый маркер.",
"Volo.Abp.Identity:InvalidUserName": "Имя пользователя '{0}' недопустимо и может содержать только буквы или цифры.",
"InvalidUserName": "Имя пользователя '{0}' недопустимо.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Пользователь с таким логином уже существует.",
"Volo.Abp.Identity:PasswordMismatch": "Неверный пароль.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Пароль должен содержать по крайней мере одну цифру.",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sk.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "Názov roly '{0}' je neplatný.",
"Volo.Abp.Identity:InvalidToken": "Neplatný token.",
"Volo.Abp.Identity:InvalidUserName": "Používateľské meno '{0}' je neplatné, môže obsahovať len písmená alebo číslice.",
"InvalidUserName": "Používateľské meno '{0}' je neplatné.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Používateľ s týmto prihlasovacím menom už existuje.",
"Volo.Abp.Identity:PasswordMismatch": "Nesprávne heslo.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Heslá musia obsahovať aspoň jednu číslicu ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/sl.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "Naziv vloge '{0}' ni veljaven.",
"Volo.Abp.Identity:InvalidToken": "Neveljaven žeton.",
"Volo.Abp.Identity:InvalidUserName": "Uporabniško ime '{0}' ni veljavno, vsebuje lahko le črke in številke.",
"InvalidUserName": "Uporabniško ime '{0}' ni veljavno.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Uporabnik s to prijavo že obstaja.",
"Volo.Abp.Identity:PasswordMismatch": "Nepravilno geslo.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Gesla morajo imeti vsaj eno številko ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "'{0}' rol ismi geçersizdir.",
"Volo.Abp.Identity:InvalidToken": "Geçersiz token.",
"Volo.Abp.Identity:InvalidUserName": "'{0}' kullanıcı adı geçersiz, sadece harf ve rakamlardan oluşmalı.",
"InvalidUserName": "'{0}' kullanıcı adı geçersiz.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Bu giriş bilgilerine sahip bir kullanıcı zaten var.",
"Volo.Abp.Identity:PasswordMismatch": "Hatalı şifre.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Şifre en az bir sayı içermeli ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/vi.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "Tên người dùng '{0}' Không hợp lệ.",
"Volo.Abp.Identity:InvalidToken": "Token không hợp lệ.",
"Volo.Abp.Identity:InvalidUserName": "Tên người dùng '{0}' không hợp lệ, chỉ có thể chứa chữ cái hoặc chữ số.",
"InvalidUserName": "Tên người dùng '{0}' không hợp lệ.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "Một người dùng có thông tin đăng nhập này đã tồn tại.",
"Volo.Abp.Identity:PasswordMismatch": "Mật khẩu không đúng.",
"Volo.Abp.Identity:PasswordRequiresDigit": "Mật khẩu phải có ít nhất một chữ số ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "角色名 '{0}' 无效.",
"Volo.Abp.Identity:InvalidToken": "token无效.",
"Volo.Abp.Identity:InvalidUserName": "用户名 '{0}' 无效, 只能包含字母或数字.",
"InvalidUserName": "用户名 '{0}' 无效.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "此登录名的用户已存在.",
"Volo.Abp.Identity:PasswordMismatch": "密码错误.",
"Volo.Abp.Identity:PasswordRequiresDigit": "密码至少包含一位数字 ('0'-'9').",

1
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json

@ -48,6 +48,7 @@
"Volo.Abp.Identity:InvalidRoleName": "角色名 '{0}' 無效.",
"Volo.Abp.Identity:InvalidToken": "token無效.",
"Volo.Abp.Identity:InvalidUserName": "使用者名稱 '{0}' 無效, 只能包含字母或數字.",
"InvalidUserName": "使用者名稱 '{0}' 無效.",
"Volo.Abp.Identity:LoginAlreadyAssociated": "此登入名的使用者已存在.",
"Volo.Abp.Identity:PasswordMismatch": "密碼錯誤.",
"Volo.Abp.Identity:PasswordRequiresDigit": "密碼至少包含一位數字 ('0'-'9').",

48
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/AbpIdentityUserValidator.cs

@ -0,0 +1,48 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Localization;
using Volo.Abp.Identity.Localization;
namespace Volo.Abp.Identity
{
public class AbpIdentityUserValidator : IUserValidator<IdentityUser>
{
protected IStringLocalizer<IdentityResource> Localizer { get; }
public AbpIdentityUserValidator(IStringLocalizer<IdentityResource> localizer)
{
Localizer = localizer;
}
public virtual async Task<IdentityResult> ValidateAsync(UserManager<IdentityUser> manager, IdentityUser user)
{
var describer = new IdentityErrorDescriber();
Check.NotNull(manager, nameof(manager));
Check.NotNull(user, nameof(user));
var errors = new List<IdentityError>();
var userName = await manager.GetUserNameAsync(user);
if (userName == null)
{
errors.Add(describer.InvalidUserName(null));
}
else
{
var owner = await manager.FindByEmailAsync(userName);
if (owner != null && !string.Equals(await manager.GetUserIdAsync(owner), await manager.GetUserIdAsync(user)))
{
errors.Add(new IdentityError
{
Code = "InvalidUserName",
Description = Localizer["InvalidUserName", userName]
});
}
}
return errors.Count > 0 ? IdentityResult.Failed(errors.ToArray()) : IdentityResult.Success;
}
}
}

36
modules/identity/test/Volo.Abp.Identity.AspNetCore.Tests/Volo/Abp/Identity/AspNetCore/AbpIdentityUserValidator_Tests.cs

@ -0,0 +1,36 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Localization;
using Shouldly;
using Volo.Abp.Identity.Localization;
using Xunit;
namespace Volo.Abp.Identity.AspNetCore;
public class AbpIdentityUserValidator_Tests : AbpIdentityAspNetCoreTestBase
{
private readonly IdentityUserManager _identityUserManager;
private readonly IStringLocalizer<IdentityResource> Localizer;
public AbpIdentityUserValidator_Tests()
{
_identityUserManager = GetRequiredService<IdentityUserManager>();
Localizer = GetRequiredService<IStringLocalizer<IdentityResource>>();
}
[Fact]
public async Task Can_Not_Use_Another_Users_Email_As_Your_Username_Test()
{
var user1 = new IdentityUser(Guid.NewGuid(), "user1", "user1@volosoft.com");
var identityResult = await _identityUserManager.CreateAsync(user1);
identityResult.Succeeded.ShouldBeTrue();
var user2 = new IdentityUser(Guid.NewGuid(), "user1@volosoft.com", "user2@volosoft.com");
identityResult = await _identityUserManager.CreateAsync(user2);
identityResult.Succeeded.ShouldBeFalse();
identityResult.Errors.Count().ShouldBe(1);
identityResult.Errors.First().Code.ShouldBe("InvalidUserName");
identityResult.Errors.First().Description.ShouldBe(Localizer["InvalidUserName", "user1@volosoft.com"]);
}
}
Loading…
Cancel
Save