using System; using System.Threading; using System.Threading.Tasks; using BlueWest.Cryptography; using BlueWest.Data.Application; using Microsoft.Extensions.Hosting; using Redis.OM; using Redis.OM.Searching; namespace BlueWest.WebApi.Session { /// /// Session Provider Context /// public sealed class SessionManager : ISessionCache { private readonly RedisConnectionProvider _provider; private readonly RedisCollection _sessionTokens; /// /// Index Creation Device /// /// Redis connection public SessionManager( RedisConnectionProvider provider) { _provider = provider; _sessionTokens = (RedisCollection)provider.RedisCollection(); } /// /// Empty constructor /// public SessionManager() { } /// /// Get a session token by the respective Id. /// /// /// public async Task GetSessionTokenByIdAsync(string tokenId) { return await _sessionTokens.Where(x => x.Id == tokenId) .FirstOrDefaultAsync(); } /// /// Create a new session token /// /// public async Task AddSessionToken(SessionToken token) { await _sessionTokens.InsertAsync(token); } /// public async Task SaveAsync() { await _sessionTokens.SaveAsync(); } /// /// Save session data /// public void Save() { _sessionTokens.Save(); } /// /// Gets a Bearer By Access Token Id /// /// public async Task 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; } /// /// Checks if a session is valid /// /// /// 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; } /// public async Task StartAsync(CancellationToken cancellationToken) { await _provider.Connection.CreateIndexAsync(typeof(SessionToken)); } /// public Task StopAsync(CancellationToken cancellationToken) { return Task.CompletedTask; } } }