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

Merge release/2.1 to main #17498

Merged
merged 4 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 1 addition & 4 deletions .github/workflows/docs_validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,15 @@ concurrency:
jobs:
validate-building-documentation:
name: Validating Building the Documentation
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
# Necessary to avoid mkdocs-git-revision-date-localized-plugin warnings.
fetch-depth: 0

- name: Install Dependencies
# Installing pip v22.0.3 is only necessary because unbuntu-latest runners include v22.0.2, which has a bug. That
# line can be removed once the runners are updated, see https://github.com/actions/runner-images?tab=readme-ov-file#available-images.
run: |
python -m pip install pip==22.0.3
pip install -r src/docs/requirements.txt -v

- name: Build Documentation
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Nightly (`main`):
[![Build status](https://github.com/OrchardCMS/OrchardCore/actions/workflows/preview_ci.yml/badge.svg)](https://github.com/OrchardCMS/OrchardCore/actions?query=workflow%3A%22Preview+-+CI%22)
[![Cloudsmith](https://api-prd.cloudsmith.io/badges/version/orchardcore/preview/nuget/OrchardCore.Application.Cms.Targets/latest/x/?render=true&badge_token=gAAAAABey9hKFD_C-ZIpLvayS3HDsIjIorQluDs53KjIdlxoDz6Ntt1TzvMNJp7a_UWvQbsfN5nS7_0IbxCyqHZsjhmZP6cBkKforo-NqwrH5-E6QCrJ3D8%3D)](https://cloudsmith.io/~orchardcore/repos/preview/packages/detail/nuget/OrchardCore.Application.Cms.Targets/latest/)

## Project Status: v2.1.5
## Project Status: v2.1.6

The software is production-ready, and capable of serving large mission-critical applications as well, and we're not aware of any fundamental bugs or missing features we deem crucial. Orchard Core continues to evolve, with each version bringing new improvements, and keeping up with the cutting-edge of .NET.

Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ nav:
- Owners: resources/owners/README.md
- Workshops: resources/workshops/README.md
- Releases:
- 2.1.6: releases/2.1.6.md
- 2.1.5: releases/2.1.5.md
- 2.1.4: releases/2.1.4.md
- 2.1.3: releases/2.1.3.md
Expand Down
2 changes: 1 addition & 1 deletion src/OrchardCore.Build/OrchardCore.Commons.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<LangVersion>12.0</LangVersion>
<VersionPrefix>2.1.5</VersionPrefix>
<VersionPrefix>2.1.6</VersionPrefix>
<VersionSuffix>preview</VersionSuffix>
<VersionSuffix Condition="'$(VersionSuffix)'!='' AND '$(BuildNumber)' != ''">$(VersionSuffix)-$(BuildNumber)</VersionSuffix>
<WarningsNotAsErrors>612,618</WarningsNotAsErrors>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Identity;
using OrchardCore.ReCaptcha.Services;
using OrchardCore.Users;
using OrchardCore.Users.Events;
Expand All @@ -7,10 +8,12 @@ namespace OrchardCore.ReCaptcha.Users.Handlers;
public class LoginFormEventEventHandler : ILoginFormEvent
{
private readonly ReCaptchaService _reCaptchaService;
private readonly SignInManager<IUser> _signInManager;

public LoginFormEventEventHandler(ReCaptchaService reCaptchaService)
public LoginFormEventEventHandler(ReCaptchaService reCaptchaService, SignInManager<IUser> signInManager)
{
_reCaptchaService = reCaptchaService;
_signInManager = signInManager;
}

public Task IsLockedOutAsync(IUser user)
Expand All @@ -23,14 +26,16 @@ public Task LoggedInAsync(IUser user)
return Task.CompletedTask;
}

public Task LoggingInAsync(string userName, Action<string, string> reportError)
public async Task LoggingInAsync(string userName, Action<string, string> reportError)
{
if (_reCaptchaService.IsThisARobot())
// When logging in via an external provider, authentication security is already handled by the provider.
// Therefore, using a CAPTCHA is unnecessary and impractical, as users wouldn't be able to complete it anyway.
if (!_reCaptchaService.IsThisARobot() || await _signInManager.GetExternalLoginInfoAsync() != null)
{
return _reCaptchaService.ValidateCaptchaAsync(reportError);
return;
}

return Task.CompletedTask;
await _reCaptchaService.ValidateCaptchaAsync(reportError);
}

public Task LoggingInFailedAsync(string userName)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Identity;
using OrchardCore.ReCaptcha.Services;
using OrchardCore.Users;
using OrchardCore.Users.Events;
Expand All @@ -7,19 +8,28 @@ namespace OrchardCore.ReCaptcha.Users.Handlers;
public class RegistrationFormEventHandler : IRegistrationFormEvents
{
private readonly ReCaptchaService _reCaptchaService;
private readonly SignInManager<IUser> _signInManager;

public RegistrationFormEventHandler(ReCaptchaService recaptchaService)
public RegistrationFormEventHandler(ReCaptchaService reCaptchaService, SignInManager<IUser> signInManager)
{
_reCaptchaService = recaptchaService;
_reCaptchaService = reCaptchaService;
_signInManager = signInManager;
}

public Task RegisteredAsync(IUser user)
{
return Task.CompletedTask;
}

public Task RegistrationValidationAsync(Action<string, string> reportError)
public async Task RegistrationValidationAsync(Action<string, string> reportError)
{
return _reCaptchaService.ValidateCaptchaAsync(reportError);
// When logging in via an external provider, authentication security is already handled by the provider.
// Therefore, using a CAPTCHA is unnecessary and impractical, as users wouldn't be able to complete it anyway.
if (await _signInManager.GetExternalLoginInfoAsync() != null)
{
return;
}

await _reCaptchaService.ValidateCaptchaAsync(reportError);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace OrchardCore.Security;

public static class SecurityHeaderDefaults
{
internal const char PoliciesSeparator = ',';
internal const char PoliciesSeparator = ';';

internal static readonly string[] ContentSecurityPolicyNames =
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public static class ManifestConstants
{
public const string OrchardCoreTeam = "The Orchard Core Team";

public const string OrchardCoreVersion = "2.1.5";
public const string OrchardCoreVersion = "2.1.6";

public const string OrchardCoreWebsite = "https://orchardcore.net";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ private async ValueTask<IEnumerable<ContentItem>> ResolveAsync(IResolveFieldCont

var query = preQuery.With<ContentItemIndex>();

query = FilterVersion(query, GetVersionOptions(context));
query = FilterVersion(query, context.GetArgument<PublicationStatusEnum>("status"));
query = FilterContentType(query, context);
query = OrderBy(query, context);

Expand Down Expand Up @@ -209,29 +209,19 @@ private static IQuery<ContentItem, ContentItemIndex> FilterContentType(IQuery<Co
return query.Where(q => q.ContentType == contentType);
}

private static VersionOptions GetVersionOptions(IResolveFieldContext context)
private static IQuery<ContentItem, ContentItemIndex> FilterVersion(IQuery<ContentItem, ContentItemIndex> query, PublicationStatusEnum status)
{
if (context.HasPopulatedArgument("status"))
if (status == PublicationStatusEnum.Published)
{
return GetVersionOption(context.GetArgument<PublicationStatusEnum>("status"));
query = query.Where(q => q.Published);
}

return VersionOptions.Published;
}

private static IQuery<ContentItem, ContentItemIndex> FilterVersion(IQuery<ContentItem, ContentItemIndex> query, VersionOptions versionOption)
{
if (versionOption.IsPublished)
{
query = query.Where(q => q.Published == true);
}
else if (versionOption.IsDraft)
else if (status == PublicationStatusEnum.Draft)
{
query = query.Where(q => q.Latest == true && q.Published == false);
query = query.Where(q => q.Latest && !q.Published);
}
else if (versionOption.IsLatest)
else if (status == PublicationStatusEnum.Latest)
{
query = query.Where(q => q.Latest == true);
query = query.Where(q => q.Latest);
}

return query;
Expand Down
2 changes: 1 addition & 1 deletion src/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Orchard Core CMS supports all major site building strategies:

## Status

The latest released version of Orchard Core is `2.1.5`. The release notes can be found under [Releases](releases/2.1.5.md).
The latest released version of Orchard Core is `2.1.6`. The release notes can be found under [Releases](releases/2.1.6.md).

## Getting Started

Expand Down
8 changes: 4 additions & 4 deletions src/docs/getting-started/templates/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ More information about `dotnet new` can be found at <https://docs.microsoft.com/
Once the .NET Core SDK has been installed, type the following command to install the templates for creating Orchard Core web applications:

```CMD
dotnet new install OrchardCore.ProjectTemplates::2.1.5
dotnet new install OrchardCore.ProjectTemplates::2.1.6
```

This will use the most stable release of Orchard Core. In order to use the latest `main` branch of Orchard Core, the following command can be used:

```CMD
dotnet new install OrchardCore.ProjectTemplates::2.1.5-* --nuget-source https://nuget.cloudsmith.io/orchardcore/preview/v3/index.json
dotnet new install OrchardCore.ProjectTemplates::2.1.6-* --nuget-source https://nuget.cloudsmith.io/orchardcore/preview/v3/index.json
```

## Create a new website
Expand Down Expand Up @@ -44,7 +44,7 @@ Options:

-ov|--orchard-version Specifies which version of Orchard Core packages to use.
string - Optional
Default: 2.1.5
Default: 2.1.6
```

Logging can be ignored with this command:
Expand Down Expand Up @@ -133,7 +133,7 @@ Options:

-ov|--orchard-version Specifies which version of Orchard Core packages to use.
string - Optional
Default: 2.1.5
Default: 2.1.6
```

```CMD
Expand Down
6 changes: 3 additions & 3 deletions src/docs/guides/add-admin-menu/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ There are different ways to create sites and modules for Orchard Core. You can l

You can install the latest released templates using this command:

```dotnet new install OrchardCore.ProjectTemplates::2.1.5-*```
```dotnet new install OrchardCore.ProjectTemplates::2.1.6-*```

!!! note
To use the development branch of the template add `--nuget-source https://nuget.cloudsmith.io/orchardcore/preview/v3/index.json`
Expand All @@ -40,10 +40,10 @@ The next step is to reference the module from the application, by adding a proje

We also need a reference to the `OrchardCore.Admin` package in order to be able to implement the required interfaces:

```dotnet add .\MyModule\MyModule.csproj package OrchardCore.Admin --version 2.1.5-*```
```dotnet add .\MyModule\MyModule.csproj package OrchardCore.Admin --version 2.1.6-*```

!!! note
To use the development branch of the template add ` --source https://nuget.cloudsmith.io/orchardcore/preview/v3/index.json --version 2.1.5-*`
To use the development branch of the template add ` --source https://nuget.cloudsmith.io/orchardcore/preview/v3/index.json --version 2.1.6-*`

## Adding our controller and views

Expand Down
2 changes: 1 addition & 1 deletion src/docs/guides/create-blazor-cms/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ In our `OCBlazorLib` blazor Library project, Let's enrich our `/content` page to
- In `OCBlazorLib.csproj` Add a NuGet package reference to `OrchardCore.ContentManagement`

```dotnetcli
dotnet add ./OCBlazorLib/OCBlazorLib.csproj package OrchardCore.ContentManagement --version 2.1.5
dotnet add ./OCBlazorLib/OCBlazorLib.csproj package OrchardCore.ContentManagement --version 2.1.6
```

- Add the following `using` statements in `_Imports.razor`
Expand Down
2 changes: 1 addition & 1 deletion src/docs/guides/create-cms-application/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ There are different ways to create sites and modules for Orchard Core. You can l

In this guide we will use our "Code Generation Templates". You can install the latest stable release of the templates using this command:

```dotnet new install OrchardCore.ProjectTemplates::2.1.5-*```
```dotnet new install OrchardCore.ProjectTemplates::2.1.6-*```

!!! note
To use the development branch of the template add `--nuget-source https://nuget.cloudsmith.io/orchardcore/preview/v3/index.json`.
Expand Down
2 changes: 1 addition & 1 deletion src/docs/guides/create-modular-application-mvc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ There are different ways to create sites and modules for Orchard Core. You can l

In this guide we will use our [Code Generation Templates](../../getting-started/templates/README.md). You can install the latest stable release of the templates using this command:

```dotnet new install OrchardCore.ProjectTemplates::2.1.5-*```
```dotnet new install OrchardCore.ProjectTemplates::2.1.6-*```

!!! note
To use the development branch of the template add `--nuget-source https://nuget.cloudsmith.io/orchardcore/preview/v3/index.json`
Expand Down
2 changes: 1 addition & 1 deletion src/docs/guides/decoupled-cms/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ This will allow for the Razor Pages to be reloaded without the need to recompile

```xml
<ItemGroup>
<PackageReference Include="OrchardCore.Application.Cms.Core.Targets" Version="2.1.5" />
<PackageReference Include="OrchardCore.Application.Cms.Core.Targets" Version="2.1.6" />
</ItemGroup>
```

Expand Down
11 changes: 11 additions & 0 deletions src/docs/releases/2.1.6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Orchard Core 2.1.6

**Release Date:** February 20, 2025

This release includes critical bug fixes related to stability.

The following bugs are fixed:

- [Recaptcha and Microsoft Entra ID don't mix](https://github.com/OrchardCMS/OrchardCore/issues/17422)
- [GraphQL: get content items with "satus: ALL" returns only published items](https://github.com/OrchardCMS/OrchardCore/issues/17115)
- [Fix CSP header policy separator](https://github.com/OrchardCMS/OrchardCore/pull/17409)
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ public void SecurityHeadersShouldAddedAccordingSuppliedOptions()
.Invoke(context);

// Assert
Assert.Equal("child-src 'none',connect-src 'self' https://www.domain1.com https://www.domain2.com,default-src *", context.Response.Headers[SecurityHeaderNames.ContentSecurityPolicy]);
Assert.Equal("child-src 'none';connect-src 'self' https://www.domain1.com https://www.domain2.com;default-src *", context.Response.Headers[SecurityHeaderNames.ContentSecurityPolicy]);
Assert.Equal(ContentTypeOptionsValue.NoSniff, context.Response.Headers[SecurityHeaderNames.XContentTypeOptions]);
Assert.Equal("camera=self,microphone=*,speaker-selection=self https://www.domain1.com https://www.domain2.com", context.Response.Headers[SecurityHeaderNames.PermissionsPolicy]);
Assert.Equal("camera=self;microphone=*;speaker-selection=self https://www.domain1.com https://www.domain2.com", context.Response.Headers[SecurityHeaderNames.PermissionsPolicy]);
Assert.Equal(ReferrerPolicyValue.Origin, context.Response.Headers[SecurityHeaderNames.ReferrerPolicy]);
}

Expand Down Expand Up @@ -90,9 +90,9 @@ public void SecurityHeadersShouldBeAddedAccordingBuildConfiguration()
.Invoke(context);

// Assert
Assert.Equal("child-src 'none',connect-src 'self' https://www.domain1.com https://www.domain2.com,default-src *", context.Response.Headers[SecurityHeaderNames.ContentSecurityPolicy]);
Assert.Equal("child-src 'none';connect-src 'self' https://www.domain1.com https://www.domain2.com;default-src *", context.Response.Headers[SecurityHeaderNames.ContentSecurityPolicy]);
Assert.Equal(ContentTypeOptionsValue.NoSniff, context.Response.Headers[SecurityHeaderNames.XContentTypeOptions]);
Assert.Equal("camera=self,microphone=*,speaker=self https://www.domain1.com https://www.domain2.com", context.Response.Headers[SecurityHeaderNames.PermissionsPolicy]);
Assert.Equal("camera=self;microphone=*;speaker=self https://www.domain1.com https://www.domain2.com", context.Response.Headers[SecurityHeaderNames.PermissionsPolicy]);
Assert.Equal(ReferrerPolicyValue.Origin, context.Response.Headers[SecurityHeaderNames.ReferrerPolicy]);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class SecurityMiddlewareTests
new object[] { new[] { $"{ContentSecurityPolicyValue.ConnectSource} {ContentSecurityPolicyOriginValue.Self} https://www.domain.com/" }, "connect-src 'self' https://www.domain.com/" },
new object[] { new[] { $"{ContentSecurityPolicyValue.DefaultSource} {ContentSecurityPolicyOriginValue.Self} https://www.domain1.com/ https://www.domain2.com/" }, "default-src 'self' https://www.domain1.com/ https://www.domain2.com/" },
new object[] { new[] { $"{ContentSecurityPolicyValue.FontSource} {ContentSecurityPolicyOriginValue.Any}"}, "font-src *" },
new object[] { new[] { $"{ContentSecurityPolicyValue.ScriptSource} {ContentSecurityPolicyOriginValue.Self} https://www.domain.com/", $"{ContentSecurityPolicyValue.StyleSource} {ContentSecurityPolicyOriginValue.Self} https://www.domain.com/" }, "script-src 'self' https://www.domain.com/,style-src 'self' https://www.domain.com/" },
new object[] { new[] { $"{ContentSecurityPolicyValue.ScriptSource} {ContentSecurityPolicyOriginValue.Self} https://www.domain.com/", $"{ContentSecurityPolicyValue.StyleSource} {ContentSecurityPolicyOriginValue.Self} https://www.domain.com/" }, "script-src 'self' https://www.domain.com/;style-src 'self' https://www.domain.com/" },
new object[] { new[] { $"{ContentSecurityPolicyValue.Sandbox}"}, "sandbox" },
new object[] { new[] { $"{ContentSecurityPolicyValue.Sandbox} allow-scripts" }, "sandbox allow-scripts" },
new object[] { new[] { $"{ContentSecurityPolicyValue.UpgradeInsecureRequests}"}, "upgrade-insecure-requests" },
Expand All @@ -27,9 +27,9 @@ public class SecurityMiddlewareTests
new object[] { new[] { $"{PermissionsPolicyValue.Camera}={PermissionsPolicyOriginValue.Self}"}, "camera=self" },
new object[] { new[] { $"{PermissionsPolicyValue.EncryptedMedia}={PermissionsPolicyOriginValue.Self} https://www.domain.com" }, "encrypted-media=self https://www.domain.com" },
new object[] { new[] { $"{PermissionsPolicyValue.FullScreen}={PermissionsPolicyOriginValue.Self} https://www.domain.com https://www.sub.domain.com" }, "fullscreen=self https://www.domain.com https://www.sub.domain.com" },
new object[] { new[] { $"{PermissionsPolicyValue.Geolocation}={PermissionsPolicyOriginValue.None}", $"{PermissionsPolicyValue.Gyroscope}={PermissionsPolicyOriginValue.Any}" }, "geolocation=(),gyroscope=*" },
new object[] { new[] { $"{PermissionsPolicyValue.Magnetometer}={PermissionsPolicyOriginValue.None}", $"{PermissionsPolicyValue.Microphone}={PermissionsPolicyOriginValue.Any}", $"{PermissionsPolicyValue.Midi}={PermissionsPolicyOriginValue.Self}" }, "magnetometer=(),microphone=*,midi=self" },
new object[] { new[] { $"{PermissionsPolicyValue.Usb}={PermissionsPolicyOriginValue.Self}", $"{PermissionsPolicyValue.Payment}={PermissionsPolicyOriginValue.Self} https://www.domain.com", $"{PermissionsPolicyValue.PictureInPicture}={PermissionsPolicyOriginValue.Self}", $"{PermissionsPolicyValue.Push}={PermissionsPolicyOriginValue.Self} https://www.domain.com https://www.sub.domain.com" }, "usb=self,payment=self https://www.domain.com,picture-in-picture=self,push=self https://www.domain.com https://www.sub.domain.com" }
new object[] { new[] { $"{PermissionsPolicyValue.Geolocation}={PermissionsPolicyOriginValue.None}", $"{PermissionsPolicyValue.Gyroscope}={PermissionsPolicyOriginValue.Any}" }, "geolocation=();gyroscope=*" },
new object[] { new[] { $"{PermissionsPolicyValue.Magnetometer}={PermissionsPolicyOriginValue.None}", $"{PermissionsPolicyValue.Microphone}={PermissionsPolicyOriginValue.Any}", $"{PermissionsPolicyValue.Midi}={PermissionsPolicyOriginValue.Self}" }, "magnetometer=();microphone=*;midi=self" },
new object[] { new[] { $"{PermissionsPolicyValue.Usb}={PermissionsPolicyOriginValue.Self}", $"{PermissionsPolicyValue.Payment}={PermissionsPolicyOriginValue.Self} https://www.domain.com", $"{PermissionsPolicyValue.PictureInPicture}={PermissionsPolicyOriginValue.Self}", $"{PermissionsPolicyValue.Push}={PermissionsPolicyOriginValue.Self} https://www.domain.com https://www.sub.domain.com" }, "usb=self;payment=self https://www.domain.com;picture-in-picture=self;push=self https://www.domain.com https://www.sub.domain.com" }
};

public static IEnumerable<object[]> ReferrerPolicies =>
Expand Down
Loading