diff options
Diffstat (limited to 'lib/Plugins.Essentials/src/Extensions')
-rw-r--r-- | lib/Plugins.Essentials/src/Extensions/ICookieController.cs | 54 | ||||
-rw-r--r-- | lib/Plugins.Essentials/src/Extensions/SingleCookieController.cs | 124 |
2 files changed, 178 insertions, 0 deletions
diff --git a/lib/Plugins.Essentials/src/Extensions/ICookieController.cs b/lib/Plugins.Essentials/src/Extensions/ICookieController.cs new file mode 100644 index 0000000..b88e648 --- /dev/null +++ b/lib/Plugins.Essentials/src/Extensions/ICookieController.cs @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2023 Vaughn Nugent +* +* Library: VNLib +* Package: VNLib.Plugins.Essentials +* File: ICookieController.cs +* +* ICookieController.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/. +*/ + +namespace VNLib.Plugins.Essentials.Extensions +{ + /// <summary> + /// Manges a single cookie for connections + /// </summary> + public interface ICookieController + { + /// <summary> + /// Sets the cookie value for the given entity + /// </summary> + /// <param name="entity">The http connection to set the cookie value for</param> + /// <param name="value">The cookie value</param> + void SetCookie(HttpEntity entity, string value); + + /// <summary> + /// Gets the cookie value for the given entity + /// </summary> + /// <param name="entity">The entity to get the cookie for</param> + /// <returns>The cookie value if set, null otherwise</returns> + string? GetCookie(HttpEntity entity); + + /// <summary> + /// Expires an existing request cookie for the given entity, avoiding + /// setting the response cookie unless necessary + /// </summary> + /// <param name="entity">The http connection to expire the cookie on</param> + /// <param name="force">Forcibly set the response cookie regardless of it's existence</param> + void ExpireCookie(HttpEntity entity, bool force); + } +}
\ No newline at end of file diff --git a/lib/Plugins.Essentials/src/Extensions/SingleCookieController.cs b/lib/Plugins.Essentials/src/Extensions/SingleCookieController.cs new file mode 100644 index 0000000..1893b6e --- /dev/null +++ b/lib/Plugins.Essentials/src/Extensions/SingleCookieController.cs @@ -0,0 +1,124 @@ +/* +* Copyright (c) 2023 Vaughn Nugent +* +* Library: VNLib +* Package: VNLib.Plugins.Essentials +* File: SingleCookieController.cs +* +* SingleCookieController.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.Collections.Generic; + +using VNLib.Net.Http; + +namespace VNLib.Plugins.Essentials.Extensions +{ + /// <summary> + /// Implements a sinlge cookie controller + /// </summary> + public class SingleCookieController : ICookieController + { + private readonly string _cookieName; + private readonly TimeSpan _validFor; + + /// <summary> + /// Creates a new <see cref="SingleCookieController"/> instance + /// </summary> + /// <param name="cookieName">The name of the cookie to manage</param> + /// <param name="validFor">The max-age cookie value</param> + public SingleCookieController(string cookieName, TimeSpan validFor) + { + _cookieName = cookieName; + _validFor = validFor; + } + + /// <summary> + /// The domain of the cookie + /// </summary> + public string? Domain { get; init; } + + /// <summary> + /// The path of the cookie + /// </summary> + public string? Path { get; init; } + + /// <summary> + /// Whether the cookie is secure + /// </summary> + public bool Secure { get; init; } + + /// <summary> + /// Whether the cookie is HTTP only + /// </summary> + public bool HttpOnly { get; init; } + + /// <summary> + /// The SameSite policy of the cookie + /// </summary> + public CookieSameSite SameSite { get; init; } + + + /// <summary> + /// Optionally clears the cookie (does not force) + /// </summary> + /// <param name="entity">The entity to clear the cookie for</param> + public void ExpireCookie(HttpEntity entity) => ExpireCookie(entity, false); + + ///<inheritdoc/> + public void ExpireCookie(HttpEntity entity, bool force) + { + _ = entity ?? throw new ArgumentNullException(nameof(entity)); + SetCookieInternal(entity, string.Empty, force); + } + + ///<inheritdoc/> + public string? GetCookie(HttpEntity entity) + { + _ = entity ?? throw new ArgumentNullException(nameof(entity)); + return entity.Server.RequestCookies.GetValueOrDefault(_cookieName); + } + + ///<inheritdoc/> + public void SetCookie(HttpEntity entity, string value) + { + _ = entity ?? throw new ArgumentNullException(nameof(entity)); + SetCookieInternal(entity, value, true); + } + + private void SetCookieInternal(HttpEntity entity, string value, bool force) + { + //Only set cooke if already exists or force is true + if (entity.Server.RequestCookies.ContainsKey(value) || force) + { + //Build and set cookie + HttpCookie cookie = new(_cookieName, value) + { + Secure = Secure, + HttpOnly = HttpOnly, + ValidFor = _validFor, + SameSite = SameSite, + Path = Path, + Domain = Domain + }; + + entity.Server.SetCookie(in cookie); + } + } + } +}
\ No newline at end of file |