Added new jwt claim for country, Moved models to correct folder instead of inside Lightlesshub.Groups
This commit is contained in:
@@ -106,7 +106,8 @@ public abstract class AuthControllerBase : Controller
|
|||||||
new Claim(LightlessClaimTypes.CharaIdent, charaIdent),
|
new Claim(LightlessClaimTypes.CharaIdent, charaIdent),
|
||||||
new Claim(LightlessClaimTypes.Alias, alias),
|
new Claim(LightlessClaimTypes.Alias, alias),
|
||||||
new Claim(LightlessClaimTypes.Expires, DateTime.UtcNow.AddHours(6).Ticks.ToString(CultureInfo.InvariantCulture)),
|
new Claim(LightlessClaimTypes.Expires, DateTime.UtcNow.AddHours(6).Ticks.ToString(CultureInfo.InvariantCulture)),
|
||||||
new Claim(LightlessClaimTypes.Continent, await _geoIPProvider.GetCountryFromIP(HttpAccessor))
|
new Claim(LightlessClaimTypes.Continent, await _geoIPProvider.GetContinentFromIP(HttpAccessor)),
|
||||||
|
new Claim(LightlessClaimTypes.Country, await _geoIPProvider.GetCountryFromIP(HttpAccessor)),
|
||||||
});
|
});
|
||||||
|
|
||||||
return Content(token.RawData);
|
return Content(token.RawData);
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
using LightlessSyncShared.Services;
|
using LightlessSyncShared.Services;
|
||||||
using LightlessSyncShared.Utils.Configuration;
|
using LightlessSyncShared.Utils.Configuration;
|
||||||
using MaxMind.GeoIP2;
|
using MaxMind.GeoIP2;
|
||||||
|
using MaxMind.GeoIP2.Model;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
namespace LightlessSyncAuthService.Services;
|
namespace LightlessSyncAuthService.Services;
|
||||||
|
|
||||||
@@ -23,7 +26,7 @@ public class GeoIPService : IHostedService
|
|||||||
_lightlessConfiguration = lightlessConfiguration;
|
_lightlessConfiguration = lightlessConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> GetCountryFromIP(IHttpContextAccessor httpContextAccessor)
|
public async Task<string> GetContinentFromIP(IHttpContextAccessor httpContextAccessor)
|
||||||
{
|
{
|
||||||
if (!_useGeoIP)
|
if (!_useGeoIP)
|
||||||
{
|
{
|
||||||
@@ -41,6 +44,7 @@ public class GeoIPService : IHostedService
|
|||||||
if (_dbReader!.TryCity(ip, out var response))
|
if (_dbReader!.TryCity(ip, out var response))
|
||||||
{
|
{
|
||||||
string? continent = response?.Continent.Code;
|
string? continent = response?.Continent.Code;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(continent) &&
|
if (!string.IsNullOrEmpty(continent) &&
|
||||||
string.Equals(continent, "NA", StringComparison.Ordinal)
|
string.Equals(continent, "NA", StringComparison.Ordinal)
|
||||||
&& response?.Location.Longitude != null)
|
&& response?.Location.Longitude != null)
|
||||||
@@ -140,4 +144,38 @@ public class GeoIPService : IHostedService
|
|||||||
_dbReader?.Dispose();
|
_dbReader?.Dispose();
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal async Task<string> GetCountryFromIP(IHttpContextAccessor httpContextAccessor)
|
||||||
|
{
|
||||||
|
if (!_useGeoIP)
|
||||||
|
{
|
||||||
|
return "*";
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var ip = httpContextAccessor.GetIpAddress();
|
||||||
|
|
||||||
|
using CancellationTokenSource waitCts = new();
|
||||||
|
waitCts.CancelAfter(TimeSpan.FromSeconds(5));
|
||||||
|
while (_processingReload) await Task.Delay(100, waitCts.Token).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (_dbReader!.TryCity(ip, out var response))
|
||||||
|
{
|
||||||
|
string? country = response?.Country.IsoCode;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(country)
|
||||||
|
&& response?.Location.Longitude != null)
|
||||||
|
{
|
||||||
|
return country;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "*";
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogWarning(ex, "Error handling Geo IP country in request");
|
||||||
|
return "*";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using LightlessSync.API.Data;
|
using LightlessSync.API.Data;
|
||||||
using LightlessSync.API.Dto.Group;
|
using LightlessSync.API.Dto.Group;
|
||||||
|
using LightlessSyncServer.Models;
|
||||||
using LightlessSyncServer.Utils;
|
using LightlessSyncServer.Utils;
|
||||||
using LightlessSyncShared.Metrics;
|
using LightlessSyncShared.Metrics;
|
||||||
using LightlessSyncShared.Models;
|
using LightlessSyncShared.Models;
|
||||||
@@ -8,7 +9,6 @@ using Microsoft.AspNetCore.SignalR;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using StackExchange.Redis;
|
using StackExchange.Redis;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace LightlessSyncServer.Hubs;
|
namespace LightlessSyncServer.Hubs;
|
||||||
|
|
||||||
@@ -20,6 +20,8 @@ public partial class LightlessHub
|
|||||||
|
|
||||||
public string Continent => Context.User?.Claims?.SingleOrDefault(c => string.Equals(c.Type, LightlessClaimTypes.Continent, StringComparison.Ordinal))?.Value ?? "UNK";
|
public string Continent => Context.User?.Claims?.SingleOrDefault(c => string.Equals(c.Type, LightlessClaimTypes.Continent, StringComparison.Ordinal))?.Value ?? "UNK";
|
||||||
|
|
||||||
|
public string Country => Context.User?.Claims?.SingleOrDefault(c => string.Equals(c.Type, LightlessClaimTypes.Country, StringComparison.Ordinal))?.Value ?? "UNK";
|
||||||
|
|
||||||
private async Task DeleteUser(User user)
|
private async Task DeleteUser(User user)
|
||||||
{
|
{
|
||||||
var ownPairData = await DbContext.ClientPairs.Where(u => u.User.UID == user.UID).ToListAsync().ConfigureAwait(false);
|
var ownPairData = await DbContext.ClientPairs.Where(u => u.User.UID == user.UID).ToListAsync().ConfigureAwait(false);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using LightlessSync.API.Data.Enum;
|
|||||||
using LightlessSync.API.Data.Extensions;
|
using LightlessSync.API.Data.Extensions;
|
||||||
using LightlessSync.API.Dto.Group;
|
using LightlessSync.API.Dto.Group;
|
||||||
using LightlessSync.API.Dto.User;
|
using LightlessSync.API.Dto.User;
|
||||||
|
using LightlessSyncServer.Models;
|
||||||
using LightlessSyncServer.Utils;
|
using LightlessSyncServer.Utils;
|
||||||
using LightlessSyncShared.Models;
|
using LightlessSyncShared.Models;
|
||||||
using LightlessSyncShared.Utils;
|
using LightlessSyncShared.Utils;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using LightlessSync.API.Data.Enum;
|
|||||||
using LightlessSync.API.Data.Extensions;
|
using LightlessSync.API.Data.Extensions;
|
||||||
using LightlessSync.API.Dto.Group;
|
using LightlessSync.API.Dto.Group;
|
||||||
using LightlessSync.API.Dto.User;
|
using LightlessSync.API.Dto.User;
|
||||||
|
using LightlessSyncServer.Models;
|
||||||
using LightlessSyncServer.Utils;
|
using LightlessSyncServer.Utils;
|
||||||
using LightlessSyncShared.Metrics;
|
using LightlessSyncShared.Metrics;
|
||||||
using LightlessSyncShared.Models;
|
using LightlessSyncShared.Models;
|
||||||
@@ -204,8 +205,8 @@ public partial class LightlessHub
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var sender = await _pairService.TryAddPairAsync(UserUID, payload.UID);
|
var sender = await _pairService.TryAddPairAsync(UserUID, payload.UID).ConfigureAwait(false);
|
||||||
var receiver = await _pairService.TryAddPairAsync(payload.UID, UserUID);
|
var receiver = await _pairService.TryAddPairAsync(payload.UID, UserUID).ConfigureAwait(false);
|
||||||
|
|
||||||
var user = await DbContext.Users.SingleAsync(u => u.UID == UserUID).ConfigureAwait(false);
|
var user = await DbContext.Users.SingleAsync(u => u.UID == UserUID).ConfigureAwait(false);
|
||||||
var otherUser = await DbContext.Users.SingleAsync(u => u.UID == payload.UID).ConfigureAwait(false);
|
var otherUser = await DbContext.Users.SingleAsync(u => u.UID == payload.UID).ConfigureAwait(false);
|
||||||
@@ -304,7 +305,6 @@ public partial class LightlessHub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task NotifyBroadcastOwnerOfPairRequest(string targetHashedCid)
|
private async Task NotifyBroadcastOwnerOfPairRequest(string targetHashedCid)
|
||||||
{
|
{
|
||||||
var myHashedCid = UserCharaIdent;
|
var myHashedCid = UserCharaIdent;
|
||||||
@@ -360,23 +360,6 @@ public partial class LightlessHub
|
|||||||
|
|
||||||
await Clients.User(entry.OwnerUID).Client_ReceiveBroadcastPairRequest(dto).ConfigureAwait(false);
|
await Clients.User(entry.OwnerUID).Client_ReceiveBroadcastPairRequest(dto).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
private class PairingPayload
|
|
||||||
{
|
|
||||||
public string UID { get; set; } = string.Empty;
|
|
||||||
public string HashedCid { get; set; } = string.Empty;
|
|
||||||
public DateTime Timestamp { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class BroadcastRedisEntry
|
|
||||||
{
|
|
||||||
public string HashedCID { get; set; } = string.Empty;
|
|
||||||
public string OwnerUID { get; set; } = string.Empty;
|
|
||||||
public string? GID { get; set; }
|
|
||||||
|
|
||||||
public bool OwnedBy(string userUid) => !string.IsNullOrEmpty(userUid) && string.Equals(OwnerUID, userUid, StringComparison.Ordinal);
|
|
||||||
|
|
||||||
public bool HasOwner() => !string.IsNullOrEmpty(OwnerUID);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Authorize(Policy = "Identified")]
|
[Authorize(Policy = "Identified")]
|
||||||
public async Task SetBroadcastStatus(bool enabled, GroupBroadcastRequestDto? groupDto = null)
|
public async Task SetBroadcastStatus(bool enabled, GroupBroadcastRequestDto? groupDto = null)
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ public partial class LightlessHub : Hub<ILightlessHub>, ILightlessHub
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
_lightlessMetrics.IncGaugeWithLabels(MetricsAPI.GaugeConnections, labels: Continent);
|
_lightlessMetrics.IncGaugeWithLabels(MetricsAPI.GaugeConnections, labels: Continent);
|
||||||
|
_lightlessMetrics.IncGaugeWithLabels(MetricsAPI.GaugeConnections, labels: Country);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_logger.LogCallInfo(LightlessHubLogger.Args(_contextAccessor.GetIpAddress(), Context.ConnectionId, UserCharaIdent));
|
_logger.LogCallInfo(LightlessHubLogger.Args(_contextAccessor.GetIpAddress(), Context.ConnectionId, UserCharaIdent));
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
namespace LightlessSyncServer.Models;
|
||||||
|
|
||||||
|
public class BroadcastRedisEntry()
|
||||||
|
{
|
||||||
|
public string? GID { get; set; }
|
||||||
|
public string HashedCID { get; set; } = string.Empty;
|
||||||
|
public string OwnerUID { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public bool OwnedBy(string userUid) => !string.IsNullOrEmpty(userUid) && string.Equals(OwnerUID, userUid, StringComparison.Ordinal);
|
||||||
|
|
||||||
|
public bool HasOwner() => !string.IsNullOrEmpty(OwnerUID);
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace LightlessSyncServer.Models;
|
||||||
|
|
||||||
|
public class PairingPayload
|
||||||
|
{
|
||||||
|
public string UID { get; set; } = string.Empty;
|
||||||
|
public string HashedCid { get; set; } = string.Empty;
|
||||||
|
public DateTime Timestamp { get; set; }
|
||||||
|
}
|
||||||
@@ -41,7 +41,6 @@ public class Program
|
|||||||
metrics.SetGaugeTo(MetricsAPI.GaugeUsersRegistered, context.Users.AsNoTracking().Count());
|
metrics.SetGaugeTo(MetricsAPI.GaugeUsersRegistered, context.Users.AsNoTracking().Count());
|
||||||
metrics.SetGaugeTo(MetricsAPI.GaugePairs, context.ClientPairs.AsNoTracking().Count());
|
metrics.SetGaugeTo(MetricsAPI.GaugePairs, context.ClientPairs.AsNoTracking().Count());
|
||||||
metrics.SetGaugeTo(MetricsAPI.GaugePairsPaused, context.Permissions.AsNoTracking().Where(p=>p.IsPaused).Count());
|
metrics.SetGaugeTo(MetricsAPI.GaugePairsPaused, context.Permissions.AsNoTracking().Where(p=>p.IsPaused).Count());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.Length == 0 || !string.Equals(args[0], "dry", StringComparison.Ordinal))
|
if (args.Length == 0 || !string.Equals(args[0], "dry", StringComparison.Ordinal))
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
using LightlessSync.API.Dto;
|
using LightlessSync.API.Dto;
|
||||||
using LightlessSync.API.SignalR;
|
using LightlessSync.API.SignalR;
|
||||||
using LightlessSyncServer.Hubs;
|
using LightlessSyncServer.Hubs;
|
||||||
|
using LightlessSyncServer.Models;
|
||||||
using LightlessSyncShared.Data;
|
using LightlessSyncShared.Data;
|
||||||
using LightlessSyncShared.Metrics;
|
using LightlessSyncShared.Metrics;
|
||||||
using LightlessSyncShared.Services;
|
using LightlessSyncShared.Services;
|
||||||
using LightlessSyncShared.Utils.Configuration;
|
using LightlessSyncShared.Utils.Configuration;
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using StackExchange.Redis;
|
|
||||||
using StackExchange.Redis.Extensions.Core.Abstractions;
|
using StackExchange.Redis.Extensions.Core.Abstractions;
|
||||||
using static LightlessSyncServer.Hubs.LightlessHub;
|
|
||||||
|
|
||||||
namespace LightlessSyncServer.Services;
|
namespace LightlessSyncServer.Services;
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ public static class LightlessClaimTypes
|
|||||||
public const string Internal = "internal";
|
public const string Internal = "internal";
|
||||||
public const string Expires = "expiration_date";
|
public const string Expires = "expiration_date";
|
||||||
public const string Continent = "continent";
|
public const string Continent = "continent";
|
||||||
|
public const string Country = "country";
|
||||||
public const string DiscordUser = "discord_user";
|
public const string DiscordUser = "discord_user";
|
||||||
public const string DiscordId = "discord_user_id";
|
public const string DiscordId = "discord_user_id";
|
||||||
public const string OAuthLoginToken = "oauth_login_token";
|
public const string OAuthLoginToken = "oauth_login_token";
|
||||||
|
|||||||
Reference in New Issue
Block a user