2022-09-27 20:12:13 +03:00
|
|
|
using System;
|
|
|
|
using System.Threading;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using BlueWest.Data.Application;
|
|
|
|
using BlueWest.Data.Auth;
|
|
|
|
using Microsoft.Extensions.Hosting;
|
|
|
|
using Redis.OM;
|
|
|
|
using Redis.OM.Searching;
|
|
|
|
|
|
|
|
namespace BlueWest.Views;
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Session Provider Context
|
|
|
|
/// </summary>
|
|
|
|
public sealed class SessionManager : ISessionCache
|
|
|
|
{
|
|
|
|
private readonly RedisConnectionProvider _provider;
|
|
|
|
private readonly RedisCollection<SessionToken> _sessionTokens;
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Index Creation Device
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="provider">Redis connection</param>
|
|
|
|
public SessionManager(
|
|
|
|
RedisConnectionProvider provider)
|
|
|
|
{
|
|
|
|
_provider = provider;
|
|
|
|
_sessionTokens = (RedisCollection<SessionToken>) provider.RedisCollection<SessionToken>();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Empty constructor
|
|
|
|
/// </summary>
|
|
|
|
public SessionManager()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Get a session token by the respective Id.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="tokenId"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
public async Task<SessionToken> GetSessionTokenByIdAsync(string tokenId)
|
|
|
|
{
|
2022-10-27 20:13:02 +03:00
|
|
|
return
|
|
|
|
await _sessionTokens.Where(x => x.Id == tokenId)
|
2022-09-27 20:12:13 +03:00
|
|
|
.FirstOrDefaultAsync();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Create a new session token
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="token"></param>
|
|
|
|
public async Task AddSessionToken(SessionToken token)
|
|
|
|
{
|
|
|
|
await _sessionTokens.InsertAsync(token);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
public async Task SaveAsync()
|
|
|
|
{
|
|
|
|
await _sessionTokens.SaveAsync();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Save session data
|
|
|
|
/// </summary>
|
|
|
|
public void Save()
|
|
|
|
{
|
|
|
|
_sessionTokens.Save();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets a Bearer By Access Token Id
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="sessionTokenId"></param>
|
|
|
|
public async Task<bool> IsSessionValidAsync(string sessionTokenId)
|
|
|
|
{
|
|
|
|
var accessToken = await _sessionTokens
|
|
|
|
.Where(t => t.Id == sessionTokenId)
|
|
|
|
.FirstOrDefaultAsync();
|
|
|
|
|
|
|
|
if (accessToken == null) return false;
|
|
|
|
|
|
|
|
if (accessToken.IsValid)
|
|
|
|
{
|
|
|
|
// Check if it's not expired
|
|
|
|
var expirationDate = accessToken.CreatedDate + accessToken.ValidFor;
|
|
|
|
var timeNow = DateTimeOffset.Now.ToUnixTimeMilliseconds();
|
|
|
|
if (expirationDate >= timeNow) return accessToken.IsValid;
|
|
|
|
accessToken.IsValid = false;
|
|
|
|
await _sessionTokens.SaveAsync();
|
|
|
|
}
|
|
|
|
|
|
|
|
return accessToken.IsValid;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Checks if a session is valid
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="sessionTokenId"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
public bool IsSessionValid(string sessionTokenId)
|
|
|
|
{
|
|
|
|
var accessToken = _sessionTokens
|
|
|
|
.FirstOrDefault(t => t.Id == sessionTokenId);
|
|
|
|
|
|
|
|
if (accessToken == null) return false;
|
|
|
|
|
|
|
|
if (!accessToken.IsValid) return accessToken.IsValid;
|
|
|
|
|
|
|
|
accessToken.Validate();
|
|
|
|
_sessionTokens.Save();
|
|
|
|
|
|
|
|
return accessToken.IsValid;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
public async Task StartAsync(CancellationToken cancellationToken)
|
|
|
|
{
|
|
|
|
await _provider.Connection.CreateIndexAsync(typeof(SessionToken));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
public Task StopAsync(CancellationToken cancellationToken)
|
|
|
|
{
|
|
|
|
return Task.CompletedTask;
|
|
|
|
}
|
|
|
|
}
|