pull/17423/head
Halil İbrahim Kalkan 2 years ago
commit 9bebe77526

@ -204,7 +204,7 @@ public class MyApplicationConfigurationDto : ApplicationConfigurationDto
}
````
### Remove contoller
### Remove controller
Configure `ControllersToRemove` of `AbpAspNetCoreMvcOptions` to remove the controllers.

@ -70,7 +70,7 @@ After you have installed these NuGet packages, you need to configure your projec
> You have to configure a storage for Hangfire.
2. If you want to use hangfire's dashboard, you can add `UseHangfireDashboard` call in the `OnApplicationInitialization` method in `Module` class:
2. If you want to use hangfire's dashboard, you can add `UseAbpHangfireDashboard` call in the `OnApplicationInitialization` method in `Module` class:
````csharp
public override void OnApplicationInitialization(ApplicationInitializationContext context)
@ -79,7 +79,7 @@ After you have installed these NuGet packages, you need to configure your projec
// ... others
app.UseHangfireDashboard(); //should add to the request pipeline before the app.UseConfiguredEndpoints()
app.UseAbpHangfireDashboard(); //should add to the request pipeline before the app.UseConfiguredEndpoints()
app.UseConfiguredEndpoints();
}
````
@ -128,9 +128,9 @@ You can integrate the Hangfire dashboard to [ABP authorization system](Authoriza
class. This class is defined in the `Volo.Abp.Hangfire` package. The following example, checks if the current user is logged in to the application:
```csharp
app.UseHangfireDashboard("/hangfire", new DashboardOptions
app.UseAbpHangfireDashboard("/hangfire", options =>
{
AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter() }
options.AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter() };
});
```
@ -146,11 +146,11 @@ app.UseHangfireDashboard("/hangfire", new DashboardOptions
If you want to require an additional permission, you can pass it into the constructor as below:
```csharp
app.UseHangfireDashboard("/hangfire", new DashboardOptions
app.UseAbpHangfireDashboard("/hangfire", options =>
{
AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter(requiredPermissionName: "MyHangFireDashboardPermissionName") }
options.AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter(requiredPermissionName: "MyHangFireDashboardPermissionName") };
});
```
**Important**: `UseHangfireDashboard` should be called after the authentication and authorization middlewares in your `Startup` class (probably at the last line). Otherwise,
**Important**: `UseAbpHangfireDashboard` should be called after the authentication and authorization middlewares in your `Startup` class (probably at the last line). Otherwise,
authorization will always fail!

@ -70,7 +70,7 @@ After you have installed these NuGet packages, you need to configure your projec
> You have to configure a storage for Hangfire.
2. If you want to use hangfire's dashboard, you can add `UseHangfireDashboard` call in the `OnApplicationInitialization` method in `Module` class
2. If you want to use hangfire's dashboard, you can add `UseAbpHangfireDashboard` call in the `OnApplicationInitialization` method in `Module` class
````csharp
public override void OnApplicationInitialization(ApplicationInitializationContext context)
@ -79,7 +79,7 @@ After you have installed these NuGet packages, you need to configure your projec
// ... others
app.UseHangfireDashboard(); //should add to the request pipeline before the app.UseConfiguredEndpoints()
app.UseAbpHangfireDashboard(); //should add to the request pipeline before the app.UseConfiguredEndpoints()
app.UseConfiguredEndpoints();
}
````

@ -471,7 +471,24 @@ In **Blazor wasm** applications, add `options.ProviderOptions.DefaultScopes.Add(
In **Angular** applications, add `offline_access` to **oAuthConfig** scopes in *environment.ts* file. (Angular applications already have this configuration).
## About localization
We don't localize any error messages in the OpenIddict module, Because the OAuth 2.0 specification restricts the charset you're allowed to use for the error and error_description parameters:
> A.7. "error" Syntax
> The "error" element is defined in Sections 4.1.2.1, 4.2.2.1, 5.2, 7.2, and 8.5:
```
error = 1*NQSCHAR
```
> A.8. "error_description" Syntax
>T he "error_description" element is defined in Sections 4.1.2.1, 4.2.2.1, 5.2, and 7.2:
```
error-description = 1*NQSCHAR
NQSCHAR = %x20-21 / %x23-5B / %x5D-7E
```
## Demo projects

@ -0,0 +1,20 @@
using System;
using Hangfire;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.BackgroundJobs.Hangfire;
namespace Microsoft.AspNetCore.Builder;
public static class AbpHangfireApplicationBuilderExtensions
{
public static IApplicationBuilder UseAbpHangfireDashboard(
this IApplicationBuilder app,
string pathMatch = "/hangfire",
Action<DashboardOptions>? configure = null,
JobStorage? storage = null)
{
var options = app.ApplicationServices.GetRequiredService<AbpDashboardOptionsProvider>().Get();
configure?.Invoke(options);
return app.UseHangfireDashboard(pathMatch, options, storage);
}
}

@ -1,4 +1,5 @@
using System.Linq;
using System.Threading;
using Hangfire;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
@ -18,8 +19,16 @@ public class AbpDashboardOptionsProvider : ITransientDependency
{
return new DashboardOptions
{
DisplayNameFunc = (dashboardContext, job) =>
AbpBackgroundJobOptions.GetJob(job.Args.First().GetType()).JobName
DisplayNameFunc = (_, job) =>
{
var jobName = job.ToString();
if (job.Args.Count == 3 && job.Args.Last() is CancellationToken)
{
jobName = AbpBackgroundJobOptions.GetJob(job.Args[1].GetType()).JobName;
}
return jobName;
}
};
}
}

@ -12,20 +12,28 @@
<a href="@Url.Page("./Login", new {returnUrl = Model.ReturnUrl, returnUrlHash = Model.ReturnUrlHash})" class="text-decoration-none">@L["Login"]</a>
</strong>
<form method="post" class="mt-4">
@if (!Model.IsExternalLogin)
@if (!Model.IsExternalLogin && Model.EnableLocalRegister)
{
<abp-input asp-for="Input.UserName" auto-focus="true"/>
}
@if(Model.EnableLocalRegister || Model.IsExternalLogin)
{
<abp-input asp-for="Input.EmailAddress"/>
}
<abp-input asp-for="Input.EmailAddress"/>
@if (!Model.IsExternalLogin)
@if (!Model.IsExternalLogin && Model.EnableLocalRegister)
{
<abp-input asp-for="Input.Password"/>
}
<div class="d-grid gap-2">
<abp-button button-type="Primary" type="submit" class="btn-lg mt-4">@L["Register"]</abp-button>
</div>
@if(Model.EnableLocalRegister || Model.IsExternalLogin)
{
<div class="d-grid gap-2">
<abp-button button-type="Primary" type="submit" class="btn-lg mt-4">@L["Register"]</abp-button>
</div>
}
</form>
@if (!Model.IsExternalLogin && Model.VisibleExternalProviders.Any())

@ -38,6 +38,9 @@ public class RegisterModel : AccountPageModel
public IEnumerable<ExternalProviderModel> ExternalProviders { get; set; }
public IEnumerable<ExternalProviderModel> VisibleExternalProviders => ExternalProviders.Where(x => !string.IsNullOrWhiteSpace(x.DisplayName));
public bool EnableLocalRegister { get; set; }
public bool IsExternalLoginOnly => EnableLocalRegister == false && ExternalProviders?.Count() == 1;
public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null;
protected IAuthenticationSchemeProvider SchemeProvider { get; }
@ -55,13 +58,20 @@ public class RegisterModel : AccountPageModel
public virtual async Task<IActionResult> OnGetAsync()
{
if (!IsExternalLogin)
ExternalProviders = await GetExternalProviders();
if (!await CheckSelfRegistrationAsync())
{
await CheckSelfRegistrationAsync();
if (IsExternalLoginOnly)
{
return await OnPostExternalLogin(ExternalLoginScheme);
}
Alerts.Warning(L["SelfRegistrationDisabledMessage"]);
}
await TrySetEmailAsync();
ExternalProviders = await GetExternalProviders();
return Page();
}
@ -96,12 +106,12 @@ public class RegisterModel : AccountPageModel
{
try
{
if (!IsExternalLogin)
ExternalProviders = await GetExternalProviders();
if (!await CheckSelfRegistrationAsync())
{
await CheckSelfRegistrationAsync();
throw new UserFriendlyException(L["SelfRegistrationDisabledMessage"]);
}
ExternalProviders = await GetExternalProviders();
if (IsExternalLogin)
{
@ -172,17 +182,27 @@ public class RegisterModel : AccountPageModel
await SignInManager.SignInAsync(user, isPersistent: true, ExternalLoginAuthSchema);
}
protected virtual async Task CheckSelfRegistrationAsync()
protected virtual async Task<bool> CheckSelfRegistrationAsync()
{
if (!await SettingProvider.IsTrueAsync(AccountSettingNames.IsSelfRegistrationEnabled) ||
!await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin))
EnableLocalRegister = await SettingProvider.IsTrueAsync(AccountSettingNames.EnableLocalLogin) &&
await SettingProvider.IsTrueAsync(AccountSettingNames.IsSelfRegistrationEnabled);
if (IsExternalLogin)
{
return true;
}
if (!EnableLocalRegister)
{
throw new UserFriendlyException(L["SelfRegistrationDisabledMessage"]);
return false;
}
return true;
}
protected virtual async Task<List<ExternalProviderModel>> GetExternalProviders()
{
var schemes = await SchemeProvider.GetAllSchemesAsync();
return schemes
@ -194,6 +214,15 @@ public class RegisterModel : AccountPageModel
})
.ToList();
}
protected virtual async Task<IActionResult> OnPostExternalLogin(string provider)
{
var redirectUrl = Url.Page("./Login", pageHandler: "ExternalLoginCallback", values: new { ReturnUrl, ReturnUrlHash });
var properties = SignInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
properties.Items["scheme"] = provider;
return await Task.FromResult(Challenge(properties, provider));
}
public class PostInput
{

Loading…
Cancel
Save