mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-04-19 23:46:49 +00:00
feat: implement login functionality with LoginRequestHandler and integrate asset loading
This commit is contained in:
parent
6e9480f503
commit
9ea5ec5d1a
7 changed files with 406 additions and 140 deletions
|
|
@ -20,3 +20,4 @@ jobs:
|
|||
tag: ${{ needs.getVersion.outputs.tag }}
|
||||
channel: ${{ needs.getVersion.outputs.channel }}
|
||||
bypassPackageCheck: true
|
||||
devToolsVersion: ${{ vars.ESSENTIALSDEVTOOLSVERSION }}
|
||||
|
|
@ -99,6 +99,8 @@ namespace PepperDash.Core.Web
|
|||
|
||||
if (_server == null) _server = new HttpCwsServer(BasePath);
|
||||
|
||||
_server.AuthenticateAllRoutes = false;
|
||||
|
||||
_server.setProcessName(Key);
|
||||
_server.HttpRequestHandler = new DefaultRequestHandler();
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,11 @@ namespace PepperDash.Essentials.Core.Web
|
|||
{
|
||||
var routes = new List<HttpCwsRoute>
|
||||
{
|
||||
new HttpCwsRoute("login")
|
||||
{
|
||||
Name = "Root",
|
||||
RouteHandler = new LoginRequestHandler()
|
||||
},
|
||||
new HttpCwsRoute("versions")
|
||||
{
|
||||
Name = "ReportVersions",
|
||||
|
|
|
|||
|
|
@ -36,17 +36,25 @@ namespace PepperDash.Essentials.Core.Web
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// MapToDeviceListObject method
|
||||
/// </summary>
|
||||
public static object MapToDeviceListObject(IKeyed device)
|
||||
{
|
||||
var interfaces = device.GetType()
|
||||
.GetInterfaces()
|
||||
.Select(i => i.Name)
|
||||
.ToList();
|
||||
|
||||
return new
|
||||
{
|
||||
device.Key,
|
||||
Name = (device is IKeyName)
|
||||
? (device as IKeyName).Name
|
||||
: "---"
|
||||
: "---",
|
||||
Interfaces = interfaces
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -110,5 +118,10 @@ namespace PepperDash.Essentials.Core.Web
|
|||
CType = device.Value.Type == null ? "---": device.Value.Type.ToString()
|
||||
};
|
||||
}
|
||||
|
||||
internal static bool IsAuthenticated(HttpCwsContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
|
||||
using System;
|
||||
using Crestron.SimplSharp.CrestronAuthentication;
|
||||
using Crestron.SimplSharp.WebScripting;
|
||||
using Newtonsoft.Json;
|
||||
using PepperDash.Core.Web.RequestHandlers;
|
||||
|
||||
namespace PepperDash.Essentials.Core.Web.RequestHandlers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a LoginRequestHandler
|
||||
/// </summary>
|
||||
public class LoginRequestHandler : WebApiBaseRequestHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// base(true) enables CORS support by default
|
||||
/// </remarks>
|
||||
public LoginRequestHandler()
|
||||
: base(true)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles POST method requests for user login and token generation
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP context for the request.</param>
|
||||
protected override void HandlePost(HttpCwsContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (context.Request.ContentLength < 0)
|
||||
{
|
||||
context.Response.StatusCode = 400;
|
||||
context.Response.StatusDescription = "Bad Request";
|
||||
context.Response.End();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var data = context.Request.GetRequestBody();
|
||||
if (string.IsNullOrEmpty(data))
|
||||
{
|
||||
context.Response.StatusCode = 400;
|
||||
context.Response.StatusDescription = "Bad Request";
|
||||
context.Response.End();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var loginRequest = JsonConvert.DeserializeObject<LoginRequest>(data);
|
||||
|
||||
if (loginRequest == null || string.IsNullOrEmpty(loginRequest.Username) || string.IsNullOrEmpty(loginRequest.Password))
|
||||
{
|
||||
context.Response.StatusCode = 400;
|
||||
context.Response.StatusDescription = "Bad Request";
|
||||
context.Response.End();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Authentication.UserToken token;
|
||||
|
||||
try
|
||||
{
|
||||
token = Authentication.GetAuthenticationToken(loginRequest.Username, loginRequest.Password);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
context.Response.StatusCode = 401;
|
||||
context.Response.StatusDescription = "Bad Request";
|
||||
context.Response.End();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!token.Valid)
|
||||
{
|
||||
context.Response.StatusCode = 401;
|
||||
context.Response.StatusDescription = "Unauthorized";
|
||||
context.Response.End();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
context.Response.StatusCode = 200;
|
||||
context.Response.StatusDescription = "OK";
|
||||
context.Response.ContentType = "application/json";
|
||||
context.Response.ContentEncoding = System.Text.Encoding.UTF8;
|
||||
context.Response.Write(JsonConvert.SerializeObject(new { Token = token }, Formatting.Indented), false);
|
||||
context.Response.End();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
context.Response.StatusCode = 500;
|
||||
context.Response.StatusDescription = "Internal Server Error";
|
||||
context.Response.ContentType = "application/json";
|
||||
context.Response.ContentEncoding = System.Text.Encoding.UTF8;
|
||||
context.Response.Write(JsonConvert.SerializeObject(new { Error = ex.Message }, Formatting.Indented), false);
|
||||
context.Response.End();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a LoginRequest
|
||||
/// </summary>
|
||||
public class LoginRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the username.
|
||||
/// </summary>
|
||||
public string Username { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the password.
|
||||
/// </summary>
|
||||
public string Password { get; set; }
|
||||
}
|
||||
}
|
||||
257
src/PepperDash.Essentials/AssetLoader.cs
Normal file
257
src/PepperDash.Essentials/AssetLoader.cs
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using PepperDash.Core;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles extracting embedded asset bundles and moving configuration files from the
|
||||
/// application directory to the program file-path prefix at startup.
|
||||
/// Implemented using <c>System.IO</c> types so it can run (and be tested) outside
|
||||
/// of a Crestron runtime environment.
|
||||
/// </summary>
|
||||
internal static class AssetLoader
|
||||
{
|
||||
/// <summary>
|
||||
/// Scans <paramref name="applicationDirectoryPath"/> for well-known zip bundles and
|
||||
/// JSON configuration files and deploys them to <paramref name="filePathPrefix"/>.
|
||||
/// </summary>
|
||||
/// <param name="applicationDirectoryPath">
|
||||
/// The directory to scan (typically the Crestron application root).
|
||||
/// </param>
|
||||
/// <param name="filePathPrefix">
|
||||
/// The program's runtime working directory (e.g. <c>/nvram/program1/</c>).
|
||||
/// </param>
|
||||
internal static void Load(string applicationDirectoryPath, string filePathPrefix)
|
||||
{
|
||||
var applicationDirectory = new DirectoryInfo(applicationDirectoryPath);
|
||||
Debug.LogMessage(LogEventLevel.Information,
|
||||
"Searching: {applicationDirectory:l} for embedded assets - {Destination}",
|
||||
applicationDirectory.FullName, filePathPrefix);
|
||||
|
||||
ExtractAssetsZip(applicationDirectory, filePathPrefix);
|
||||
ExtractHtmlAssetsZip(applicationDirectory, filePathPrefix);
|
||||
ExtractDevToolsZip(applicationDirectory, filePathPrefix);
|
||||
MoveConfigurationFile(applicationDirectory, filePathPrefix);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Private helpers
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private static void ExtractAssetsZip(DirectoryInfo applicationDirectory, string filePathPrefix)
|
||||
{
|
||||
var zipFiles = applicationDirectory.GetFiles("assets*.zip");
|
||||
|
||||
if (zipFiles.Length > 1)
|
||||
throw new Exception("Multiple assets zip files found. Cannot continue.");
|
||||
|
||||
if (zipFiles.Length == 1)
|
||||
{
|
||||
var zipFile = zipFiles[0];
|
||||
var assetsRoot = Path.GetFullPath(filePathPrefix);
|
||||
if (!assetsRoot.EndsWith(Path.DirectorySeparatorChar.ToString()) &&
|
||||
!assetsRoot.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
|
||||
{
|
||||
assetsRoot += Path.DirectorySeparatorChar;
|
||||
}
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Information,
|
||||
"Found assets zip file: {zipFile:l}... Unzipping...", zipFile.FullName);
|
||||
|
||||
using (var archive = ZipFile.OpenRead(zipFile.FullName))
|
||||
{
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
var destinationPath = Path.Combine(filePathPrefix, entry.FullName);
|
||||
var fullDest = Path.GetFullPath(destinationPath);
|
||||
if (!fullDest.StartsWith(assetsRoot, StringComparison.OrdinalIgnoreCase))
|
||||
throw new InvalidOperationException(
|
||||
$"Entry '{entry.FullName}' is trying to extract outside of the target directory.");
|
||||
|
||||
if (string.IsNullOrEmpty(entry.Name))
|
||||
{
|
||||
Directory.CreateDirectory(destinationPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Directory.Exists(destinationPath))
|
||||
Directory.Delete(destinationPath, recursive: true);
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(destinationPath));
|
||||
entry.ExtractToFile(destinationPath, overwrite: true);
|
||||
Debug.LogMessage(LogEventLevel.Information,
|
||||
"Extracted: {entry:l} to {Destination}", entry.FullName, destinationPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var file in zipFiles)
|
||||
File.Delete(file.FullName);
|
||||
}
|
||||
|
||||
private static void ExtractHtmlAssetsZip(DirectoryInfo applicationDirectory, string filePathPrefix)
|
||||
{
|
||||
var htmlZipFiles = applicationDirectory.GetFiles("htmlassets*.zip");
|
||||
|
||||
if (htmlZipFiles.Length > 1)
|
||||
throw new Exception(
|
||||
"Multiple htmlassets zip files found in application directory. " +
|
||||
"Please ensure only one htmlassets*.zip file is present and retry.");
|
||||
|
||||
if (htmlZipFiles.Length == 1)
|
||||
{
|
||||
var htmlZipFile = htmlZipFiles[0];
|
||||
var programDir = new DirectoryInfo(
|
||||
filePathPrefix.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
|
||||
var userOrNvramDir = programDir.Parent;
|
||||
var rootDir = userOrNvramDir?.Parent;
|
||||
if (rootDir == null)
|
||||
throw new Exception(
|
||||
$"Unable to determine root directory for html extraction. Current path: {filePathPrefix}");
|
||||
|
||||
var htmlDir = Path.Combine(rootDir.FullName, "html");
|
||||
var htmlRoot = Path.GetFullPath(htmlDir);
|
||||
if (!htmlRoot.EndsWith(Path.DirectorySeparatorChar.ToString()) &&
|
||||
!htmlRoot.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
|
||||
{
|
||||
htmlRoot += Path.DirectorySeparatorChar;
|
||||
}
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Information,
|
||||
"Found htmlassets zip file: {zipFile:l}... Unzipping...", htmlZipFile.FullName);
|
||||
|
||||
using (var archive = ZipFile.OpenRead(htmlZipFile.FullName))
|
||||
{
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
var destinationPath = Path.Combine(htmlDir, entry.FullName);
|
||||
var fullDest = Path.GetFullPath(destinationPath);
|
||||
if (!fullDest.StartsWith(htmlRoot, StringComparison.OrdinalIgnoreCase))
|
||||
throw new InvalidOperationException(
|
||||
$"Entry '{entry.FullName}' is trying to extract outside of the target directory.");
|
||||
|
||||
if (string.IsNullOrEmpty(entry.Name))
|
||||
{
|
||||
Directory.CreateDirectory(destinationPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (File.Exists(destinationPath))
|
||||
File.Delete(destinationPath);
|
||||
|
||||
var parentDir = Path.GetDirectoryName(destinationPath);
|
||||
if (!string.IsNullOrEmpty(parentDir))
|
||||
Directory.CreateDirectory(parentDir);
|
||||
|
||||
entry.ExtractToFile(destinationPath, overwrite: true);
|
||||
Debug.LogMessage(LogEventLevel.Information,
|
||||
"Extracted: {entry:l} to {Destination}", entry.FullName, destinationPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var file in htmlZipFiles)
|
||||
File.Delete(file.FullName);
|
||||
}
|
||||
|
||||
private static void ExtractDevToolsZip(DirectoryInfo applicationDirectory, string filePathPrefix)
|
||||
{
|
||||
var devToolsZipFiles = applicationDirectory.GetFiles("essentials-devtools*.zip");
|
||||
|
||||
if (devToolsZipFiles.Length > 1)
|
||||
throw new Exception(
|
||||
"Multiple essentials-devtools zip files found in application directory. " +
|
||||
"Please ensure only one essentials-devtools*.zip file is present and retry.");
|
||||
|
||||
if (devToolsZipFiles.Length == 1)
|
||||
{
|
||||
var devToolsZipFile = devToolsZipFiles[0];
|
||||
var programDir = new DirectoryInfo(
|
||||
filePathPrefix.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
|
||||
var userOrNvramDir = programDir.Parent;
|
||||
var rootDir = userOrNvramDir?.Parent;
|
||||
if (rootDir == null)
|
||||
throw new Exception(
|
||||
$"Unable to determine root directory for debug html extraction. Current path: {filePathPrefix}");
|
||||
|
||||
var debugDir = Path.Combine(rootDir.FullName, "html", "debug");
|
||||
var debugRoot = Path.GetFullPath(debugDir);
|
||||
if (!debugRoot.EndsWith(Path.DirectorySeparatorChar.ToString()) &&
|
||||
!debugRoot.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
|
||||
{
|
||||
debugRoot += Path.DirectorySeparatorChar;
|
||||
}
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Information,
|
||||
"Found essentials-devtools zip file: {zipFile:l}... Unzipping to {Destination}...",
|
||||
devToolsZipFile.FullName, debugDir);
|
||||
|
||||
using (var archive = ZipFile.OpenRead(devToolsZipFile.FullName))
|
||||
{
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
var destinationPath = Path.Combine(debugDir, entry.FullName);
|
||||
var fullDest = Path.GetFullPath(destinationPath);
|
||||
if (!fullDest.StartsWith(debugRoot, StringComparison.OrdinalIgnoreCase))
|
||||
throw new InvalidOperationException(
|
||||
$"Entry '{entry.FullName}' is trying to extract outside of the target directory.");
|
||||
|
||||
if (string.IsNullOrEmpty(entry.Name))
|
||||
{
|
||||
Directory.CreateDirectory(destinationPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (File.Exists(destinationPath))
|
||||
File.Delete(destinationPath);
|
||||
|
||||
var parentDir = Path.GetDirectoryName(destinationPath);
|
||||
if (!string.IsNullOrEmpty(parentDir))
|
||||
Directory.CreateDirectory(parentDir);
|
||||
|
||||
entry.ExtractToFile(destinationPath, overwrite: true);
|
||||
Debug.LogMessage(LogEventLevel.Information,
|
||||
"Extracted: {entry:l} to {Destination}", entry.FullName, destinationPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var file in devToolsZipFiles)
|
||||
File.Delete(file.FullName);
|
||||
}
|
||||
|
||||
private static void MoveConfigurationFile(DirectoryInfo applicationDirectory, string filePathPrefix)
|
||||
{
|
||||
var jsonFiles = applicationDirectory.GetFiles("*configurationFile*.json");
|
||||
|
||||
if (jsonFiles.Length > 1)
|
||||
{
|
||||
Debug.LogError("Multiple configuration files found in application directory: {@jsonFiles}",
|
||||
jsonFiles.Select(f => f.FullName).ToArray());
|
||||
throw new Exception("Multiple configuration files found. Cannot continue.");
|
||||
}
|
||||
|
||||
if (jsonFiles.Length == 1)
|
||||
{
|
||||
var jsonFile = jsonFiles[0];
|
||||
var finalPath = Path.Combine(filePathPrefix, jsonFile.Name);
|
||||
Debug.LogMessage(LogEventLevel.Information,
|
||||
"Found configuration file: {jsonFile:l}... Moving to: {Destination}",
|
||||
jsonFile.FullName, finalPath);
|
||||
|
||||
if (File.Exists(finalPath))
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information,
|
||||
"Removing existing configuration file: {Destination}", finalPath);
|
||||
File.Delete(finalPath);
|
||||
}
|
||||
|
||||
jsonFile.MoveTo(finalPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -245,7 +245,7 @@ namespace PepperDash.Essentials
|
|||
// _ = new ProcessorExtensionDeviceFactory();
|
||||
// _ = new MobileControlFactory();
|
||||
|
||||
LoadAssets();
|
||||
LoadAssets(Global.ApplicationDirectoryPathPrefix, Global.FilePathPrefix);
|
||||
|
||||
Debug.LogMessage(LogEventLevel.Information, "Starting Essentials load from configuration");
|
||||
|
||||
|
|
@ -825,142 +825,8 @@ namespace PepperDash.Essentials
|
|||
}
|
||||
}
|
||||
|
||||
private static void LoadAssets()
|
||||
{
|
||||
var applicationDirectory = new DirectoryInfo(Global.ApplicationDirectoryPathPrefix);
|
||||
Debug.LogMessage(LogEventLevel.Information, "Searching: {applicationDirectory:l} for embedded assets - {Destination}", applicationDirectory.FullName, Global.FilePathPrefix);
|
||||
internal static void LoadAssets(string applicationDirectoryPath, string filePathPrefix) =>
|
||||
AssetLoader.Load(applicationDirectoryPath, filePathPrefix);
|
||||
|
||||
var zipFiles = applicationDirectory.GetFiles("assets*.zip");
|
||||
|
||||
if (zipFiles.Length > 1)
|
||||
{
|
||||
throw new Exception("Multiple assets zip files found. Cannot continue.");
|
||||
}
|
||||
|
||||
if (zipFiles.Length == 1)
|
||||
{
|
||||
var zipFile = zipFiles[0];
|
||||
var assetsRoot = System.IO.Path.GetFullPath(Global.FilePathPrefix);
|
||||
if (!assetsRoot.EndsWith(Path.DirectorySeparatorChar.ToString()) && !assetsRoot.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
|
||||
{
|
||||
assetsRoot += Path.DirectorySeparatorChar;
|
||||
}
|
||||
Debug.LogMessage(LogEventLevel.Information, "Found assets zip file: {zipFile:l}... Unzipping...", zipFile.FullName);
|
||||
using (var archive = ZipFile.OpenRead(zipFile.FullName))
|
||||
{
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
var destinationPath = Path.Combine(Global.FilePathPrefix, entry.FullName);
|
||||
var fullDest = System.IO.Path.GetFullPath(destinationPath);
|
||||
if (!fullDest.StartsWith(assetsRoot, StringComparison.OrdinalIgnoreCase))
|
||||
throw new InvalidOperationException($"Entry '{entry.FullName}' is trying to extract outside of the target directory.");
|
||||
|
||||
if (string.IsNullOrEmpty(entry.Name))
|
||||
{
|
||||
Directory.CreateDirectory(destinationPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If a directory exists where a file should go, delete it
|
||||
if (Directory.Exists(destinationPath))
|
||||
Directory.Delete(destinationPath, true);
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(destinationPath));
|
||||
entry.ExtractToFile(destinationPath, true);
|
||||
Debug.LogMessage(LogEventLevel.Information, "Extracted: {entry:l} to {Destination}", entry.FullName, destinationPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cleaning up zip files
|
||||
foreach (var file in zipFiles)
|
||||
{
|
||||
File.Delete(file.FullName);
|
||||
}
|
||||
|
||||
var htmlZipFiles = applicationDirectory.GetFiles("htmlassets*.zip");
|
||||
|
||||
if (htmlZipFiles.Length > 1)
|
||||
{
|
||||
throw new Exception("Multiple htmlassets zip files found in application directory. Please ensure only one htmlassets*.zip file is present and retry.");
|
||||
}
|
||||
|
||||
|
||||
if (htmlZipFiles.Length == 1)
|
||||
{
|
||||
var htmlZipFile = htmlZipFiles[0];
|
||||
var programDir = new DirectoryInfo(Global.FilePathPrefix.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
|
||||
var userOrNvramDir = programDir.Parent;
|
||||
var rootDir = userOrNvramDir?.Parent;
|
||||
if (rootDir == null)
|
||||
{
|
||||
throw new Exception($"Unable to determine root directory for html extraction. Current path: {Global.FilePathPrefix}");
|
||||
}
|
||||
var htmlDir = Path.Combine(rootDir.FullName, "html");
|
||||
var htmlRoot = System.IO.Path.GetFullPath(htmlDir);
|
||||
if (!htmlRoot.EndsWith(Path.DirectorySeparatorChar.ToString()) &&
|
||||
!htmlRoot.EndsWith(Path.AltDirectorySeparatorChar.ToString()))
|
||||
{
|
||||
htmlRoot += Path.DirectorySeparatorChar;
|
||||
}
|
||||
Debug.LogMessage(LogEventLevel.Information, "Found htmlassets zip file: {zipFile:l}... Unzipping...", htmlZipFile.FullName);
|
||||
using (var archive = ZipFile.OpenRead(htmlZipFile.FullName))
|
||||
{
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
var destinationPath = Path.Combine(htmlDir, entry.FullName);
|
||||
var fullDest = System.IO.Path.GetFullPath(destinationPath);
|
||||
if (!fullDest.StartsWith(htmlRoot, StringComparison.OrdinalIgnoreCase))
|
||||
throw new InvalidOperationException($"Entry '{entry.FullName}' is trying to extract outside of the target directory.");
|
||||
|
||||
if (string.IsNullOrEmpty(entry.Name))
|
||||
{
|
||||
Directory.CreateDirectory(destinationPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only delete the file if it exists and is a file, not a directory
|
||||
if (File.Exists(destinationPath))
|
||||
File.Delete(destinationPath);
|
||||
|
||||
var parentDir = Path.GetDirectoryName(destinationPath);
|
||||
if (!string.IsNullOrEmpty(parentDir))
|
||||
Directory.CreateDirectory(parentDir);
|
||||
|
||||
entry.ExtractToFile(destinationPath, true);
|
||||
Debug.LogMessage(LogEventLevel.Information, "Extracted: {entry:l} to {Destination}", entry.FullName, destinationPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cleaning up html zip files
|
||||
foreach (var file in htmlZipFiles)
|
||||
{
|
||||
File.Delete(file.FullName);
|
||||
}
|
||||
|
||||
var jsonFiles = applicationDirectory.GetFiles("*configurationFile*.json");
|
||||
|
||||
if (jsonFiles.Length > 1)
|
||||
{
|
||||
Debug.LogError("Multiple configuration files found in application directory: {@jsonFiles}", jsonFiles.Select(f => f.FullName).ToArray());
|
||||
throw new Exception("Multiple configuration files found. Cannot continue.");
|
||||
}
|
||||
|
||||
if (jsonFiles.Length == 1)
|
||||
{
|
||||
var jsonFile = jsonFiles[0];
|
||||
var finalPath = Path.Combine(Global.FilePathPrefix, jsonFile.Name);
|
||||
Debug.LogMessage(LogEventLevel.Information, "Found configuration file: {jsonFile:l}... Moving to: {Destination}", jsonFile.FullName, finalPath);
|
||||
|
||||
if (File.Exists(finalPath))
|
||||
{
|
||||
Debug.LogMessage(LogEventLevel.Information, "Removing existing configuration file: {Destination}", finalPath);
|
||||
File.Delete(finalPath);
|
||||
}
|
||||
|
||||
jsonFile.MoveTo(finalPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue