Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

URL Rewriting Module #16687

Merged
merged 97 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
edcb175
Sync with upstream OrchardCMS/dev
arkadiuszwojcik Jul 10, 2020
ad39ce7
Merge pull request #3 from OrchardCMS/dev
arkadiuszwojcik Dec 17, 2020
67ff75e
Merge pull request #4 from OrchardCMS/dev
arkadiuszwojcik Dec 21, 2020
0c6761b
Merge pull request #5 from OrchardCMS/dev
arkadiuszwojcik Dec 27, 2020
f8ec4e2
Merge branch 'OrchardCMS:main' into dev
arkadiuszwojcik Sep 7, 2024
4661da6
Rewrite module
Sep 7, 2024
49f3939
Fix warning as errors
Sep 7, 2024
d7e6f61
Update OrchardCore.Rewrite.csproj
MikeAlhayek Sep 9, 2024
171c170
Code cleanup after code review
Sep 10, 2024
0f2914a
Rename module
Sep 11, 2024
3cbccfb
Rename classes to match module name
Sep 13, 2024
2eeefea
- Constant for module order
Sep 15, 2024
40bf27b
- Introduce ConfigureOptions
Sep 15, 2024
5a0a436
Merge branch 'OrchardCMS:main' into dev
arkadiuszwojcik Sep 16, 2024
3d86a84
Merge branch 'dev' into new_rewrite_module
Sep 16, 2024
6d1f4b4
UrlRewriting UI - part 1
Sep 18, 2024
ff64d23
Merge branch 'OrchardCMS:main' into dev
arkadiuszwojcik Sep 18, 2024
1735f9a
Merge branch 'dev' into new_rewrite_module
Sep 18, 2024
8080821
UrlRewriting UI - part 2
Sep 22, 2024
23546cb
UrlRewriting UI - part 3
Sep 25, 2024
060a19c
UrlRewriting UI - part 4
Sep 30, 2024
61e2ce7
Merge branch 'OrchardCMS:main' into dev
arkadiuszwojcik Sep 30, 2024
397ffa0
Merge branch 'dev' into new_rewrite_module
Sep 30, 2024
2963137
Add recipe step
Oct 2, 2024
7ffe421
Mark classes as sealed
Oct 2, 2024
806be17
Bug fixes
Oct 2, 2024
8b23ca1
UI fix
Oct 2, 2024
45d1547
Cleanup, add Id to Rules and other things
MikeAlhayek Oct 3, 2024
8fb929f
Merge branch 'main' into new_rewrite_module
MikeAlhayek Oct 3, 2024
78d7943
add site release warning
MikeAlhayek Oct 3, 2024
f5cd1f5
style
MikeAlhayek Oct 3, 2024
1f83775
Use Queries like UI and change everything
MikeAlhayek Oct 3, 2024
342d69b
remove old properties from RewriteStep
MikeAlhayek Oct 3, 2024
a1de614
missed method
MikeAlhayek Oct 3, 2024
b567e92
Fix the UI, add order and simplify drivers and views
MikeAlhayek Oct 4, 2024
c6e52e3
Merge branch 'main' into new_rewrite_module
MikeAlhayek Oct 4, 2024
f1f0923
fix build and add docs
MikeAlhayek Oct 5, 2024
81bd0ee
Merge branch 'new_rewrite_module' of https://github.com/arkadiuszwojc…
MikeAlhayek Oct 5, 2024
3e58f22
fix docs
MikeAlhayek Oct 5, 2024
d4a4b2b
add all the handlers
MikeAlhayek Oct 5, 2024
5c25ba2
fix build
MikeAlhayek Oct 5, 2024
59a9353
Merge branch 'main' into new_rewrite_module
MikeAlhayek Oct 5, 2024
d7627ed
Fix flags creation
Oct 6, 2024
2925e7c
Fix for RewriteRuleSource
Oct 6, 2024
11e657a
Move SkipFurtherRules to RewriteUrl metadata
Oct 6, 2024
a33b104
Fix RedirectRule flags creation
Oct 6, 2024
b4647d9
Merge branch 'main' into new_rewrite_module
MikeAlhayek Oct 7, 2024
b534431
fix build
MikeAlhayek Oct 7, 2024
53b08e2
cleanup
MikeAlhayek Oct 7, 2024
d688d18
Fix names Queries -> Rules
Oct 8, 2024
0bd925b
Autogen initial rule order
Oct 8, 2024
f6d3b70
Fix names
Oct 8, 2024
ba20fb5
Merge branch 'main' into new_rewrite_module
MikeAlhayek Oct 8, 2024
dda221c
remove buttons shape
MikeAlhayek Oct 8, 2024
e280d84
fix conflict
MikeAlhayek Oct 8, 2024
2faad49
handle bulk remove abd cleanup
MikeAlhayek Oct 8, 2024
80cfe0a
Change 'Skip Further Rules' to 'Stop processing of subsequent rules'
Oct 9, 2024
4c81d44
Rename Url to SubstitutionUrl
Oct 11, 2024
6a5f621
Fix exception in Max fun if there is no rules
Oct 11, 2024
03770b1
Merge branch 'main' into new_rewrite_module
MikeAlhayek Oct 13, 2024
396c05d
minor change
MikeAlhayek Oct 13, 2024
7378ffe
improve logic
MikeAlhayek Oct 13, 2024
a2efe8b
cleanup
MikeAlhayek Oct 13, 2024
f6a494b
Update RewriteRuleOptions.cs
MikeAlhayek Oct 13, 2024
5ffd90b
Update RewriteRule.Buttons.SummaryAdmin.cshtml
MikeAlhayek Oct 13, 2024
9518870
Forgotten SubstitutionUrl rename in UrlRedirectSourceMetadata
Oct 13, 2024
21ba143
- Align rule construction code
Oct 13, 2024
efa342c
Fix flags append
Oct 14, 2024
15c307d
Remove using
Oct 14, 2024
cb238d0
Fix recipe step, add validate handlers, and simplify
MikeAlhayek Oct 14, 2024
d0aa57c
add recipe docs and allow updating rule from recipe
MikeAlhayek Oct 14, 2024
c251813
address feedback
MikeAlhayek Oct 14, 2024
4c83d8e
remove extra quotes
MikeAlhayek Oct 14, 2024
56dc8dc
Merge branch 'main' into new_rewrite_module
MikeAlhayek Oct 14, 2024
6cacc1a
improve labels
MikeAlhayek Oct 15, 2024
1018f4a
improve docs
MikeAlhayek Oct 15, 2024
431185e
improve docs and cleanup
MikeAlhayek Oct 15, 2024
92cc77a
Merge branch 'main' into new_rewrite_module
MikeAlhayek Oct 15, 2024
41816e6
Add extra hint
Oct 15, 2024
001d983
address feedback
MikeAlhayek Oct 15, 2024
354cd5f
Merge branch 'main' into new_rewrite_module
MikeAlhayek Oct 15, 2024
1010bca
cleanup
MikeAlhayek Oct 15, 2024
dc7abcb
address feedback
MikeAlhayek Oct 15, 2024
b592a11
better order counting
MikeAlhayek Oct 15, 2024
15f7a59
Merge branch 'main' into new_rewrite_module
MikeAlhayek Oct 15, 2024
148fccb
Merge branch 'main' into new_rewrite_module
MikeAlhayek Oct 16, 2024
7972b09
add sorting UI instead of an input
MikeAlhayek Oct 16, 2024
0ed0b77
save
MikeAlhayek Oct 17, 2024
b4c8a59
fix sort logic
MikeAlhayek Oct 17, 2024
eca859e
move JS into scrtipt file, use drop down menu for the query string po…
MikeAlhayek Oct 17, 2024
85a22d2
cleanup
MikeAlhayek Oct 18, 2024
0b77fa1
Merge branch 'main' into new_rewrite_module
MikeAlhayek Oct 18, 2024
6823a92
Add a display name for the source
MikeAlhayek Oct 19, 2024
76b5ed0
Merge branch 'main' into new_rewrite_module
MikeAlhayek Oct 19, 2024
0ddb4b5
cleanup
MikeAlhayek Oct 19, 2024
9c88223
improve docs
MikeAlhayek Oct 19, 2024
f2740c2
cleaner table
MikeAlhayek Oct 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions OrchardCore.sln
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Rules.Core", "s
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Queries.Core", "src\OrchardCore\OrchardCore.Queries.Core\OrchardCore.Queries.Core.csproj", "{61B358F2-702C-40AA-9DF7-7121248FE6DE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.UrlRewriting", "src\OrchardCore.Modules\OrchardCore.UrlRewriting\OrchardCore.UrlRewriting.csproj", "{D0F8B342-BDA8-44CB-AA43-7A65C79636A2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -1389,6 +1391,10 @@ Global
{61B358F2-702C-40AA-9DF7-7121248FE6DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61B358F2-702C-40AA-9DF7-7121248FE6DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61B358F2-702C-40AA-9DF7-7121248FE6DE}.Release|Any CPU.Build.0 = Release|Any CPU
{D0F8B342-BDA8-44CB-AA43-7A65C79636A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D0F8B342-BDA8-44CB-AA43-7A65C79636A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D0F8B342-BDA8-44CB-AA43-7A65C79636A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D0F8B342-BDA8-44CB-AA43-7A65C79636A2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1629,6 +1635,7 @@ Global
{E8A1097D-A65A-4B17-A3A2-F50D79552732} = {A066395F-6F73-45DC-B5A6-B4E306110DCE}
{4BAA08A2-878C-4B96-86BF-5B3DB2B6C2C7} = {F23AC6C2-DE44-4699-999D-3C478EF3D691}
{61B358F2-702C-40AA-9DF7-7121248FE6DE} = {F23AC6C2-DE44-4699-999D-3C478EF3D691}
{D0F8B342-BDA8-44CB-AA43-7A65C79636A2} = {A066395F-6F73-45DC-B5A6-B4E306110DCE}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {46A1D25A-78D1-4476-9CBF-25B75E296341}
Expand Down
38 changes: 38 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.UrlRewriting/AdminMenu.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Localization;
using OrchardCore.Navigation;
using OrchardCore.UrlRewriting.Drivers;

namespace OrchardCore.UrlRewriting;

public sealed class AdminMenu : AdminNavigationProvider
{
private static readonly RouteValueDictionary _routeValues = new()
{
{ "area", "OrchardCore.Settings" },
{ "groupId", UrlRewritingSettingsDisplayDriver.GroupId },
};

public readonly IStringLocalizer S;
MikeAlhayek marked this conversation as resolved.
Show resolved Hide resolved

public AdminMenu(IStringLocalizer<AdminMenu> stringLocalizer)
{
S = stringLocalizer;
}

protected override ValueTask BuildAsync(NavigationBuilder builder)
{
builder
.Add(S["Configuration"], configuration => configuration
.Add(S["Settings"], settings => settings
.Add(S["URL Rewriting"], S["URL Rewriting"].PrefixPosition(), seo => seo
arkadiuszwojcik marked this conversation as resolved.
Show resolved Hide resolved
.Permission(Permissions.ManageUrlRewriting)
.Action("Index", "Admin", _routeValues)
.LocalNav()
)
)
);

return ValueTask.CompletedTask;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Rewrite;
using Microsoft.Extensions.Localization;
using OrchardCore.DisplayManagement.Entities;
using OrchardCore.DisplayManagement.Handlers;
using OrchardCore.DisplayManagement.ModelBinding;
using OrchardCore.DisplayManagement.Views;
using OrchardCore.Environment.Shell;
using OrchardCore.UrlRewriting.Models;
using OrchardCore.UrlRewriting.ViewModels;
using OrchardCore.Settings;
using OrchardCore.Mvc.ModelBinding;

namespace OrchardCore.UrlRewriting.Drivers;

internal sealed class UrlRewritingSettingsDisplayDriver : SiteDisplayDriver<UrlRewritingSettings>
{
public const string GroupId = "UrlRewriting";

private readonly IAuthorizationService _authorizationService;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IShellReleaseManager _shellReleaseManager;
internal readonly IStringLocalizer S;
arkadiuszwojcik marked this conversation as resolved.
Show resolved Hide resolved

public UrlRewritingSettingsDisplayDriver(
IAuthorizationService authorizationService,
IHttpContextAccessor httpContextAccessor,
IShellReleaseManager shellReleaseManager,
IStringLocalizer<UrlRewritingSettingsDisplayDriver> stringLocalizer)
{
_authorizationService = authorizationService;
_httpContextAccessor = httpContextAccessor;
_shellReleaseManager = shellReleaseManager;
S = stringLocalizer;
}

protected override string SettingsGroupId => GroupId;

public override async Task<IDisplayResult> EditAsync(ISite site, UrlRewritingSettings settings, BuildEditorContext context)
{
var user = _httpContextAccessor.HttpContext?.User;

if (!await _authorizationService.AuthorizeAsync(user, Permissions.ManageUrlRewriting))
{
return null;
}

context.AddTenantReloadWarningWrapper();

return Initialize<UrlRewritingSettingsViewModel>("UrlRewritingSettings_Edit", model =>
{
model.ApacheModRewrite = settings.ApacheModRewrite;
}).Location("Content:1")
.OnGroup(SettingsGroupId);
}

public override async Task<IDisplayResult> UpdateAsync(ISite site, UrlRewritingSettings settings, UpdateEditorContext context)
{
var user = _httpContextAccessor.HttpContext?.User;

if (!await _authorizationService.AuthorizeAsync(user, Permissions.ManageUrlRewriting))
{
return null;
}

var model = new UrlRewritingSettingsViewModel();

await context.Updater.TryUpdateModelAsync(model, Prefix);

settings.ApacheModRewrite = model.ApacheModRewrite;

ValidateUrls(settings, context.Updater);

_shellReleaseManager.RequestRelease();

return await EditAsync(site, settings, context);
}

private void ValidateUrls(UrlRewritingSettings settings, IUpdateModel updater)
{
try
{
var rewriteOptions = new RewriteOptions();
using var apacheModRewrite = new StringReader(settings.ApacheModRewrite);
rewriteOptions.AddApacheModRewrite(apacheModRewrite);
}
catch (FormatException ex)
{
updater.ModelState.AddModelError(Prefix, nameof(UrlRewritingSettingsViewModel.ApacheModRewrite), S["Parsing error: {0}", ex.Message]);
}
catch (NotImplementedException ex)
{
updater.ModelState.AddModelError(Prefix, nameof(UrlRewritingSettingsViewModel.ApacheModRewrite), S["Parsing error: {0}", ex.Message]);
}
}
}
10 changes: 10 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.UrlRewriting/Manifest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using OrchardCore.Modules.Manifest;

[assembly: Module(
Name = "URL Rewriting",
Author = ManifestConstants.OrchardCoreTeam,
Website = ManifestConstants.OrchardCoreWebsite,
Version = ManifestConstants.OrchardCoreVersion,
Description = "Enables URL rewrites and redirects for incoming requests.",
Category = "Infrastructure"
)]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace OrchardCore.UrlRewriting.Models;

public class UrlRewritingSettings
{
public string ApacheModRewrite { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<!-- NuGet properties-->
<Title>OrchardCore Rewrite</Title>
<Description>
$(OCCMSDescription)

Provides url rewrite capabilities.
</Description>
<PackageTags>$(PackageTags) OrchardCoreCMS</PackageTags>
</PropertyGroup>

<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\OrchardCore\OrchardCore.Module.Targets\OrchardCore.Module.Targets.csproj" />
<ProjectReference Include="..\..\OrchardCore\OrchardCore.Navigation.Core\OrchardCore.Navigation.Core.csproj" />
</ItemGroup>

</Project>
25 changes: 25 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.UrlRewriting/Permissions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using OrchardCore.Security.Permissions;

namespace OrchardCore.UrlRewriting;

public sealed class Permissions : IPermissionProvider
{
public static readonly Permission ManageUrlRewriting = new Permission("ManageUrlRewriting", "Manage URLs rewrites");

private readonly IEnumerable<Permission> _allPermissions =
[
ManageUrlRewriting,
];

public Task<IEnumerable<Permission>> GetPermissionsAsync()
=> Task.FromResult(_allPermissions);

public IEnumerable<PermissionStereotype> GetDefaultStereotypes() =>
[
new PermissionStereotype
{
Name = OrchardCoreConstants.Roles.Administrator,
Permissions = _allPermissions,
}
];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Rewrite;

namespace OrchardCore.UrlRewriting.Rules;

internal sealed class ExcludeAdminUIRule : IRule
{
private readonly PathString _adminUrlPrefix;

public ExcludeAdminUIRule(string adminUrlPrefix)
{
_adminUrlPrefix = new PathString("/" + adminUrlPrefix);
}

public void ApplyRule(RewriteContext context)
{
if (context.HttpContext.Request.Path.StartsWithSegments(_adminUrlPrefix))
{
context.Result = RuleResult.SkipRemainingRules;
}
else
{
context.Result = RuleResult.ContinueRules;
}
}
}
54 changes: 54 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.UrlRewriting/Startup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Rewrite;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using OrchardCore.Admin;
using OrchardCore.Navigation;
using OrchardCore.Security.Permissions;
using OrchardCore.Settings;
using OrchardCore.Modules;
using OrchardCore.UrlRewriting.Rules;
using OrchardCore.UrlRewriting.Models;
using OrchardCore.UrlRewriting.Drivers;
using OrchardCore.DisplayManagement.Handlers;

namespace OrchardCore.UrlRewriting;

public sealed class Startup : StartupBase
{
public override int Order
=> OrchardCoreConstants.ConfigureOrder.InfrastructureService;

private readonly AdminOptions _adminOptions;

public Startup(IOptions<AdminOptions> adminOptions)
{
_adminOptions = adminOptions.Value;
}

public override void ConfigureServices(IServiceCollection services)
{
services.AddNavigationProvider<AdminMenu>();
services.AddSiteDisplayDriver<UrlRewritingSettingsDisplayDriver>();
services.AddPermissionProvider<Permissions>();
}

public override async ValueTask ConfigureAsync(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider)
{
var siteService = app.ApplicationServices.GetRequiredService<ISiteService>();
var modRewriteSettings = await siteService.GetSettingsAsync<UrlRewritingSettings>();

using var apacheModRewrite = new StringReader(modRewriteSettings.ApacheModRewrite ?? string.Empty);

var options = new RewriteOptions()
.AddApacheModRewrite(apacheModRewrite);

if (options.Rules.Count > 0)
{
// Exclude admin ui requests to prevent accidental access bricking by provided rules
options.Rules.Insert(0, new ExcludeAdminUIRule(_adminOptions.AdminUrlPrefix));
app.UseRewriter(options);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace OrchardCore.UrlRewriting.ViewModels;

public class UrlRewritingSettingsViewModel
{
public string ApacheModRewrite { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@model OrchardCore.UrlRewriting.ViewModels.UrlRewritingSettingsViewModel

<div class="form-group">
<label asp-for="ApacheModRewrite" class="form-label">@T["Apache Mod Rewrite"]</label>
<textarea asp-for="ApacheModRewrite" type="text" class="form-control"></textarea>
<span asp-validation-for="ApacheModRewrite" class="text-danger"></span>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@inherits OrchardCore.DisplayManagement.Razor.RazorPage<TModel>

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, OrchardCore.DisplayManagement
@addTagHelper *, OrchardCore.ResourceManagement
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
<ProjectReference Include="..\..\OrchardCore.Modules\OrchardCore.Redis\OrchardCore.Redis.csproj" PrivateAssets="none" />
<ProjectReference Include="..\..\OrchardCore.Modules\OrchardCore.Resources\OrchardCore.Resources.csproj" PrivateAssets="none" />
<ProjectReference Include="..\..\OrchardCore.Modules\OrchardCore.ResponseCompression\OrchardCore.ResponseCompression.csproj" PrivateAssets="none" />
<ProjectReference Include="..\..\OrchardCore.Modules\OrchardCore.UrlRewriting\OrchardCore.UrlRewriting.csproj" PrivateAssets="none" />
<ProjectReference Include="..\..\OrchardCore.Modules\OrchardCore.ReverseProxy\OrchardCore.ReverseProxy.csproj" PrivateAssets="none" />
<ProjectReference Include="..\..\OrchardCore.Modules\OrchardCore.Rules\OrchardCore.Rules.csproj" PrivateAssets="none" />
<ProjectReference Include="..\..\OrchardCore.Modules\OrchardCore.Roles\OrchardCore.Roles.csproj" PrivateAssets="none" />
Expand Down