diff options
Diffstat (limited to 'Libs/VNLib.Plugins.Essentials.Sessions.VNCache')
6 files changed, 0 insertions, 556 deletions
diff --git a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/IWebSessionIdFactory.cs b/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/IWebSessionIdFactory.cs deleted file mode 100644 index f1fdf39..0000000 --- a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/IWebSessionIdFactory.cs +++ /dev/null @@ -1,50 +0,0 @@ -/* -* Copyright (c) 2022 Vaughn Nugent -* -* Library: VNLib -* Package: VNLib.Plugins.Essentials.Sessions.VNCache -* File: IWebSessionIdFactory.cs -* -* IWebSessionIdFactory.cs is part of VNLib.Plugins.Essentials.Sessions.VNCache which is part of the larger -* VNLib collection of libraries and utilities. -* -* VNLib.Plugins.Essentials.Sessions.VNCache 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.Essentials.Sessions.VNCache 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 VNLib.Net.Http; -using VNLib.Plugins.Essentials.Sessions.Runtime; - -namespace VNLib.Plugins.Essentials.Sessions.VNCache -{ - /// <summary> - /// Id factory for <see cref="WebSessionProvider"/> - /// </summary> - internal interface IWebSessionIdFactory: ISessionIdFactory - { - /// <summary> - /// The maxium amount of time a session is valid for. Sessions will be invalidated - /// after this time - /// </summary> - TimeSpan ValidFor { get; } - - /// <summary> - /// Gets a new session-id for the connection and manipulates the entity as necessary - /// </summary> - /// <param name="entity">The connection to generate the new session for</param> - /// <returns>The new session-id</returns> - string GenerateSessionId(IHttpEvent entity); - } - - -} diff --git a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/VNLib.Plugins.Essentials.Sessions.VNCache.csproj b/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/VNLib.Plugins.Essentials.Sessions.VNCache.csproj deleted file mode 100644 index 9895eea..0000000 --- a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/VNLib.Plugins.Essentials.Sessions.VNCache.csproj +++ /dev/null @@ -1,43 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - - <PropertyGroup> - <TargetFramework>net6.0</TargetFramework> - <ImplicitUsings>enable</ImplicitUsings> - <Nullable>enable</Nullable> - <Authors>Vaughn Nugent</Authors> - <Copyright>Copyright © 2022 Vaughn Nugent</Copyright> - <Version>1.0.1.1</Version> - <SignAssembly>False</SignAssembly> - <PackageProjectUrl>https://www.vaughnnugent.com/resources</PackageProjectUrl> - - <EnableDynamicLoading>true</EnableDynamicLoading> - <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> - <GenerateDocumentationFile>True</GenerateDocumentationFile> - <AnalysisLevel>latest-all</AnalysisLevel> - <SignAssembly>True</SignAssembly> - <AssemblyOriginatorKeyFile>\\vaughnnugent.com\Internal\Folder Redirection\vman\Documents\Programming\Software\StrongNameingKey.snk</AssemblyOriginatorKeyFile> - </PropertyGroup> - - <ItemGroup> - <Folder Include="Endpoints\" /> - </ItemGroup> - - <ItemGroup> - <ProjectReference Include="..\..\..\..\VNLib\Http\src\VNLib.Net.Http.csproj" /> - <ProjectReference Include="..\..\..\..\VNLib\Utils\src\VNLib.Utils.csproj" /> - <ProjectReference Include="..\..\..\Extensions\VNLib.Plugins.Extensions.Loading\VNLib.Plugins.Extensions.Loading.csproj" /> - <ProjectReference Include="..\..\..\Extensions\VNLib.Plugins.Extensions.VNCache\VNLib.Plugins.Extensions.VNCache.csproj" /> - <ProjectReference Include="..\..\..\PluginBase\VNLib.Plugins.PluginBase.csproj" /> - <ProjectReference Include="..\VNLib.Plugins.Essentials.Sessions.Runtime\VNLib.Plugins.Essentials.Sessions.Runtime.csproj" /> - <ProjectReference Include="..\VNLib.Plugins.Sessions.Cache.Client\VNLib.Plugins.Sessions.Cache.Client.csproj" /> - </ItemGroup> - - <Target Name="PostBuild" AfterTargets="PostBuildEvent"> - <Exec Command="start xcopy "$(TargetDir)" "F:\Programming\Web Plugins\DevPlugins\RuntimeAssets\$(TargetName)" /E /Y /R" /> - </Target> - - <Target Name="PreBuild" BeforeTargets="PreBuildEvent"> - <Exec Command="erase "F:\Programming\Web Plugins\DevPlugins\RuntimeAssets\$(TargetName)" /q > nul" /> - </Target> - -</Project> diff --git a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSession.cs b/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSession.cs deleted file mode 100644 index 87e08e7..0000000 --- a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSession.cs +++ /dev/null @@ -1,124 +0,0 @@ -/* -* Copyright (c) 2022 Vaughn Nugent -* -* Library: VNLib -* Package: VNLib.Plugins.Essentials.Sessions.VNCache -* File: WebSession.cs -* -* WebSession.cs is part of VNLib.Plugins.Essentials.Sessions.VNCache which is part of the larger -* VNLib collection of libraries and utilities. -* -* VNLib.Plugins.Essentials.Sessions.VNCache 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.Essentials.Sessions.VNCache 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 VNLib.Net.Http; -using VNLib.Plugins.Essentials.Extensions; -using VNLib.Plugins.Sessions.Cache.Client; -using static VNLib.Plugins.Essentials.Sessions.ISessionExtensions; - -namespace VNLib.Plugins.Essentials.Sessions.VNCache -{ - internal class WebSession : RemoteSession - { - protected const ulong UPGRADE_MSK = 0b0000000000010000UL; - - protected readonly Func<IHttpEvent, string, string> UpdateId; - private string? _oldId; - - public WebSession(string sessionId, IRemoteCacheStore client, TimeSpan backgroundTimeOut, Func<IHttpEvent, string, string> UpdateId) - : base(sessionId, client, backgroundTimeOut) - { - this.UpdateId = UpdateId; - } - - protected override void IndexerSet(string key, string value) - { - //Set value - base.IndexerSet(key, value); - switch (key) - { - //Set the upgrade flag when token data is modified - case LOGIN_TOKEN_ENTRY: - case TOKEN_ENTRY: - Flags.Set(UPGRADE_MSK); - break; - } - } - - public override async Task WaitAndLoadAsync(IHttpEvent entity, CancellationToken cancellationToken) - { - //Wait for the session to load - await base.WaitAndLoadAsync(entity, cancellationToken); - //If the session is new, set to web mode - if (IsNew) - { - SessionType = SessionType.Web; - } - } - - private async Task ProcessUpgradeAsync() - { - //Setup timeout cancellation for the update, to cancel it - using CancellationTokenSource cts = new(UpdateTimeout); - await Client.AddOrUpdateObjectAsync(_oldId!, SessionID, DataStore, cts.Token); - _oldId = null; - } - - protected override ValueTask<Task?> UpdateResource(bool isAsync, IHttpEvent state) - { - Task? result = null; - //Check flags in priority level, Invalid is highest state priority - if (Flags.IsSet(INVALID_MSK)) - { - //Clear all stored values - DataStore!.Clear(); - //Reset ip-address - UserIP = state.Server.GetTrustedIp(); - //Update created time - Created = DateTimeOffset.UtcNow; - //Init the new session-data - this.InitNewSession(state.Server); - //Restore session type - SessionType = SessionType.Web; - //generate new session-id and update the record in the store - _oldId = SessionID; - //Update the session-id - SessionID = UpdateId(state, _oldId); - //write update to server - result = Task.Run(ProcessUpgradeAsync); - } - else if (Flags.IsSet(UPGRADE_MSK | REGEN_ID_MSK)) - { - //generate new session-id and update the record in the store - _oldId = SessionID; - //Update the session-id - SessionID = UpdateId(state, _oldId); - //Update created time - Created = DateTimeOffset.UtcNow; - //write update to server - result = Task.Run(ProcessUpgradeAsync); - } - else if (Flags.IsSet(MODIFIED_MSK)) - { - //Send update to server - result = Task.Run(ProcessUpdateAsync); - } - - //Clear all flags - Flags.ClearAll(); - - return ValueTask.FromResult<Task?>(null); - } - } -} diff --git a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionIdFactoryImpl.cs b/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionIdFactoryImpl.cs deleted file mode 100644 index 8dfda77..0000000 --- a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionIdFactoryImpl.cs +++ /dev/null @@ -1,120 +0,0 @@ -/* -* Copyright (c) 2022 Vaughn Nugent -* -* Library: VNLib -* Package: VNLib.Plugins.Essentials.Sessions.VNCache -* File: WebSessionIdFactoryImpl.cs -* -* WebSessionIdFactoryImpl.cs is part of VNLib.Plugins.Essentials.Sessions.VNCache which is part of the larger -* VNLib collection of libraries and utilities. -* -* VNLib.Plugins.Essentials.Sessions.VNCache 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.Essentials.Sessions.VNCache 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.Diagnostics.CodeAnalysis; - -using VNLib.Hashing; -using VNLib.Utils.Memory; -using VNLib.Utils.Extensions; -using VNLib.Plugins.Essentials.Extensions; -using VNLib.Net.Http; -using VNLib.Plugins.Essentials.Sessions.Runtime; - -namespace VNLib.Plugins.Essentials.Sessions.VNCache -{ - /// <summary> - /// <see cref="IWebSessionIdFactory"/> implementation, using - /// http cookies as session id storage - /// </summary> - internal sealed class WebSessionIdFactoryImpl : IWebSessionIdFactory - { - public TimeSpan ValidFor { get; } - - public string GenerateSessionId(IHttpEvent entity) - { - //Random hex hash - string cookie = RandomHash.GetRandomBase32(_tokenSize); - - //Set the session id cookie - entity.Server.SetCookie(SessionCookieName, cookie, ValidFor, secure: true, httpOnly: true); - - //return session-id value from cookie value - return ComputeSessionIdFromCookie(cookie); - } - - bool ISessionIdFactory.TryGetSessionId(IHttpEvent entity, [NotNullWhen(true)] out string? sessionId) - { - //Get authorization token and make sure its not too large to cause a buffer overflow - if (entity.Server.GetCookie(SessionCookieName, out string? cookie) && (cookie.Length + SessionIdPrefix.Length) <= _bufferSize) - { - //Compute session id from token - sessionId = ComputeSessionIdFromCookie(cookie); - - return true; - } - //Only add sessions for user-agents - else if(entity.Server.IsBrowser()) - { - //Get a new session id - sessionId = GenerateSessionId(entity); - - return true; - } - else - { - sessionId = null; - return false; - } - } - - private readonly string SessionCookieName; - private readonly string SessionIdPrefix; - private readonly int _bufferSize; - private readonly int _tokenSize; - - /// <summary> - /// Initialzies a new web session Id factory - /// </summary> - /// <param name="cookieSize">The size of the cookie in bytes</param> - /// <param name="sessionCookieName">The name of the session cookie</param> - /// <param name="sessionIdPrefix">The session-id internal prefix</param> - /// <param name="validFor">The time the session cookie is valid for</param> - public WebSessionIdFactoryImpl(uint cookieSize, string sessionCookieName, string sessionIdPrefix, TimeSpan validFor) - { - ValidFor = validFor; - SessionCookieName = sessionCookieName; - SessionIdPrefix = sessionIdPrefix; - _tokenSize = (int)cookieSize; - //Calc buffer size - _bufferSize = Math.Max(32, ((int)cookieSize * 3) + sessionIdPrefix.Length); - } - - - private string ComputeSessionIdFromCookie(string sessionId) - { - //Buffer to copy data to - using UnsafeMemoryHandle<char> buffer = Memory.UnsafeAlloc<char>(_bufferSize, true); - - //Writer to accumulate data - ForwardOnlyWriter<char> writer = new(buffer.Span); - - //Append prefix and session id - writer.Append(SessionIdPrefix); - writer.Append(sessionId); - - //Compute base64 hash of token and - return ManagedHash.ComputeBase64Hash(writer.AsSpan(), HashAlg.SHA256); - } - } -}
\ No newline at end of file diff --git a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionProvider.cs b/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionProvider.cs deleted file mode 100644 index ebc3c3d..0000000 --- a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionProvider.cs +++ /dev/null @@ -1,137 +0,0 @@ -/* -* Copyright (c) 2022 Vaughn Nugent -* -* Library: VNLib -* Package: VNLib.Plugins.Essentials.Sessions.VNCache -* File: WebSessionProvider.cs -* -* WebSessionProvider.cs is part of VNLib.Plugins.Essentials.Sessions.VNCache which is part of the larger -* VNLib collection of libraries and utilities. -* -* VNLib.Plugins.Essentials.Sessions.VNCache 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.Essentials.Sessions.VNCache 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; - -using VNLib.Net.Http; -using VNLib.Plugins.Extensions.Loading; -using VNLib.Plugins.Sessions.Cache.Client; - -namespace VNLib.Plugins.Essentials.Sessions.VNCache -{ - /// <summary> - /// The implementation of a VNCache web based session - /// </summary> - [ConfigurationName("web")] - internal sealed class WebSessionProvider : SessionCacheClient, ISessionProvider - { - static readonly TimeSpan BackgroundUpdateTimeout = TimeSpan.FromSeconds(10); - - private readonly IWebSessionIdFactory factory; - private readonly uint MaxConnections; - - /// <summary> - /// Initializes a new <see cref="WebSessionProvider"/> - /// </summary> - /// <param name="client">The cache client to make cache operations against</param> - /// <param name="maxCacheItems">The max number of items to store in cache</param> - /// <param name="maxWaiting">The maxium number of waiting session events before 503s are sent</param> - /// <param name="factory">The session-id factory</param> - public WebSessionProvider(IRemoteCacheStore client, int maxCacheItems, uint maxWaiting, IWebSessionIdFactory factory) : base(client, maxCacheItems) - { - this.factory = factory; - MaxConnections = maxWaiting; - } - - private string UpdateSessionId(IHttpEvent entity, string oldId) - { - //Generate and set a new sessionid - string newid = factory.GenerateSessionId(entity); - //Aquire lock on cache - lock (CacheLock) - { - //Change the cache lookup id - if (CacheTable.Remove(oldId, out RemoteSession? session)) - { - CacheTable.Add(newid, session); - } - } - return newid; - } - - protected override RemoteSession SessionCtor(string sessionId) => new WebSession(sessionId, Store, BackgroundUpdateTimeout, UpdateSessionId); - - public async ValueTask<SessionHandle> GetSessionAsync(IHttpEvent entity, CancellationToken cancellationToken) - { - //Callback to close the session when the handle is closeed - static ValueTask HandleClosedAsync(ISession session, IHttpEvent entity) - { - return (session as SessionBase)!.UpdateAndRelease(true, entity); - } - - try - { - //Get session id - if (!factory.TryGetSessionId(entity, out string? sessionId)) - { - //Id not allowed/found, so do not attach a session - return SessionHandle.Empty; - } - - //Limit max number of waiting clients - if (WaitingConnections > MaxConnections) - { - //Set 503 for temporary unavail - entity.CloseResponse(System.Net.HttpStatusCode.ServiceUnavailable); - return new SessionHandle(null, FileProcessArgs.VirtualSkip, null); - } - - //Get session - RemoteSession session = await GetSessionAsync(entity, sessionId, cancellationToken); - - //If the session is new (not in cache), then overwrite the session id with a new one as user may have specified their own - if (session.IsNew) - { - session.RegenID(); - } - - //Make sure the session has not expired yet - if (session.Created.Add(factory.ValidFor) < DateTimeOffset.UtcNow) - { - //Invalidate the session, so its technically valid for this request, but will be cleared on this handle close cycle - session.Invalidate(); - //Clear basic login status - session.Token = null; - session.UserID = null; - session.Privilages = 0; - session.SetLoginToken(null); - } - - return new SessionHandle(session, HandleClosedAsync); - } - catch (OperationCanceledException) - { - throw; - } - catch (SessionException) - { - throw; - } - catch (Exception ex) - { - throw new SessionException("Exception raised while retreiving or loading Web session", ex); - } - } - } -} diff --git a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionProviderEntry.cs b/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionProviderEntry.cs deleted file mode 100644 index 309db47..0000000 --- a/Libs/VNLib.Plugins.Essentials.Sessions.VNCache/WebSessionProviderEntry.cs +++ /dev/null @@ -1,82 +0,0 @@ -/* -* Copyright (c) 2022 Vaughn Nugent -* -* Library: VNLib -* Package: VNLib.Plugins.Essentials.Sessions.VNCache -* File: WebSessionProviderEntry.cs -* -* WebSessionProviderEntry.cs is part of VNLib.Plugins.Essentials.Sessions.VNCache which is part of the larger -* VNLib collection of libraries and utilities. -* -* VNLib.Plugins.Essentials.Sessions.VNCache 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.Essentials.Sessions.VNCache 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.Text.Json; - -using VNLib.Net.Http; -using VNLib.Utils.Logging; -using VNLib.Utils.Extensions; -using VNLib.Data.Caching; -using VNLib.Plugins.Sessions.Cache.Client; -using VNLib.Plugins.Essentials.Sessions.Runtime; -using VNLib.Plugins.Extensions.Loading; -using VNLib.Plugins.Extensions.VNCache; - -namespace VNLib.Plugins.Essentials.Sessions.VNCache -{ - public sealed class WebSessionProviderEntry : IRuntimeSessionProvider - { - const string WEB_SESSION_CONFIG = "web"; - - private WebSessionProvider? _sessions; - - //Web sessions can always be provided so long as cache is loaded - bool IRuntimeSessionProvider.CanProcess(IHttpEvent entity) => _sessions != null; - - ValueTask<SessionHandle> ISessionProvider.GetSessionAsync(IHttpEvent entity, CancellationToken cancellationToken) - { - return _sessions!.GetSessionAsync(entity, cancellationToken); - } - - void IRuntimeSessionProvider.Load(PluginBase plugin, ILogProvider localized) - { - //Try get vncache config element - IReadOnlyDictionary<string, JsonElement> webSessionConfig = plugin.GetConfigForType<WebSessionProvider>(); - - uint cookieSize = webSessionConfig["cookie_size"].GetUInt32(); - string cookieName = webSessionConfig["cookie_name"].GetString() ?? throw new KeyNotFoundException($"Missing required element 'cookie_name' for config '{WEB_SESSION_CONFIG}'"); - string cachePrefix = webSessionConfig["cache_prefix"].GetString() ?? throw new KeyNotFoundException($"Missing required element 'cache_prefix' for config '{WEB_SESSION_CONFIG}'"); - int cacheLimit = (int)webSessionConfig["cache_size"].GetUInt32(); - uint maxConnections = webSessionConfig["max_waiting_connections"].GetUInt32(); - TimeSpan validFor = webSessionConfig["valid_for_sec"].GetTimeSpan(TimeParseType.Seconds); - - //Init id factory - WebSessionIdFactoryImpl idFactory = new(cookieSize, cookieName, cachePrefix, validFor); - - //Get shared global-cache - IGlobalCacheProvider globalCache = plugin.GetGlobalCache(); - - //Create cache store from global cache - GlobalCacheStore cacheStore = new(globalCache); - - //Init provider - _sessions = new(cacheStore, cacheLimit, maxConnections, idFactory); - - //Load and run cached sessions on deferred task lib - _ = plugin.DeferTask(() => _sessions.CleanupExpiredSessionsAsync(localized, plugin.UnloadToken), 1000); - - localized.Information("Session provider loaded"); - } - } -}
\ No newline at end of file |