🐛 Serval bug fixes

This commit is contained in:
2025-07-17 14:24:30 +08:00
parent b14af43996
commit 4e2a7ebbce
12 changed files with 111 additions and 77 deletions

View File

@@ -1 +1,2 @@
/wwwroot/dist /wwwroot/dist
/Keys

View File

@@ -12,7 +12,7 @@ namespace DysonNetwork.Pass.Account;
[Index(nameof(Name), IsUnique = true)] [Index(nameof(Name), IsUnique = true)]
public class Account : ModelBase public class Account : ModelBase
{ {
public Guid Id { get; set; } public Guid Id { get; set; } = Guid.NewGuid();
[MaxLength(256)] public string Name { get; set; } = string.Empty; [MaxLength(256)] public string Name { get; set; } = string.Empty;
[MaxLength(256)] public string Nick { get; set; } = string.Empty; [MaxLength(256)] public string Nick { get; set; } = string.Empty;
[MaxLength(32)] public string Language { get; set; } = string.Empty; [MaxLength(32)] public string Language { get; set; } = string.Empty;

View File

@@ -83,9 +83,6 @@ public class AccountService(
bool isEmailVerified = false, bool isEmailVerified = false,
bool isActivated = false bool isActivated = false
) )
{
await using var transaction = await db.Database.BeginTransactionAsync();
try
{ {
var dupeNameCount = await db.Accounts.Where(a => a.Name == name).CountAsync(); var dupeNameCount = await db.Accounts.Where(a => a.Name == name).CountAsync();
if (dupeNameCount > 0) if (dupeNameCount > 0)
@@ -133,8 +130,12 @@ public class AccountService(
}); });
} }
} }
else
{ db.Accounts.Add(account);
await db.SaveChangesAsync();
if (isActivated) return account;
var spell = await spells.CreateMagicSpell( var spell = await spells.CreateMagicSpell(
account, account,
MagicSpellType.AccountActivation, MagicSpellType.AccountActivation,
@@ -144,20 +145,9 @@ public class AccountService(
} }
); );
await spells.NotifyMagicSpell(spell, true); await spells.NotifyMagicSpell(spell, true);
}
db.Accounts.Add(account);
await db.SaveChangesAsync();
await transaction.CommitAsync();
return account; return account;
} }
catch
{
await transaction.RollbackAsync();
throw;
}
}
public async Task<Account> CreateAccount(OidcUserInfo userInfo) public async Task<Account> CreateAccount(OidcUserInfo userInfo)
{ {

View File

@@ -31,6 +31,7 @@ public class AuthSession : ModelBase
LastGrantedAt = LastGrantedAt?.ToTimestamp(), LastGrantedAt = LastGrantedAt?.ToTimestamp(),
ExpiredAt = ExpiredAt?.ToTimestamp(), ExpiredAt = ExpiredAt?.ToTimestamp(),
AccountId = AccountId.ToString(), AccountId = AccountId.ToString(),
Account = Account.ToProtoValue(),
ChallengeId = ChallengeId.ToString(), ChallengeId = ChallengeId.ToString(),
Challenge = Challenge.ToProtoValue(), Challenge = Challenge.ToProtoValue(),
AppId = AppId?.ToString() AppId = AppId?.ToString()

View File

@@ -1,4 +1,3 @@
using System.Text.Json;
using DysonNetwork.Pass; using DysonNetwork.Pass;
using DysonNetwork.Pass.Pages.Data; using DysonNetwork.Pass.Pages.Data;
using DysonNetwork.Pass.Startup; using DysonNetwork.Pass.Startup;
@@ -6,7 +5,6 @@ using DysonNetwork.Shared.Http;
using DysonNetwork.Shared.PageData; using DysonNetwork.Shared.PageData;
using DysonNetwork.Shared.Registry; using DysonNetwork.Shared.Registry;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileProviders;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
@@ -18,11 +16,12 @@ builder.Services.AddAppMetrics();
// Add application services // Add application services
builder.Services.AddRegistryService(builder.Configuration); builder.Services.AddRegistryService(builder.Configuration);
builder.Services.AddPusherService();
builder.Services.AddAppServices(builder.Configuration); builder.Services.AddAppServices(builder.Configuration);
builder.Services.AddAppRateLimiting(); builder.Services.AddAppRateLimiting();
builder.Services.AddAppAuthentication(); builder.Services.AddAppAuthentication();
builder.Services.AddAppSwagger(); builder.Services.AddAppSwagger();
builder.Services.AddPusherService();
builder.Services.AddDriveService();
// Add flush handlers and websocket handlers // Add flush handlers and websocket handlers
builder.Services.AddAppFlushHandlers(); builder.Services.AddAppFlushHandlers();

View File

@@ -75,6 +75,7 @@ public static class ApplicationConfiguration
app.MapGrpcService<AccountServiceGrpc>(); app.MapGrpcService<AccountServiceGrpc>();
app.MapGrpcService<AuthServiceGrpc>(); app.MapGrpcService<AuthServiceGrpc>();
app.MapGrpcService<ActionLogServiceGrpc>(); app.MapGrpcService<ActionLogServiceGrpc>();
app.MapGrpcService<PermissionServiceGrpc>();
return app; return app;
} }

View File

@@ -16,6 +16,7 @@ builder.Services.AddAppRateLimiting();
builder.Services.AddAppAuthentication(); builder.Services.AddAppAuthentication();
builder.Services.AddAppSwagger(); builder.Services.AddAppSwagger();
builder.Services.AddDysonAuth(); builder.Services.AddDysonAuth();
builder.Services.AddAccountService();
// Add flush handlers and websocket handlers // Add flush handlers and websocket handlers
builder.Services.AddAppFlushHandlers(); builder.Services.AddAppFlushHandlers();

View File

@@ -29,8 +29,6 @@ public class DysonTokenAuthHandler(
try try
{ {
var now = SystemClock.Instance.GetCurrentInstant();
// Validate token and extract session ID // Validate token and extract session ID
AuthSession session; AuthSession session;
try try
@@ -59,8 +57,20 @@ public class DysonTokenAuthHandler(
new("token_type", tokenInfo.Type.ToString()) new("token_type", tokenInfo.Type.ToString())
}; };
// return AuthenticateResult.Success(ticket); // Add scopes as claims
return AuthenticateResult.NoResult(); session.Challenge.Scopes.ToList().ForEach(scope => claims.Add(new Claim("scope", scope)));
// Add superuser claim if applicable
if (session.Account.IsSuperuser)
claims.Add(new Claim("is_superuser", "1"));
// Create the identity and principal
var identity = new ClaimsIdentity(claims, AuthConstants.SchemeName);
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, AuthConstants.SchemeName);
return AuthenticateResult.Success(ticket);
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -50,6 +50,18 @@ public static class GrpcClientHelper
clientCertPassword)); clientCertPassword));
} }
public static async Task<ActionLogService.ActionLogServiceClient> CreateActionLogServiceClient(
IEtcdClient etcdClient,
string clientCertPath,
string clientKeyPath,
string? clientCertPassword = null
)
{
var url = await GetServiceUrlFromEtcd(etcdClient, "DysonNetwork.Pass");
return new ActionLogService.ActionLogServiceClient(CreateCallInvoker(url, clientCertPath, clientKeyPath,
clientCertPassword));
}
public static async Task<AuthService.AuthServiceClient> CreateAuthServiceClient( public static async Task<AuthService.AuthServiceClient> CreateAuthServiceClient(
IEtcdClient etcdClient, IEtcdClient etcdClient,
string clientCertPath, string clientCertPath,

View File

@@ -42,6 +42,20 @@ public static class ServiceHelper
.GetResult(); .GetResult();
}); });
services.AddSingleton<ActionLogService.ActionLogServiceClient>(sp =>
{
var etcdClient = sp.GetRequiredService<IEtcdClient>();
var config = sp.GetRequiredService<IConfiguration>();
var clientCertPath = config["Service:ClientCert"]!;
var clientKeyPath = config["Service:ClientKey"]!;
var clientCertPassword = config["Service:CertPassword"];
return GrpcClientHelper
.CreateActionLogServiceClient(etcdClient, clientCertPath, clientKeyPath, clientCertPassword)
.GetAwaiter()
.GetResult();
});
return services; return services;
} }

View File

@@ -8,8 +8,12 @@ namespace DysonNetwork.Shared.Registry;
public class ServiceRegistry(IEtcdClient etcd, ILogger<ServiceRegistry> logger) public class ServiceRegistry(IEtcdClient etcd, ILogger<ServiceRegistry> logger)
{ {
public async Task RegisterService(string serviceName, string serviceUrl, long leaseTtlSeconds = 60, public async Task RegisterService(
CancellationToken cancellationToken = default) string serviceName,
string serviceUrl,
long leaseTtlSeconds = 60,
CancellationToken cancellationToken = default
)
{ {
var key = $"/services/{serviceName}"; var key = $"/services/{serviceName}";
var leaseResponse = await etcd.LeaseGrantAsync( var leaseResponse = await etcd.LeaseGrantAsync(

View File

@@ -177,6 +177,7 @@
<_ContentIncludedByDefault Remove="Pages\Auth\VerifyFactor.cshtml" /> <_ContentIncludedByDefault Remove="Pages\Auth\VerifyFactor.cshtml" />
<_ContentIncludedByDefault Remove="Pages\Checkpoint\CheckpointPage.cshtml" /> <_ContentIncludedByDefault Remove="Pages\Checkpoint\CheckpointPage.cshtml" />
<_ContentIncludedByDefault Remove="Pages\Spell\MagicSpellPage.cshtml" /> <_ContentIncludedByDefault Remove="Pages\Spell\MagicSpellPage.cshtml" />
<_ContentIncludedByDefault Remove="Keys\Solian.json" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>