diff --git a/src/Volo.Abp.AspNetCore.Mvc.UI/wwwroot/libs/abp/abp.js b/src/Volo.Abp.AspNetCore.Mvc.UI/wwwroot/libs/abp/abp.js index 12f596ce7f..dbfbdd6649 100644 --- a/src/Volo.Abp.AspNetCore.Mvc.UI/wwwroot/libs/abp/abp.js +++ b/src/Volo.Abp.AspNetCore.Mvc.UI/wwwroot/libs/abp/abp.js @@ -107,6 +107,60 @@ abp.localization.defaultResourceName = undefined; + /* AUTHORIZATION **********************************************/ + + abp.auth = abp.auth || {}; + + abp.auth.policies = abp.auth.policies || {}; + + abp.auth.grantedPolicies = abp.auth.grantedPolicies || {}; + + abp.auth.isGranted = function (policyName) { + return abp.auth.policies[policyName] != undefined && abp.auth.grantedPolicies[policyName] != undefined; + }; + + abp.auth.isAnyGranted = function () { + if (!arguments || arguments.length <= 0) { + return true; + } + + for (var i = 0; i < arguments.length; i++) { + if (abp.auth.isGranted(arguments[i])) { + return true; + } + } + + return false; + }; + + abp.auth.areAllGranted = function () { + if (!arguments || arguments.length <= 0) { + return true; + } + + for (var i = 0; i < arguments.length; i++) { + if (!abp.auth.isGranted(arguments[i])) { + return false; + } + } + + return true; + }; + + abp.auth.tokenCookieName = 'Abp.AuthToken'; + + abp.auth.setToken = function (authToken, expireDate) { + abp.utils.setCookieValue(abp.auth.tokenCookieName, authToken, expireDate, abp.appPath, abp.domain); + }; + + abp.auth.getToken = function () { + return abp.utils.getCookieValue(abp.auth.tokenCookieName); + } + + abp.auth.clearToken = function () { + abp.auth.setToken(); + } + /* NOTIFICATION *********************************************/ //Defines Notification API, not implements it diff --git a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationController.cs b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationController.cs index adcb07242a..b117a68956 100644 --- a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationController.cs +++ b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationController.cs @@ -16,7 +16,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations [HttpGet] public Task Get() { - return _configurationBuilder.Get(); + return _configurationBuilder.GetAsync(); } } } \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationScriptController.cs b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationScriptController.cs index 51906199d4..9698f3f302 100644 --- a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationScriptController.cs +++ b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationScriptController.cs @@ -25,8 +25,9 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations [Produces("text/javascript", "text/plain")] public async Task Get() { - var config = await _configurationBuilder.Get(); - return CreateAbpExtendScript(config); + return CreateAbpExtendScript( + await _configurationBuilder.GetAsync() + ); } private string CreateAbpExtendScript(ApplicationConfigurationDto config) diff --git a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationAuthConfigurationDto.cs b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationAuthConfigurationDto.cs new file mode 100644 index 0000000000..4981955ba0 --- /dev/null +++ b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationAuthConfigurationDto.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; + +namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations +{ + public class ApplicationAuthConfigurationDto + { + public Dictionary Policies { get; set; } + + public Dictionary GrantedPolicies { get; set; } + + public ApplicationAuthConfigurationDto() + { + Policies = new Dictionary(); + GrantedPolicies = new Dictionary(); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationBuilder.cs b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationBuilder.cs index 58f9f41348..9e0ea0e825 100644 --- a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationBuilder.cs +++ b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationBuilder.cs @@ -2,9 +2,11 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Options; +using Volo.Abp.Authorization; using Volo.Abp.DependencyInjection; using Volo.Abp.Localization; @@ -14,27 +16,51 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations { private readonly AbpLocalizationOptions _localizationOptions; private readonly IServiceProvider _serviceProvider; + private readonly IAbpAuthorizationPolicyProvider _abpAuthorizationPolicyProvider; + private readonly IAuthorizationService _authorizationService; - public ApplicationConfigurationBuilder(IOptions localizationOptions, IServiceProvider serviceProvider) + public ApplicationConfigurationBuilder( + IOptions localizationOptions, + IServiceProvider serviceProvider, + IAbpAuthorizationPolicyProvider abpAuthorizationPolicyProvider, + IAuthorizationService authorizationService) { _serviceProvider = serviceProvider; + _abpAuthorizationPolicyProvider = abpAuthorizationPolicyProvider; + _authorizationService = authorizationService; _localizationOptions = localizationOptions.Value; } - public Task Get() + public async Task GetAsync() //TODO: Test, at least with a simple Get { - var config = new ApplicationConfigurationDto + //TODO: Optimize & cache..? + + return new ApplicationConfigurationDto { + Auth = await GetAuthConfig(), Localization = GetLocalizationConfig() }; - - return Task.FromResult(config); } - private ApplicationLocalizationConfigurationDto GetLocalizationConfig() + protected virtual async Task GetAuthConfig() { - //TODO: Optimize & cache + var authConfig = new ApplicationAuthConfigurationDto(); + + foreach (var policyName in await _abpAuthorizationPolicyProvider.GetPoliciesNamesAsync()) + { + authConfig.Policies[policyName] = true; + if (await _authorizationService.IsGrantedAsync(policyName)) + { + authConfig.GrantedPolicies[policyName] = true; + } + } + + return authConfig; + } + + protected virtual ApplicationLocalizationConfigurationDto GetLocalizationConfig() + { var localizationConfig = new ApplicationLocalizationConfigurationDto(); foreach (var resource in _localizationOptions.Resources.Values) diff --git a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationDto.cs b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationDto.cs index fa8786efe2..d7aab53482 100644 --- a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationDto.cs +++ b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationDto.cs @@ -3,5 +3,7 @@ public class ApplicationConfigurationDto { public ApplicationLocalizationConfigurationDto Localization { get; set; } + + public ApplicationAuthConfigurationDto Auth { get; set; } } } \ No newline at end of file diff --git a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/IApplicationConfigurationBuilder.cs b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/IApplicationConfigurationBuilder.cs index 4b2f98311c..2b820f48c6 100644 --- a/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/IApplicationConfigurationBuilder.cs +++ b/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/IApplicationConfigurationBuilder.cs @@ -4,6 +4,6 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations { public interface IApplicationConfigurationBuilder { - Task Get(); + Task GetAsync(); } } \ No newline at end of file diff --git a/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AuthorizationOptionsExtensions.cs b/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AuthorizationOptionsExtensions.cs new file mode 100644 index 0000000000..499c2431c5 --- /dev/null +++ b/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AuthorizationOptionsExtensions.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace Microsoft.AspNetCore.Authorization +{ + public static class AuthorizationOptionsExtensions + { + private static readonly PropertyInfo PolicyMapProperty = typeof(AuthorizationOptions) + .GetProperty("PolicyMap", BindingFlags.Instance | BindingFlags.NonPublic); + + /// + /// Gets all policies. + /// + /// IMPORTANT NOTE: Use this method carefully. + /// It relies on reflection to get all policies from a private field of the . + /// This method may be removed in the future if internals of changes. + /// + /// + /// + public static List GetPoliciesNames(this AuthorizationOptions options) + { + return ((IDictionary) PolicyMapProperty.GetValue(options)).Keys.ToList(); + } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationPolicyProvider.cs b/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationPolicyProvider.cs index da3234d22c..e573c70c58 100644 --- a/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationPolicyProvider.cs +++ b/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationPolicyProvider.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Options; @@ -7,16 +9,18 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Authorization { - public class AbpAuthorizationPolicyProvider : DefaultAuthorizationPolicyProvider, ITransientDependency + public class AbpAuthorizationPolicyProvider : DefaultAuthorizationPolicyProvider, IAbpAuthorizationPolicyProvider, ITransientDependency { + private readonly AuthorizationOptions _options; private readonly IPermissionDefinitionManager _permissionDefinitionManager; public AbpAuthorizationPolicyProvider( IOptions options, - IPermissionDefinitionManager permissionDefinitionManager) + IPermissionDefinitionManager permissionDefinitionManager) : base(options) { _permissionDefinitionManager = permissionDefinitionManager; + _options = options.Value; } public override async Task GetPolicyAsync(string policyName) @@ -28,10 +32,23 @@ namespace Volo.Abp.Authorization return await base.GetPolicyAsync(policyName); } - //TODO: Optimize! + //TODO: Optimize & Cache! var policyBuilder = new AuthorizationPolicyBuilder(Array.Empty()); policyBuilder.Requirements.Add(new PermissionRequirement(policyName)); return policyBuilder.Build(); } + + public Task> GetPoliciesNamesAsync() + { + return Task.FromResult( + _options.GetPoliciesNames() + .Union( + _permissionDefinitionManager + .GetPermissions() + .Select(p => p.Name) + ) + .ToList() + ); + } } } diff --git a/src/Volo.Abp.Authorization/Volo/Abp/Authorization/IAbpAuthorizationPolicyProvider.cs b/src/Volo.Abp.Authorization/Volo/Abp/Authorization/IAbpAuthorizationPolicyProvider.cs new file mode 100644 index 0000000000..4444f064ad --- /dev/null +++ b/src/Volo.Abp.Authorization/Volo/Abp/Authorization/IAbpAuthorizationPolicyProvider.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; + +namespace Volo.Abp.Authorization +{ + public interface IAbpAuthorizationPolicyProvider : IAuthorizationPolicyProvider + { + Task> GetPoliciesNamesAsync(); + } +} \ No newline at end of file diff --git a/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationBuilder_Tests.cs b/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationBuilder_Tests.cs new file mode 100644 index 0000000000..0d2e84a0cf --- /dev/null +++ b/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationConfigurationBuilder_Tests.cs @@ -0,0 +1,20 @@ +using System.Threading.Tasks; +using Shouldly; +using Xunit; + +namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations +{ + public class ApplicationConfigurationBuilder_Tests : AspNetCoreMvcTestBase + { + [Fact] + public async Task ApplicationConfigurationBuilder_GetAsync() + { + var applicationConfigurationBuilder = GetRequiredService(); + + var config = await applicationConfigurationBuilder.GetAsync(); + + config.Auth.ShouldNotBeNull(); + config.Localization.ShouldNotBeNull(); + } + } +} diff --git a/test/Volo.Abp.Authorization.Tests/Microsoft/AspNetCore/Authorization/AuthorizationOptionsExtensions_Tests.cs b/test/Volo.Abp.Authorization.Tests/Microsoft/AspNetCore/Authorization/AuthorizationOptionsExtensions_Tests.cs new file mode 100644 index 0000000000..f5eaac2aa0 --- /dev/null +++ b/test/Volo.Abp.Authorization.Tests/Microsoft/AspNetCore/Authorization/AuthorizationOptionsExtensions_Tests.cs @@ -0,0 +1,19 @@ +using Shouldly; +using Xunit; + +namespace Microsoft.AspNetCore.Authorization +{ + public class AuthorizationOptionsExtensions_Tests + { + [Fact] + public void GetPoliciesNames() + { + var options = new AuthorizationOptions(); + + options.AddPolicy("TestPolicy1", policy => policy.RequireClaim("MyClaim")); + options.AddPolicy("TestPolicy2", policy => policy.RequireRole("MyRole")); + + options.GetPoliciesNames().Count.ShouldBe(2); + } + } +}