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;
///
/// Internal class used to manage cookies
///
public class CookieManager : ICookieManager
{
private readonly IUserManager _userManager;
///
/// Default constructor
///
///
public CookieManager(IUserManager userManager)
{
_userManager = userManager;
}
private const string ssoNewUserLinkCookieName = "eSuiteNewUserLinkCookie";
private const string ssoProfileLinkCookieName = "eSuiteProfileLinkCookie";
private const string ssoIdCookieName = "eSuiteSsoProvider";
///
/// Creates the session cookie with appropriate settings
///
///
///
///
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;
}
///
/// Deletes any existing session cookie
///
///
///
public Task DeleteSessionCookie(HttpResponse response)
{
response.Cookies.Delete(AuthenticationExtension.SessionCookieName);
return Task.CompletedTask;
}
///
/// Creates cookie used with an Sso Identity to a user account
///
///
///
///
///
///
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 = "/"
});
}
///
/// Creates cookie used with an Sso Identity to a user account
///
///
///
///
///
///
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 = "/"
});
}
///
/// Used to find a profile link cookie and find the appropriate user account
///
///
///
///
///
public async Task 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;
}
///
/// Delete any existing Profile link cookie.
///
///
///
public Task DeleteLinkCookie(HttpResponse response)
{
response.Cookies.Delete(ssoProfileLinkCookieName);
response.Cookies.Delete(ssoNewUserLinkCookieName);
return Task.CompletedTask;
}
///
/// Find the SsoProvider Id using a cookie to save user input
///
///
///
public Task GetSsoIdFromSsoIdCookie(HttpRequest request)
{
return Task.FromResult(request.Cookies.ContainsKey(ssoIdCookieName) ? request.Cookies[ssoIdCookieName].ToLong() : null);
}
///
/// Delete the SsoProvider cookie as the user has manually logged out
///
///
///
public Task DeleteSsoIdCookie(HttpResponse response)
{
response.Cookies.Delete(ssoIdCookieName);
return Task.CompletedTask;
}
///
/// Create the SsoProvider cookie, so that the login provess can be sped up for user convenience
///
///
///
///
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;
}
}