Is there anyway to automate the creation process of AppPermissions? Is there any particular reason to put AppAuthorizationProvider in .Core level? I intended to create AppPermissions for all Application Service, but I cannot use reflection as the AppAuthorizationProvider is in .Core level while all services are in .Application level
3 Answer(s)
-
0
Here you go. Adapt this to your needs:
Core project - MyAppAuthorizationProvider.cs:
using Abp.Authorization; using Abp.Localization; using Abp.MultiTenancy; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace MyApp.Authorization { public class MyAppAuthorizationProvider : AuthorizationProvider { public override void SetPermissions(IPermissionDefinitionContext context) { List<PermissionInfo> permissionInfos = new List<PermissionInfo>(); foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { if (!assembly.IsDynamic) { foreach (TypeInfo typeInfo in assembly.GetExportedTypes()) { // Attributes on Fields (Constants) foreach (FieldInfo fieldInfo in typeInfo.GetFields()) { var permissionAttribute = fieldInfo.GetCustomAttribute<PermissionAttribute>(false); if (permissionAttribute != null) { permissionInfos.Add( new PermissionInfo() { Name = (string)fieldInfo.GetRawConstantValue(), DisplayName = permissionAttribute.DisplayName, IsGrantedByDefault = permissionAttribute.IsGrantedByDefault, MultiTenancySides = permissionAttribute.MultiTenancySides }); } } } } } foreach (PermissionInfo permissionInfo in permissionInfos.OrderBy(p => p.Name)) { Permission parentPermission = null; Permission newPermission = null; if (permissionInfo.Name.Contains(".")) { string parentName = permissionInfo.Name.Substring(0, permissionInfo.Name.LastIndexOf('.')); parentPermission = context.GetPermissionOrNull(parentName); if (parentPermission == null) { throw new Exception("Permission not defined: '" + parentName + "'"); } newPermission = parentPermission.CreateChildPermission( name: permissionInfo.Name, displayName: F(permissionInfo.DisplayName), isGrantedByDefault: permissionInfo.IsGrantedByDefault, description: F(permissionInfo.Description), multiTenancySides: permissionInfo.MultiTenancySides); } else { newPermission = context.CreatePermission( name: permissionInfo.Name, displayName: F(permissionInfo.DisplayName), isGrantedByDefault: permissionInfo.IsGrantedByDefault, description: F(permissionInfo.Description), multiTenancySides: permissionInfo.MultiTenancySides); } } } public class PermissionInfo { public string Name; public string DisplayName; public string Description; public MultiTenancySides MultiTenancySides; public bool IsGrantedByDefault; } /// <summary> /// Creates a fixed localizable string (avoids using localization - just pass it the text directly) /// </summary> private static ILocalizableString F(string value) { return new FixedLocalizableString(value); } private static ILocalizableString L(string name) { return new LocalizableString(name, MyAppConstants.LocalizationSourceName); } } }
Core project - PermissionAttribute.cs
using Abp.MultiTenancy; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MyApp.Authorization { public partial class PermissionAttribute : Attribute { // Note: The Name (not display name) of the property is defined by the name of the constant the attribute is applied to. public string DisplayName { get; set; } public string Description { get; set; } private MultiTenancySides _multiTenancySides = MultiTenancySides.Host | MultiTenancySides.Tenant; public MultiTenancySides MultiTenancySides { get { return _multiTenancySides; } set { _multiTenancySides = value; } } public bool IsGrantedByDefault { get; set; } } }
Then, ANYWHERE in your solution, in ANY PROJECT, you can define classes like this:
using MyApp.Authorization; using System.ComponentModel; namespace MyApp.Authorization { public static partial class PermissionNames { [Permission(DisplayName = "Administration")] // MultiTenancySides defaults to Host & Tenant if not specified. This way, the host AND customers (tenants) can have admin sections. public const string Administration = "Administration"; [Permission(DisplayName = "Customer Management", MultiTenancySides = Abp.MultiTenancy.MultiTenancySides.Host)] public const string CustomerManagement = "Administration.CustomerManagement"; // Permissions will automatically be arranged into the proper hierarchy (parent/child) based on the Parent.Child.Grandchild dot-based naming pattern. [Permission(DisplayName = "Customer Portal", MultiTenancySides = Abp.MultiTenancy.MultiTenancySides.Tenant)] public const string CustomerPortal = "CustomerPortal"; // Only customers (tenants) can be assigned this permission } }
And the core auth code will find the attributes on the constants and automagically create your permissions with the correct hierarchical structure
-
0
I wrote:
// Note: The Name (not display name) of the property is defined by the name of the constant the attribute is applied to.
But it should actually say this:
// Note: The Name (not display name) of the property is defined by the value of the constant the attribute is applied to.
-
0
ONE MORE CORRECTION, SORRY! This time I tested it ;)
using Abp.Authorization; using Abp.Localization; using Abp.MultiTenancy; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace MyApp.Authorization { public class MyAppAuthorizationProvider : AuthorizationProvider { public override void SetPermissions(IPermissionDefinitionContext context) { List<PermissionInfo> permissionInfos = new List<PermissionInfo>(); foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { if (!assembly.IsDynamic) { foreach (TypeInfo typeInfo in assembly.GetExportedTypes()) { // Attributes on Fields (Constants) foreach (FieldInfo fieldInfo in typeInfo.GetFields()) { var permissionAttribute = fieldInfo.GetCustomAttribute<PermissionAttribute>(false); if (permissionAttribute != null) { permissionInfos.Add( new PermissionInfo() { Name = (string)fieldInfo.GetRawConstantValue(), DisplayName = permissionAttribute.DisplayName, IsGrantedByDefault = permissionAttribute.IsGrantedByDefault, MultiTenancySides = permissionAttribute.MultiTenancySides }); } } } } } var parentNameBuilder = new StringBuilder(); foreach (PermissionInfo permissionInfo in permissionInfos.OrderBy(p => p.Name)) { if (!permissionInfo.Name.Contains(".")) { // Create top level permission var newPermission = context.CreatePermission( name: permissionInfo.Name, displayName: F(permissionInfo.DisplayName), isGrantedByDefault: permissionInfo.IsGrantedByDefault, description: F(permissionInfo.Description), multiTenancySides: permissionInfo.MultiTenancySides); } else { // Create child permission under appropriate parent var nameParts = permissionInfo.Name.Split('.'); parentNameBuilder.Clear(); parentNameBuilder.Append(nameParts[0]); Permission parentPermission = context.GetPermissionOrNull(parentNameBuilder.ToString()); for (int i = 1; i < nameParts.Length - 1; i++) { parentNameBuilder.Append("."); parentNameBuilder.Append(nameParts[i]); parentPermission = parentPermission.Children.Where(p => string.Compare(p.Name, parentNameBuilder.ToString(), true) == 0).FirstOrDefault(); } if (parentPermission == null) { throw new Exception("Parent permission not defined: '" + parentNameBuilder.ToString() + "'"); } var newPermission = parentPermission.CreateChildPermission( name: permissionInfo.Name, displayName: F(permissionInfo.DisplayName), isGrantedByDefault: permissionInfo.IsGrantedByDefault, description: F(permissionInfo.Description), multiTenancySides: permissionInfo.MultiTenancySides); } } } public class PermissionInfo { public string Name; public string DisplayName; public string Description; public MultiTenancySides MultiTenancySides; public bool IsGrantedByDefault; } /// <summary> /// Creates a fixed localizable string (avoids using localization - just pass it the text directly) /// </summary> private static ILocalizableString F(string value) { return new FixedLocalizableString(value); } private static ILocalizableString L(string name) { return new LocalizableString(name, MyAppConstants.LocalizationSourceName); } } }