aboutsummaryrefslogtreecommitdiff
path: root/lib/Plugins.Essentials/src/Extensions
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Plugins.Essentials/src/Extensions')
-rw-r--r--lib/Plugins.Essentials/src/Extensions/ICookieController.cs54
-rw-r--r--lib/Plugins.Essentials/src/Extensions/SingleCookieController.cs124
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