199 lines
7.2 KiB
C#
199 lines
7.2 KiB
C#
using e_suite.API.Common.exceptions;
|
|
using e_suite.API.Common.models;
|
|
using e_suite.Database.Audit;
|
|
using eSuite.API.Extensions;
|
|
using eSuite.API.Middleware;
|
|
using eSuite.Core.Miscellaneous;
|
|
using IUserManager = e_suite.API.Common.IUserManager;
|
|
// ReSharper disable All
|
|
|
|
namespace eSuite.API.SingleSignOn;
|
|
|
|
/// <summary>
|
|
/// Internal class used to manage cookies
|
|
/// </summary>
|
|
public class CookieManager : ICookieManager
|
|
{
|
|
private readonly IUserManager _userManager;
|
|
|
|
/// <summary>
|
|
/// Default constructor
|
|
/// </summary>
|
|
/// <param name="userManager"></param>
|
|
public CookieManager(IUserManager userManager)
|
|
{
|
|
_userManager = userManager;
|
|
}
|
|
|
|
private const string ssoNewUserLinkCookieName = "eSuiteNewUserLinkCookie";
|
|
private const string ssoProfileLinkCookieName = "eSuiteProfileLinkCookie";
|
|
private const string ssoIdCookieName = "eSuiteSsoProvider";
|
|
|
|
/// <summary>
|
|
/// Creates the session cookie with appropriate settings
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="loginResponse"></param>
|
|
/// <returns></returns>
|
|
public Task CreateSessionCookie(HttpResponse response, LoginResponse loginResponse)
|
|
{
|
|
response.Cookies.Append(AuthenticationExtension.SessionCookieName, loginResponse.Token, new CookieOptions
|
|
{
|
|
HttpOnly = false, //Set False as Javascript (React) needs to read the cookie.
|
|
SameSite = SameSiteMode.Strict,
|
|
Secure = true,
|
|
IsEssential = true,
|
|
Expires = null, //Session Cookie
|
|
Path = "/"
|
|
});
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deletes any existing session cookie
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <returns></returns>
|
|
public Task DeleteSessionCookie(HttpResponse response)
|
|
{
|
|
response.Cookies.Delete(AuthenticationExtension.SessionCookieName);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates cookie used with an Sso Identity to a user account
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="auditUserDetails"></param>
|
|
/// <param name="generalIdRef"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task CreateProfileLinkCookie(HttpResponse response, AuditUserDetails auditUserDetails, GeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
|
{
|
|
var guid = await _userManager.CreateSingleUseGuid(auditUserDetails, generalIdRef, cancellationToken);
|
|
|
|
response.Cookies.Append(ssoProfileLinkCookieName, guid.ToString(), new CookieOptions
|
|
{
|
|
HttpOnly = true, //Set True only the server side app needs to know about this
|
|
SameSite = SameSiteMode.Lax, //Used when returning from an sso authorisation
|
|
Secure = true,
|
|
IsEssential = true,
|
|
Expires = null, //Session Cookie
|
|
Path = "/"
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates cookie used with an Sso Identity to a user account
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="auditUserDetails"></param>
|
|
/// <param name="generalIdRef"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task CreateNewUserLinkCookie(HttpResponse response, AuditUserDetails auditUserDetails, GeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
|
{
|
|
var guid = await _userManager.CreateSingleUseGuid(auditUserDetails, generalIdRef, cancellationToken);
|
|
|
|
response.Cookies.Append(ssoNewUserLinkCookieName, guid.ToString(), new CookieOptions
|
|
{
|
|
HttpOnly = true, //Set True only the server side app needs to know about this
|
|
SameSite = SameSiteMode.Lax, //Used when returning from an sso authorisation
|
|
Secure = true,
|
|
IsEssential = true,
|
|
Expires = null, //Session Cookie
|
|
Path = "/"
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Used to find a profile link cookie and find the appropriate user account
|
|
/// </summary>
|
|
/// <param name="request"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="NotFoundException"></exception>
|
|
public async Task<CookieLink?> GetUserIdFromLinkCookie(HttpRequest request, CancellationToken cancellationToken)
|
|
{
|
|
var cookieContent = string.Empty;
|
|
var cookieLink = new CookieLink()
|
|
{
|
|
LinkType = LinkType.None
|
|
};
|
|
|
|
if (request.Cookies.ContainsKey(ssoProfileLinkCookieName))
|
|
{
|
|
cookieContent = request.Cookies[ssoProfileLinkCookieName] ?? throw new NotFoundException();
|
|
cookieLink.LinkType = LinkType.Profile;
|
|
}
|
|
|
|
if (request.Cookies.ContainsKey(ssoNewUserLinkCookieName))
|
|
{
|
|
cookieContent = request.Cookies[ssoNewUserLinkCookieName] ?? throw new NotFoundException();
|
|
cookieLink.LinkType = LinkType.NewUser;
|
|
}
|
|
|
|
if (cookieLink.LinkType == LinkType.None)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var guid = new Guid(cookieContent);
|
|
|
|
cookieLink.User = await _userManager.GetUserWithSingleUseGuid(guid, cancellationToken);
|
|
return cookieLink;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Delete any existing Profile link cookie.
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <returns></returns>
|
|
public Task DeleteLinkCookie(HttpResponse response)
|
|
{
|
|
response.Cookies.Delete(ssoProfileLinkCookieName);
|
|
response.Cookies.Delete(ssoNewUserLinkCookieName);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Find the SsoProvider Id using a cookie to save user input
|
|
/// </summary>
|
|
/// <param name="request"></param>
|
|
/// <returns></returns>
|
|
public Task<long?> GetSsoIdFromSsoIdCookie(HttpRequest request)
|
|
{
|
|
return Task.FromResult(request.Cookies.ContainsKey(ssoIdCookieName) ? request.Cookies[ssoIdCookieName].ToLong() : null);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Delete the SsoProvider cookie as the user has manually logged out
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <returns></returns>
|
|
public Task DeleteSsoIdCookie(HttpResponse response)
|
|
{
|
|
response.Cookies.Delete(ssoIdCookieName);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create the SsoProvider cookie, so that the login provess can be sped up for user convenience
|
|
/// </summary>
|
|
/// <param name="response"></param>
|
|
/// <param name="ssoId"></param>
|
|
/// <returns></returns>
|
|
public Task CreateSsoIdCookie(HttpResponse response, long ssoId)
|
|
{
|
|
response.Cookies.Append(ssoIdCookieName, ssoId.ToString(), new CookieOptions()
|
|
{
|
|
HttpOnly = true,
|
|
SameSite = SameSiteMode.Strict,
|
|
Secure = true,
|
|
IsEssential = true,
|
|
Expires = DateTime.UtcNow.AddMonths(1), //cookie will expire after a month.
|
|
Path = "/"
|
|
});
|
|
return Task.CompletedTask;
|
|
}
|
|
} |