Browse Source

Merge pull request #25218 from abpframework/auto-merge/rel-10-2/4475

Merge branch rel-10.3 with rel-10.2
pull/25219/head
Volosoft Agent 6 months ago
committed by GitHub
parent
commit
b0c5693ee9
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      .github/workflows/auto-pr.yml
  2. 7
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/QueryStringTenantResolveContributor.cs
  3. 38
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs
  4. 11
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNpmPackageAdder.cs
  5. 47
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/NpmHelper.cs
  6. 32
      framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_Without_DomainResolver_Tests.cs
  7. 64
      framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater_Tests.cs
  8. 2
      modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Detail.cshtml

2
.github/workflows/auto-pr.yml

@ -15,7 +15,7 @@ jobs:
steps:
- uses: actions/checkout@v2
with:
ref: dev
ref: rel-10.3
- name: Reset promotion branch
run: |
git fetch origin rel-10.3:rel-10.3

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

@ -19,13 +19,10 @@ public class QueryStringTenantResolveContributor : HttpTenantResolveContributorB
if (httpContext.Request.Query.ContainsKey(tenantKey))
{
var tenantValue = httpContext.Request.Query[tenantKey].ToString();
if (tenantValue.IsNullOrWhiteSpace())
if (!tenantValue.IsNullOrWhiteSpace())
{
context.Handled = true;
return Task.FromResult<string?>(null);
return Task.FromResult<string?>(tenantValue);
}
return Task.FromResult(tenantValue)!;
}
}

38
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs

@ -359,18 +359,38 @@ public class NpmPackagesUpdater : ITransientDependency
var properties = dependencies.Properties().ToList();
abpPackages
.AddRange(
properties.Where(
p => p.Name.StartsWith("@abp/")
|| p.Name.StartsWith("@volo/")
|| p.Name.StartsWith("@volosoft/")).ToList()
);
foreach (var p in properties.Where(
p => p.Name.StartsWith("@abp/")
|| p.Name.StartsWith("@volo/")
|| p.Name.StartsWith("@volosoft/")))
{
if (IsValidNpmPackageName(p.Name))
{
abpPackages.Add(p);
}
else
{
Logger.LogWarning($"Skipping invalid npm package name: {NpmHelper.SanitizeForLog(p.Name)}");
}
}
}
return abpPackages;
}
public static bool IsValidNpmPackageName(string packageName)
{
try
{
NpmHelper.EnsureSafePackageName(packageName);
return true;
}
catch (CliUsageException)
{
return false;
}
}
protected virtual async Task RunInstallLibsAsync(string fileDirectory)
{
Logger.LogInformation("Installing client-side packages...");
@ -380,13 +400,13 @@ public class NpmPackagesUpdater : ITransientDependency
protected virtual void RunYarn(string fileDirectory)
{
Logger.LogInformation($"Running Yarn on {fileDirectory}");
CmdHelper.RunCmd($"npx yarn", fileDirectory);
CmdHelper.RunCmd($"npx yarn --ignore-scripts", fileDirectory);
}
protected virtual void RunNpmInstall(string fileDirectory)
{
Logger.LogInformation($"Running npm install on {fileDirectory}");
CmdHelper.RunCmd($"npm install", fileDirectory);
CmdHelper.RunCmd($"npm install --ignore-scripts", fileDirectory);
}
protected virtual List<string> GetPackageVersionList(JProperty package, string workingDirectory = null)

11
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNpmPackageAdder.cs

@ -72,6 +72,9 @@ public class ProjectNpmPackageAdder : ITransientDependency
return;
}
NpmHelper.EnsureSafePackageName(npmPackage.Name);
NpmHelper.EnsureSafeVersion(version);
Logger.LogInformation($"Installing '{npmPackage.Name}' package to the project '{packageJsonFilePath}'...");
if (!File.ReadAllText(packageJsonFilePath).Contains($"\"{npmPackage.Name}\""))
@ -81,7 +84,7 @@ public class ProjectNpmPackageAdder : ITransientDependency
using (DirectoryHelper.ChangeCurrentDirectory(directory))
{
Logger.LogInformation("yarn add " + npmPackage.Name + versionPostfix);
CmdHelper.RunCmd("npx yarn add " + npmPackage.Name + versionPostfix);
CmdHelper.RunCmd("npx yarn add " + npmPackage.Name + versionPostfix + " --ignore-scripts");
}
}
else
@ -130,6 +133,8 @@ public class ProjectNpmPackageAdder : ITransientDependency
public async Task AddMvcPackageAsync(string directory, NpmPackageInfo npmPackage, string version = null,
bool skipInstallingLibs = false)
{
NpmHelper.EnsureSafePackageName(npmPackage.Name);
var packageJsonFilePath = Path.Combine(directory, "package.json");
if (!File.Exists(packageJsonFilePath) ||
File.ReadAllText(packageJsonFilePath).Contains($"\"{npmPackage.Name}\""))
@ -144,12 +149,14 @@ public class ProjectNpmPackageAdder : ITransientDependency
version = DetectAbpVersionOrNull(Path.Combine(directory, "package.json"));
}
NpmHelper.EnsureSafeVersion(version);
var versionPostfix = version != null ? $"@{version}" : string.Empty;
using (DirectoryHelper.ChangeCurrentDirectory(directory))
{
Logger.LogInformation("yarn add " + npmPackage.Name + versionPostfix);
CmdHelper.RunCmd("npx yarn add " + npmPackage.Name + versionPostfix);
CmdHelper.RunCmd("npx yarn add " + npmPackage.Name + versionPostfix + " --ignore-scripts");
if (skipInstallingLibs)
{

47
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Utils/NpmHelper.cs

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using NuGet.Versioning;
@ -53,26 +54,64 @@ public class NpmHelper : ITransientDependency
public void RunNpmInstall(string directory, params string[] args)
{
Logger.LogInformation($"Running npm install on {directory}");
CmdHelper.RunCmd($"npm install {args.JoinAsString(" ")}", directory);
CmdHelper.RunCmd($"npm install --ignore-scripts {args.JoinAsString(" ")}", directory);
}
public void RunYarn(string directory)
{
Logger.LogInformation($"Running Yarn on {directory}");
CmdHelper.RunCmd($"npx yarn", directory);
CmdHelper.RunCmd($"npx yarn --ignore-scripts", directory);
}
[Obsolete("This method is deprecated. Use 'YarnAddPackage' instead (it uses 'npx', so there is no need for 'yarn' to be globally installed.")]
public void NpmInstallPackage(string package, string version, string directory)
{
EnsureSafePackageName(package);
EnsureSafeVersion(version);
var packageVersion = !string.IsNullOrWhiteSpace(version) ? $"@{version}" : string.Empty;
CmdHelper.RunCmd("npm install " + package + packageVersion, workingDirectory: directory);
CmdHelper.RunCmd("npm install --ignore-scripts " + package + packageVersion, workingDirectory: directory);
}
public void YarnAddPackage(string package, string version, string directory)
{
EnsureSafePackageName(package);
EnsureSafeVersion(version);
var packageVersion = !string.IsNullOrWhiteSpace(version) ? $"@{version}" : string.Empty;
CmdHelper.RunCmd("npx yarn add " + package + packageVersion, workingDirectory: directory);
CmdHelper.RunCmd("npx yarn add " + package + packageVersion + " --ignore-scripts", workingDirectory: directory);
}
private static readonly Regex SafePackageNameRegex = new(
@"^(@[a-zA-Z0-9][a-zA-Z0-9._-]*/)?[a-zA-Z0-9][a-zA-Z0-9._-]*$",
RegexOptions.Compiled);
private static readonly Regex SafeVersionRegex = new(
@"^[a-zA-Z0-9._~^+\-]+$",
RegexOptions.Compiled);
public static void EnsureSafePackageName(string packageName)
{
if (string.IsNullOrWhiteSpace(packageName) || !SafePackageNameRegex.IsMatch(packageName))
{
throw new CliUsageException($"Invalid npm package name detected: {SanitizeForLog(packageName)}");
}
}
public static void EnsureSafeVersion(string version)
{
if (!string.IsNullOrWhiteSpace(version) && !SafeVersionRegex.IsMatch(version))
{
throw new CliUsageException($"Invalid npm package version detected: {SanitizeForLog(version)}");
}
}
public static string SanitizeForLog(string value)
{
if (value == null)
{
return "(null)";
}
return Regex.Replace(value, @"[\x00-\x1F\x7F]", "?");
}
public string GetInstalledNpmPackages()

32
framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_Without_DomainResolver_Tests.cs

@ -70,4 +70,36 @@ public class AspNetCoreMultiTenancy_Without_DomainResolver_Tests : AspNetCoreMul
var result = await GetResponseAsObjectAsync<Dictionary<string, string>>("http://abp.io");
result["TenantId"].ShouldBe(_testTenantId.ToString());
}
[Fact]
public async Task Should_Use_Header_Tenant_Id_When_QueryString_Tenant_Is_Empty()
{
Client.DefaultRequestHeaders.Add(_options.TenantKey, _testTenantId.ToString());
var result = await GetResponseAsObjectAsync<Dictionary<string, string>>($"http://abp.io?{_options.TenantKey}=");
result["TenantId"].ShouldBe(_testTenantId.ToString());
}
[Fact]
public async Task Should_Fallback_To_Host_When_QueryString_Tenant_Is_Empty_And_No_Other_Resolver()
{
var result = await GetResponseAsObjectAsync<Dictionary<string, string>>($"http://abp.io?{_options.TenantKey}=");
result["TenantId"].ShouldBe("");
}
[Fact]
public async Task Should_Use_Header_Tenant_Id_When_QueryString_Tenant_Is_Whitespace()
{
Client.DefaultRequestHeaders.Add(_options.TenantKey, _testTenantId.ToString());
var result = await GetResponseAsObjectAsync<Dictionary<string, string>>($"http://abp.io?{_options.TenantKey}=%20");
result["TenantId"].ShouldBe(_testTenantId.ToString());
}
[Fact]
public async Task Should_Fallback_To_Host_When_QueryString_Tenant_Is_Whitespace_And_No_Other_Resolver()
{
var result = await GetResponseAsObjectAsync<Dictionary<string, string>>($"http://abp.io?{_options.TenantKey}=%20");
result["TenantId"].ShouldBe("");
}
}

64
framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater_Tests.cs

@ -0,0 +1,64 @@
using Shouldly;
using Volo.Abp.Cli.ProjectModification;
using Volo.Abp.Cli.Utils;
using Xunit;
namespace Volo.Abp.Cli;
public class NpmPackagesUpdater_Tests
{
[Theory]
[InlineData("@abp/ng.core", true)]
[InlineData("@abp/ng.theme.shared", true)]
[InlineData("@abp/ng.components", true)]
[InlineData("@volo/abp.ng.lepton-x.core", true)]
[InlineData("@volo/abp.commercial.ng.ui", true)]
[InlineData("@volosoft/abp.ng.theme.lepton", true)]
[InlineData("@abp/core && calc.exe", false)]
[InlineData("@abp/core; rm -rf /", false)]
[InlineData("@abp/core | curl evil.com", false)]
[InlineData("@abp/core`whoami`", false)]
[InlineData("@abp/core$(id)", false)]
[InlineData("@abp/core\nnewline", false)]
[InlineData("@abp/ space", false)]
[InlineData("@abp/", false)]
[InlineData("@abp/ng core", false)]
[InlineData(null, false)]
[InlineData("", false)]
public void IsValidNpmPackageName(string packageName, bool expected)
{
NpmPackagesUpdater.IsValidNpmPackageName(packageName).ShouldBe(expected);
}
[Theory]
[InlineData("1.0.0", false)]
[InlineData("^8.0.0", false)]
[InlineData("~8.0.0", false)]
[InlineData("8.0.0-preview.1", false)]
[InlineData("8.0.0-preview20260401", false)]
[InlineData("8.0.0+build.123", false)]
[InlineData("latest", false)]
[InlineData("next", false)]
[InlineData(null, false)]
[InlineData("", false)]
[InlineData("1.0.0 && calc.exe", true)]
[InlineData("1.0.0; rm -rf /", true)]
[InlineData("1.0.0 | curl evil.com", true)]
[InlineData("1.0.0`whoami`", true)]
[InlineData("1.0.0$(id)", true)]
[InlineData("1.0.0\nnewline", true)]
[InlineData(">1.0.0", true)]
[InlineData("<2.0.0", true)]
[InlineData("1.0.0|2.0.0", true)]
public void EnsureSafeVersion(string version, bool shouldThrow)
{
if (shouldThrow)
{
Should.Throw<CliUsageException>(() => NpmHelper.EnsureSafeVersion(version));
}
else
{
Should.NotThrow(() => NpmHelper.EnsureSafeVersion(version));
}
}
}

2
modules/blogging/src/Volo.Blogging.Web/Pages/Blogs/Posts/Detail.cshtml

@ -95,7 +95,7 @@
<i class="fa fa-pencil"></i> @L["Edit"]
</a>
}
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Posts.Delete) || (CurrentUser.Id.HasValue && CurrentUser.Id == Model.Post.CreatorId))
@if (await Authorization.IsGrantedAsync(BloggingPermissions.Posts.Delete))
{
<span class="seperator">|</span>
<a href="#" id="DeletePostLink" data-postid="@Model.Post.Id" data-blogShortName="@Model.BlogShortName">

Loading…
Cancel
Save