From f77ff50150e6ff5d1f2b03c4f465846d5bb49a96 Mon Sep 17 00:00:00 2001 From: vnugent Date: Fri, 7 Jun 2024 15:45:56 -0400 Subject: Squashed commit of the following: commit 8ed4663e539d9c2ea58aaad02a1fc2896956f6b6 Author: vnugent Date: Fri Jun 7 15:43:48 2024 -0400 fix: invalid chars in status cookie name commit 9d1df65d99732a68b4fe96dcc75273442cbd322f Author: vnugent Date: Thu Jun 6 21:31:30 2024 -0400 fix: Some container fixes and compatability commit 5ecd6b39cccdc9500540b10685605b5fcba61f69 Author: vnugent Date: Thu Jun 6 17:19:48 2024 -0400 Update and expose storage config for container commit 3a62bafd210a2e00d23d3df773e47011e09eba6e Author: vnugent Date: Thu Jun 6 16:18:36 2024 -0400 ci: build admin lib before building front-end commit 35920ad6c8596fc14bcfed66303511e8c249be8d Author: vnugent Date: Thu Jun 6 15:56:36 2024 -0400 ci: Local vite config, force set lib versions commit 3c228b3cc5172fae398af8de72b64bd780ace20c Author: vnugent Date: Wed Jun 5 19:55:39 2024 -0400 ci: Update packages and add container build commit 21d2719701f851d4a555c363b141f289f14a5192 Author: vnugent Date: Wed Jun 5 15:58:07 2024 -0400 fix: #1 new channel page when hitting new button commit eefba88ac4e2c70517aa71c79ed94c346f9de554 Author: vnugent Date: Wed Jun 5 15:26:15 2024 -0400 chore: Package updates commit 9eed4022a79f2cba139c9f8a359bfc8c1f9c31c5 Author: vnugent Date: Wed Jun 5 14:44:08 2024 -0400 ci: Stage blocking changes --- back-end/src/CMNext.sample.json | 21 +++++------- back-end/src/Content.Publishing.Blog.Admin.csproj | 8 ++--- back-end/src/Storage/FtpStorageManager.cs | 40 +++++++++++++---------- back-end/src/Storage/ManagedStorage.cs | 23 +++++++------ back-end/src/Storage/MinioClientManager.cs | 24 +++++--------- 5 files changed, 55 insertions(+), 61 deletions(-) (limited to 'back-end/src') diff --git a/back-end/src/CMNext.sample.json b/back-end/src/CMNext.sample.json index 1b3c516..8af8e8d 100644 --- a/back-end/src/CMNext.sample.json +++ b/back-end/src/CMNext.sample.json @@ -20,25 +20,22 @@ "index_file_name": "blogs/channels.json" }, - //S3 setup with vault secrets - "disabled s3_config": { + "storage": { + //The custom storage assembly to use + "custom_storage_assembly": null, + + "type": "s3", //s3 | ftp + + //s3 config "server_address": "", "access_key": "", "bucket": "", - "use_ssl": true, + "use_ssl": false, "Region": null }, - "disabled ftp_config": { - "url": "", - "username": "", - //Base path within the ftp user's directory - "base_path": "" - }, - "secrets": { //Set the vault path to the s3 secret - "s3_secret": "", - "ftp_password": "" + "storage_secret": "", } } \ No newline at end of file diff --git a/back-end/src/Content.Publishing.Blog.Admin.csproj b/back-end/src/Content.Publishing.Blog.Admin.csproj index 9c446af..1e55a31 100644 --- a/back-end/src/Content.Publishing.Blog.Admin.csproj +++ b/back-end/src/Content.Publishing.Blog.Admin.csproj @@ -33,10 +33,10 @@ - - - - + + + + diff --git a/back-end/src/Storage/FtpStorageManager.cs b/back-end/src/Storage/FtpStorageManager.cs index d64d4ea..d775d54 100644 --- a/back-end/src/Storage/FtpStorageManager.cs +++ b/back-end/src/Storage/FtpStorageManager.cs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Vaughn Nugent +* Copyright (c) 2024 Vaughn Nugent * * Library: CMNext * Package: Content.Publishing.Blog.Admin @@ -24,7 +24,6 @@ using System.IO; using System.Net; using System.Threading; using System.Threading.Tasks; -using System.Collections.Generic; using FluentFTP; using FluentFTP.Exceptions; @@ -36,40 +35,47 @@ using VNLib.Plugins.Extensions.Loading; namespace Content.Publishing.Blog.Admin.Storage { - [ConfigurationName("ftp_config")] + + [ConfigurationName("storage")] internal class FtpStorageManager : StorageBase, IDisposable { private readonly AsyncFtpClient _client; - private readonly string _username; - private readonly string? _baasePath; + private readonly S3Config _storageConf; - protected override string? BasePath => _baasePath; + protected override string? BasePath => _storageConf.BaseBucket; public FtpStorageManager(PluginBase plugin, IConfigScope config) { - string? url = config["url"].GetString(); - _username = config["username"].GetString() ?? throw new KeyNotFoundException("Missing required username in config"); - _baasePath = config["base_path"].GetString(); + _storageConf = config.Deserialze(); - Uri uri = new (url!); + Uri uri = new (_storageConf.ServerAddress!); //Init new client _client = new( uri.Host, uri.Port, //Logger in debug mode - logger:plugin.IsDebug() ? new FtpDebugLogger(plugin.Log) : null + logger: plugin.IsDebug() ? new FtpDebugLogger(plugin.Log) : null ); } public override async Task ConfigureServiceAsync(PluginBase plugin) { - using ISecretResult password = await plugin.GetSecretAsync("ftp_password"); + using ISecretResult password = await plugin.Secrets().GetSecretAsync("storage_secret"); //Init client credentials - _client.Credentials = new NetworkCredential(_username, password?.Result.ToString()); - _client.Config.EncryptionMode = FtpEncryptionMode.Auto; - _client.Config.ValidateAnyCertificate = true; + _client.Credentials = new NetworkCredential(_storageConf.ClientId, password?.Result.ToString()); + + //If the user forces ssl, then assume it's an implicit connection and force certificate checking + if(_storageConf.UseSsl == true) + { + _client.Config.EncryptionMode = FtpEncryptionMode.Implicit; + } + else + { + _client.Config.EncryptionMode = FtpEncryptionMode.Auto; + _client.Config.ValidateAnyCertificate = true; + } plugin.Log.Information("Connecting to ftp server"); @@ -115,7 +121,7 @@ namespace Content.Publishing.Blog.Admin.Storage /// public override string GetExternalFilePath(string filePath) { - return string.IsNullOrWhiteSpace(_baasePath) ? filePath : $"{_baasePath}/{filePath}"; + return string.IsNullOrWhiteSpace(BasePath) ? filePath : $"{BasePath}/{filePath}"; } public void Dispose() @@ -123,7 +129,7 @@ namespace Content.Publishing.Blog.Admin.Storage _client?.Dispose(); } - sealed record class FtpDebugLogger(ILogProvider Log) : IFtpLogger + sealed class FtpDebugLogger(ILogProvider Log) : IFtpLogger { void IFtpLogger.Log(FtpLogEntry entry) { diff --git a/back-end/src/Storage/ManagedStorage.cs b/back-end/src/Storage/ManagedStorage.cs index 66e9a4a..a28ff50 100644 --- a/back-end/src/Storage/ManagedStorage.cs +++ b/back-end/src/Storage/ManagedStorage.cs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Vaughn Nugent +* Copyright (c) 2024 Vaughn Nugent * * Library: CMNext * Package: Content.Publishing.Blog.Admin @@ -30,28 +30,27 @@ using VNLib.Plugins.Extensions.Loading; namespace Content.Publishing.Blog.Admin.Storage { - [ConfigurationName("storage", Required = false)] + [ConfigurationName("storage")] internal sealed class ManagedStorage : ISimpleFilesystem { - private readonly ISimpleFilesystem _backingStorage; + private readonly ISimpleFilesystem _backingStorage; - public ManagedStorage(PluginBase plugin) : this(plugin, null) - { } - - public ManagedStorage(PluginBase plugin, IConfigScope? config) + public ManagedStorage(PluginBase plugin, IConfigScope config) { + string type = config.GetRequiredProperty("type", p => p.GetString()!); + //try to get custom storage assembly - if (config != null && config.ContainsKey("custom_storage_assembly")) + if (config.TryGetProperty("custom_storage_assembly", p => p.GetString(), out string? storageAssembly) + && !string.IsNullOrWhiteSpace(storageAssembly)) { - string storageAssembly = config.GetRequiredProperty("custom_storage_assembly", p => p.GetString()!); - _backingStorage = plugin.CreateServiceExternal(storageAssembly); + _backingStorage = plugin.CreateServiceExternal(storageAssembly!); } - else if (plugin.HasConfigForType()) + else if (string.Equals(type, "s3", StringComparison.OrdinalIgnoreCase)) { //Use minio storage _backingStorage = plugin.GetOrCreateSingleton(); } - else if (plugin.HasConfigForType()) + else if (string.Equals(type, "ftp", StringComparison.OrdinalIgnoreCase)) { //Use ftp storage _backingStorage = plugin.GetOrCreateSingleton(); diff --git a/back-end/src/Storage/MinioClientManager.cs b/back-end/src/Storage/MinioClientManager.cs index c7867b2..0c161af 100644 --- a/back-end/src/Storage/MinioClientManager.cs +++ b/back-end/src/Storage/MinioClientManager.cs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Vaughn Nugent +* Copyright (c) 2024 Vaughn Nugent * * Library: CMNext * Package: Content.Publishing.Blog.Admin @@ -37,18 +37,11 @@ using static Content.Publishing.Blog.Admin.Model.PostManager; namespace Content.Publishing.Blog.Admin.Storage { - [ConfigurationName("s3_config")] - internal sealed class MinioClientManager : StorageBase + [ConfigurationName("storage")] + internal sealed class MinioClientManager(PluginBase pbase, IConfigScope s3Config) : StorageBase { - private readonly MinioClient Client; - private readonly S3Config Config; - - public MinioClientManager(PluginBase pbase, IConfigScope s3Config) - { - //Deserialize the config - Config = s3Config.Deserialze(); - Client = new(); - } + private readonly MinioClient Client = new(); + private readonly S3Config Config = s3Config.Deserialze(); /// protected override string? BasePath => Config.BaseBucket; @@ -56,12 +49,11 @@ namespace Content.Publishing.Blog.Admin.Storage /// public override async Task ConfigureServiceAsync(PluginBase plugin) { - using ISecretResult? secret = await plugin.GetSecretAsync("s3_secret"); + using ISecretResult? secret = await plugin.GetSecretAsync("storage_secret"); Client.WithEndpoint(Config.ServerAddress) - .WithCredentials(Config.ClientId, secret.Result.ToString()); - - Client.WithSSL(Config.UseSsl.HasValue && Config.UseSsl.Value); + .WithCredentials(Config.ClientId, secret.Result.ToString()) + .WithSSL(Config.UseSsl == true); //Accept optional region if (!string.IsNullOrWhiteSpace(Config.Region)) -- cgit