Browse Source

Merge branch 'dev' into blazor-ui-entit-actions-component

pull/5890/head
İlkay İlknur 6 years ago
parent
commit
6fabe4255f
  1. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
  2. 10
      docs/en/Migration-Guides/Abp-4_0.md
  3. 4
      docs/en/Module-Development-Basics.md
  4. 3
      docs/en/Multi-Tenancy.md
  5. 22
      docs/en/UI/AspNetCore/JavaScript-API/Features.md
  6. 3
      docs/zh-Hans/Multi-Tenancy.md
  7. 1
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/MainLayout.razor
  8. 8
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs
  9. 43
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpWebAssemblyConventionalRegistrar.cs
  10. 32
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertList.cs
  11. 14
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertManager.cs
  12. 30
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertMessage.cs
  13. 15
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertType.cs
  14. 7
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/IAlertManager.cs
  15. 32
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ServiceProviderComponentActivator.cs
  16. 9
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/CookieTenantResolveContributor.cs
  17. 19
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/DomainTenantResolveContributor.cs
  18. 8
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/FormTenantResolveContributor.cs
  19. 9
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HeaderTenantResolveContributor.cs
  20. 13
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HttpTenantResolveContributerBase.cs
  21. 14
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/QueryStringTenantResolveContributor.cs
  22. 12
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/RouteTenantResolveContributor.cs
  23. 4
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Brand/Default.cshtml
  24. 3
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Account.cshtml
  25. 5
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Application.cshtml
  26. 5
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Empty.cshtml
  27. 13
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Components/DefaultBrandingProvider.cs
  28. 17
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Components/IBrandingProvider.cs
  29. 10
      framework/src/Volo.Abp.BlazoriseUI/Components/AlertWrapper.cs
  30. 16
      framework/src/Volo.Abp.BlazoriseUI/Components/PageAlert.razor
  31. 83
      framework/src/Volo.Abp.BlazoriseUI/Components/PageAlert.razor.cs
  32. 3
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GetSourceCommand.cs
  33. 16
      framework/src/Volo.Abp.Core/Volo/Abp/Reflection/ReflectionHelper.cs
  34. 2
      framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs
  35. 6
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ActionTenantResolveContributor.cs
  36. 13
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/CurrentUserTenantResolveContributor.cs
  37. 6
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ITenantResolveContributor.cs
  38. 5
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ITenantResolver.cs
  39. 2
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfigurationProvider.cs
  40. 7
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantResolveContributorBase.cs
  41. 9
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantResolver.cs
  42. 49
      framework/test/Volo.Abp.Core.Tests/Volo/Abp/Reflection/ReflectionHelper_Tests.cs
  43. 2
      modules/blogging/app/Volo.BloggingTestApp/Branding/BloggingTestAppBrandingProvider.cs
  44. 2
      modules/client-simulation/demo/Volo.ClientSimulation.Demo/BrandingProvider.cs
  45. 2
      modules/cms-kit/host/Volo.CmsKit.Web.Host/CmsKitBrandingProvider.cs
  46. 2
      modules/docs/app/VoloDocs.Web/Branding/VoloDocsBrandingProvider.cs
  47. 2
      modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityUserAppService.cs
  48. 4
      modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs
  49. 4
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json
  50. 6
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json
  51. 4
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json
  52. 4
      modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json
  53. 8
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerBuilderExtensions.cs
  54. 75
      modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpUserClaimsFactory.cs
  55. 2
      modules/virtual-file-explorer/app/Volo.Abp.VirtualFileExplorer.DemoApp/Branding/AbpVirtualFileExplorerDemoAppBrandingProvider.cs
  56. 15
      npm/packs/core/src/abp.js
  57. 19
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/wwwroot/main.css
  58. 2
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameBrandingProvider.cs
  59. 2
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/MyProjectNameBrandingProvider.cs
  60. 2
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameBrandingProvider.cs
  61. 2
      templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/MyProjectNameBrandingProvider.cs

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json

@ -84,6 +84,7 @@
"Edit": "Edit",
"ProfileImageChange": "Change the profile image",
"BlogItemErrorMessage": "Could not get the latest blog post details from ABP.",
"PlannedReleaseDate": "Planned release date"
"PlannedReleaseDate": "Planned release date",
"CommunityArticleRequestErrorMessage": "Could not get the latest article request from Github."
}
}

10
docs/en/Migration-Guides/Abp-4_0.md

@ -14,6 +14,10 @@ As the **most important breaking change**, Identity Server 4.x places the `ApiSc
Also, added `Enabled(string)` and `Description(bool,true)` properties.
#### ApiResource
* Added `AllowedAccessTokenSigningAlgorithms (string)` and `ShowInDiscoveryDocument(bool, default: true)` properties
#### Client
* Added `RequireRequestObject (bool)` and `AllowedIdentityTokenSigningAlgorithms (string)` properties.
@ -26,11 +30,7 @@ Also, added `Enabled(string)` and `Description(bool,true)` properties.
#### PersistedGrant
* Added `SessionId (string)` and `ShowInDiscoveryDocument (bool, default: true)` properties
#### ApiResource
* Added `AllowedAccessTokenSigningAlgorithms (string)` and `Description (string)` and `ConsumedTime (DateTime?)` properties
* Added `SessionId (string)` and `Description(string)` and `ConsumedTime (DateTime?)` properties
## Migrating the Database

4
docs/en/Module-Development-Basics.md

@ -57,7 +57,7 @@ public class BlogModule : AbpModule
}
````
See Configuration (TODO: link) document for more about the configuration system.
See the [Configuration](Configuration.md) document for more about the configuration system.
#### Pre & Post Configure Services
@ -139,4 +139,4 @@ A depended module may depend on another module, but you only need to define your
There are **two types of modules.** They don't have any structural difference but categorized by functionality and purpose:
- **Framework modules**: These are **core modules of the framework** like caching, emailing, theming, security, serialization, validation, EF Core integration, MongoDB integration... etc. They do not have application/business functionalities but makes your daily development easier by providing common infrastructure, integration and abstractions.
- **Application modules**: These modules implement **specific application/business functionalities** like blogging, document management, identity management, tenant management... etc. They generally have their own entities, services, APIs and UI components. See [pre-built application modules](Modules/Index.md).
- **Application modules**: These modules implement **specific application/business functionalities** like blogging, document management, identity management, tenant management... etc. They generally have their own entities, services, APIs and UI components. See [pre-built application modules](Modules/Index.md).

3
docs/en/Multi-Tenancy.md

@ -329,6 +329,7 @@ Configure<AbpTenantResolveOptions>(options =>
`MyCustomTenantResolveContributor` must inherit from the `TenantResolveContributorBase` (or implement the `ITenantResolveContributor`) as shown below:
````csharp
using System.Threading.Tasks;
using Volo.Abp.MultiTenancy;
namespace MultiTenancyDemo.Web
@ -337,7 +338,7 @@ namespace MultiTenancyDemo.Web
{
public override string Name => "Custom";
public override void Resolve(ITenantResolveContext context)
public override Task ResolveAsync(ITenantResolveContext context)
{
//TODO...
}

22
docs/en/UI/AspNetCore/JavaScript-API/Features.md

@ -6,10 +6,24 @@
## Basic Usage
`abp.features.values` can be used to access to the all feature values.
````js
var excelExportFeatureValue = abp.features.values["ExportingToExcel"];
//Gets a value as string.
var value = abp.features.get('ExportingToExcel');
//Check the feature is enabled
var enabled = abp.features.isEnabled('ExportingToExcel.Enabled');
````
Then you can check the value of the feature to perform your logic.
## All Values
`abp.features.values` can be used to access to the all feature values.
An example value of this object is shown below:
````js
{
Identity.TwoFactor: "Optional",
ExportingToExcel.Enabled: "true",
...
}
````

3
docs/zh-Hans/Multi-Tenancy.md

@ -127,13 +127,14 @@ namespace MyCompany.MyProject
`MyCustomTenantResolveContributor`必须像下面这样实现**ITenantResolveContributor**接口:
````C#
using System.Threading.Tasks;
using Volo.Abp.MultiTenancy;
namespace MyCompany.MyProject
{
public class MyCustomTenantResolveContributor : ITenantResolveContributor
{
public void Resolve(ITenantResolveContext context)
public override Task ResolveAsync(ITenantResolveContext context)
{
context.TenantIdOrName = ... //从其他地方获取租户id或租户名字...
}

1
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme/Themes/Basic/MainLayout.razor

@ -18,6 +18,7 @@
</div>
</nav>
<div class="container">
<PageAlert />
@Body
<UiMessageAlert />

8
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpAspNetCoreComponentsWebAssemblyModule.cs

@ -1,4 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Volo.Abp.AspNetCore.Components.WebAssembly.ExceptionHandling;
using Volo.Abp.AspNetCore.Mvc.Client;
@ -16,6 +18,8 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddConventionalRegistrar(new AbpWebAssemblyConventionalRegistrar());
PreConfigure<AbpHttpClientBuilderOptions>(options =>
{
options.ProxyClientBuildActions.Add((_, builder) =>
@ -27,6 +31,8 @@ namespace Volo.Abp.AspNetCore.Components.WebAssembly
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Replace(ServiceDescriptor.Transient<IComponentActivator, ServiceProviderComponentActivator>());
context.Services
.GetHostBuilder().Logging
.AddProvider(new AbpExceptionHandlingLoggerProvider(context.Services));

43
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/AbpWebAssemblyConventionalRegistrar.cs

@ -0,0 +1,43 @@
using System;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.WebAssembly
{
public class AbpWebAssemblyConventionalRegistrar : ConventionalRegistrarBase
{
public override void AddType(IServiceCollection services, Type type)
{
if (IsConventionalRegistrationDisabled(type))
{
return;
}
if (!IsComponent(type))
{
return;
}
var serviceTypes = ExposedServiceExplorer.GetExposedServices(type);
TriggerServiceExposing(services, type, serviceTypes);
foreach (var serviceType in serviceTypes)
{
services.Add(
ServiceDescriptor.Describe(
serviceType,
type,
ServiceLifetime.Transient
)
);
}
}
private static bool IsComponent(Type type)
{
return typeof(ComponentBase).IsAssignableFrom(type);
}
}
}

32
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertList.cs

@ -0,0 +1,32 @@
using System.Collections.ObjectModel;
namespace Volo.Abp.AspNetCore.Components.WebAssembly.Alerts
{
public class AlertList : ObservableCollection<AlertMessage>
{
public void Add(AlertType type, string text, string title = null, bool dismissible = true)
{
Add(new AlertMessage(type, text, title, dismissible));
}
public void Info(string text, string title = null, bool dismissible = true)
{
Add(new AlertMessage(AlertType.Info, text, title, dismissible));
}
public void Warning(string text, string title = null, bool dismissible = true)
{
Add(new AlertMessage(AlertType.Warning, text, title, dismissible));
}
public void Danger(string text, string title = null, bool dismissible = true)
{
Add(new AlertMessage(AlertType.Danger, text, title, dismissible));
}
public void Success(string text, string title = null, bool dismissible = true)
{
Add(new AlertMessage(AlertType.Success, text, title, dismissible));
}
}
}

14
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertManager.cs

@ -0,0 +1,14 @@
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.WebAssembly.Alerts
{
public class AlertManager : IAlertManager, IScopedDependency
{
public AlertList Alerts { get; }
public AlertManager()
{
Alerts = new AlertList();
}
}
}

30
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertMessage.cs

@ -0,0 +1,30 @@
using JetBrains.Annotations;
namespace Volo.Abp.AspNetCore.Components.WebAssembly.Alerts
{
public class AlertMessage
{
[NotNull]
public string Text
{
get => _text;
set => _text = Check.NotNullOrWhiteSpace(value, nameof(value));
}
private string _text;
public AlertType Type { get; set; }
[CanBeNull]
public string Title { get; set; }
public bool Dismissible { get; set; }
public AlertMessage(AlertType type, [NotNull] string text, string title = null, bool dismissible = true)
{
Type = type;
Text = Check.NotNullOrWhiteSpace(text, nameof(text));
Title = title;
Dismissible = dismissible;
}
}
}

15
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/AlertType.cs

@ -0,0 +1,15 @@
namespace Volo.Abp.AspNetCore.Components.WebAssembly.Alerts
{
public enum AlertType
{
Default,
Primary,
Secondary,
Success,
Danger,
Warning,
Info,
Light,
Dark
}
}

7
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/Alerts/IAlertManager.cs

@ -0,0 +1,7 @@
namespace Volo.Abp.AspNetCore.Components.WebAssembly.Alerts
{
public interface IAlertManager
{
AlertList Alerts { get; }
}
}

32
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ServiceProviderComponentActivator.cs

@ -0,0 +1,32 @@
using System;
using Microsoft.AspNetCore.Components;
namespace Volo.Abp.AspNetCore.Components.WebAssembly
{
public class ServiceProviderComponentActivator : IComponentActivator
{
public IServiceProvider ServiceProvider { get; }
public ServiceProviderComponentActivator(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
}
public IComponent CreateInstance(Type componentType)
{
var instance = ServiceProvider.GetService(componentType);
if (instance == null)
{
instance = Activator.CreateInstance(componentType);
}
if (!(instance is IComponent component))
{
throw new ArgumentException($"The type {componentType.FullName} does not implement {nameof(IComponent)}.", nameof(componentType));
}
return component;
}
}
}

9
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/CookieTenantResolveContributor.cs

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AspNetCore.MultiTenancy
@ -9,9 +10,9 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
public override string Name => ContributorName;
protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext)
protected override Task<string> GetTenantIdOrNameFromHttpContextOrNullAsync(ITenantResolveContext context, HttpContext httpContext)
{
return httpContext.Request?.Cookies[context.GetAbpAspNetCoreMultiTenancyOptions().TenantKey];
return Task.FromResult(httpContext.Request?.Cookies[context.GetAbpAspNetCoreMultiTenancyOptions().TenantKey]);
}
}
}
}

19
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/DomainTenantResolveContributor.cs

@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Text.Formatting;
@ -22,26 +23,14 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
_domainFormat = domainFormat.RemovePreFix(ProtocolPrefixes);
}
protected override string GetTenantIdOrNameFromHttpContextOrNull(
ITenantResolveContext context,
HttpContext httpContext)
protected override Task<string> GetTenantIdOrNameFromHttpContextOrNullAsync(ITenantResolveContext context, HttpContext httpContext)
{
if (httpContext.Request?.Host == null)
{
return null;
}
var hostName = httpContext.Request.Host.Host.RemovePreFix(ProtocolPrefixes);
var extractResult = FormattedStringValueExtracter.Extract(hostName, _domainFormat, ignoreCase: true);
context.Handled = true;
if (!extractResult.IsMatch)
{
return null;
}
return extractResult.Matches[0].Value;
return extractResult.IsMatch ? Task.FromResult(extractResult.Matches[0].Value) : null;
}
}
}
}

8
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/FormTenantResolveContributor.cs

@ -1,4 +1,5 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Volo.Abp.MultiTenancy;
@ -10,14 +11,15 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
public override string Name => ContributorName;
protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext)
protected async override Task<string> GetTenantIdOrNameFromHttpContextOrNullAsync(ITenantResolveContext context, HttpContext httpContext)
{
if (httpContext.Request == null || !httpContext.Request.HasFormContentType || !httpContext.Request.Form.Any())
if (!httpContext.Request.HasFormContentType)
{
return null;
}
return httpContext.Request.Form[context.GetAbpAspNetCoreMultiTenancyOptions().TenantKey];
var form = await httpContext.Request.ReadFormAsync();
return form[context.GetAbpAspNetCoreMultiTenancyOptions().TenantKey];
}
}
}

9
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HeaderTenantResolveContributor.cs

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@ -13,9 +14,9 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
public override string Name => ContributorName;
protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext)
protected override Task<string> GetTenantIdOrNameFromHttpContextOrNullAsync(ITenantResolveContext context, HttpContext httpContext)
{
if (httpContext.Request == null || httpContext.Request.Headers.IsNullOrEmpty())
if (httpContext.Request.Headers.IsNullOrEmpty())
{
return null;
}
@ -33,7 +34,7 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
Log(context, $"HTTP request includes more than one {tenantIdKey} header value. First one will be used. All of them: {tenantIdHeader.JoinAsString(", ")}");
}
return tenantIdHeader.First();
return Task.FromResult(tenantIdHeader.First());
}
protected virtual void Log(ITenantResolveContext context, string text)
@ -44,4 +45,4 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
.LogWarning(text);
}
}
}
}

13
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HttpTenantResolveContributerBase.cs

@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
@ -9,7 +10,7 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
{
public abstract class HttpTenantResolveContributorBase : TenantResolveContributorBase
{
public override void Resolve(ITenantResolveContext context)
public async override Task ResolveAsync(ITenantResolveContext context)
{
var httpContext = context.GetHttpContext();
if (httpContext == null)
@ -19,7 +20,7 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
try
{
ResolveFromHttpContext(context, httpContext);
await ResolveFromHttpContextAsync(context, httpContext);
}
catch (Exception e)
{
@ -29,15 +30,15 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
}
}
protected virtual void ResolveFromHttpContext(ITenantResolveContext context, HttpContext httpContext)
protected virtual async Task ResolveFromHttpContextAsync(ITenantResolveContext context, HttpContext httpContext)
{
var tenantIdOrName = GetTenantIdOrNameFromHttpContextOrNull(context, httpContext);
var tenantIdOrName = await GetTenantIdOrNameFromHttpContextOrNullAsync(context, httpContext);
if (!tenantIdOrName.IsNullOrEmpty())
{
context.TenantIdOrName = tenantIdOrName;
}
}
protected abstract string GetTenantIdOrNameFromHttpContextOrNull([NotNull] ITenantResolveContext context, [NotNull] HttpContext httpContext);
protected abstract Task<string> GetTenantIdOrNameFromHttpContextOrNullAsync([NotNull] ITenantResolveContext context, [NotNull] HttpContext httpContext);
}
}
}

14
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/QueryStringTenantResolveContributor.cs

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AspNetCore.MultiTenancy
@ -9,14 +10,11 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
public override string Name => ContributorName;
protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext)
protected override Task<string> GetTenantIdOrNameFromHttpContextOrNullAsync(ITenantResolveContext context, HttpContext httpContext)
{
if (httpContext.Request == null || !httpContext.Request.QueryString.HasValue)
{
return null;
}
return httpContext.Request.Query[context.GetAbpAspNetCoreMultiTenancyOptions().TenantKey];
return httpContext.Request.QueryString.HasValue
? Task.FromResult(httpContext.Request.Query[context.GetAbpAspNetCoreMultiTenancyOptions().TenantKey].ToString())
: null;
}
}
}

12
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/RouteTenantResolveContributor.cs

@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Volo.Abp.MultiTenancy;
@ -11,15 +12,10 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
public override string Name => ContributorName;
protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext)
protected override Task<string> GetTenantIdOrNameFromHttpContextOrNullAsync(ITenantResolveContext context, HttpContext httpContext)
{
var tenantId = httpContext.GetRouteValue(context.GetAbpAspNetCoreMultiTenancyOptions().TenantKey);
if (tenantId == null)
{
return null;
}
return Convert.ToString(tenantId);
return tenantId != null ? Task.FromResult(Convert.ToString(tenantId)) : null;
}
}
}
}

4
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Brand/Default.cshtml

@ -1,3 +1,3 @@
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components
@using Volo.Abp.Ui.Branding
@inject IBrandingProvider BrandingProvider
<a class="navbar-brand" href="~/">@BrandingProvider.AppName</a>
<a class="navbar-brand" href="~/">@BrandingProvider.AppName</a>

3
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Account.cshtml

@ -1,18 +1,17 @@
@using Microsoft.Extensions.Localization
@using Microsoft.Extensions.Options
@using Volo.Abp.AspNetCore.MultiTenancy
@using Volo.Abp.AspNetCore.Mvc.AntiForgery
@using Volo.Abp.AspNetCore.Mvc.UI.Components.LayoutHook
@using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Bundling
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.MainNavbar
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.PageAlerts
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components
@using Volo.Abp.AspNetCore.Mvc.UI.Theming
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetScripts
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetStyles
@using Volo.Abp.MultiTenancy
@using Volo.Abp.Localization
@using Volo.Abp.Ui.Branding
@inject IBrandingProvider BrandingProvider
@inject IOptions<AbpMultiTenancyOptions> MultiTenancyOptions
@inject ICurrentTenant CurrentTenant

5
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Application.cshtml

@ -1,14 +1,13 @@
@using Volo.Abp.AspNetCore.Mvc.AntiForgery
@using Volo.Abp.AspNetCore.Mvc.UI.Components.LayoutHook
@using Volo.Abp.AspNetCore.Mvc.UI.Components.LayoutHook
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Bundling
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.MainNavbar
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.PageAlerts
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components
@using Volo.Abp.AspNetCore.Mvc.UI.Theming
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetScripts
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetStyles
@using Volo.Abp.Localization
@using Volo.Abp.Ui.Branding
@inject IBrandingProvider BrandingProvider
@inject IPageLayout PageLayout
@{

5
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Empty.cshtml

@ -1,13 +1,12 @@
@using Volo.Abp.AspNetCore.Mvc.AntiForgery
@using Volo.Abp.AspNetCore.Mvc.UI.Components.LayoutHook
@using Volo.Abp.AspNetCore.Mvc.UI.Components.LayoutHook
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Bundling
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.PageAlerts
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components
@using Volo.Abp.AspNetCore.Mvc.UI.Theming
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetScripts
@using Volo.Abp.AspNetCore.Mvc.UI.Widgets.Components.WidgetStyles
@using Volo.Abp.Localization
@using Volo.Abp.Ui.Branding
@inject IBrandingProvider BrandingProvider
@inject IPageLayout PageLayout
@{

13
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Components/DefaultBrandingProvider.cs

@ -1,13 +0,0 @@
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components
{
public class DefaultBrandingProvider : IBrandingProvider, ITransientDependency
{
public virtual string AppName => "MyApplication";
public virtual string LogoUrl => null;
public virtual string LogoReverseUrl => null;
}
}

17
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Components/IBrandingProvider.cs

@ -1,17 +0,0 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components
{
public interface IBrandingProvider
{
string AppName { get; }
/// <summary>
/// Logo on white background
/// </summary>
string LogoUrl { get; }
/// <summary>
/// Logo on dark background
/// </summary>
string LogoReverseUrl { get; }
}
}

10
framework/src/Volo.Abp.BlazoriseUI/Components/AlertWrapper.cs

@ -0,0 +1,10 @@
using Volo.Abp.AspNetCore.Components.WebAssembly.Alerts;
namespace Volo.Abp.BlazoriseUI.Components
{
internal class AlertWrapper
{
public AlertMessage AlertMessage { get; set; }
public bool IsVisible { get; set; }
}
}

16
framework/src/Volo.Abp.BlazoriseUI/Components/PageAlert.razor

@ -0,0 +1,16 @@
@foreach (var alert in Alerts)
{
<Alert Visible="@alert.IsVisible" Dismisable="@alert.AlertMessage.Dismissible" Color="@GetAlertColor(alert.AlertMessage.Type)">
@if (!string.IsNullOrEmpty(alert.AlertMessage.Title))
{
<Heading Size="HeadingSize.Is4" Class="alert-heading">
@alert.AlertMessage.Title
@if (alert.AlertMessage.Dismissible)
{
<CloseButton Clicked="() => alert.IsVisible = false" />
}
</Heading>
}
<Paragraph>@alert.AlertMessage.Text</Paragraph>
</Alert>
}

83
framework/src/Volo.Abp.BlazoriseUI/Components/PageAlert.razor.cs

@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using Blazorise;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Routing;
using Volo.Abp.AspNetCore.Components.WebAssembly.Alerts;
namespace Volo.Abp.BlazoriseUI.Components
{
public partial class PageAlert : ComponentBase, IDisposable
{
private List<AlertWrapper> Alerts = new List<AlertWrapper>();
[Inject]
protected IAlertManager AlertManager { get; set; }
[Inject]
protected NavigationManager NavigationManager { get; set; }
protected override void OnInitialized()
{
base.OnInitialized();
NavigationManager.LocationChanged += NavigationManager_LocationChanged;
AlertManager.Alerts.CollectionChanged += Alerts_CollectionChanged;
Alerts.AddRange(AlertManager.Alerts.Select(t => new AlertWrapper
{
AlertMessage = t,
IsVisible = true
}));
}
//Since Blazor WASM doesn't support scoped dependency, we need to clear alerts on each location changed event.
private void NavigationManager_LocationChanged(object sender, LocationChangedEventArgs e)
{
AlertManager.Alerts.Clear();
Alerts.Clear();
}
private void Alerts_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (var item in e.NewItems)
{
Alerts.Add(new AlertWrapper
{
AlertMessage = (AspNetCore.Components.WebAssembly.Alerts.AlertMessage)item,
IsVisible = true
});
}
}
StateHasChanged();
}
protected virtual Color GetAlertColor(AlertType alertType)
{
var color = alertType switch
{
AlertType.Info => Color.Info,
AlertType.Success => Color.Success,
AlertType.Warning => Color.Warning,
AlertType.Danger => Color.Danger,
AlertType.Dark => Color.Dark,
AlertType.Default => Color.None,
AlertType.Light => Color.Light,
AlertType.Primary => Color.Primary,
AlertType.Secondary => Color.Secondary,
_ => Color.None,
};
return color;
}
public void Dispose()
{
NavigationManager.LocationChanged -= NavigationManager_LocationChanged;
AlertManager.Alerts.CollectionChanged -= Alerts_CollectionChanged;
}
}
}

3
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GetSourceCommand.cs

@ -2,14 +2,11 @@
using System.IO;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Cli.Args;
using Volo.Abp.Cli.Commands.Services;
using Volo.Abp.Cli.ProjectBuilding;
using Volo.Abp.Cli.ProjectBuilding.Building;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Cli.Commands

16
framework/src/Volo.Abp.Core/Volo/Abp/Reflection/ReflectionHelper.cs

@ -124,7 +124,7 @@ namespace Volo.Abp.Reflection
? customAttributes.Concat(declaringTypeCustomAttributes).Distinct()
: customAttributes;
}
/// <summary>
/// Gets value of a property by it's full path from given object
/// </summary>
@ -134,7 +134,7 @@ namespace Volo.Abp.Reflection
var currentType = objectType;
var objectPath = currentType.FullName;
var absolutePropertyPath = propertyPath;
if (absolutePropertyPath.StartsWith(objectPath))
if (objectPath != null && absolutePropertyPath.StartsWith(objectPath))
{
absolutePropertyPath = absolutePropertyPath.Replace(objectPath + ".", "");
}
@ -142,8 +142,16 @@ namespace Volo.Abp.Reflection
foreach (var propertyName in absolutePropertyPath.Split('.'))
{
var property = currentType.GetProperty(propertyName);
value = property.GetValue(value, null);
currentType = property.PropertyType;
if (property != null)
{
value = property.GetValue(value, null);
currentType = property.PropertyType;
}
else
{
value = null;
break;
}
}
return value;

2
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs

@ -57,7 +57,7 @@ namespace Volo.Abp.Application.Services
protected override Task<TEntityDto> MapToGetListOutputDtoAsync(TEntity entity)
{
return base.MapToGetOutputDtoAsync(entity);
return MapToGetOutputDtoAsync(entity);
}
protected override TEntityDto MapToGetListOutputDto(TEntity entity)

6
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ActionTenantResolveContributor.cs

@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
namespace Volo.Abp.MultiTenancy
@ -18,9 +19,10 @@ namespace Volo.Abp.MultiTenancy
_resolveAction = resolveAction;
}
public override void Resolve(ITenantResolveContext context)
public override Task ResolveAsync(ITenantResolveContext context)
{
_resolveAction(context);
return Task.CompletedTask;
}
}
}
}

13
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/CurrentUserTenantResolveContributor.cs

@ -1,3 +1,4 @@
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Users;
@ -9,16 +10,16 @@ namespace Volo.Abp.MultiTenancy
public override string Name => ContributorName;
public override void Resolve(ITenantResolveContext context)
public override Task ResolveAsync(ITenantResolveContext context)
{
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
if (currentUser.IsAuthenticated != true)
if (currentUser.IsAuthenticated)
{
return;
context.Handled = true;
context.TenantIdOrName = currentUser.TenantId?.ToString();
}
context.Handled = true;
context.TenantIdOrName = currentUser.TenantId?.ToString();
return Task.CompletedTask;
}
}
}
}

6
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ITenantResolveContributor.cs

@ -1,9 +1,11 @@
using System.Threading.Tasks;
namespace Volo.Abp.MultiTenancy
{
public interface ITenantResolveContributor
{
string Name { get; }
void Resolve(ITenantResolveContext context);
Task ResolveAsync(ITenantResolveContext context);
}
}
}

5
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ITenantResolver.cs

@ -1,3 +1,4 @@
using System.Threading.Tasks;
using JetBrains.Annotations;
namespace Volo.Abp.MultiTenancy
@ -11,6 +12,6 @@ namespace Volo.Abp.MultiTenancy
/// Tenant id, unique name or null (if could not resolve).
/// </returns>
[NotNull]
TenantResolveResult ResolveTenantIdOrName();
Task<TenantResolveResult> ResolveTenantIdOrNameAsync();
}
}
}

2
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfigurationProvider.cs

@ -22,7 +22,7 @@ namespace Volo.Abp.MultiTenancy
public virtual async Task<TenantConfiguration> GetAsync(bool saveResolveResult = false)
{
var resolveResult = TenantResolver.ResolveTenantIdOrName();
var resolveResult = await TenantResolver.ResolveTenantIdOrNameAsync();
if (saveResolveResult)
{

7
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantResolveContributorBase.cs

@ -1,10 +1,11 @@
using System.Threading.Tasks;
namespace Volo.Abp.MultiTenancy
{
public abstract class TenantResolveContributorBase : ITenantResolveContributor
{
public abstract string Name { get; }
//TODO: We can make this async
public abstract void Resolve(ITenantResolveContext context);
public abstract Task ResolveAsync(ITenantResolveContext context);
}
}
}

9
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantResolver.cs

@ -1,6 +1,5 @@
using System;
using System.Linq;
using JetBrains.Annotations;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
@ -18,7 +17,7 @@ namespace Volo.Abp.MultiTenancy
_options = options.Value;
}
public TenantResolveResult ResolveTenantIdOrName()
public virtual async Task<TenantResolveResult> ResolveTenantIdOrNameAsync()
{
var result = new TenantResolveResult();
@ -28,7 +27,7 @@ namespace Volo.Abp.MultiTenancy
foreach (var tenantResolver in _options.TenantResolvers)
{
tenantResolver.Resolve(context);
await tenantResolver.ResolveAsync(context);
result.AppliedResolvers.Add(tenantResolver.Name);
@ -43,4 +42,4 @@ namespace Volo.Abp.MultiTenancy
return result;
}
}
}
}

49
framework/test/Volo.Abp.Core.Tests/Volo/Abp/Reflection/ReflectionHelper_Tests.cs

@ -1,4 +1,5 @@
using System.Linq;
using System;
using System.Linq;
using Shouldly;
using Xunit;
@ -8,6 +9,50 @@ namespace Volo.Abp.Reflection
{
//TODO: ...
class GetValueByPathTestClass
{
public string Name { get; set; }
public int Count { get; set; }
public DateTime Time { get; set; }
public GetValueByPathTestChildrenClass Children { get; set; }
}
class GetValueByPathTestChildrenClass
{
public string Name { get; set; }
public int Count { get; set; }
}
[Fact]
public void GetValueByPath_Test()
{
var value = new GetValueByPathTestClass
{
Name = "test",
Count = 8,
Time = DateTime.Parse("2020-01-01"),
Children = new GetValueByPathTestChildrenClass
{
Name = "test-children",
Count = 9,
}
};
ReflectionHelper.GetValueByPath(value, value.GetType(), "Name").ShouldBe("test");
ReflectionHelper.GetValueByPath(value, value.GetType(), "Volo.Abp.Reflection.ReflectionHelper_Tests+GetValueByPathTestClass.Name").ShouldBe("test");
ReflectionHelper.GetValueByPath(value, value.GetType(), "Count").ShouldBe(8);
ReflectionHelper.GetValueByPath(value, value.GetType(), "Time").ShouldBe(DateTime.Parse("2020-01-01"));
ReflectionHelper.GetValueByPath(value, value.GetType(), "Children.Name").ShouldBe("test-children");
ReflectionHelper.GetValueByPath(value, value.GetType(), "Children.Count").ShouldBe(9);
ReflectionHelper.GetValueByPath(value, value.GetType(), "Volo.Abp.Reflection.ReflectionHelper_Tests+GetValueByPathTestClass.Children.Name").ShouldBe("test-children");
ReflectionHelper.GetValueByPath(value, value.GetType(), "Children.NotExist").ShouldBeNull();
ReflectionHelper.GetValueByPath(value, value.GetType(), "NotExist").ShouldBeNull();
}
[Fact]
public void GetPublicConstantsRecursively_Test()
@ -99,4 +144,4 @@ namespace Volo.Abp.Reflection
}
}
}
}

2
modules/blogging/app/Volo.BloggingTestApp/Branding/BloggingTestAppBrandingProvider.cs

@ -1,5 +1,5 @@
using Microsoft.AspNetCore.Mvc.Localization;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components;
using Volo.Abp.Ui.Branding;
using Volo.Abp.DependencyInjection;
using Volo.Blogging.Localization;

2
modules/client-simulation/demo/Volo.ClientSimulation.Demo/BrandingProvider.cs

@ -1,4 +1,4 @@
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components;
using Volo.Abp.Ui.Branding;
using Volo.Abp.DependencyInjection;
namespace Volo.ClientSimulation.Demo

2
modules/cms-kit/host/Volo.CmsKit.Web.Host/CmsKitBrandingProvider.cs

@ -1,4 +1,4 @@
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components;
using Volo.Abp.Ui.Branding;
using Volo.Abp.DependencyInjection;
namespace Volo.CmsKit

2
modules/docs/app/VoloDocs.Web/Branding/VoloDocsBrandingProvider.cs

@ -1,6 +1,6 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Localization;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components;
using Volo.Abp.Ui.Branding;
using Volo.Abp.DependencyInjection;
using Volo.Docs.Localization;

2
modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityUserAppService.cs

@ -19,7 +19,7 @@ namespace Volo.Abp.Identity
Task UpdateRolesAsync(Guid id, IdentityUserUpdateRolesDto input);
Task<IdentityUserDto> FindByUsernameAsync(string username);
Task<IdentityUserDto> FindByUsernameAsync(string userName);
Task<IdentityUserDto> FindByEmailAsync(string email);
}

4
modules/identity/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs

@ -135,10 +135,10 @@ namespace Volo.Abp.Identity
}
[Authorize(IdentityPermissions.Users.Default)]
public virtual async Task<IdentityUserDto> FindByUsernameAsync(string username)
public virtual async Task<IdentityUserDto> FindByUsernameAsync(string userName)
{
return ObjectMapper.Map<IdentityUser, IdentityUserDto>(
await UserManager.FindByNameAsync(username)
await UserManager.FindByNameAsync(userName)
);
}

4
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/en.json

@ -79,8 +79,8 @@
"Permission:UserManagement": "User management",
"Permission:UserLookup": "User lookup",
"Feature:IdentityGroup": "Identity",
"Feature:TwoFactor": "Two Factor",
"Feature:TwoFactorDescription": "Two Factor",
"Feature:TwoFactor": "Two factor behaviour",
"Feature:TwoFactorDescription": "Set two factor behaviour. Optional values: Optional,Disabled,Forced",
"Feature:TwoFactor.Optional": "Optional",
"Feature:TwoFactor.Disabled": "Disabled",
"Feature:TwoFactor.Forced": "Forced",

6
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/tr.json

@ -78,10 +78,10 @@
"Permission:UserLookup": "Kullanıcı sorgulama",
"Feature:IdentityGroup": "Kimlik",
"Feature:TwoFactor": "İki faktörlü kimlik doğrulama",
"Feature:TwoFactorDescription": "İki faktörlü kimlik doğrulama",
"Feature:TwoFactorDescription": "İki faktörlü kimlik doğrulamanın talep edileceği durumu seçin",
"Feature:TwoFactor.Optional": "İsteğe bağlı",
"Feature:TwoFactor.Disabled": "Devre dışı",
"Feature:TwoFactor.Forced": "Zorunlu",
"Feature:TwoFactor.Disabled": "Asla",
"Feature:TwoFactor.Forced": "Her zaman",
"DisplayName:Abp.Identity.Password.RequiredLength": "Uzunluk gerekli",
"DisplayName:Abp.Identity.Password.RequiredUniqueChars": "Tekil karakter gerekli",
"DisplayName:Abp.Identity.Password.RequireNonAlphanumeric": "Alfasayısal olmayan karakter gerekli",

4
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json

@ -79,8 +79,8 @@
"Permission:UserManagement": "用户管理",
"Permission:UserLookup": "用户查询",
"Feature:IdentityGroup": "身份标识",
"Feature:TwoFactor": "双因素身份验证",
"Feature:TwoFactorDescription": "双因素身份验证",
"Feature:TwoFactor": "双因素身份验证行为",
"Feature:TwoFactorDescription": "设置双因素身份验证行为. 可选值:可选,禁用,强制启用",
"Feature:TwoFactor.Optional": "可选",
"Feature:TwoFactor.Disabled": "禁用",
"Feature:TwoFactor.Forced": "强制启用",

4
modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hant.json

@ -79,8 +79,8 @@
"Permission:UserManagement": "使用者管理",
"Permission:UserLookup": "使用者查詢",
"Feature:IdentityGroup": "身份識別",
"Feature:TwoFactor": "雙因素",
"Feature:TwoFactorDescription": "雙因素",
"Feature:TwoFactor": "雙因素身份驗證行為",
"Feature:TwoFactorDescription": "設置雙因素身份驗證行為. 可選值:可選,禁用,強制啟用",
"Feature:TwoFactor.Optional": "選用",
"Feature:TwoFactor.Disabled": "關閉",
"Feature:TwoFactor.Forced": "強制啟用",

8
modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerBuilderExtensions.cs

@ -1,17 +1,21 @@
using System;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using IdentityModel;
using IdentityServer4;
using IdentityServer4.Configuration;
using IdentityServer4.Services;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Newtonsoft.Json.Linq;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
using Volo.Abp.IdentityServer.AspNetIdentity;
using Volo.Abp.Security.Claims;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
namespace Volo.Abp.IdentityServer
{
@ -32,6 +36,10 @@ namespace Volo.Abp.IdentityServer
builder.AddAspNetIdentity<IdentityUser>();
builder.AddProfileService<AbpProfileService>();
builder.AddResourceOwnerValidator<AbpResourceOwnerPasswordValidator>();
builder.Services.Remove(builder.Services.LastOrDefault(x => x.ServiceType == typeof(IUserClaimsPrincipalFactory<IdentityUser>)));
builder.Services.AddTransient<IUserClaimsPrincipalFactory<IdentityUser>, AbpUserClaimsFactory<IdentityUser>>();
builder.Services.AddTransient<IObjectAccessor<IUserClaimsPrincipalFactory<IdentityUser>>, ObjectAccessor<AbpUserClaimsPrincipalFactory>>();
}
builder.Services.Replace(ServiceDescriptor.Transient<IClaimsService, AbpClaimsService>());

75
modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/AbpUserClaimsFactory.cs

@ -0,0 +1,75 @@
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using IdentityModel;
using Microsoft.AspNetCore.Identity;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Identity;
namespace Volo.Abp.IdentityServer.AspNetIdentity
{
public class AbpUserClaimsFactory<TUser> : IUserClaimsPrincipalFactory<TUser>
where TUser : class
{
private readonly IObjectAccessor<IUserClaimsPrincipalFactory<TUser>> _inner;
private readonly UserManager<TUser> _userManager;
public AbpUserClaimsFactory(IObjectAccessor<IUserClaimsPrincipalFactory<TUser>> inner,
UserManager<TUser> userManager)
{
_inner = inner;
_userManager = userManager;
}
public async Task<ClaimsPrincipal> CreateAsync(TUser user)
{
var principal = await _inner.Value.CreateAsync(user);
var identity = principal.Identities.First();
if (!identity.HasClaim(x => x.Type == JwtClaimTypes.Subject))
{
var sub = await _userManager.GetUserIdAsync(user);
identity.AddIfNotContains(new Claim(JwtClaimTypes.Subject, sub));
}
var username = await _userManager.GetUserNameAsync(user);
var usernameClaim = identity.FindFirst(claim =>
claim.Type == _userManager.Options.ClaimsIdentity.UserNameClaimType && claim.Value == username);
if (usernameClaim != null)
{
identity.RemoveClaim(usernameClaim);
identity.AddIfNotContains(new Claim(JwtClaimTypes.PreferredUserName, username));
}
if (!identity.HasClaim(x => x.Type == JwtClaimTypes.Name))
{
identity.AddIfNotContains(new Claim(JwtClaimTypes.Name, username));
}
if (_userManager.SupportsUserEmail)
{
var email = await _userManager.GetEmailAsync(user);
if (!string.IsNullOrWhiteSpace(email))
{
identity.AddIfNotContains(new Claim(JwtClaimTypes.Email, email));
identity.AddIfNotContains(new Claim(JwtClaimTypes.EmailVerified,
await _userManager.IsEmailConfirmedAsync(user) ? "true" : "false", ClaimValueTypes.Boolean));
}
}
if (_userManager.SupportsUserPhoneNumber)
{
var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
if (!string.IsNullOrWhiteSpace(phoneNumber))
{
identity.AddIfNotContains(new Claim(JwtClaimTypes.PhoneNumber, phoneNumber));
identity.AddIfNotContains(new Claim(JwtClaimTypes.PhoneNumberVerified,
await _userManager.IsPhoneNumberConfirmedAsync(user) ? "true" : "false",
ClaimValueTypes.Boolean));
}
}
return principal;
}
}
}

2
modules/virtual-file-explorer/app/Volo.Abp.VirtualFileExplorer.DemoApp/Branding/AbpVirtualFileExplorerDemoAppBrandingProvider.cs

@ -1,4 +1,4 @@
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components;
using Volo.Abp.Ui.Branding;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.VirtualFileExplorer.DemoApp.Branding

15
npm/packs/core/src/abp.js

@ -750,5 +750,20 @@ var abp = abp || {};
return toUtc(date);
}
};
/* FEATURES *************************************************/
abp.features = abp.features || {};
abp.features.values = abp.features.values || {};
abp.features.isEnabled = function(name){
var value = abp.features.get(name);
return value == 'true' || value == 'True';
}
abp.features.get = function (name) {
return abp.features.values[name];
};
})();

19
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/wwwroot/main.css

@ -1,18 +1 @@
#blazor-error-ui {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}


2
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyProjectNameBrandingProvider.cs

@ -1,4 +1,4 @@
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components;
using Volo.Abp.Ui.Branding;
using Volo.Abp.DependencyInjection;
namespace MyCompanyName.MyProjectName

2
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/MyProjectNameBrandingProvider.cs

@ -1,4 +1,4 @@
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components;
using Volo.Abp.Ui.Branding;
using Volo.Abp.DependencyInjection;
namespace MyCompanyName.MyProjectName.Web

2
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyProjectNameBrandingProvider.cs

@ -1,4 +1,4 @@
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components;
using Volo.Abp.Ui.Branding;
using Volo.Abp.DependencyInjection;
namespace MyCompanyName.MyProjectName.Web

2
templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/MyProjectNameBrandingProvider.cs

@ -1,4 +1,4 @@
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components;
using Volo.Abp.Ui.Branding;
using Volo.Abp.DependencyInjection;
namespace MyCompanyName.MyProjectName

Loading…
Cancel
Save