MyBookmark/Modules.User.Application/UserContext.cs
2024-11-16 02:52:33 +03:00

115 lines
4.4 KiB
C#

using MediatR;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Modules.User.Application.Models;
using Modules.User.Application.Queries;
using Modules.User.Application.Settings;
using System.Net.Http.Json;
using System.Security.Claims;
namespace Modules.User.Application;
public class UserContext
{
private readonly IMediator _mediator;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly JwtSettings _jwtSettings;
private Models.User? _user;
public UserContext(IOptionsMonitor<JwtSettings> jwtSettingsOptions, IMediator mediator, IHttpContextAccessor httpContextAccessor, IConfiguration configuration)
{
_mediator = mediator;
_httpContextAccessor = httpContextAccessor;
_jwtSettings = jwtSettingsOptions.CurrentValue;
}
public JwtSettings GetJwtSettings() => _jwtSettings;
public async Task<Models.User> GetUserInfo(CancellationToken cancellationToken = default)
{
var a = _httpContextAccessor.HttpContext?.User.FindFirstValue(Constants.SessionIdKey);
if (_user == null || !_user.IsAuthenticated)
{
if (Guid.TryParse(_httpContextAccessor.HttpContext?.User.FindFirstValue(Constants.AccountIdKey), out Guid accountId))
_user = await _mediator.Send(new GetUserQuery
{
AccountId = accountId,
SessionId = Guid.TryParse(_httpContextAccessor.HttpContext?.User.FindFirstValue(Constants.SessionIdKey), out Guid sessionId) ? sessionId : null,
}, cancellationToken);
else _user = new Models.User();
//await RetrieveUserInfo(_user);
if (!_user.IsAuthenticated) { }
}
return _user;
}
//private async Task RetrieveUserInfo(Models.User user)
//{
// var ip = GetClientIp();
// var ipAddressWithoutPort = ip?.Split(':')[0];
// var location = await GetLocation(ipAddressWithoutPort);
// var clientInfo = new ClientInfo
// {
// Ip = !string.IsNullOrWhiteSpace(ipAddressWithoutPort) ? ipAddressWithoutPort : null,
// UserAgent = _httpContextAccessor.HttpContext?.Request.Headers.UserAgent,
// Location = location,
// };
// user.ClientInfo = clientInfo;
//}
internal string? GetUserAgent() => _httpContextAccessor.HttpContext?.Request.Headers.UserAgent;
internal string? GetRefreshToken(string refreshTokenName) => _httpContextAccessor.HttpContext?.Request
.Cookies.TryGetValue(refreshTokenName, out string? refreshToken) == true ? refreshToken : null;
private string? GetClientIp()
{
var ip = _httpContextAccessor.HttpContext?.GetServerVariable("HTTP_X_FORWARDED_FOR");
if (string.IsNullOrWhiteSpace(ip)) ip = _httpContextAccessor.HttpContext?.Request.Headers["CF-CONNECTING-IP"];
if (string.IsNullOrWhiteSpace(ip)) ip = _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress?.ToString();
return ip?.Trim();
}
//вынести в сервис
internal async Task<Location?> GetLocation(string? ip)
{
if (string.IsNullOrWhiteSpace(ip))
{
ip = GetClientIp();
if (string.IsNullOrWhiteSpace(ip))
{
return null;
}
}
var client = new HttpClient() { BaseAddress = new Uri("http://ip-api.com") };
try
{
var response = await client.GetFromJsonAsync<IpApiResponse>($"/json/{ip}");
return response == null || (!response.lat.HasValue || !response.lon.HasValue) ? null : new Location
{
Latitude = response.lat.Value,
Longutude = response.lon.Value,
Country = response.country,
Region = response.regionName,
};
}
catch { return null; }
}
public sealed class IpApiResponse
{
public string? status { get; set; }
public string? continent { get; set; }
public string? country { get; set; }
public string? regionName { get; set; }
public string? city { get; set; }
public string? district { get; set; }
public string? zip { get; set; }
public double? lat { get; set; }
public double? lon { get; set; }
public string? isp { get; set; }
public string? query { get; set; }
}
}