diff options
Diffstat (limited to 'lib/VNLib.Plugins.Extensions.Loading/src')
-rw-r--r-- | lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs | 58 | ||||
-rw-r--r-- | lib/VNLib.Plugins.Extensions.Loading/src/Users/UserManager.cs (renamed from lib/VNLib.Plugins.Extensions.Loading/src/UserManager.cs) | 44 | ||||
-rw-r--r-- | lib/VNLib.Plugins.Extensions.Loading/src/Users/UserPassValResult.cs | 52 |
3 files changed, 120 insertions, 34 deletions
diff --git a/lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs b/lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs index fa39b44..554e40f 100644 --- a/lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs +++ b/lib/VNLib.Plugins.Extensions.Loading/src/LoadingExtensions.cs @@ -100,6 +100,39 @@ namespace VNLib.Plugins.Extensions.Loading public static T GetOrCreateSingleton<T>(PluginBase plugin, Func<PluginBase, T> serviceFactory) => (T)GetOrCreateSingleton(plugin, typeof(T), p => serviceFactory(p)!); + + /// <summary> + /// Gets the full file path for the assembly asset file name within the assets + /// directory. + /// </summary> + /// <param name="plugin"></param> + /// <param name="assemblyName">The name of the assembly (ex: 'file.dll') to search for</param> + /// <param name="searchOption">Directory search flags</param> + /// <returns>The full path to the assembly asset file, or null if the file does not exist</returns> + /// <exception cref="ArgumentNullException"></exception> + public static string? GetAssetFilePath(this PluginBase plugin, string assemblyName, SearchOption searchOption) + { + plugin.ThrowIfUnloaded(); + _ = assemblyName ?? throw new ArgumentNullException(nameof(assemblyName)); + + /* + * Allow an assets directory to limit the scope of the search for the desired + * assembly, otherwise search all plugins directories + */ + + string? assetDir = plugin.GetAssetsPath(); + assetDir ??= plugin.GetPluginsPath(); + + /* + * This should never happen since this method can only be called from a + * plugin context, which means this path was used to load the current plugin + */ + _ = assetDir ?? throw new ArgumentNullException(ConfigurationExtensions.PLUGIN_ASSET_KEY, "No plugin path is defined for the current host configuration, this is likely a bug"); + + //Get the first file that matches the search file + return Directory.EnumerateFiles(assetDir, assemblyName, searchOption).FirstOrDefault(); + } + /// <summary> /// Loads an assembly into the current plugin's load context and will unload when disposed /// or the plugin is unloaded from the host application. @@ -115,7 +148,6 @@ namespace VNLib.Plugins.Extensions.Loading /// <returns>The <see cref="AssemblyLoader{T}"/> managing the loaded assmbly in the current AppDomain</returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="FileNotFoundException"></exception> - /// <exception cref="EntryPointNotFoundException"></exception> /// <remarks> /// The assembly is searched within the 'assets' directory specified in the plugin config /// or the global plugins ('path' key) directory if an assets directory is not defined. @@ -126,27 +158,9 @@ namespace VNLib.Plugins.Extensions.Loading SearchOption dirSearchOption = SearchOption.AllDirectories, AssemblyLoadContext? explictAlc = null) { - plugin.ThrowIfUnloaded(); - _ = assemblyName ?? throw new ArgumentNullException(nameof(assemblyName)); - - - /* - * Allow an assets directory to limit the scope of the search for the desired - * assembly, otherwise search all plugins directories - */ - - string? assetDir = plugin.GetAssetsPath(); - assetDir ??= plugin.GetPluginsPath(); - - /* - * This should never happen since this method can only be called from a - * plugin context, which means this path was used to load the current plugin - */ - _ = assetDir ?? throw new ArgumentNullException(ConfigurationExtensions.PLUGIN_ASSET_KEY, "No plugin path is defined for the current host configuration, this is likely a bug"); - - //Get the first file that matches the search file - string? asmFile = Directory.EnumerateFiles(assetDir, assemblyName, dirSearchOption).FirstOrDefault(); - _ = asmFile ?? throw new FileNotFoundException($"Failed to load custom assembly {assemblyName} from plugin directory"); + //Get the file path for the assembly + string asmFile = GetAssetFilePath(plugin, assemblyName, dirSearchOption) + ?? throw new FileNotFoundException($"Failed to load custom assembly {assemblyName} from plugin directory"); //Get the plugin's load context if not explicitly supplied explictAlc ??= GetPluginLoadContext(); diff --git a/lib/VNLib.Plugins.Extensions.Loading/src/UserManager.cs b/lib/VNLib.Plugins.Extensions.Loading/src/Users/UserManager.cs index e668b3e..3e9dbde 100644 --- a/lib/VNLib.Plugins.Extensions.Loading/src/UserManager.cs +++ b/lib/VNLib.Plugins.Extensions.Loading/src/Users/UserManager.cs @@ -30,6 +30,7 @@ using VNLib.Utils; using VNLib.Utils.Memory; using VNLib.Utils.Logging; using VNLib.Plugins.Essentials.Users; +using VNLib.Plugins.Essentials.Accounts; namespace VNLib.Plugins.Extensions.Loading.Users { @@ -39,7 +40,8 @@ namespace VNLib.Plugins.Extensions.Loading.Users /// </summary> [ConfigurationName("users", Required = false)] public class UserManager : IUserManager - { + { + public const string USER_CUSTOM_ASSEMBLY = "custom_assembly"; public const string DEFAULT_USER_ASM = "VNLib.Plugins.Essentials.Users.dll"; @@ -72,22 +74,22 @@ namespace VNLib.Plugins.Extensions.Loading.Users return externManager; } - ///<inheritdoc/> - public Task<IUser> CreateUserAsync(string userid, string emailAddress, ulong privilages, PrivateString passHash, CancellationToken cancellation = default) - { - return _dynamicLoader.CreateUserAsync(userid, emailAddress, privilages, passHash, cancellation); - } + /// <summary> + /// Gets the underlying <see cref="IUserManager"/> that was dynamically loaded. + /// </summary> + /// <returns>The user manager instance</returns> + public IUserManager InternalManager => _dynamicLoader; ///<inheritdoc/> - public Task<IUser?> GetUserAndPassFromEmailAsync(string emailAddress, CancellationToken cancellationToken = default) + public Task<IUser> CreateUserAsync(IUserCreationRequest creation, string? userId, CancellationToken cancellation = default) { - return _dynamicLoader.GetUserAndPassFromEmailAsync(emailAddress, cancellationToken); + return _dynamicLoader.CreateUserAsync(creation, userId, cancellation); } ///<inheritdoc/> - public Task<IUser?> GetUserAndPassFromIDAsync(string userid, CancellationToken cancellation = default) + public IPasswordHashingProvider? GetHashProvider() { - return _dynamicLoader.GetUserAndPassFromIDAsync(userid, cancellation); + return _dynamicLoader.GetHashProvider(); } ///<inheritdoc/> @@ -109,9 +111,27 @@ namespace VNLib.Plugins.Extensions.Loading.Users } ///<inheritdoc/> - public Task<ERRNO> UpdatePassAsync(IUser user, PrivateString newPass, CancellationToken cancellation = default) + public Task<PrivateString?> RecoverPasswordAsync(IUser user, CancellationToken cancellation = default) + { + return _dynamicLoader.RecoverPasswordAsync(user, cancellation); + } + + ///<inheritdoc/> + public Task<ERRNO> UpdatePasswordAsync(IUser user, PrivateString newPass, CancellationToken cancellation = default) + { + return _dynamicLoader.UpdatePasswordAsync(user, newPass, cancellation); + } + + ///<inheritdoc/> + public Task<ERRNO> ValidatePasswordAsync(IUser user, PrivateString password, PassValidateFlags flags, CancellationToken cancellation = default) + { + return _dynamicLoader.ValidatePasswordAsync(user, password, flags, cancellation); + } + + ///<inheritdoc/> + public string ComputeSafeUserId(string input) { - return _dynamicLoader.UpdatePassAsync(user, newPass, cancellation); + return _dynamicLoader.ComputeSafeUserId(input); } } }
\ No newline at end of file diff --git a/lib/VNLib.Plugins.Extensions.Loading/src/Users/UserPassValResult.cs b/lib/VNLib.Plugins.Extensions.Loading/src/Users/UserPassValResult.cs new file mode 100644 index 0000000..ccfc62d --- /dev/null +++ b/lib/VNLib.Plugins.Extensions.Loading/src/Users/UserPassValResult.cs @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2023 Vaughn Nugent +* +* Library: VNLib +* Package: VNLib.Plugins.Extensions.Loading +* File: UserPassValResult.cs +* +* UserPassValResult.cs is part of VNLib.Plugins.Extensions.Loading which is +* part of the larger VNLib collection of libraries and utilities. +* +* VNLib.Plugins.Extensions.Loading is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as +* published by the Free Software Foundation, either version 3 of the +* License, or (at your option) any later version. +* +* VNLib.Plugins.Extensions.Loading is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see https://www.gnu.org/licenses/. +*/ + +using System.Threading; + +using VNLib.Utils.Memory; +using VNLib.Plugins.Essentials.Users; + +namespace VNLib.Plugins.Extensions.Loading.Users +{ + /// <summary> + /// Result codes for <see cref="IUserManager.ValidatePasswordAsync(IUser, PrivateString, PassValidateFlags, CancellationToken)"/> + /// </summary> + public static class UserPassValResult + { + /// <summary> + /// The passwords matched + /// </summary> + public const int Success = 1; + + /// <summary> + /// Failed because the user did not have a password stored + /// </summary> + public const int Null = 0; + + /// <summary> + /// Failed because the passwords did not match + /// </summary> + public const int Failed = -1; + } +}
\ No newline at end of file |