diff options
Diffstat (limited to 'Plugins.Essentials/src/Sessions/SessionBase.cs')
-rw-r--r-- | Plugins.Essentials/src/Sessions/SessionBase.cs | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/Plugins.Essentials/src/Sessions/SessionBase.cs b/Plugins.Essentials/src/Sessions/SessionBase.cs new file mode 100644 index 0000000..d386b8b --- /dev/null +++ b/Plugins.Essentials/src/Sessions/SessionBase.cs @@ -0,0 +1,168 @@ +/* +* Copyright (c) 2022 Vaughn Nugent +* +* Library: VNLib +* Package: VNLib.Plugins.Essentials +* File: SessionBase.cs +* +* SessionBase.cs is part of VNLib.Plugins.Essentials which is part of the larger +* VNLib collection of libraries and utilities. +* +* VNLib.Plugins.Essentials 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 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 System.Net; +using System.Runtime.CompilerServices; + +using VNLib.Net.Http; +using VNLib.Utils; +using VNLib.Utils.Async; + +namespace VNLib.Plugins.Essentials.Sessions +{ + /// <summary> + /// Provides a base class for the <see cref="ISession"/> interface for exclusive use within a multithreaded + /// context + /// </summary> + public abstract class SessionBase : AsyncExclusiveResource<IHttpEvent>, ISession + { + protected const ulong MODIFIED_MSK = 0b0000000000000001UL; + protected const ulong IS_NEW_MSK = 0b0000000000000010UL; + protected const ulong REGEN_ID_MSK = 0b0000000000000100UL; + protected const ulong INVALID_MSK = 0b0000000000001000UL; + protected const ulong ALL_INVALID_MSK = 0b0000000000100000UL; + + protected const string USER_ID_ENTRY = "__.i.uid"; + protected const string TOKEN_ENTRY = "__.i.tk"; + protected const string PRIV_ENTRY = "__.i.pl"; + protected const string IP_ADDRESS_ENTRY = "__.i.uip"; + protected const string SESSION_TYPE_ENTRY = "__.i.tp"; + + /// <summary> + /// A <see cref="BitField"/> of status flags for the state of the current session. + /// May be used internally + /// </summary> + protected BitField Flags { get; } = new(0); + + /// <summary> + /// Gets or sets the Modified flag + /// </summary> + protected bool IsModified + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => Flags.IsSet(MODIFIED_MSK); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set => Flags.Set(MODIFIED_MSK, value); + } + + ///<inheritdoc/> + public virtual string SessionID { get; protected set; } + ///<inheritdoc/> + public virtual DateTimeOffset Created { get; protected set; } + + ///<inheritdoc/> + ///<exception cref="ObjectDisposedException"></exception> + public string this[string index] + { + get + { + Check(); + return IndexerGet(index); + } + set + { + Check(); + IndexerSet(index, value); + } + } + ///<inheritdoc/> + public virtual IPAddress UserIP + { + get + { + //try to parse the IP address, otherwise return null + _ = IPAddress.TryParse(this[IP_ADDRESS_ENTRY], out IPAddress ip); + return ip; + } + protected set + { + //Store the IP address as its string representation + this[IP_ADDRESS_ENTRY] = value?.ToString(); + } + } + ///<inheritdoc/> + public virtual SessionType SessionType + { + get => Enum.Parse<SessionType>(this[SESSION_TYPE_ENTRY]); + protected set => this[SESSION_TYPE_ENTRY] = ((byte)value).ToString(); + } + + ///<inheritdoc/> + public virtual ulong Privilages + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => Convert.ToUInt64(this[PRIV_ENTRY], 16); + //Store in hexadecimal to conserve space + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set => this[PRIV_ENTRY] = value.ToString("X"); + } + ///<inheritdoc/> + public bool IsNew + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => Flags.IsSet(IS_NEW_MSK); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set => Flags.Set(IS_NEW_MSK, value); + } + ///<inheritdoc/> + public virtual string UserID + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => this[USER_ID_ENTRY]; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set => this[USER_ID_ENTRY] = value; + } + ///<inheritdoc/> + public virtual string Token + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => this[TOKEN_ENTRY]; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set => this[TOKEN_ENTRY] = value; + } + ///<inheritdoc/> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public virtual void Invalidate(bool all = false) + { + Flags.Set(INVALID_MSK); + Flags.Set(ALL_INVALID_MSK, all); + } + ///<inheritdoc/> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public virtual void RegenID() => Flags.Set(REGEN_ID_MSK); + /// <summary> + /// Invoked when the indexer is is called to + /// </summary> + /// <param name="key">The key/index to get the value for</param> + /// <returns>The value stored at the specified key</returns> + protected abstract string IndexerGet(string key); + /// <summary> + /// Sets a value requested by the indexer + /// </summary> + /// <param name="key">The key to associate the value with</param> + /// <param name="value">The value to store</param> + protected abstract void IndexerSet(string key, string value); + } +}
\ No newline at end of file |