예제 #1
0
        public void Discover(ShapeTableBuilder builder)
        {
            var shapeAttributeOccurrences = new List <ShapeAttributeOccurrence>();

            foreach (var shapeProvider in _shapeProviders)
            {
                var serviceType = shapeProvider.GetType();

                IFeatureInfo feature = _typeFeatureProvider.GetFeatureForDependency(serviceType);
                if (builder.ExcludedFeatureIds.Contains(feature.Id))
                {
                    continue;
                }

                foreach (var method in serviceType.GetMethods())
                {
                    var customAttributes = method.GetCustomAttributes(typeof(ShapeAttribute), false).OfType <ShapeAttribute>();
                    foreach (var customAttribute in customAttributes)
                    {
                        shapeAttributeOccurrences.Add(new ShapeAttributeOccurrence(customAttribute, method, serviceType));
                    }
                }
            }

            foreach (var iter in shapeAttributeOccurrences)
            {
                var occurrence = iter;
                var shapeType  = occurrence.ShapeAttribute.ShapeType ?? occurrence.MethodInfo.Name;
                builder.Describe(shapeType)
                .From(_typeFeatureProvider.GetFeatureForDependency(occurrence.ServiceType))
                .BoundAs(
                    occurrence.MethodInfo.DeclaringType.FullName + "::" + occurrence.MethodInfo.Name,
                    descriptor => CreateDelegate(occurrence, descriptor));
            }
        }
예제 #2
0
        private async Task <IDictionary <PermissionGroupKey, IEnumerable <Permission> > > GetInstalledPermissionsAsync()
        {
            var installedPermissions = new Dictionary <PermissionGroupKey, IEnumerable <Permission> >();

            foreach (var permissionProvider in _permissionProviders)
            {
                var feature     = _typeFeatureProvider.GetFeatureForDependency(permissionProvider.GetType());
                var permissions = await permissionProvider.GetPermissionsAsync();

                foreach (var permission in permissions)
                {
                    var groupKey = GetGroupKey(feature, permission.Category);

                    if (installedPermissions.ContainsKey(groupKey))
                    {
                        installedPermissions[groupKey] = installedPermissions[groupKey].Concat(new[] { permission });

                        continue;
                    }

                    installedPermissions.Add(groupKey, new[] { permission });
                }
            }

            return(installedPermissions);
        }
예제 #3
0
        private async Task <IDictionary <string, IEnumerable <Permission> > > GetInstalledPermissionsAsync()
        {
            var installedPermissions = new Dictionary <string, IEnumerable <Permission> >();

            foreach (var permissionProvider in _permissionProviders)
            {
                var feature     = _typeFeatureProvider.GetFeatureForDependency(permissionProvider.GetType());
                var featureName = feature.Id;

                var permissions = await permissionProvider.GetPermissionsAsync();

                foreach (var permission in permissions)
                {
                    var category = permission.Category;

                    string title = String.IsNullOrWhiteSpace(category) ? S["{0} Feature", featureName] : category;

                    if (installedPermissions.ContainsKey(title))
                    {
                        installedPermissions[title] = installedPermissions[title].Concat(new[] { permission });
                    }
                    else
                    {
                        installedPermissions.Add(title, new[] { permission });
                    }
                }
            }

            return(installedPermissions);
        }
예제 #4
0
        // Called the 1st time a page is requested or if any page has been updated.
        public void OnProvidersExecuted(PageApplicationModelProviderContext context)
        {
            // Check if the page belongs to an enabled module.
            var relativePath   = context.ActionDescriptor.RelativePath;
            var found          = false;
            var featureForPath = _features.Where(f =>
                                                 relativePath.StartsWith('/' + f.Extension.SubPath + "/Pages/", StringComparison.Ordinal))
                                 .OrderBy(f => f.Id == f.Extension.Id ? 1 : 0).ToArray();

            // All pages with internal model types are available to module
            var pageModelType = context.PageApplicationModel.ModelType.AsType();

            if (!IsComponentType(pageModelType))
            {
                found = featureForPath.Any(f => f.Id == f.Extension.Id);
            }
            else
            {
                // Pages with public model types containing [Feature] attribute
                // are available only if feature is enabled
                foreach (var feature in featureForPath)
                {
                    var blueprint = _typeFeatureProvider.GetFeatureForDependency(pageModelType);
                    if (blueprint != null && feature.Id == blueprint.Id)
                    {
                        found = true;
                        break;
                    }
                }
            }

            context.PageApplicationModel.Filters.Add(new ModularPageViewEnginePathFilter(found));
        }
예제 #5
0
        public void OnProvidersExecuted(ApplicationModelProviderContext context)
        {
            // This code is called only once per tenant during the construction of routes.
            // Or if an 'IActionDescriptorChangeProvider' tells that an action descriptor
            // has changed. E.g 'PageActionDescriptorChangeProvider' after any page update.

            foreach (var controller in context.Result.Controllers)
            {
                var controllerType = controller.ControllerType.AsType();
                var blueprint      = _typeFeatureProvider.GetFeatureForDependency(controllerType);

                if (blueprint != null)
                {
                    if (blueprint.Extension.Id == _hostingEnvironment.ApplicationName &&
                        _shellSettings.State != TenantState.Running)
                    {
                        // Don't serve any action of the application'module which is enabled during a setup.
                        foreach (var action in controller.Actions)
                        {
                            action.Selectors.Clear();
                        }

                        controller.Selectors.Clear();
                    }
                    else
                    {
                        // Add an "area" route value equal to the module id.
                        controller.RouteValues.Add("area", blueprint.Extension.Id);
                    }
                }
            }
        }
예제 #6
0
        public async Task <IEnumerable <string> > GetFeaturesThatNeedUpdateAsync()
        {
            var currentVersions = (await GetDataMigrationRecordAsync()).DataMigrations
                                  .ToDictionary(r => r.DataMigrationClass);

            var outOfDateMigrations = _dataMigrations.Where(dataMigration =>
            {
                DataMigration record;
                if (currentVersions.TryGetValue(dataMigration.GetType().FullName, out record))
                {
                    return(CreateUpgradeLookupTable(dataMigration).ContainsKey(record.Version.Value));
                }

                return(GetCreateMethod(dataMigration) != null);
            });

            return(outOfDateMigrations.Select(m => _typeFeatureProvider.GetFeatureForDependency(m.GetType()).Descriptor.Id).ToList());
        }
예제 #7
0
 public void OnProvidersExecuted(ApplicationModelProviderContext context)
 {
     foreach (var controller in context.Result.Controllers)
     {
         var feature = _typeFeatureProvider.GetFeatureForDependency(controller.ControllerType.AsType());
         if (feature != null)
         {
             controller.RouteValues.Add("area", feature.Id);
         }
     }
 }
 public void OnProvidersExecuted(ApplicationModelProviderContext context)
 {
     foreach (var controller in context.Result.Controllers)
     {
         var schema = _provider.GetFeatureForDependency(controller.ControllerType.AsType());
         if (schema != null)
         {
             controller.RouteValues.Add("area", schema.Plugin.Id);
         }
     }
 }
 public void OnProvidersExecuted(ApplicationModelProviderContext context)
 {
     foreach (var controller in context.Result.Controllers)
     {
         var feature = _typeFeatureProvider.GetFeatureForDependency(controller.ControllerType.AsType());
         if (feature != null)
         {
             controller.RouteConstraints.Add(new AreaAttribute(feature.Descriptor.Id));
         }
     }
 }
예제 #10
0
 public void OnProvidersExecuted(ApplicationModelProviderContext context)
 {
     // This code is called only once per tenant during the construction of routes
     foreach (var controller in context.Result.Controllers)
     {
         var feature = _typeFeatureProvider.GetFeatureForDependency(controller.ControllerType.AsType());
         if (feature != null)
         {
             controller.RouteValues.Add("area", feature.Extension.Id);
         }
     }
 }
 public void Discover(ShapeTableBuilder builder)
 {
     foreach (var iter in _shapeAttributeOccurrences)
     {
         var occurrence = iter;
         var shapeType  = occurrence.ShapeAttribute.ShapeType ?? occurrence.MethodInfo.Name;
         builder.Describe(shapeType)
         .From(_typeFeatureProvider.GetFeatureForDependency(occurrence.ServiceType))
         .BoundAs(
             occurrence.MethodInfo.DeclaringType.FullName + "::" + occurrence.MethodInfo.Name,
             descriptor => CreateDelegate(occurrence, descriptor));
     }
 }
예제 #12
0
        public async Task <string> ExecuteAsync(string recipeFileName, IDataMigration migration)
        {
            var featureInfo = _typeFeatureProvider.GetFeatureForDependency(migration.GetType());

            var recipeBasePath   = Path.Combine(featureInfo.Extension.SubPath, "Migrations").Replace('\\', '/');
            var recipeFilePath   = Path.Combine(recipeBasePath, recipeFileName).Replace('\\', '/');
            var recipeFileInfo   = _hostingEnvironment.ContentRootFileProvider.GetFileInfo(recipeFilePath);
            var recipeDescriptor = await _recipeReader.GetRecipeDescriptor(recipeBasePath, recipeFileInfo, _hostingEnvironment.ContentRootFileProvider);

            recipeDescriptor.RequireNewScope = false;

            var executionId = Guid.NewGuid().ToString("n");

            return(await _recipeExecutor.ExecuteAsync(executionId, recipeDescriptor, new object(), CancellationToken.None));
        }
예제 #13
0
        public async Task <string> ExecuteAsync(string recipeFileName, IDataMigration migration)
        {
            var featureInfo = _typeFeatureProvider.GetFeatureForDependency(migration.GetType());

            var recipeBasePath   = Path.Combine(featureInfo.Extension.SubPath, "Migrations").Replace('\\', '/');
            var recipeFilePath   = Path.Combine(recipeBasePath, recipeFileName).Replace('\\', '/');
            var recipeFileInfo   = _hostingEnvironment.ContentRootFileProvider.GetFileInfo(recipeFilePath);
            var recipeDescriptor = await _recipeReader.GetRecipeDescriptor(recipeBasePath, recipeFileInfo, _hostingEnvironment.ContentRootFileProvider);

            recipeDescriptor.RequireNewScope = false;

            var environment = new Dictionary <string, object>();

            await _environmentProviders.OrderBy(x => x.Order).InvokeAsync((provider, env) => provider.PopulateEnvironmentAsync(env), environment, _logger);

            var executionId = Guid.NewGuid().ToString("n");

            return(await _recipeExecutor.ExecuteAsync(executionId, recipeDescriptor, environment, CancellationToken.None));
        }
예제 #14
0
        public async Task AddDefaultRolesForFeatureAsync(IFeatureInfo feature)
        {
            var providersForEnabledModule = _permissionProviders
                                            .Where(x => _typeFeatureProvider.GetFeatureForDependency(x.GetType()).Id == feature.Id);

            foreach (var permissionProvider in providersForEnabledModule)
            {
                var stereotypes = permissionProvider.GetDefaultStereotypes();
                foreach (var stereotype in stereotypes)
                {
                    var role = await _roleManager.FindByNameAsync(stereotype.Name);

                    if (role == null)
                    {
                        role = new Role {
                            Rolename = stereotype.Name
                        };
                        await _roleManager.CreateAsync(role);
                    }

                    var stereotypePermissionNames = (stereotype.Permissions ?? Enumerable.Empty <PermissionInfo>()).Select(x => x.Name);
                    var currentPermissionNames    = ((Role)role).RoleClaims.Where(x => x.ClaimType == PermissionInfo.ClaimType).Select(x => x.ClaimValue);

                    var distinctPermissionNames = currentPermissionNames
                                                  .Union(stereotypePermissionNames)
                                                  .Distinct();

                    var additionalPermissionNames = distinctPermissionNames.Except(currentPermissionNames);

                    if (additionalPermissionNames.Any())
                    {
                        foreach (var permissionName in additionalPermissionNames)
                        {
                            await _roleManager.AddClaimAsync(role, new Claim(PermissionInfo.ClaimType, permissionName));
                        }
                    }
                }
            }
        }
예제 #15
0
        private IDictionary <string, IEnumerable <PermissionInfo> > GetPermissions()
        {
            var existPermissions = new Dictionary <string, IEnumerable <PermissionInfo> >();

            foreach (var permissionProvider in _permissionProviders)
            {
                var feature     = _typeFeatureProvider.GetFeatureForDependency(permissionProvider.GetType());
                var permissions = permissionProvider.GetPermissions();
                foreach (var permission in permissions)
                {
                    string title = String.IsNullOrWhiteSpace(permission.Category) ? feature.Name : permission.Category;

                    if (existPermissions.ContainsKey(title))
                    {
                        existPermissions[title] = existPermissions[title].Concat(new[] { permission });
                    }
                    else
                    {
                        existPermissions.Add(title, new[] { permission });
                    }
                }
            }
            return(existPermissions);
        }
예제 #16
0
            public ShapeTable GetShapeTable(string themeId)
            {
                var cacheKey = $"ShapeTable:{themeId}";

                ShapeTable shapeTable;

                if (!_memoryCache.TryGetValue(cacheKey, out shapeTable))
                {
                    if (_logger.IsEnabled(LogLevel.Information))
                    {
                        _logger.LogInformation("Start building shape table");
                    }

                    var excludedFeatures = _shapeDescriptors.Count == 0 ? new List <string>() :
                                           _shapeDescriptors.Select(kv => kv.Value.Feature.Id).Distinct().ToList();

                    foreach (var bindingStrategy in _bindingStrategies)
                    {
                        IFeatureInfo strategyFeature = _typeFeatureProvider.GetFeatureForDependency(bindingStrategy.GetType());

                        if (!(bindingStrategy is IShapeTableHarvester) && excludedFeatures.Contains(strategyFeature.Id))
                        {
                            continue;
                        }

                        var builder = new ShapeTableBuilder(strategyFeature, excludedFeatures);
                        bindingStrategy.Discover(builder);
                        var builtAlterations = builder.BuildAlterations();

                        BuildDescriptors(bindingStrategy, builtAlterations);
                    }

                    var enabledAndOrderedFeatureIds = _shellFeaturesManager
                                                      .GetEnabledFeaturesAsync()
                                                      .GetAwaiter()
                                                      .GetResult()
                                                      .Select(f => f.Id)
                                                      .ToList();

                    var descriptors = _shapeDescriptors
                                      .Where(sd => enabledAndOrderedFeatureIds.Contains(sd.Value.Feature.Id))
                                      .Where(sd => IsModuleOrRequestedTheme(sd.Value.Feature, themeId))
                                      .OrderBy(sd => enabledAndOrderedFeatureIds.IndexOf(sd.Value.Feature.Id))
                                      .GroupBy(sd => sd.Value.ShapeType, StringComparer.OrdinalIgnoreCase)
                                      .Select(group => new ShapeDescriptorIndex
                                              (
                                                  shapeType: group.Key,
                                                  alterationKeys: group.Select(kv => kv.Key),
                                                  descriptors: _shapeDescriptors
                                              ));

                    shapeTable = new ShapeTable
                    {
                        Descriptors = descriptors.Cast <ShapeDescriptor>().ToDictionary(sd => sd.ShapeType, StringComparer.OrdinalIgnoreCase),
                        Bindings    = descriptors.SelectMany(sd => sd.Bindings).ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase)
                    };

                    if (_logger.IsEnabled(LogLevel.Information))
                    {
                        _logger.LogInformation("Done building shape table");
                    }

                    _memoryCache.Set(cacheKey, shapeTable, new MemoryCacheEntryOptions {
                        Priority = CacheItemPriority.NeverRemove
                    });
                }

                return(shapeTable);
            }
예제 #17
0
        public ShapeTable GetShapeTable(string themeId)
        {
            var cacheKey = $"ShapeTable:{themeId}";

            if (!_memoryCache.TryGetValue(cacheKey, out ShapeTable shapeTable))
            {
                if (_logger.IsEnabled(LogLevel.Information))
                {
                    _logger.LogInformation("Start building shape table");
                }

                HashSet <string> excludedFeatures;

                // Here we don't use a lock for thread safety but for atomicity.
                lock (_syncLock)
                {
                    excludedFeatures = new HashSet <string>(_shapeDescriptors.Select(kv => kv.Value.Feature.Id));
                }

                var shapeDescriptors = new Dictionary <string, FeatureShapeDescriptor>();

                foreach (var bindingStrategy in _bindingStrategies)
                {
                    var strategyFeature = _typeFeatureProvider.GetFeatureForDependency(bindingStrategy.GetType());

                    if (!(bindingStrategy is IShapeTableHarvester) && excludedFeatures.Contains(strategyFeature.Id))
                    {
                        continue;
                    }

                    var builder = new ShapeTableBuilder(strategyFeature, excludedFeatures);
                    bindingStrategy.Discover(builder);
                    var builtAlterations = builder.BuildAlterations();

                    BuildDescriptors(bindingStrategy, builtAlterations, shapeDescriptors);
                }

                // Here we don't use a lock for thread safety but for atomicity.
                lock (_syncLock)
                {
                    foreach (var kv in shapeDescriptors)
                    {
                        _shapeDescriptors[kv.Key] = kv.Value;
                    }
                }

                var enabledAndOrderedFeatureIds = _shellFeaturesManager
                                                  .GetEnabledFeaturesAsync()
                                                  .GetAwaiter()
                                                  .GetResult()
                                                  .Select(f => f.Id)
                                                  .ToList();

                // let the application acting as a super theme for shapes rendering.
                if (enabledAndOrderedFeatureIds.Remove(_hostingEnvironment.ApplicationName))
                {
                    enabledAndOrderedFeatureIds.Add(_hostingEnvironment.ApplicationName);
                }

                var descriptors = _shapeDescriptors
                                  .Where(sd => enabledAndOrderedFeatureIds.Contains(sd.Value.Feature.Id))
                                  .Where(sd => IsModuleOrRequestedTheme(sd.Value.Feature, themeId))
                                  .OrderBy(sd => enabledAndOrderedFeatureIds.IndexOf(sd.Value.Feature.Id))
                                  .GroupBy(sd => sd.Value.ShapeType, StringComparer.OrdinalIgnoreCase)
                                  .Select(group => new ShapeDescriptorIndex
                                          (
                                              shapeType: group.Key,
                                              alterationKeys: group.Select(kv => kv.Key),
                                              descriptors: _shapeDescriptors
                                          ))
                                  .ToList();

                shapeTable = new ShapeTable
                {
                    Descriptors = descriptors.ToDictionary(sd => sd.ShapeType, x => (ShapeDescriptor)x, StringComparer.OrdinalIgnoreCase),
                    Bindings    = descriptors.SelectMany(sd => sd.Bindings).ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase)
                };

                if (_logger.IsEnabled(LogLevel.Information))
                {
                    _logger.LogInformation("Done building shape table");
                }

                _memoryCache.Set(cacheKey, shapeTable, new MemoryCacheEntryOptions {
                    Priority = CacheItemPriority.NeverRemove
                });
            }

            return(shapeTable);
        }
예제 #18
0
        public async Task AddDefaultRolesForFeatureAsync(Feature feature)
        {
            var featureName = feature.Descriptor.Id;

            // when another module is being enabled, locate matching permission providers
            var providersForEnabledModule = _permissionProviders.Where(x => _typeFeatureProvider.GetFeatureForDependency(x.GetType())?.Descriptor?.Id == featureName);

            if (Logger.IsEnabled(LogLevel.Debug))
            {
                if (providersForEnabledModule.Any())
                {
                    Logger.LogDebug($"Configuring default roles for module {featureName}");
                }
                else
                {
                    Logger.LogDebug($"No default roles for module {featureName}");
                }
            }

            foreach (var permissionProvider in providersForEnabledModule)
            {
                // get and iterate stereotypical groups of permissions
                var stereotypes = permissionProvider.GetDefaultStereotypes();
                foreach (var stereotype in stereotypes)
                {
                    // turn those stereotypes into roles
                    var role = await _roleManager.GetRoleByNameAsync(stereotype.Name);

                    if (role == null)
                    {
                        if (Logger.IsEnabled(LogLevel.Information))
                        {
                            Logger.LogInformation($"Defining new role {stereotype.Name} for permission stereotype");
                        }

                        role = await _roleManager.CreateRoleAsync(stereotype.Name);
                    }

                    // and merge the stereotypical permissions into that role
                    var stereotypePermissionNames = (stereotype.Permissions ?? Enumerable.Empty <Permission>()).Select(x => x.Name);
                    var currentPermissionNames    = role.RoleClaims.Where(x => x.ClaimType == Permission.ClaimType).Select(x => x.ClaimValue);

                    var distinctPermissionNames = currentPermissionNames
                                                  .Union(stereotypePermissionNames)
                                                  .Distinct();


                    // update role if set of permissions has increased
                    var additionalPermissionNames = distinctPermissionNames.Except(currentPermissionNames);

                    if (additionalPermissionNames.Any())
                    {
                        foreach (var permissionName in additionalPermissionNames)
                        {
                            if (Logger.IsEnabled(LogLevel.Debug))
                            {
                                Logger.LogInformation("Default role {0} granted permission {1}", stereotype.Name, permissionName);
                            }

                            role.RoleClaims.Add(new RoleClaim()
                            {
                                ClaimType = Permission.ClaimType, ClaimValue = permissionName
                            });
                        }
                    }
                }
            }

            _roleManager.UpdateRoles();
        }
        public ShapeTable GetShapeTable(string themeName)
        {
            var cacheKey = $"ShapeTable:{themeName}";

            ShapeTable shapeTable;

            if (!_memoryCache.TryGetValue(cacheKey, out shapeTable))
            {
                if (_logger.IsEnabled(LogLevel.Information))
                {
                    _logger.LogInformation("Start building shape table");
                }
                IList <IReadOnlyList <ShapeAlteration> > alterationSets = new List <IReadOnlyList <ShapeAlteration> >();
                foreach (var bindingStrategy in _bindingStrategies)
                {
                    Feature strategyDefaultFeature =
                        _typeFeatureProvider.GetFeatureForDependency(bindingStrategy.GetType());

                    var builder = new ShapeTableBuilder(strategyDefaultFeature);
                    bindingStrategy.Discover(builder);
                    var builtAlterations = builder.BuildAlterations().ToReadOnlyCollection();
                    if (builtAlterations.Any())
                    {
                        alterationSets.Add(builtAlterations);
                    }
                }

                var alterations = alterationSets
                                  .SelectMany(shapeAlterations => shapeAlterations)
                                  .Where(alteration => IsModuleOrRequestedTheme(alteration, themeName))
                                  .OrderByDependenciesAndPriorities(AlterationHasDependency, GetPriority)
                                  .ToList();

                var descriptors = alterations.GroupBy(alteration => alteration.ShapeType, StringComparer.OrdinalIgnoreCase)
                                  .Select(group => group.Aggregate(
                                              new ShapeDescriptor {
                    ShapeType = group.Key
                },
                                              (descriptor, alteration) =>
                {
                    alteration.Alter(descriptor);
                    return(descriptor);
                })).ToList();

                foreach (var descriptor in descriptors)
                {
                    foreach (var alteration in alterations.Where(a => a.ShapeType == descriptor.ShapeType).ToList())
                    {
                        var local = new ShapeDescriptor {
                            ShapeType = descriptor.ShapeType
                        };
                        alteration.Alter(local);
                        descriptor.BindingSources.Add(local.BindingSource);
                    }
                }

                shapeTable = new ShapeTable
                {
                    Descriptors = descriptors.ToDictionary(sd => sd.ShapeType, StringComparer.OrdinalIgnoreCase),
                    Bindings    = descriptors.SelectMany(sd => sd.Bindings).ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase),
                };

                //await _eventBus.NotifyAsync<IShapeTableEventHandler>(x => x.ShapeTableCreated(result));

                if (_logger.IsEnabled(LogLevel.Information))
                {
                    _logger.LogInformation("Done building shape table");
                }

                _memoryCache.Set(cacheKey, shapeTable, new MemoryCacheEntryOptions {
                    Priority = CacheItemPriority.NeverRemove
                });
            }

            return(shapeTable);
        }
예제 #20
0
        public async Task AddDefaultRolesForFeatureAsync(IFeatureInfo feature)
        {
            // when another module is being enabled, locate matching permission providers
            var providersForEnabledModule = _permissionProviders
                                            .Where(x => _typeFeatureProvider.GetFeatureForDependency(x.GetType()).Id == feature.Id);

            if (_logger.IsEnabled(LogLevel.Debug))
            {
                if (providersForEnabledModule.Any())
                {
                    _logger.LogDebug("Configuring default roles for feature '{FeatureName}'", feature.Id);
                }
                else
                {
                    _logger.LogDebug("No default roles for feature '{FeatureName}'", feature.Id);
                }
            }

            foreach (var permissionProvider in providersForEnabledModule)
            {
                // get and iterate stereotypical groups of permissions
                var stereotypes = permissionProvider.GetDefaultStereotypes();
                foreach (var stereotype in stereotypes)
                {
                    // turn those stereotypes into roles
                    var role = await _roleManager.FindByNameAsync(stereotype.Name);

                    if (role == null)
                    {
                        if (_logger.IsEnabled(LogLevel.Information))
                        {
                            _logger.LogInformation("Defining new role '{RoleName}' for permission stereotype", stereotype.Name);
                        }

                        role = new Role {
                            RoleName = stereotype.Name, RoleDescription = stereotype.Name + " role"
                        };
                        await _roleManager.CreateAsync(role);
                    }

                    // and merge the stereotypical permissions into that role
                    var stereotypePermissionNames = (stereotype.Permissions ?? Enumerable.Empty <Permission>()).Select(x => x.Name);
                    var currentPermissionNames    = ((Role)role).RoleClaims.Where(x => x.ClaimType == Permission.ClaimType).Select(x => x.ClaimValue);

                    var distinctPermissionNames = currentPermissionNames
                                                  .Union(stereotypePermissionNames)
                                                  .Distinct();

                    // update role if set of permissions has increased
                    var additionalPermissionNames = distinctPermissionNames.Except(currentPermissionNames);

                    if (additionalPermissionNames.Any())
                    {
                        foreach (var permissionName in additionalPermissionNames)
                        {
                            if (_logger.IsEnabled(LogLevel.Debug))
                            {
                                _logger.LogDebug("Default role '{Role}' granted permission '{Permission}'", stereotype.Name, permissionName);
                            }

                            await _roleManager.AddClaimAsync(role, new Claim(Permission.ClaimType, permissionName));
                        }
                    }
                }
            }
        }
예제 #21
0
        public ShapeTable GetShapeTable(string themeName)
        {
            // Use a lazy initialized factory to prevent multiple threads from building
            // the same table in parallel as it is costly
            return(_shapeTables.GetOrAdd(themeName ?? "", new Lazy <ShapeTable>(() =>
            {
                if (_logger.IsEnabled(LogLevel.Information))
                {
                    _logger.LogInformation("Start building shape table");
                }
                IList <IReadOnlyList <ShapeAlteration> > alterationSets = new List <IReadOnlyList <ShapeAlteration> >();
                foreach (var bindingStrategy in _bindingStrategies)
                {
                    Feature strategyDefaultFeature =
                        _typeFeatureProvider.GetFeatureForDependency(bindingStrategy.GetType());

                    var builder = new ShapeTableBuilder(strategyDefaultFeature);
                    bindingStrategy.Discover(builder);
                    var builtAlterations = builder.BuildAlterations().ToReadOnlyCollection();
                    if (builtAlterations.Any())
                    {
                        alterationSets.Add(builtAlterations);
                    }
                }

                var alterations = alterationSets
                                  .SelectMany(shapeAlterations => shapeAlterations)
                                  .Where(alteration => IsModuleOrRequestedTheme(alteration, themeName))
                                  .OrderByDependenciesAndPriorities(AlterationHasDependency, GetPriority)
                                  .ToList();

                var descriptors = alterations.GroupBy(alteration => alteration.ShapeType, StringComparer.OrdinalIgnoreCase)
                                  .Select(group => group.Aggregate(
                                              new ShapeDescriptor {
                    ShapeType = group.Key
                },
                                              (descriptor, alteration) =>
                {
                    alteration.Alter(descriptor);
                    return descriptor;
                })).ToList();

                foreach (var descriptor in descriptors)
                {
                    foreach (var alteration in alterations.Where(a => a.ShapeType == descriptor.ShapeType).ToList())
                    {
                        var local = new ShapeDescriptor {
                            ShapeType = descriptor.ShapeType
                        };
                        alteration.Alter(local);
                        descriptor.BindingSources.Add(local.BindingSource);
                    }
                }

                var result = new ShapeTable
                {
                    Descriptors = descriptors.ToDictionary(sd => sd.ShapeType, StringComparer.OrdinalIgnoreCase),
                    Bindings = descriptors.SelectMany(sd => sd.Bindings).ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase),
                };

                //await _eventBus.NotifyAsync<IShapeTableEventHandler>(x => x.ShapeTableCreated(result));

                if (_logger.IsEnabled(LogLevel.Information))
                {
                    _logger.LogInformation("Done building shape table");
                }
                return result;
            })).Value);
        }
예제 #22
0
        // void IFeatureEventHandler.Installing(IFeatureInfo feature)
        // {
        // }

        // void IFeatureEventHandler.Installed(IFeatureInfo feature)
        // {
        //     AddDefaultRolesForFeatureAsync(feature).Wait();
        // }

        // void IFeatureEventHandler.Enabling(IFeatureInfo feature)
        // {
        // }

        // void IFeatureEventHandler.Enabled(IFeatureInfo feature)
        // {
        // }

        // void IFeatureEventHandler.Disabling(IFeatureInfo feature)
        // {
        // }

        // void IFeatureEventHandler.Disabled(IFeatureInfo feature)
        // {
        // }

        // void IFeatureEventHandler.Uninstalling(IFeatureInfo feature)
        // {
        // }

        // void IFeatureEventHandler.Uninstalled(IFeatureInfo feature)
        // {
        // }

        public async Task AddDefaultRolesForFeatureAsync(IFeatureInfo feature)
        {
            var providersForEnabledModule = _permissionProviders
                                            .Where(x => _typeFeatureProvider.GetFeatureForDependency(x.GetType()).Id == feature.Id);

            if (Logger.IsEnabled(LogLevel.Debug))
            {
                if (providersForEnabledModule.Any())
                {
                    Logger.LogDebug("Configuring default roles for feature '{FeatureName}'", feature.Id);
                }
                else
                {
                    Logger.LogDebug("No default roles for feature '{FeatureName}'", feature.Id);
                }
            }

            foreach (var permissionProvider in providersForEnabledModule)
            {
                var stereotypes = permissionProvider.GetDefaultStereotypes();
                foreach (var stereotype in stereotypes)
                {
                    var role = await _roleManager.FindByNameAsync(stereotype.Name);

                    if (role == null)
                    {
                        if (Logger.IsEnabled(LogLevel.Information))
                        {
                            Logger.LogInformation("Defining new role '{RoleName}' for permission stereotype", stereotype.Name);
                        }

                        role = new RoleInfo {
                            RoleName = stereotype.Name
                        };
                        await _roleManager.CreateAsync(role);
                    }

                    var stereotypePermissionNames = (stereotype.Permissions ?? Enumerable.Empty <Permission>()).Select(x => x.Name);
                    var currentPermissionNames    = ((RoleInfo)role).RoleClaims.Where(x => x.ClaimType == Permission.ClaimType).Select(x => x.ClaimValue);

                    var distinctPermissionNames = currentPermissionNames
                                                  .Union(stereotypePermissionNames)
                                                  .Distinct();

                    var additionalPermissionNames = distinctPermissionNames.Except(currentPermissionNames);

                    if (additionalPermissionNames.Any())
                    {
                        foreach (var permissionName in additionalPermissionNames)
                        {
                            if (Logger.IsEnabled(LogLevel.Debug))
                            {
                                Logger.LogDebug("Default role '{Role}' granted permission '{Permission}'", stereotype.Name, permissionName);
                            }

                            await _roleManager.AddClaimAsync(role, new Claim(Permission.ClaimType, permissionName));
                        }
                    }
                }
            }
        }