✨ Proper trace for auth session
This commit is contained in:
@@ -3,6 +3,7 @@ using System.Text.Json;
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using DysonNetwork.Shared.Cache;
|
using DysonNetwork.Shared.Cache;
|
||||||
using DysonNetwork.Shared.Data;
|
using DysonNetwork.Shared.Data;
|
||||||
|
using DysonNetwork.Shared.GeoIp;
|
||||||
using DysonNetwork.Shared.Models;
|
using DysonNetwork.Shared.Models;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using NodaTime;
|
using NodaTime;
|
||||||
@@ -14,7 +15,8 @@ public class AuthService(
|
|||||||
IConfiguration config,
|
IConfiguration config,
|
||||||
IHttpClientFactory httpClientFactory,
|
IHttpClientFactory httpClientFactory,
|
||||||
IHttpContextAccessor httpContextAccessor,
|
IHttpContextAccessor httpContextAccessor,
|
||||||
ICacheService cache
|
ICacheService cache,
|
||||||
|
GeoIpService geo
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
private HttpContext HttpContext => httpContextAccessor.HttpContext!;
|
private HttpContext HttpContext => httpContextAccessor.HttpContext!;
|
||||||
@@ -49,7 +51,9 @@ public class AuthService(
|
|||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
var recentChallengeIds =
|
var recentChallengeIds =
|
||||||
recentSessions.Where(s => s.ChallengeId != null).Select(s => s.ChallengeId.Value).ToList();
|
recentSessions
|
||||||
|
.Where(s => s.ChallengeId != null)
|
||||||
|
.Select(s => s.ChallengeId!.Value).ToList();
|
||||||
var recentChallenges = await db.AuthChallenges.Where(c => recentChallengeIds.Contains(c.Id)).ToListAsync();
|
var recentChallenges = await db.AuthChallenges.Where(c => recentChallengeIds.Contains(c.Id)).ToListAsync();
|
||||||
|
|
||||||
var ipAddress = request.HttpContext.Connection.RemoteIpAddress?.ToString();
|
var ipAddress = request.HttpContext.Connection.RemoteIpAddress?.ToString();
|
||||||
@@ -184,16 +188,23 @@ public class AuthService(
|
|||||||
return totalRequiredSteps;
|
return totalRequiredSteps;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<SnAuthSession> CreateSessionForOidcAsync(SnAccount account, Instant time,
|
public async Task<SnAuthSession> CreateSessionForOidcAsync(
|
||||||
Guid? customAppId = null, SnAuthSession? parentSession = null)
|
SnAccount account,
|
||||||
|
Instant time,
|
||||||
|
Guid? customAppId = null,
|
||||||
|
SnAuthSession? parentSession = null
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
var ipAddr = HttpContext.Connection.RemoteIpAddress?.ToString();
|
||||||
|
var geoLocation = ipAddr is not null ? geo.GetPointFromIp(ipAddr) : null;
|
||||||
var session = new SnAuthSession
|
var session = new SnAuthSession
|
||||||
{
|
{
|
||||||
AccountId = account.Id,
|
AccountId = account.Id,
|
||||||
CreatedAt = time,
|
CreatedAt = time,
|
||||||
LastGrantedAt = time,
|
LastGrantedAt = time,
|
||||||
IpAddress = HttpContext.Connection.RemoteIpAddress?.ToString(),
|
IpAddress = ipAddr,
|
||||||
UserAgent = HttpContext.Request.Headers.UserAgent,
|
UserAgent = HttpContext.Request.Headers.UserAgent,
|
||||||
|
Location = geoLocation,
|
||||||
AppId = customAppId,
|
AppId = customAppId,
|
||||||
ParentSessionId = parentSession?.Id,
|
ParentSessionId = parentSession?.Id,
|
||||||
Type = customAppId is not null ? SessionType.OAuth : SessionType.Oidc,
|
Type = customAppId is not null ? SessionType.OAuth : SessionType.Oidc,
|
||||||
@@ -212,7 +223,8 @@ public class AuthService(
|
|||||||
ClientPlatform platform = ClientPlatform.Unidentified
|
ClientPlatform platform = ClientPlatform.Unidentified
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
var device = await db.AuthClients.FirstOrDefaultAsync(d => d.DeviceId == deviceId && d.AccountId == accountId);
|
var device = await db.AuthClients
|
||||||
|
.FirstOrDefaultAsync(d => d.DeviceId == deviceId && d.AccountId == accountId);
|
||||||
if (device is not null) return device;
|
if (device is not null) return device;
|
||||||
device = new SnAuthClient
|
device = new SnAuthClient
|
||||||
{
|
{
|
||||||
@@ -333,12 +345,8 @@ public class AuthService(
|
|||||||
/// <param name="sessionsToRevoke">A HashSet to store the IDs of all sessions to be revoked.</param>
|
/// <param name="sessionsToRevoke">A HashSet to store the IDs of all sessions to be revoked.</param>
|
||||||
private async Task CollectSessionsToRevoke(Guid currentSessionId, HashSet<Guid> sessionsToRevoke)
|
private async Task CollectSessionsToRevoke(Guid currentSessionId, HashSet<Guid> sessionsToRevoke)
|
||||||
{
|
{
|
||||||
if (sessionsToRevoke.Contains(currentSessionId))
|
if (!sessionsToRevoke.Add(currentSessionId))
|
||||||
{
|
|
||||||
return; // Already processed this session
|
return; // Already processed this session
|
||||||
}
|
|
||||||
|
|
||||||
sessionsToRevoke.Add(currentSessionId);
|
|
||||||
|
|
||||||
// Find direct children
|
// Find direct children
|
||||||
var childSessions = await db.AuthSessions
|
var childSessions = await db.AuthSessions
|
||||||
@@ -425,6 +433,7 @@ public class AuthService(
|
|||||||
AccountId = challenge.AccountId,
|
AccountId = challenge.AccountId,
|
||||||
IpAddress = challenge.IpAddress,
|
IpAddress = challenge.IpAddress,
|
||||||
UserAgent = challenge.UserAgent,
|
UserAgent = challenge.UserAgent,
|
||||||
|
Location = challenge.Location,
|
||||||
Scopes = challenge.Scopes,
|
Scopes = challenge.Scopes,
|
||||||
Audiences = challenge.Audiences,
|
Audiences = challenge.Audiences,
|
||||||
ChallengeId = challenge.Id,
|
ChallengeId = challenge.Id,
|
||||||
@@ -679,9 +688,16 @@ public class AuthService(
|
|||||||
{
|
{
|
||||||
var device = await GetOrCreateDeviceAsync(parentSession.AccountId, deviceId, deviceName, platform);
|
var device = await GetOrCreateDeviceAsync(parentSession.AccountId, deviceId, deviceName, platform);
|
||||||
|
|
||||||
|
var ipAddress = HttpContext.Connection.RemoteIpAddress?.ToString();
|
||||||
|
var userAgent = HttpContext.Request.Headers.UserAgent.ToString();
|
||||||
|
var geoLocation = ipAddress is not null ? geo.GetPointFromIp(ipAddress) : null;
|
||||||
|
|
||||||
var now = SystemClock.Instance.GetCurrentInstant();
|
var now = SystemClock.Instance.GetCurrentInstant();
|
||||||
var session = new SnAuthSession
|
var session = new SnAuthSession
|
||||||
{
|
{
|
||||||
|
IpAddress = ipAddress,
|
||||||
|
UserAgent = userAgent,
|
||||||
|
Location = geoLocation,
|
||||||
AccountId = parentSession.AccountId,
|
AccountId = parentSession.AccountId,
|
||||||
CreatedAt = now,
|
CreatedAt = now,
|
||||||
LastGrantedAt = now,
|
LastGrantedAt = now,
|
||||||
|
|||||||
2886
DysonNetwork.Pass/Migrations/20251203163459_AddLocationToSession.Designer.cs
generated
Normal file
2886
DysonNetwork.Pass/Migrations/20251203163459_AddLocationToSession.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
|||||||
|
using DysonNetwork.Shared.GeoIp;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace DysonNetwork.Pass.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddLocationToSession : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<GeoPoint>(
|
||||||
|
name: "location",
|
||||||
|
table: "auth_sessions",
|
||||||
|
type: "jsonb",
|
||||||
|
nullable: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "location",
|
||||||
|
table: "auth_sessions");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1053,6 +1053,10 @@ namespace DysonNetwork.Pass.Migrations
|
|||||||
.HasColumnType("timestamp with time zone")
|
.HasColumnType("timestamp with time zone")
|
||||||
.HasColumnName("last_granted_at");
|
.HasColumnName("last_granted_at");
|
||||||
|
|
||||||
|
b.Property<GeoPoint>("Location")
|
||||||
|
.HasColumnType("jsonb")
|
||||||
|
.HasColumnName("location");
|
||||||
|
|
||||||
b.Property<Guid?>("ParentSessionId")
|
b.Property<Guid?>("ParentSessionId")
|
||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("parent_session_id");
|
.HasColumnName("parent_session_id");
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ public class SnAuthSession : ModelBase
|
|||||||
[Column(TypeName = "jsonb")] public List<string> Scopes { get; set; } = [];
|
[Column(TypeName = "jsonb")] public List<string> Scopes { get; set; } = [];
|
||||||
[MaxLength(128)] public string? IpAddress { get; set; }
|
[MaxLength(128)] public string? IpAddress { get; set; }
|
||||||
[MaxLength(512)] public string? UserAgent { get; set; }
|
[MaxLength(512)] public string? UserAgent { get; set; }
|
||||||
|
[Column(TypeName = "jsonb")] public GeoPoint? Location { get; set; }
|
||||||
|
|
||||||
public Guid AccountId { get; set; }
|
public Guid AccountId { get; set; }
|
||||||
[JsonIgnore] public SnAccount Account { get; set; } = null!;
|
[JsonIgnore] public SnAccount Account { get; set; } = null!;
|
||||||
|
|||||||
Reference in New Issue
Block a user