mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Fix quoting issues with authored files
This commit is contained in:
parent
77bd85bb47
commit
b503394de0
@ -1,3 +1,6 @@
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Web;
|
||||
using Wabbajack.Hashing.xxHash64;
|
||||
using Wabbajack.Paths;
|
||||
|
||||
@ -12,4 +15,5 @@ public class FileDefinition
|
||||
public PartDefinition[] Parts { get; set; } = { };
|
||||
public string? ServerAssignedUniqueId { get; set; }
|
||||
public string MungedName => $"{OriginalFileName}_{ServerAssignedUniqueId!}";
|
||||
|
||||
}
|
@ -16,6 +16,7 @@ using Wabbajack.DTOs.JsonConverters;
|
||||
using Wabbajack.Networking.GitHub;
|
||||
using Wabbajack.Paths.IO;
|
||||
using Wabbajack.Server.DataModels;
|
||||
using Wabbajack.Server.Extensions;
|
||||
using Wabbajack.Server.Services;
|
||||
|
||||
namespace Wabbajack.BuildServer.Controllers;
|
||||
@ -89,7 +90,7 @@ public class AuthorControls : ControllerBase
|
||||
{
|
||||
var data = await KnownFolders.EntryPoint.Combine(@"Controllers\Templates\AuthorControls.html")
|
||||
.ReadAllTextAsync();
|
||||
var func = NettleEngine.GetCompiler().Compile(data);
|
||||
var func = NettleEngine.GetCompiler().RegisterWJFunctions().Compile(data);
|
||||
return func(o);
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ using Wabbajack.DTOs.JsonConverters;
|
||||
using Wabbajack.Hashing.xxHash64;
|
||||
using Wabbajack.Server.DataModels;
|
||||
using Wabbajack.Server.DTOs;
|
||||
using Wabbajack.Server.Extensions;
|
||||
using Wabbajack.Server.Services;
|
||||
|
||||
namespace Wabbajack.BuildServer.Controllers;
|
||||
@ -26,16 +27,16 @@ namespace Wabbajack.BuildServer.Controllers;
|
||||
[Route("/authored_files")]
|
||||
public class AuthoredFiles : ControllerBase
|
||||
{
|
||||
private static readonly Func<object, string> HandleGetListTemplate = NettleEngine.GetCompiler().Compile(@"
|
||||
private static readonly Func<object, string> HandleGetListTemplate = NettleEngine.GetCompiler().RegisterWJFunctions().Compile(@"
|
||||
<html><body>
|
||||
<table>
|
||||
{{each $.files }}
|
||||
<tr>
|
||||
<td><a href='https://authored-files.wabbajack.org/{{$.Definition.MungedName}}'>{{$.Definition.OriginalFileName}}</a></td>
|
||||
<td><a href='https://authored-files.wabbajack.org/{{@UrlEncode($.Definition.MungedName)}}'>{{$.Definition.OriginalFileName}}</a></td>
|
||||
<td>{{$.HumanSize}}</td>
|
||||
<td>{{$.Definition.Author}}</td>
|
||||
<td>{{$.Updated}}</td>
|
||||
<td><a href='/authored_files/direct_link/{{$.Definition.MungedName}}'>(Slow) HTTP Direct Link</a></td>
|
||||
<td><a href='/authored_files/direct_link/{{@UrlEncode($.Definition.MungedName)}}'>(Slow) HTTP Direct Link</a></td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</table>
|
||||
@ -178,6 +179,7 @@ public class AuthoredFiles : ControllerBase
|
||||
[Route("direct_link/{mungedName}")]
|
||||
public async Task DirectLink(string mungedName)
|
||||
{
|
||||
mungedName = _authoredFiles.DecodeName(mungedName);
|
||||
var definition = await _authoredFiles.ReadDefinition(mungedName);
|
||||
Response.Headers.ContentDisposition =
|
||||
new StringValues($"attachment; filename={definition.OriginalFileName}");
|
||||
|
@ -19,7 +19,7 @@
|
||||
{{each $.WabbajackFiles }}
|
||||
<tr>
|
||||
<td>
|
||||
<button onclick="deleteFile('{{$.MangledName}}');">Delete</button>
|
||||
<button onclick="deleteFile('{{@Escape($.MangledName)}}');">Delete</button>
|
||||
</td>
|
||||
<td>{{$.Name}}</td>
|
||||
<td>{{$.Size}}</td>
|
||||
@ -43,7 +43,7 @@
|
||||
{{each $.OtherFiles }}
|
||||
<tr>
|
||||
<td>
|
||||
<button onclick="deleteFile('{{$.MangledName}}');">Delete</button>
|
||||
<button onclick="deleteFile('{{@Escape($.MangledName)}}');">Delete</button>
|
||||
</td>
|
||||
<td>{{$.Name}}</td>
|
||||
<td>{{$.Size}}</td>
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.IO.Compression;
|
||||
using System.Web;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Wabbajack.BuildServer;
|
||||
using Wabbajack.Common;
|
||||
@ -44,9 +45,9 @@ public class AuthorFiles
|
||||
return defs.ToArray();
|
||||
}
|
||||
|
||||
public async Task<Stream> StreamForPart(string hashAsHex, int part)
|
||||
public async Task<Stream> StreamForPart(string mungedName, int part)
|
||||
{
|
||||
return AuthorFilesLocation.Combine(hashAsHex, "parts", part.ToString()).Open(FileMode.Open);
|
||||
return AuthorFilesLocation.Combine(mungedName, "parts", part.ToString()).Open(FileMode.Open);
|
||||
}
|
||||
|
||||
public async Task<Stream> CreatePart(string mungedName, int part)
|
||||
@ -74,6 +75,11 @@ public class AuthorFiles
|
||||
return await ReadDefinition(AuthorFilesLocation.Combine(mungedName, "definition.json.gz"));
|
||||
}
|
||||
|
||||
public bool IsDefinition(string mungedName)
|
||||
{
|
||||
return AuthorFilesLocation.Combine(mungedName, "definition.json.gz").FileExists();
|
||||
}
|
||||
|
||||
private async Task<FileDefinition> ReadDefinition(AbsolutePath file)
|
||||
{
|
||||
var gz = new GZipStream(new MemoryStream(await file.ReadAllBytesAsync()), CompressionMode.Decompress);
|
||||
@ -101,4 +107,10 @@ public class AuthorFiles
|
||||
await AllAuthoredFiles();
|
||||
return _byServerId[serverAssignedUniqueId];
|
||||
}
|
||||
|
||||
public string DecodeName(string mungedName)
|
||||
{
|
||||
var decoded = HttpUtility.UrlDecode(mungedName);
|
||||
return IsDefinition(decoded) ? decoded : mungedName;
|
||||
}
|
||||
}
|
48
Wabbajack.Server/Extensions/NettleFunctions.cs
Normal file
48
Wabbajack.Server/Extensions/NettleFunctions.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using Nettle.Compiler;
|
||||
using Nettle.Functions;
|
||||
|
||||
namespace Wabbajack.Server.Extensions;
|
||||
|
||||
public static class NettleFunctions
|
||||
{
|
||||
public static INettleCompiler RegisterWJFunctions(this INettleCompiler compiler)
|
||||
{
|
||||
compiler.RegisterFunction(new UrlEncode());
|
||||
compiler.RegisterFunction(new Escape());
|
||||
return compiler;
|
||||
}
|
||||
|
||||
private sealed class UrlEncode : FunctionBase
|
||||
{
|
||||
public UrlEncode() : base()
|
||||
{
|
||||
DefineRequiredParameter("text", "text to encode", typeof(string));
|
||||
}
|
||||
|
||||
protected override object GenerateOutput(TemplateContext context, params object[] parameterValues)
|
||||
{
|
||||
var value = GetParameterValue<string>("text", parameterValues);
|
||||
return HttpUtility.UrlEncode(value);
|
||||
}
|
||||
|
||||
public override string Description => "URL encodes a string";
|
||||
}
|
||||
|
||||
private sealed class Escape : FunctionBase
|
||||
{
|
||||
public Escape() : base()
|
||||
{
|
||||
DefineRequiredParameter("text", "text to escape", typeof(string));
|
||||
}
|
||||
|
||||
protected override object GenerateOutput(TemplateContext context, params object[] parameterValues)
|
||||
{
|
||||
var value = GetParameterValue<string>("text", parameterValues);
|
||||
return Regex.Escape(value);
|
||||
}
|
||||
|
||||
public override string Description => "Escapes a string";
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user