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

OrchardCore.Cors #2682

Merged
merged 21 commits into from
Dec 27, 2020
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
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
9 changes: 8 additions & 1 deletion OrchardCore.sln
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28822.285
Expand Down Expand Up @@ -343,6 +342,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Application.Cms
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Media.Core", "src\OrchardCore\OrchardCore.Media.Core\OrchardCore.Media.Core.csproj", "{8BC282D3-B7AF-495A-A5B1-D175875EB90E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Cors", "src\OrchardCore.Modules\OrchardCore.Cors\OrchardCore.Cors.csproj", "{854876B6-23C9-4400-8B79-D5097B6AE6BE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Benchmarks", "test\OrchardCore.Benchmarks\OrchardCore.Benchmarks.csproj", "{85610AB6-07E8-45E3-9C48-34D952CC5DD2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Sitemaps.Abstractions", "src\OrchardCore\OrchardCore.Sitemaps.Abstractions\OrchardCore.Sitemaps.Abstractions.csproj", "{5899FB03-AB3F-4113-A3F0-59096B48FA37}"
Expand All @@ -352,6 +353,7 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Contents.TagHelpers", "src\OrchardCore\OrchardCore.Contents.TagHelpers\OrchardCore.Contents.TagHelpers.csproj", "{6236734E-507B-461B-8E92-068886058E84}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Search.Abstractions", "src\OrchardCore\OrchardCore.Search.Abstractions\OrchardCore.Search.Abstractions.csproj", "{5283A8BC-DFF4-436D-AA9C-EE2DBFC5D51A}"
>>>>>>> dev
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah no one notice this ;)

EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.PublishLater", "src\OrchardCore.Modules\OrchardCore.PublishLater\OrchardCore.PublishLater.csproj", "{FADCA695-7A6C-40F1-B17C-8A011EBC6F10}"
EndProject
Expand Down Expand Up @@ -975,6 +977,10 @@ Global
{85610AB6-07E8-45E3-9C48-34D952CC5DD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{85610AB6-07E8-45E3-9C48-34D952CC5DD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{85610AB6-07E8-45E3-9C48-34D952CC5DD2}.Release|Any CPU.Build.0 = Release|Any CPU
{854876B6-23C9-4400-8B79-D5097B6AE6BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{854876B6-23C9-4400-8B79-D5097B6AE6BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{854876B6-23C9-4400-8B79-D5097B6AE6BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{854876B6-23C9-4400-8B79-D5097B6AE6BE}.Release|Any CPU.Build.0 = Release|Any CPU
{5899FB03-AB3F-4113-A3F0-59096B48FA37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5899FB03-AB3F-4113-A3F0-59096B48FA37}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5899FB03-AB3F-4113-A3F0-59096B48FA37}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -1208,6 +1214,7 @@ Global
{AEDB2C9D-938E-484A-8DD8-7429E2BBB2A2} = {3398AB60-2DB7-464C-B211-C4120BE75582}
{8BC282D3-B7AF-495A-A5B1-D175875EB90E} = {F23AC6C2-DE44-4699-999D-3C478EF3D691}
{85610AB6-07E8-45E3-9C48-34D952CC5DD2} = {B8D16C60-99B4-43D5-A3AD-4CD89AF39B25}
{854876B6-23C9-4400-8B79-D5097B6AE6BE} = {A066395F-6F73-45DC-B5A6-B4E306110DCE}
{5899FB03-AB3F-4113-A3F0-59096B48FA37} = {F23AC6C2-DE44-4699-999D-3C478EF3D691}
{D87557AF-668B-4A0F-B079-FA35F71D1C56} = {90030E85-0C4F-456F-B879-443E8A3F220D}
{6236734E-507B-461B-8E92-068886058E84} = {F23AC6C2-DE44-4699-999D-3C478EF3D691}
Expand Down
37 changes: 37 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.Cors/AdminMenu.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Localization;
using OrchardCore.Navigation;

namespace OrchardCore.Cors
{
public class AdminMenu : INavigationProvider
{
public AdminMenu(IStringLocalizer<AdminMenu> localizer)
{
T = localizer;
}

public IStringLocalizer T { get; set; }

public Task BuildNavigationAsync(string name, NavigationBuilder builder)
{
if (!String.Equals(name, "admin", StringComparison.OrdinalIgnoreCase))
{
return Task.CompletedTask;
}

builder
.Add(T["Configuration"], configuration => configuration
.Add(T["Settings"], settings => settings
.Add(T["Cors"], "100", entry => entry
.Action("Index", "Admin", new { area = "OrchardCore.Cors" })
.Permission(Permissions.ManageCorsSettings)
.LocalNav()
))
);

return Task.CompletedTask;
}
}
}
8 changes: 8 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.Cors/Assets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"inputs": [
"Assets/Admin/cors-admin.js"
],
"output": "wwwroot/Scripts/cors-admin.js"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
var optionsList = Vue.component('options-list',
{
props: ['options', 'optionType', 'title', 'subTitle'],
template: '#options-list',
data: function () {
return {
'newOption': ''
};
},
methods: {
addOption: function (value) {
this.options.push(value);
},
deleteOption: function (value) {
this.options.splice($.inArray(value[0], this.options), 1);
}
}
});

var policyDetails = Vue.component('policy-details',
{
components: { optionsList : optionsList },
props: ['policy'],
template: '#policy-details'
});

var corsApp = new Vue({
el: '#corsAdmin',
components: { policyDetails : policyDetails, optionsList : optionsList },
data: {
selectedPolicy: null,
policies: null,
defaultPolicyName: null
},
methods: {
newPolicy: function () {
this.selectedPolicy = {
Name: 'New policy',
AllowedOrigins: [],
AllowAnyOrigin: true,
AllowedMethods: [],
AllowAnyMethod: true,
AllowedHeaders: [],
AllowAnyHeader: true,
AllowCredentials: true,
IsDefaultPolicy: false
};
},
editPolicy: function (policy) {
this.selectedPolicy = Object.assign({}, policy);
this.selectedPolicy.OriginalName = this.selectedPolicy.Name;
},
deletePolicy: function (policy, event) {
this.selectedPolicy = null;
var policyToRemove = this.policies.filter(function (item) { return item.Name === policy.Name; });
if (policyToRemove.length > 0)
this.policies.splice($.inArray(policyToRemove[0], this.policies), 1);
event.stopPropagation();
this.save();
},
updatePolicy: function (policy, event) {
if (policy.IsDefaultPolicy) {
this.policies.forEach(p => p.IsDefaultPolicy = false);
}
if (policy.OriginalName) {
var policyIndex = this.policies.findIndex((oldPolicy) => oldPolicy.Name === policy.OriginalName);
this.policies[policyIndex] = policy;
}
else {
this.policies.push(policy);
}
this.save();
this.back();
},
save: function () {
document.getElementById('CorsSettings').value = JSON.stringify(this.policies);
document.getElementById('corsForm').submit();
},
back: function () {
this.selectedPolicy = null;
}
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Localization;
using Microsoft.Extensions.Localization;
using Newtonsoft.Json;
using OrchardCore.Admin;
using OrchardCore.Cors.Services;
using OrchardCore.Cors.Settings;
using OrchardCore.Cors.ViewModels;
using OrchardCore.DisplayManagement.Notify;

namespace OrchardCore.Cors.Controllers
{
[Admin]
public class AdminController : Controller
{
private readonly IAuthorizationService _authorizationService;
private readonly CorsService _corsService;
private readonly INotifier _notifier;

private readonly IStringLocalizer T;
private readonly IHtmlLocalizer<AdminController> TH;

public AdminController(
IAuthorizationService authorizationService,
IStringLocalizer<AdminController> stringLocalizer,
IHtmlLocalizer<AdminController> htmlLocalizer,
CorsService corsService,
INotifier notifier
)
{
TH = htmlLocalizer;
_notifier = notifier;
_corsService = corsService;
T = stringLocalizer;
_authorizationService = authorizationService;
}

[HttpGet]
public async Task<ActionResult> Index()
{
if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageCorsSettings))
{
return Unauthorized();
}

var settings = await _corsService.GetSettingsAsync();

var list = new List<CorsPolicyViewModel>();

if (settings?.Policies != null)
{
foreach (var policySetting in settings.Policies)
{
var policyViewModel = new CorsPolicyViewModel()
{
Name = policySetting.Name,
AllowAnyHeader = policySetting.AllowAnyHeader,
AllowedHeaders = policySetting.AllowedHeaders,
AllowAnyMethod = policySetting.AllowAnyMethod,
AllowedMethods = policySetting.AllowedMethods,
AllowAnyOrigin = policySetting.AllowAnyOrigin,
AllowedOrigins = policySetting.AllowedOrigins,
AllowCredentials = policySetting.AllowCredentials,
IsDefaultPolicy = policySetting.IsDefaultPolicy
};

list.Add(policyViewModel);
}
}

var viewModel = new CorsSettingsViewModel
{
Policies = list.ToArray()
};

return View(viewModel);
}

[HttpPost]
[ActionName(nameof(Index))]
public async Task<ActionResult> IndexPOST()
{
if (!await _authorizationService.AuthorizeAsync(User, Permissions.ManageCorsSettings))
{
return Unauthorized();
}

var model = new CorsSettingsViewModel();
var configJson = Request.Form["CorsSettings"].First();
model.Policies = JsonConvert.DeserializeObject<CorsPolicyViewModel[]>(configJson);

var corsPolicies = new List<CorsPolicySetting>();

foreach (var settingViewModel in model.Policies)
{
corsPolicies.Add(new CorsPolicySetting
{
Name = settingViewModel.Name,
AllowAnyHeader = settingViewModel.AllowAnyHeader,
AllowAnyMethod = settingViewModel.AllowAnyMethod,
AllowAnyOrigin = settingViewModel.AllowAnyOrigin,
AllowCredentials = settingViewModel.AllowCredentials,
AllowedHeaders = settingViewModel.AllowedHeaders,
AllowedMethods = settingViewModel.AllowedMethods,
AllowedOrigins = settingViewModel.AllowedOrigins,
IsDefaultPolicy =settingViewModel.IsDefaultPolicy

});
}

var corsSettings = new CorsSettings()
{
Policies = corsPolicies
};

await _corsService.UpdateSettingsAsync(corsSettings);

_notifier.Success(TH["Cors settings are updated"]);

return View(model);
}
}
}
9 changes: 9 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.Cors/Manifest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using OrchardCore.Modules.Manifest;

[assembly: Module(
Name = "Cors Configuration",
Author = "The Orchard Team",
Website = "http://orchardproject.net",
Version = "2.0.0",
Description = "Enables configuration of Cors settings",
Category = "Security")]
20 changes: 20 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.Cors/OrchardCore.Cors.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<TargetFramework>$(AspNetCoreTargetFramework)</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
</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" />
<ProjectReference Include="..\..\OrchardCore\OrchardCore.Admin.Abstractions\OrchardCore.Admin.Abstractions.csproj" />
<ProjectReference Include="..\..\OrchardCore\OrchardCore.DisplayManagement\OrchardCore.DisplayManagement.csproj" />
<ProjectReference Include="..\..\OrchardCore\OrchardCore.Users.Core\OrchardCore.Users.Core.csproj" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing reference to OrchardCore.ResourceManagement busted in production as it won't find the Taghelpers. Easy to fix @scleaver

</ItemGroup>

</Project>
MatthijsKrempel marked this conversation as resolved.
Show resolved Hide resolved
32 changes: 32 additions & 0 deletions src/OrchardCore.Modules/OrchardCore.Cors/Permissions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using OrchardCore.Security.Permissions;

namespace OrchardCore.Cors
{
public class Permissions : IPermissionProvider
{
public static readonly Permission ManageCorsSettings = new Permission("ManageCorsSettings", "Managing Cors Settings", isSecurityCritical: true);

public Task<IEnumerable<Permission>> GetPermissionsAsync()
{
return Task.FromResult(new[]
{
ManageCorsSettings
}
.AsEnumerable());
}

public IEnumerable<PermissionStereotype> GetDefaultStereotypes()
{
return new[] {
new PermissionStereotype {
Name = "Administrator",
Permissions = new[] { ManageCorsSettings }
},
};
}

}
}
Loading