diff --git a/framework/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AbpAuthorizationServiceExtensions.cs b/framework/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AbpAuthorizationServiceExtensions.cs
index 45650b06a4..86d18b4309 100644
--- a/framework/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AbpAuthorizationServiceExtensions.cs
+++ b/framework/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AbpAuthorizationServiceExtensions.cs
@@ -95,7 +95,8 @@ namespace Microsoft.AspNetCore.Authorization
{
if (!await authorizationService.IsGrantedAsync(policyName))
{
- throw new AbpAuthorizationException("Authorization failed! Given policy has not granted: " + policyName);
+ throw new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenPolicyHasNotGrantedWithPolicyName)
+ .WithData("PolicyName", policyName);
}
}
@@ -103,7 +104,8 @@ namespace Microsoft.AspNetCore.Authorization
{
if (!await authorizationService.IsGrantedAsync(resource, requirement))
{
- throw new AbpAuthorizationException("Authorization failed! Given requirement has not granted for given resource: " + resource);
+ throw new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenRequirementHasNotGrantedForGivenResource)
+ .WithData("PolicyName", resource);
}
}
@@ -111,7 +113,8 @@ namespace Microsoft.AspNetCore.Authorization
{
if (!await authorizationService.IsGrantedAsync(resource, policy))
{
- throw new AbpAuthorizationException("Authorization failed! Given policy has not granted for given resource: " + resource);
+ throw new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenPolicyHasNotGrantedForGivenResource)
+ .WithData("ResourceName", resource);
}
}
@@ -119,7 +122,7 @@ namespace Microsoft.AspNetCore.Authorization
{
if (!await authorizationService.IsGrantedAsync(policy))
{
- throw new AbpAuthorizationException("Authorization failed! Given policy has not granted.");
+ throw new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenPolicyHasNotGranted);
}
}
@@ -127,7 +130,8 @@ namespace Microsoft.AspNetCore.Authorization
{
if (!await authorizationService.IsGrantedAsync(resource, requirements))
{
- throw new AbpAuthorizationException("Authorization failed! Given requirements have not granted for given resource: " + resource);
+ throw new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenRequirementsHasNotGrantedForGivenResource)
+ .WithData("ResourceName", resource);
}
}
@@ -135,7 +139,8 @@ namespace Microsoft.AspNetCore.Authorization
{
if (!await authorizationService.IsGrantedAsync(resource, policyName))
{
- throw new AbpAuthorizationException("Authorization failed! Given polist has not granted for given resource: " + resource);
+ throw new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenPolicyHasNotGrantedForGivenResource)
+ .WithData("ResourceName", resource);
}
}
@@ -149,4 +154,4 @@ namespace Microsoft.AspNetCore.Authorization
return abpAuthorizationService;
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj b/framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj
index 9e355531fa..66dd574322 100644
--- a/framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj
+++ b/framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj
@@ -19,7 +19,12 @@
-
+
+
+
+
+
+
diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationErrorCodes.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationErrorCodes.cs
new file mode 100644
index 0000000000..0d4562eba3
--- /dev/null
+++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationErrorCodes.cs
@@ -0,0 +1,15 @@
+namespace Volo.Abp.Authorization
+{
+ public static class AbpAuthorizationErrorCodes
+ {
+ public const string GivenPolicyHasNotGranted = "Volo.Authorization:010001";
+
+ public const string GivenPolicyHasNotGrantedWithPolicyName = "Volo.Authorization:010002";
+
+ public const string GivenPolicyHasNotGrantedForGivenResource = "Volo.Authorization:010003";
+
+ public const string GivenRequirementHasNotGrantedForGivenResource = "Volo.Authorization:010004";
+
+ public const string GivenRequirementsHasNotGrantedForGivenResource = "Volo.Authorization:010005";
+ }
+}
diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs
index b16e08a214..b4d5795b9c 100644
--- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs
+++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs
@@ -3,17 +3,20 @@ using System.Collections.Generic;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
+using Volo.Abp.Authorization.Localization;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Localization;
+using Volo.Abp.Localization.ExceptionHandling;
using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Security;
+using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.Authorization
{
[DependsOn(
typeof(AbpSecurityModule),
- typeof(AbpLocalizationAbstractionsModule),
+ typeof(AbpLocalizationModule),
typeof(AbpMultiTenancyModule)
)]
public class AbpAuthorizationModule : AbpModule
@@ -38,6 +41,23 @@ namespace Volo.Abp.Authorization
options.ValueProviders.Add();
options.ValueProviders.Add();
});
+
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+
+ Configure(options =>
+ {
+ options.Resources
+ .Add("en")
+ .AddVirtualJson("/Volo/Abp/Authorization/Localization");
+ });
+
+ Configure(options =>
+ {
+ options.MapCodeNamespace("Volo.Authorization", typeof(AbpAuthorizationResource));
+ });
}
private static void AutoAddDefinitionProviders(IServiceCollection services)
diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/AbpAuthorizationResource.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/AbpAuthorizationResource.cs
new file mode 100644
index 0000000000..2888509915
--- /dev/null
+++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/AbpAuthorizationResource.cs
@@ -0,0 +1,10 @@
+using Volo.Abp.Localization;
+
+namespace Volo.Abp.Authorization.Localization
+{
+ [LocalizationResourceName("AbpAuthorization")]
+ public class AbpAuthorizationResource
+ {
+
+ }
+}
diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/en.json b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/en.json
new file mode 100644
index 0000000000..e7bc77c341
--- /dev/null
+++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/en.json
@@ -0,0 +1,10 @@
+{
+ "culture": "en",
+ "texts": {
+ "Volo.Authorization:010001": "Authorization failed! Given policy has not granted.",
+ "Volo.Authorization:010002": "Authorization failed! Given policy has not granted: {PolicyName}",
+ "Volo.Authorization:010003": "Authorization failed! Given policy has not granted for given resource: {ResourceName}",
+ "Volo.Authorization:010004": "Authorization failed! Given requirement has not granted for given resource: {ResourceName}",
+ "Volo.Authorization:010005": "Authorization failed! Given requirements has not granted for given resource: {ResourceName}"
+ }
+}
diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/tr.json b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/tr.json
new file mode 100644
index 0000000000..03ca832432
--- /dev/null
+++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/tr.json
@@ -0,0 +1,10 @@
+{
+ "culture": "tr",
+ "texts": {
+ "Volo.Authorization:010001": "Yetkilendirme başarısız oldu! Verilen politika verilmemiştir.",
+ "Volo.Authorization:010002": "Yetkilendirme başarısız oldu! Verilen politika vermedi: {PolicyName}",
+ "Volo.Authorization:010003": "Yetkilendirme başarısız oldu! Verilen politika, verilen kaynak için verilmemiştir: {ResourceName}",
+ "Volo.Authorization:010004": "Yetkilendirme başarısız oldu! Belirtilen kaynak için verilen şart verilmedi {ResourceName}",
+ "Volo.Authorization:010005": "Yetkilendirme başarısız oldu! Verilen gereksinimler, verilen kaynak için verilmemiştir: {ResourceName}"
+ }
+}
diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/zh-Hans.json b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/zh-Hans.json
new file mode 100644
index 0000000000..d0946ef6a5
--- /dev/null
+++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/zh-Hans.json
@@ -0,0 +1,10 @@
+{
+ "culture": "zh-Hans",
+ "texts": {
+ "Volo.Authorization:010001": "授权失败! 提供的策略尚未授予.",
+ "Volo.Authorization:010002": "授权失败! 提供的策略尚未授予: {PolicyName}",
+ "Volo.Authorization:010003": "授权失败! 提供的策略未授予提供的资源: {ResourceName}",
+ "Volo.Authorization:010004": "授权失败! 提供的要求未授予提供的资源: {ResourceName}",
+ "Volo.Authorization:010005": "授权失败! 提供的要求未授予提供的资源: {ResourceName}"
+ }
+}
diff --git a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/DefaultExceptionToErrorInfoConverter.cs b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/DefaultExceptionToErrorInfoConverter.cs
index 6367bd24ff..eb8c4eb804 100644
--- a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/DefaultExceptionToErrorInfoConverter.cs
+++ b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/AspNetCore/ExceptionHandling/DefaultExceptionToErrorInfoConverter.cs
@@ -62,12 +62,6 @@ namespace Volo.Abp.AspNetCore.ExceptionHandling
return CreateEntityNotFoundError(exception as EntityNotFoundException);
}
- if (exception is AbpAuthorizationException)
- {
- var authorizationException = exception as AbpAuthorizationException;
- return new RemoteServiceErrorInfo(authorizationException.Message);
- }
-
var errorInfo = new RemoteServiceErrorInfo();
if (exception is IUserFriendlyException)
diff --git a/framework/src/Volo.Abp.Features/Volo.Abp.Features.csproj b/framework/src/Volo.Abp.Features/Volo.Abp.Features.csproj
index a2d098f970..3bea3ea77f 100644
--- a/framework/src/Volo.Abp.Features/Volo.Abp.Features.csproj
+++ b/framework/src/Volo.Abp.Features/Volo.Abp.Features.csproj
@@ -15,7 +15,12 @@
-
+
+
+
+
+
+
diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/AbpFeatureErrorCodes.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/AbpFeatureErrorCodes.cs
new file mode 100644
index 0000000000..a5a4cf3a58
--- /dev/null
+++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/AbpFeatureErrorCodes.cs
@@ -0,0 +1,11 @@
+namespace Volo.Abp.Features
+{
+ public static class AbpFeatureErrorCodes
+ {
+ public const string FeatureIsNotEnabled = "Volo.Feature:010001";
+
+ public const string AllOfTheseFeaturesMustBeEnabled = "Volo.Feature:010002";
+
+ public const string AtLeastOneOfTheseFeaturesMustBeEnabled = "Volo.Feature:010003";
+ }
+}
diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/AbpFeaturesModule.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/AbpFeaturesModule.cs
index f30017feed..70c6e7f37d 100644
--- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/AbpFeaturesModule.cs
+++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/AbpFeaturesModule.cs
@@ -1,15 +1,18 @@
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
+using Volo.Abp.Features.Localization;
using Volo.Abp.Localization;
+using Volo.Abp.Localization.ExceptionHandling;
using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Validation;
+using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.Features
{
[DependsOn(
- typeof(AbpLocalizationAbstractionsModule),
+ typeof(AbpLocalizationModule),
typeof(AbpMultiTenancyModule),
typeof(AbpValidationModule)
)]
@@ -29,6 +32,23 @@ namespace Volo.Abp.Features
options.ValueProviders.Add();
options.ValueProviders.Add();
});
+
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+
+ Configure(options =>
+ {
+ options.Resources
+ .Add("en")
+ .AddVirtualJson("/Volo/Abp/Features/Localization");
+ });
+
+ Configure(options =>
+ {
+ options.MapCodeNamespace("Volo.Feature", typeof(AbpFeatureResource));
+ });
}
private static void AutoAddDefinitionProviders(IServiceCollection services)
diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureCheckerExtensions.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureCheckerExtensions.cs
index 8850408df0..ba2b640031 100644
--- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureCheckerExtensions.cs
+++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureCheckerExtensions.cs
@@ -9,8 +9,8 @@ namespace Volo.Abp.Features
public static class FeatureCheckerExtensions
{
public static async Task GetAsync(
- [NotNull] this IFeatureChecker featureChecker,
- [NotNull] string name,
+ [NotNull] this IFeatureChecker featureChecker,
+ [NotNull] string name,
T defaultValue = default)
where T : struct
{
@@ -56,10 +56,11 @@ namespace Volo.Abp.Features
{
if (!(await featureChecker.IsEnabledAsync(featureName)))
{
- throw new AbpAuthorizationException("Feature is not enabled: " + featureName);
+ throw new AbpAuthorizationException(code: AbpFeatureErrorCodes.FeatureIsNotEnabled).WithData(
+ "FeatureName", featureName);
}
}
-
+
public static async Task CheckEnabledAsync(this IFeatureChecker featureChecker, bool requiresAll, params string[] featureNames)
{
if (featureNames.IsNullOrEmpty())
@@ -73,10 +74,8 @@ namespace Volo.Abp.Features
{
if (!(await featureChecker.IsEnabledAsync(featureName)))
{
- throw new AbpAuthorizationException(
- "Required features are not enabled. All of these features must be enabled: " +
- string.Join(", ", featureNames)
- );
+ throw new AbpAuthorizationException(code: AbpFeatureErrorCodes.AllOfTheseFeaturesMustBeEnabled)
+ .WithData("FeatureNames", string.Join(", ", featureNames));
}
}
}
@@ -90,11 +89,9 @@ namespace Volo.Abp.Features
}
}
- throw new AbpAuthorizationException(
- "Required features are not enabled. At least one of these features must be enabled: " +
- string.Join(", ", featureNames)
- );
+ throw new AbpAuthorizationException(code: AbpFeatureErrorCodes.AtLeastOneOfTheseFeaturesMustBeEnabled)
+ .WithData("FeatureNames", string.Join(", ", featureNames));
}
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/AbpFeatureResource.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/AbpFeatureResource.cs
new file mode 100644
index 0000000000..5871d550ad
--- /dev/null
+++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/AbpFeatureResource.cs
@@ -0,0 +1,10 @@
+using Volo.Abp.Localization;
+
+namespace Volo.Abp.Features.Localization
+{
+ [LocalizationResourceName("AbpFeature")]
+ public class AbpFeatureResource
+ {
+
+ }
+}
diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/en.json b/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/en.json
new file mode 100644
index 0000000000..de03dc11d0
--- /dev/null
+++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/en.json
@@ -0,0 +1,8 @@
+{
+ "culture": "en",
+ "texts": {
+ "Volo.Feature:010001": "Feature is not enabled: {FeatureName}",
+ "Volo.Feature:010002": "Required features are not enabled. All of these features must be enabled: {FeatureNames}",
+ "Volo.Feature:010003": "Required features are not enabled. At least one of these features must be enabled: {FeatureNames}"
+ }
+}
diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/tr.json b/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/tr.json
new file mode 100644
index 0000000000..9277b63530
--- /dev/null
+++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/tr.json
@@ -0,0 +1,8 @@
+{
+ "culture": "tr",
+ "texts": {
+ "Volo.Feature:010001": "Özellik etkinleştirilmedi: {FeatureName}",
+ "Volo.Feature:010002": "Gerekli özellikler etkinleştirilmedi. Bu özelliklerin tümü etkinleştirilmelidir: {FeatureNames}",
+ "Volo.Feature:010003": "Gerekli özellikler etkinleştirilmedi. Bu özelliklerden en az birinin etkinleştirilmesi gerekir: {FeatureNames}"
+ }
+}
diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/zh-Hans.json b/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/zh-Hans.json
new file mode 100644
index 0000000000..4c6d99c281
--- /dev/null
+++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/zh-Hans.json
@@ -0,0 +1,8 @@
+{
+ "culture": "zh-Hans",
+ "texts": {
+ "Volo.Feature:010001": "功能未启用: {FeatureName}",
+ "Volo.Feature:010002": "必要的功能未启用. 这些功能需要启用: {FeatureNames}",
+ "Volo.Feature:010003": "必要的功能未启用. 需要启用这些功能中的一项:{FeatureNames}"
+ }
+}
diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Authorization/AbpAuthorizationException.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Authorization/AbpAuthorizationException.cs
index ad5b0b65a3..c0a8c4d4f8 100644
--- a/framework/src/Volo.Abp.Security/Volo/Abp/Authorization/AbpAuthorizationException.cs
+++ b/framework/src/Volo.Abp.Security/Volo/Abp/Authorization/AbpAuthorizationException.cs
@@ -1,6 +1,7 @@
using System;
using System.Runtime.Serialization;
using Microsoft.Extensions.Logging;
+using Volo.Abp.ExceptionHandling;
using Volo.Abp.Logging;
namespace Volo.Abp.Authorization
@@ -9,7 +10,7 @@ namespace Volo.Abp.Authorization
/// This exception is thrown on an unauthorized request.
///
[Serializable]
- public class AbpAuthorizationException : AbpException, IHasLogLevel
+ public class AbpAuthorizationException : AbpException, IHasLogLevel, IHasErrorCode
{
///
/// Severity of the exception.
@@ -17,6 +18,11 @@ namespace Volo.Abp.Authorization
///
public LogLevel LogLevel { get; set; }
+ ///
+ /// Error code.
+ ///
+ public string Code { get; }
+
///
/// Creates a new object.
///
@@ -54,5 +60,24 @@ namespace Volo.Abp.Authorization
{
LogLevel = LogLevel.Warning;
}
+
+ ///
+ /// Creates a new object.
+ ///
+ /// Exception message
+ /// Exception code
+ /// Inner exception
+ public AbpAuthorizationException(string message = null, string code = null, Exception innerException = null)
+ : base(message, innerException)
+ {
+ Code = code;
+ LogLevel = LogLevel.Warning;
+ }
+
+ public AbpAuthorizationException WithData(string name, object value)
+ {
+ Data[name] = value;
+ return this;
+ }
}
-}
\ No newline at end of file
+}
diff --git a/framework/test/Volo.Abp.Authorization.Tests/Microsoft/AspNetCore/Authorization/AbpAuthorizationServiceExtensions_Tests.cs b/framework/test/Volo.Abp.Authorization.Tests/Microsoft/AspNetCore/Authorization/AbpAuthorizationServiceExtensions_Tests.cs
new file mode 100644
index 0000000000..e8876aaebf
--- /dev/null
+++ b/framework/test/Volo.Abp.Authorization.Tests/Microsoft/AspNetCore/Authorization/AbpAuthorizationServiceExtensions_Tests.cs
@@ -0,0 +1,49 @@
+using Shouldly;
+using Volo.Abp.AspNetCore.ExceptionHandling;
+using Volo.Abp.Authorization;
+using Volo.Abp.Localization;
+using Xunit;
+
+namespace Microsoft.AspNetCore.Authorization
+{
+ public class AbpAuthorizationServiceExtensions_Tests : AuthorizationTestBase
+ {
+ private readonly IExceptionToErrorInfoConverter _exceptionToErrorInfoConverter;
+
+ public AbpAuthorizationServiceExtensions_Tests()
+ {
+ _exceptionToErrorInfoConverter = GetRequiredService();
+ }
+
+ [Fact]
+ public void Test_AbpAuthorizationException_Localization()
+ {
+ using (CultureHelper.Use("zh-Hans"))
+ {
+ var exception = new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenPolicyHasNotGranted);
+ var errorInfo = _exceptionToErrorInfoConverter.Convert(exception, false);
+ errorInfo.Message.ShouldBe("授权失败! 提供的策略尚未授予.");
+
+ exception = new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenPolicyHasNotGrantedWithPolicyName)
+ .WithData("PolicyName", "my_policy_name");
+ errorInfo = _exceptionToErrorInfoConverter.Convert(exception, false);
+ errorInfo.Message.ShouldBe("授权失败! 提供的策略尚未授予: my_policy_name");
+
+ exception = new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenPolicyHasNotGrantedForGivenResource)
+ .WithData("ResourceName", "my_resource_name");
+ errorInfo = _exceptionToErrorInfoConverter.Convert(exception, false);
+ errorInfo.Message.ShouldBe("授权失败! 提供的策略未授予提供的资源: my_resource_name");
+
+ exception = new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenRequirementHasNotGrantedForGivenResource)
+ .WithData("ResourceName", "my_resource_name");
+ errorInfo = _exceptionToErrorInfoConverter.Convert(exception, false);
+ errorInfo.Message.ShouldBe("授权失败! 提供的要求未授予提供的资源: my_resource_name");
+
+ exception = new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenRequirementsHasNotGrantedForGivenResource)
+ .WithData("ResourceName", "my_resource_name");
+ errorInfo = _exceptionToErrorInfoConverter.Convert(exception, false);
+ errorInfo.Message.ShouldBe("授权失败! 提供的要求未授予提供的资源: my_resource_name");
+ }
+ }
+ }
+}
diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo.Abp.Authorization.Tests.csproj b/framework/test/Volo.Abp.Authorization.Tests/Volo.Abp.Authorization.Tests.csproj
index 165aaaa1d0..279523610e 100644
--- a/framework/test/Volo.Abp.Authorization.Tests/Volo.Abp.Authorization.Tests.csproj
+++ b/framework/test/Volo.Abp.Authorization.Tests/Volo.Abp.Authorization.Tests.csproj
@@ -12,6 +12,7 @@
+
diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AbpAuthorizationTestModule.cs b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AbpAuthorizationTestModule.cs
index 492a36f8b9..69417e48c6 100644
--- a/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AbpAuthorizationTestModule.cs
+++ b/framework/test/Volo.Abp.Authorization.Tests/Volo/Abp/Authorization/AbpAuthorizationTestModule.cs
@@ -2,12 +2,14 @@
using Volo.Abp.Authorization.TestServices;
using Volo.Abp.Autofac;
using Volo.Abp.DynamicProxy;
+using Volo.Abp.ExceptionHandling;
using Volo.Abp.Modularity;
namespace Volo.Abp.Authorization
{
[DependsOn(typeof(AbpAutofacModule))]
[DependsOn(typeof(AbpAuthorizationModule))]
+ [DependsOn(typeof(AbpExceptionHandlingModule))]
public class AbpAuthorizationTestModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
@@ -22,4 +24,4 @@ namespace Volo.Abp.Authorization
});
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/test/Volo.Abp.Features.Tests/Volo.Abp.Features.Tests.csproj b/framework/test/Volo.Abp.Features.Tests/Volo.Abp.Features.Tests.csproj
index 3edc355ca2..713b541431 100644
--- a/framework/test/Volo.Abp.Features.Tests/Volo.Abp.Features.Tests.csproj
+++ b/framework/test/Volo.Abp.Features.Tests/Volo.Abp.Features.Tests.csproj
@@ -9,6 +9,7 @@
+
diff --git a/framework/test/Volo.Abp.Features.Tests/Volo/Abp/Features/AbpFeaturesTestModule.cs b/framework/test/Volo.Abp.Features.Tests/Volo/Abp/Features/AbpFeaturesTestModule.cs
index 7b0927b80d..f5ff20e6f2 100644
--- a/framework/test/Volo.Abp.Features.Tests/Volo/Abp/Features/AbpFeaturesTestModule.cs
+++ b/framework/test/Volo.Abp.Features.Tests/Volo/Abp/Features/AbpFeaturesTestModule.cs
@@ -1,10 +1,12 @@
using Volo.Abp.Autofac;
+using Volo.Abp.ExceptionHandling;
using Volo.Abp.Modularity;
namespace Volo.Abp.Features
{
[DependsOn(
typeof(AbpFeaturesModule),
+ typeof(AbpExceptionHandlingModule),
typeof(AbpTestBaseModule),
typeof(AbpAutofacModule)
)]
@@ -12,7 +14,7 @@ namespace Volo.Abp.Features
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
-
+
}
}
}
diff --git a/framework/test/Volo.Abp.Features.Tests/Volo/Abp/Features/FeatureCheckerExtensions_Tests.cs b/framework/test/Volo.Abp.Features.Tests/Volo/Abp/Features/FeatureCheckerExtensions_Tests.cs
new file mode 100644
index 0000000000..0df9548f3c
--- /dev/null
+++ b/framework/test/Volo.Abp.Features.Tests/Volo/Abp/Features/FeatureCheckerExtensions_Tests.cs
@@ -0,0 +1,40 @@
+using Shouldly;
+using Volo.Abp.AspNetCore.ExceptionHandling;
+using Volo.Abp.Authorization;
+using Volo.Abp.Localization;
+using Xunit;
+
+namespace Volo.Abp.Features
+{
+ public class FeatureCheckerExtensions_Tests : FeatureTestBase
+ {
+ private readonly IExceptionToErrorInfoConverter _exceptionToErrorInfoConverter;
+
+ public FeatureCheckerExtensions_Tests()
+ {
+ _exceptionToErrorInfoConverter = GetRequiredService();
+ }
+
+ [Fact]
+ public void Test_AbpAuthorizationException_Localization()
+ {
+ using (CultureHelper.Use("zh-Hans"))
+ {
+ var exception = new AbpAuthorizationException(code: AbpFeatureErrorCodes.FeatureIsNotEnabled)
+ .WithData("FeatureName", "my_feature_name");
+ var errorInfo = _exceptionToErrorInfoConverter.Convert(exception, false);
+ errorInfo.Message.ShouldBe("功能未启用: my_feature_name");
+
+ exception = new AbpAuthorizationException(code: AbpFeatureErrorCodes.AllOfTheseFeaturesMustBeEnabled)
+ .WithData("FeatureNames", "my_feature_name, my_feature_name2");
+ errorInfo = _exceptionToErrorInfoConverter.Convert(exception, false);
+ errorInfo.Message.ShouldBe("必要的功能未启用. 这些功能需要启用: my_feature_name, my_feature_name2");
+
+ exception = new AbpAuthorizationException(code: AbpFeatureErrorCodes.AtLeastOneOfTheseFeaturesMustBeEnabled)
+ .WithData("FeatureNames", "my_feature_name, my_feature_name2");
+ errorInfo = _exceptionToErrorInfoConverter.Convert(exception, false);
+ errorInfo.Message.ShouldBe("必要的功能未启用. 需要启用这些功能中的一项:my_feature_name, my_feature_name2");
+ }
+ }
+ }
+}