diff --git a/docs/en/Authorization.md b/docs/en/Authorization.md index ebd6d4c3ea..d6cb8cee3f 100644 --- a/docs/en/Authorization.md +++ b/docs/en/Authorization.md @@ -412,6 +412,35 @@ public override void ConfigureServices(ServiceConfigurationContext context) This is already done for the startup template integration tests. +### Claims Principal Factory + +Claims are important elements of authentication and authorization. ABP uses the `IAbpClaimsPrincipalFactory` service to create claims on authentication. This service was designed as extensible. If you need to add your custom claims to the authentication ticket, you can implement the `IAbpClaimsPrincipalContributor` in your application. + +**Example: Add a `SocialSecurityNumber` claim:** + +```csharp +public class SocialSecurityNumberClaimsPrincipalContributor : IAbpClaimsPrincipalContributor, ITransientDependency +{ + public async Task ContributeAsync(AbpClaimsPrincipalContributorContext context) + { + var identity = context.ClaimsPrincipal.Identities.FirstOrDefault(); + if (identity != null) + { + var currentUser = context.ServiceProvider.GetRequiredService(); + if (currentUser.Id.HasValue) + { + var userService = context.ServiceProvider.GetRequiredService(); //Your custom service + var socialSecurityNumber = await userService.GetSocialSecurityNumberAsync(currentUser.Id.Value); + if (userService != null) + { + identity.AddOrReplace(new Claim("SocialSecurityNumber", userService)); + } + } + } + } +} +``` + ## See Also * [Permission Management Module](Modules/Permission-Management.md) diff --git a/docs/en/Modules/Docs.md b/docs/en/Modules/Docs.md index 35478d9ce0..90c0699dfa 100644 --- a/docs/en/Modules/Docs.md +++ b/docs/en/Modules/Docs.md @@ -320,7 +320,7 @@ Open `DocsProjects` in your database, and insert a new record with the following * **ShortName**: A short and URL friendly name that will be used in your docs URL. * **Format**: The format of the document (for Markdown: `md`, for HTML: `html`) * **DefaultDocumentName**: The document for the initial page. -* **NavigationDocumentName**: The document to be used for the navigation menu (index). +* **NavigationDocumentName**: The document to be used for the navigation menu (Index). * **MinimumVersion**: The minimum version to show the docs. Below version will not be listed. * **DocumentStoreType**: The source of the documents (for GitHub:`GitHub`, for file system`FileSystem`) * **ExtraProperties**: A serialized `JSON` that stores special configuration for the selected `DocumentStoreType`. @@ -625,4 +625,4 @@ If your `IElasticClient` needs additional configuration, please use override `IE ## Next -Docs Module is also available as a standalone application. Check out [VoloDocs](../Apps/VoloDocs). \ No newline at end of file +Docs Module is also available as a standalone application. Check out [VoloDocs](../Apps/VoloDocs). diff --git a/docs/en/Repositories.md b/docs/en/Repositories.md index 3d0ea84821..7ed10b9bb8 100644 --- a/docs/en/Repositories.md +++ b/docs/en/Repositories.md @@ -70,8 +70,8 @@ Generic Repositories provides some standard CRUD features out of the box: There are overloads of these methods. -* Provides `Update` and `Delete` methods to update or delete an entity by entity object or it's id. -* Provides `Delete` method to delete multiple entities by a filter. +* Provides `UpdateAsync` and `DeleteAsync` methods to update or delete an entity by entity object or it's id. +* Provides `DeleteAsync` method to delete multiple entities by a filter. ### Querying / LINQ over the Repositories diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlingService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlingService.cs index cc8d9c0bf5..74be59e014 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlingService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Bundling/BundlingService.cs @@ -77,17 +77,25 @@ namespace Volo.Abp.Cli.Bundling BundleName = bundleConfig.Name.IsNullOrEmpty() ? "global" : bundleConfig.Name, Minify = bundleConfig.Mode == BundlingMode.BundleAndMinify }; - + + Logger.LogInformation("Generating style bundle..."); styleDefinitions = StyleBundler.Bundle(options, styleContext); + Logger.LogInformation($"Style bundle has been generated successfully."); + + Logger.LogInformation("Generating script bundle..."); scriptDefinitions = ScriptBundler.Bundle(options, scriptContext); + Logger.LogInformation($"Script bundle has been generated successfully."); } else { + Logger.LogInformation("Generating style references..."); styleDefinitions = GenerateStyleDefinitions(styleContext); + Logger.LogInformation("Generating script references..."); scriptDefinitions = GenerateScriptDefinitions(scriptContext); } - + await UpdateDependenciesInHtmlFileAsync(directory, styleDefinitions, scriptDefinitions); + Logger.LogInformation("Script and style references in the index.html file have been updated."); } private BundleContext GetScriptContext(List bundleDefinitions, diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/IAbpCommonDbContextRegistrationOptionsBuilder.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/IAbpCommonDbContextRegistrationOptionsBuilder.cs index ebe49718b2..34e74d90cd 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/IAbpCommonDbContextRegistrationOptionsBuilder.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/IAbpCommonDbContextRegistrationOptionsBuilder.cs @@ -9,43 +9,42 @@ namespace Volo.Abp.DependencyInjection IServiceCollection Services { get; } /// - /// Registers default repositories for this DbContext. + /// Registers default repositories for all the entities in this DbContext. /// /// /// Registers repositories only for aggregate root entities by default. - /// set to true to include all entities. + /// Set to true to include all entities. /// IAbpCommonDbContextRegistrationOptionsBuilder AddDefaultRepositories(bool includeAllEntities = false); /// - /// Registers default repositories for this DbContext. + /// Registers default repositories for all the entities in this DbContext. /// Default repositories will use given . /// /// DbContext type that will be used by default repositories /// /// Registers repositories only for aggregate root entities by default. - /// set to true to include all entities. + /// Set to true to include all entities. /// IAbpCommonDbContextRegistrationOptionsBuilder AddDefaultRepositories(bool includeAllEntities = false); /// - /// Registers default repositories for this DbContext. + /// Registers default repositories for all the entities in this DbContext. /// Default repositories will use given . /// /// DbContext type that will be used by default repositories /// /// Registers repositories only for aggregate root entities by default. - /// set to true to include all entities. + /// Set to true to include all entities. /// IAbpCommonDbContextRegistrationOptionsBuilder AddDefaultRepositories(Type defaultRepositoryDbContextType, bool includeAllEntities = false); /// - /// Registers custom repository for a specific entity. + /// Registers default repository for a specific entity. /// /// Entity type IAbpCommonDbContextRegistrationOptionsBuilder AddDefaultRepository(); - /// /// Registers default repository for a specific entity. /// diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs index 200f002e07..299994e695 100644 --- a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs +++ b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/GlobalFeatureDefinitionExtensions.cs @@ -1,4 +1,5 @@ -using JetBrains.Annotations; +using System; +using JetBrains.Annotations; using Volo.Abp.Authorization.Permissions; namespace Volo.Abp.GlobalFeatures @@ -6,12 +7,12 @@ namespace Volo.Abp.GlobalFeatures public static class GlobalFeatureDefinitionExtensions { public static PermissionDefinition RequireGlobalFeatures( - this PermissionDefinition permissionDefinition, + this PermissionDefinition permissionDefinition, params string[] globalFeatures) { return permissionDefinition.RequireGlobalFeatures(true, globalFeatures); } - + public static PermissionDefinition RequireGlobalFeatures( [NotNull] this PermissionDefinition permissionDefinition, bool requiresAll, @@ -25,5 +26,25 @@ namespace Volo.Abp.GlobalFeatures ); } + public static PermissionDefinition RequireGlobalFeatures( + this PermissionDefinition permissionDefinition, + params Type[] globalFeatures) + { + return permissionDefinition.RequireGlobalFeatures(true, globalFeatures); + } + + public static PermissionDefinition RequireGlobalFeatures( + [NotNull] this PermissionDefinition permissionDefinition, + bool requiresAll, + params Type[] globalFeatures) + { + Check.NotNull(permissionDefinition, nameof(permissionDefinition)); + Check.NotNullOrEmpty(globalFeatures, nameof(globalFeatures)); + + return permissionDefinition.AddStateProviders( + new RequireGlobalFeaturesPermissionStateProvider(requiresAll, globalFeatures) + ); + } + } } diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesPermissionStateProvider.cs b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesPermissionStateProvider.cs index 40df2a14b3..c96e652e8c 100644 --- a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesPermissionStateProvider.cs +++ b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/RequireGlobalFeaturesPermissionStateProvider.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using System.Threading.Tasks; using Volo.Abp.Authorization.Permissions; @@ -13,7 +14,7 @@ namespace Volo.Abp.GlobalFeatures : this(true, globalFeatureNames) { } - + public RequireGlobalFeaturesPermissionStateProvider(bool requiresAll, params string[] globalFeatureNames) { Check.NotNullOrEmpty(globalFeatureNames, nameof(globalFeatureNames)); @@ -22,12 +23,20 @@ namespace Volo.Abp.GlobalFeatures _globalFeatureNames = globalFeatureNames; } + public RequireGlobalFeaturesPermissionStateProvider(bool requiresAll, params Type[] globalFeatureNames) + { + Check.NotNullOrEmpty(globalFeatureNames, nameof(globalFeatureNames)); + + _requiresAll = requiresAll; + _globalFeatureNames = globalFeatureNames.Select(GlobalFeatureNameAttribute.GetName).ToArray(); + } + public Task IsEnabledAsync(PermissionStateContext context) { bool isEnabled = _requiresAll ? _globalFeatureNames.All(x => GlobalFeatureManager.Instance.IsEnabled(x)) : _globalFeatureNames.Any(x => GlobalFeatureManager.Instance.IsEnabled(x)); - + return Task.FromResult(isEnabled); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs index 3df0e205d5..a260b71e99 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs @@ -13,41 +13,48 @@ namespace Volo.CmsKit.Permissions { var cmsGroup = context.GetGroupOrNull(CmsKitAdminPermissions.GroupName) ?? context.AddGroup(CmsKitAdminPermissions.GroupName, L("Permission:CmsKit")); - if (GlobalFeatureManager.Instance.IsEnabled()) - { - var contentGroup = cmsGroup.AddPermission(CmsKitAdminPermissions.Comments.Default, L("Permission:Comments")); - contentGroup.AddChild(CmsKitAdminPermissions.Comments.Delete, L("Permission:Comments.Delete")); - } - - if (GlobalFeatureManager.Instance.IsEnabled()) - { - var tagGroup = cmsGroup.AddPermission(CmsKitAdminPermissions.Tags.Default, L("Permission:TagManagement")); - tagGroup.AddChild(CmsKitAdminPermissions.Tags.Create, L("Permission:TagManagement.Create")); - tagGroup.AddChild(CmsKitAdminPermissions.Tags.Update, L("Permission:TagManagement.Update")); - tagGroup.AddChild(CmsKitAdminPermissions.Tags.Delete, L("Permission:TagManagement.Delete")); - } + var contentGroup = cmsGroup.AddPermission(CmsKitAdminPermissions.Comments.Default, L("Permission:Comments")) + .RequireGlobalFeatures(typeof(CommentsFeature)); + contentGroup.AddChild(CmsKitAdminPermissions.Comments.Delete, L("Permission:Comments.Delete")) + .RequireGlobalFeatures(typeof(CommentsFeature)); - if (GlobalFeatureManager.Instance.IsEnabled()) - { - var pageManagement = cmsGroup.AddPermission(CmsKitAdminPermissions.Pages.Default, L("Permission:PageManagement")); - pageManagement.AddChild(CmsKitAdminPermissions.Pages.Create, L("Permission:PageManagement:Create")); - pageManagement.AddChild(CmsKitAdminPermissions.Pages.Update, L("Permission:PageManagement:Update")); - pageManagement.AddChild(CmsKitAdminPermissions.Pages.Delete, L("Permission:PageManagement:Delete")); - } + var tagGroup = cmsGroup.AddPermission(CmsKitAdminPermissions.Tags.Default, L("Permission:TagManagement")) + .RequireGlobalFeatures(typeof(TagsFeature)); + tagGroup.AddChild(CmsKitAdminPermissions.Tags.Create, L("Permission:TagManagement.Create")) + .RequireGlobalFeatures(typeof(TagsFeature)); + tagGroup.AddChild(CmsKitAdminPermissions.Tags.Update, L("Permission:TagManagement.Update")) + .RequireGlobalFeatures(typeof(TagsFeature)); + tagGroup.AddChild(CmsKitAdminPermissions.Tags.Delete, L("Permission:TagManagement.Delete")) + .RequireGlobalFeatures(typeof(TagsFeature)); - if (GlobalFeatureManager.Instance.IsEnabled()) - { - var blogManagement = cmsGroup.AddPermission(CmsKitAdminPermissions.Blogs.Default, L("Permission:BlogManagement")); - blogManagement.AddChild(CmsKitAdminPermissions.Blogs.Create, L("Permission:BlogManagement.Create")); - blogManagement.AddChild(CmsKitAdminPermissions.Blogs.Update, L("Permission:BlogManagement.Update")); - blogManagement.AddChild(CmsKitAdminPermissions.Blogs.Delete, L("Permission:BlogManagement.Delete")); - blogManagement.AddChild(CmsKitAdminPermissions.Blogs.Features, L("Permission:BlogManagement.Features")); + var pageManagement = cmsGroup.AddPermission(CmsKitAdminPermissions.Pages.Default, L("Permission:PageManagement")) + .RequireGlobalFeatures(typeof(PagesFeature)); + pageManagement.AddChild(CmsKitAdminPermissions.Pages.Create, L("Permission:PageManagement:Create")) + .RequireGlobalFeatures(typeof(PagesFeature)); + pageManagement.AddChild(CmsKitAdminPermissions.Pages.Update, L("Permission:PageManagement:Update")) + .RequireGlobalFeatures(typeof(PagesFeature)); + pageManagement.AddChild(CmsKitAdminPermissions.Pages.Delete, L("Permission:PageManagement:Delete")) + .RequireGlobalFeatures(typeof(PagesFeature)); - var blogPostManagement = cmsGroup.AddPermission(CmsKitAdminPermissions.BlogPosts.Default, L("Permission:BlogPostManagement")); - blogPostManagement.AddChild(CmsKitAdminPermissions.BlogPosts.Create, L("Permission:BlogPostManagement.Create")); - blogPostManagement.AddChild(CmsKitAdminPermissions.BlogPosts.Update, L("Permission:BlogPostManagement.Update")); - blogPostManagement.AddChild(CmsKitAdminPermissions.BlogPosts.Delete, L("Permission:BlogPostManagement.Delete")); - } + var blogManagement = cmsGroup.AddPermission(CmsKitAdminPermissions.Blogs.Default, L("Permission:BlogManagement")) + .RequireGlobalFeatures(typeof(BlogsFeature)); + blogManagement.AddChild(CmsKitAdminPermissions.Blogs.Create, L("Permission:BlogManagement.Create")) + .RequireGlobalFeatures(typeof(BlogsFeature)); + blogManagement.AddChild(CmsKitAdminPermissions.Blogs.Update, L("Permission:BlogManagement.Update")) + .RequireGlobalFeatures(typeof(BlogsFeature)); + blogManagement.AddChild(CmsKitAdminPermissions.Blogs.Delete, L("Permission:BlogManagement.Delete")) + .RequireGlobalFeatures(typeof(BlogsFeature)); + blogManagement.AddChild(CmsKitAdminPermissions.Blogs.Features, L("Permission:BlogManagement.Features")) + .RequireGlobalFeatures(typeof(BlogsFeature)); + + var blogPostManagement = cmsGroup.AddPermission(CmsKitAdminPermissions.BlogPosts.Default, L("Permission:BlogPostManagement")) + .RequireGlobalFeatures(typeof(BlogsFeature)); + blogPostManagement.AddChild(CmsKitAdminPermissions.BlogPosts.Create, L("Permission:BlogPostManagement.Create")) + .RequireGlobalFeatures(typeof(BlogsFeature)); + blogPostManagement.AddChild(CmsKitAdminPermissions.BlogPosts.Update, L("Permission:BlogPostManagement.Update")) + .RequireGlobalFeatures(typeof(BlogsFeature)); + blogPostManagement.AddChild(CmsKitAdminPermissions.BlogPosts.Delete, L("Permission:BlogPostManagement.Delete")) + .RequireGlobalFeatures(typeof(BlogsFeature)); } private static LocalizableString L(string name) diff --git a/npm/ng-packs/packages/core/src/lib/tokens/app-config.token.ts b/npm/ng-packs/packages/core/src/lib/tokens/app-config.token.ts new file mode 100644 index 0000000000..a6343af170 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/tokens/app-config.token.ts @@ -0,0 +1,7 @@ +import { InjectionToken } from '@angular/core'; + +export type AppInitErrorFn = (error: any) => void; + +export const APP_INIT_ERROR_HANDLERS = new InjectionToken( + 'APP_INIT_ERROR_HANDLERS', +); diff --git a/npm/ng-packs/packages/core/src/lib/tokens/index.ts b/npm/ng-packs/packages/core/src/lib/tokens/index.ts index afad50b1c8..c40fbc1bc0 100644 --- a/npm/ng-packs/packages/core/src/lib/tokens/index.ts +++ b/npm/ng-packs/packages/core/src/lib/tokens/index.ts @@ -2,3 +2,4 @@ export * from './list.token'; export * from './lodaer-delay.token'; export * from './manage-profile.token'; export * from './options.token'; +export * from './app-config.token'; diff --git a/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts b/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts index 9d5f7483fe..c4edc800b5 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts @@ -1,7 +1,8 @@ import { registerLocaleData } from '@angular/common'; import { Injector } from '@angular/core'; import { OAuthService } from 'angular-oauth2-oidc'; -import { tap } from 'rxjs/operators'; +import { tap, catchError } from 'rxjs/operators'; +import { throwError } from 'rxjs'; import { ABP } from '../models/common'; import { Environment } from '../models/environment'; import { AbpApplicationConfigurationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service'; @@ -12,6 +13,7 @@ import { EnvironmentService } from '../services/environment.service'; import { SessionStateService } from '../services/session-state.service'; import { clearOAuthStorage } from '../strategies/auth-flow.strategy'; import { CORE_OPTIONS } from '../tokens/options.token'; +import { APP_INIT_ERROR_HANDLERS } from '../tokens/app-config.token'; import { getRemoteEnv } from './environment-utils'; import { parseTenantFromUrl } from './multi-tenancy-utils'; @@ -38,6 +40,14 @@ export function getInitialData(injector: Injector) { const currentTenant = configState.getOne('currentTenant') as CurrentTenantDto; injector.get(SessionStateService).setTenant(currentTenant); }), + catchError(error => { + const appInitErrorHandlers = injector.get(APP_INIT_ERROR_HANDLERS); + if (appInitErrorHandlers && appInitErrorHandlers.length) { + appInitErrorHandlers.forEach(fn => fn(error)); + } + + return throwError(error); + }), ) .toPromise(); };