using System.Collections.Generic; using System.Threading.Tasks; using Abp.Application.Features; using Abp.Authorization; using Abp.Collections.Extensions; using Abp.Dependency; using Abp.Localization; using Abp.MultiTenancy; using Abp.Runtime.Session; namespace Abp.Application.Navigation { internal class UserNavigationManager : IUserNavigationManager, ITransientDependency { public IAbpSession AbpSession { get; set; } private readonly INavigationManager _navigationManager; private readonly ILocalizationContext _localizationContext; private readonly IIocResolver _iocResolver; public UserNavigationManager( INavigationManager navigationManager, ILocalizationContext localizationContext, IIocResolver iocResolver) { _navigationManager = navigationManager; _localizationContext = localizationContext; _iocResolver = iocResolver; AbpSession = NullAbpSession.Instance; } public async Task GetMenuAsync(string menuName, UserIdentifier user) { var menuDefinition = _navigationManager.Menus.GetOrDefault(menuName); if (menuDefinition == null) { throw new AbpException("There is no menu with given name: " + menuName); } var userMenu = new UserMenu(menuDefinition, _localizationContext); await FillUserMenuItems(user, menuDefinition.Items, userMenu.Items); return userMenu; } public async Task> GetMenusAsync(UserIdentifier user) { var userMenus = new List(); foreach (var menu in _navigationManager.Menus.Values) { userMenus.Add(await GetMenuAsync(menu.Name, user)); } return userMenus; } private async Task FillUserMenuItems(UserIdentifier user, IList menuItemDefinitions, IList userMenuItems) { //TODO: Can be optimized by re-using FeatureDependencyContext. var addedMenuItemCount = 0; using (var scope = _iocResolver.CreateScope()) { var permissionDependencyContext = scope.Resolve(); permissionDependencyContext.User = user; var featureDependencyContext = scope.Resolve(); featureDependencyContext.TenantId = user == null ? null : user.TenantId; foreach (var menuItemDefinition in menuItemDefinitions) { if (menuItemDefinition.RequiresAuthentication && user == null) { continue; } if (!string.IsNullOrEmpty(menuItemDefinition.RequiredPermissionName)) { var permissionDependency = new SimplePermissionDependency(menuItemDefinition.RequiredPermissionName); if (user == null || !(await permissionDependency.IsSatisfiedAsync(permissionDependencyContext))) { continue; } } if (menuItemDefinition.PermissionDependency != null && (user == null || !(await menuItemDefinition.PermissionDependency.IsSatisfiedAsync(permissionDependencyContext)))) { continue; } if (menuItemDefinition.FeatureDependency != null && (AbpSession.MultiTenancySide == MultiTenancySides.Tenant || (user != null && user.TenantId != null)) && !(await menuItemDefinition.FeatureDependency.IsSatisfiedAsync(featureDependencyContext))) { continue; } var userMenuItem = new UserMenuItem(menuItemDefinition, _localizationContext); if (menuItemDefinition.IsLeaf || (await FillUserMenuItems(user, menuItemDefinition.Items, userMenuItem.Items)) > 0) { userMenuItems.Add(userMenuItem); ++addedMenuItemCount; } } } return addedMenuItemCount; } } }