♻️ Refind bot account
This commit is contained in:
@@ -51,7 +51,8 @@ public class Account : ModelBase
|
||||
Profile = Profile.ToProtoValue(),
|
||||
PerkSubscription = PerkSubscription?.ToProtoValue(),
|
||||
CreatedAt = CreatedAt.ToTimestamp(),
|
||||
UpdatedAt = UpdatedAt.ToTimestamp()
|
||||
UpdatedAt = UpdatedAt.ToTimestamp(),
|
||||
AutomatedId = AutomatedId?.ToString()
|
||||
};
|
||||
|
||||
// Add contacts
|
||||
@@ -81,6 +82,7 @@ public class Account : ModelBase
|
||||
: null,
|
||||
CreatedAt = proto.CreatedAt.ToInstant(),
|
||||
UpdatedAt = proto.UpdatedAt.ToInstant(),
|
||||
AutomatedId = proto.AutomatedId is not null ? Guid.Parse(proto.AutomatedId) : null
|
||||
};
|
||||
|
||||
account.Profile = AccountProfile.FromProtoValue(proto.Profile);
|
||||
@@ -119,7 +121,7 @@ public abstract class Leveling
|
||||
|
||||
public class AccountProfile : ModelBase, IIdentifiedResource
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
[MaxLength(256)] public string? FirstName { get; set; }
|
||||
[MaxLength(256)] public string? MiddleName { get; set; }
|
||||
[MaxLength(256)] public string? LastName { get; set; }
|
||||
|
@@ -30,6 +30,7 @@ public class AccountCurrentController(
|
||||
{
|
||||
[HttpGet]
|
||||
[ProducesResponseType<Account>(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType<ApiError>(StatusCodes.Status401Unauthorized)]
|
||||
public async Task<ActionResult<Account>> GetCurrentIdentity()
|
||||
{
|
||||
if (HttpContext.Items["CurrentUser"] is not Account currentUser) return Unauthorized();
|
||||
|
@@ -6,6 +6,7 @@ using DysonNetwork.Pass.Email;
|
||||
using DysonNetwork.Pass.Localization;
|
||||
using DysonNetwork.Pass.Permission;
|
||||
using DysonNetwork.Shared.Cache;
|
||||
using DysonNetwork.Shared.Data;
|
||||
using DysonNetwork.Shared.Proto;
|
||||
using DysonNetwork.Shared.Stream;
|
||||
using EFCore.BulkExtensions;
|
||||
@@ -21,6 +22,8 @@ namespace DysonNetwork.Pass.Account;
|
||||
public class AccountService(
|
||||
AppDatabase db,
|
||||
MagicSpellService spells,
|
||||
FileService.FileServiceClient files,
|
||||
FileReferenceService.FileReferenceServiceClient fileRefs,
|
||||
AccountUsernameService uname,
|
||||
EmailService mailer,
|
||||
PusherService.PusherServiceClient pusher,
|
||||
@@ -182,7 +185,7 @@ public class AccountService(
|
||||
);
|
||||
}
|
||||
|
||||
public async Task<Account> CreateBotAccount(Account account, Guid automatedId)
|
||||
public async Task<Account> CreateBotAccount(Account account, Guid automatedId, string? pictureId, string? backgroundId)
|
||||
{
|
||||
var dupeAutomateCount = await db.Accounts.Where(a => a.AutomatedId == automatedId).CountAsync();
|
||||
if (dupeAutomateCount > 0)
|
||||
@@ -195,8 +198,38 @@ public class AccountService(
|
||||
account.AutomatedId = automatedId;
|
||||
account.ActivatedAt = SystemClock.Instance.GetCurrentInstant();
|
||||
account.IsSuperuser = false;
|
||||
|
||||
if (!string.IsNullOrEmpty(pictureId))
|
||||
{
|
||||
var file = await files.GetFileAsync(new GetFileRequest { Id = pictureId });
|
||||
await fileRefs.CreateReferenceAsync(
|
||||
new CreateReferenceRequest
|
||||
{
|
||||
ResourceId = account.Profile.ResourceIdentifier,
|
||||
FileId = pictureId,
|
||||
Usage = "profile.picture"
|
||||
}
|
||||
);
|
||||
account.Profile.Picture = CloudFileReferenceObject.FromProtoValue(file);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(backgroundId))
|
||||
{
|
||||
var file = await files.GetFileAsync(new GetFileRequest { Id = backgroundId });
|
||||
await fileRefs.CreateReferenceAsync(
|
||||
new CreateReferenceRequest
|
||||
{
|
||||
ResourceId = account.Profile.ResourceIdentifier,
|
||||
FileId = backgroundId,
|
||||
Usage = "profile.background"
|
||||
}
|
||||
);
|
||||
account.Profile.Background = CloudFileReferenceObject.FromProtoValue(file);
|
||||
}
|
||||
|
||||
db.Accounts.Add(account);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
return account;
|
||||
}
|
||||
|
||||
|
@@ -42,6 +42,26 @@ public class AccountServiceGrpc(
|
||||
return account.ToProtoValue();
|
||||
}
|
||||
|
||||
public override async Task<Shared.Proto.Account> GetBotAccount(GetBotAccountRequest request,
|
||||
ServerCallContext context)
|
||||
{
|
||||
if (!Guid.TryParse(request.AutomatedId, out var automatedId))
|
||||
throw new RpcException(new Grpc.Core.Status(StatusCode.InvalidArgument, "Invalid automated ID format"));
|
||||
|
||||
var account = await _db.Accounts
|
||||
.AsNoTracking()
|
||||
.Include(a => a.Profile)
|
||||
.FirstOrDefaultAsync(a => a.AutomatedId == automatedId);
|
||||
|
||||
if (account == null)
|
||||
throw new RpcException(new Grpc.Core.Status(StatusCode.NotFound, $"Account with automated ID {request.AutomatedId} not found"));
|
||||
|
||||
var perk = await subscriptions.GetPerkSubscriptionAsync(account.Id);
|
||||
account.PerkSubscription = perk?.ToReference();
|
||||
|
||||
return account.ToProtoValue();
|
||||
}
|
||||
|
||||
public override async Task<GetAccountBatchResponse> GetAccountBatch(GetAccountBatchRequest request,
|
||||
ServerCallContext context)
|
||||
{
|
||||
@@ -56,7 +76,35 @@ public class AccountServiceGrpc(
|
||||
.Where(a => accountIds.Contains(a.Id))
|
||||
.Include(a => a.Profile)
|
||||
.ToListAsync();
|
||||
|
||||
|
||||
var perks = await subscriptions.GetPerkSubscriptionsAsync(
|
||||
accounts.Select(x => x.Id).ToList()
|
||||
);
|
||||
foreach (var account in accounts)
|
||||
if (perks.TryGetValue(account.Id, out var perk))
|
||||
account.PerkSubscription = perk?.ToReference();
|
||||
|
||||
var response = new GetAccountBatchResponse();
|
||||
response.Accounts.AddRange(accounts.Select(a => a.ToProtoValue()));
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
public override async Task<GetAccountBatchResponse> GetBotAccountBatch(GetBotAccountBatchRequest request,
|
||||
ServerCallContext context)
|
||||
{
|
||||
var automatedIds = request.AutomatedId
|
||||
.Select(id => Guid.TryParse(id, out var automatedId) ? automatedId : (Guid?)null)
|
||||
.Where(id => id.HasValue)
|
||||
.Select(id => id!.Value)
|
||||
.ToList();
|
||||
|
||||
var accounts = await _db.Accounts
|
||||
.AsNoTracking()
|
||||
.Where(a => a.AutomatedId != null && automatedIds.Contains(a.AutomatedId.Value))
|
||||
.Include(a => a.Profile)
|
||||
.ToListAsync();
|
||||
|
||||
var perks = await subscriptions.GetPerkSubscriptionsAsync(
|
||||
accounts.Select(x => x.Id).ToList()
|
||||
);
|
||||
@@ -76,7 +124,8 @@ public class AccountServiceGrpc(
|
||||
return status.ToProtoValue();
|
||||
}
|
||||
|
||||
public override async Task<GetAccountStatusBatchResponse> GetAccountStatusBatch(GetAccountBatchRequest request, ServerCallContext context)
|
||||
public override async Task<GetAccountStatusBatchResponse> GetAccountStatusBatch(GetAccountBatchRequest request,
|
||||
ServerCallContext context)
|
||||
{
|
||||
var accountIds = request.Id
|
||||
.Select(id => Guid.TryParse(id, out var accountId) ? accountId : (Guid?)null)
|
||||
@@ -98,14 +147,14 @@ public class AccountServiceGrpc(
|
||||
.Where(a => accountNames.Contains(a.Name))
|
||||
.Include(a => a.Profile)
|
||||
.ToListAsync();
|
||||
|
||||
|
||||
var perks = await subscriptions.GetPerkSubscriptionsAsync(
|
||||
accounts.Select(x => x.Id).ToList()
|
||||
);
|
||||
foreach (var account in accounts)
|
||||
if (perks.TryGetValue(account.Id, out var perk))
|
||||
account.PerkSubscription = perk?.ToReference();
|
||||
|
||||
|
||||
var response = new GetAccountBatchResponse();
|
||||
response.Accounts.AddRange(accounts.Select(a => a.ToProtoValue()));
|
||||
return response;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
using DysonNetwork.Shared.Data;
|
||||
using DysonNetwork.Shared.Proto;
|
||||
using Grpc.Core;
|
||||
using NodaTime;
|
||||
@@ -5,7 +6,12 @@ using NodaTime.Serialization.Protobuf;
|
||||
|
||||
namespace DysonNetwork.Pass.Account;
|
||||
|
||||
public class BotAccountReceiverGrpc(AppDatabase db, AccountService accounts)
|
||||
public class BotAccountReceiverGrpc(
|
||||
AppDatabase db,
|
||||
AccountService accounts,
|
||||
FileService.FileServiceClient files,
|
||||
FileReferenceService.FileReferenceServiceClient fileRefs
|
||||
)
|
||||
: BotAccountReceiverService.BotAccountReceiverServiceBase
|
||||
{
|
||||
public override async Task<CreateBotAccountResponse> CreateBotAccount(
|
||||
@@ -14,7 +20,12 @@ public class BotAccountReceiverGrpc(AppDatabase db, AccountService accounts)
|
||||
)
|
||||
{
|
||||
var account = Account.FromProtoValue(request.Account);
|
||||
account = await accounts.CreateBotAccount(account, Guid.Parse(request.AutomatedId));
|
||||
account = await accounts.CreateBotAccount(
|
||||
account,
|
||||
Guid.Parse(request.AutomatedId),
|
||||
request.PictureId,
|
||||
request.BackgroundId
|
||||
);
|
||||
|
||||
return new CreateBotAccountResponse
|
||||
{
|
||||
@@ -34,16 +45,44 @@ public class BotAccountReceiverGrpc(AppDatabase db, AccountService accounts)
|
||||
ServerCallContext context
|
||||
)
|
||||
{
|
||||
var automatedId = Guid.Parse(request.AutomatedId);
|
||||
var account = await accounts.GetBotAccount(automatedId);
|
||||
if (account is null)
|
||||
throw new RpcException(new Grpc.Core.Status(StatusCode.NotFound, "Account not found"));
|
||||
var account = Account.FromProtoValue(request.Account);
|
||||
|
||||
if (request.PictureId is not null)
|
||||
{
|
||||
var file = await files.GetFileAsync(new GetFileRequest { Id = request.PictureId });
|
||||
if (account.Profile.Picture is not null)
|
||||
await fileRefs.DeleteResourceReferencesAsync(
|
||||
new DeleteResourceReferencesRequest { ResourceId = account.Profile.ResourceIdentifier }
|
||||
);
|
||||
await fileRefs.CreateReferenceAsync(
|
||||
new CreateReferenceRequest
|
||||
{
|
||||
ResourceId = account.Profile.ResourceIdentifier,
|
||||
FileId = request.PictureId,
|
||||
Usage = "profile.picture"
|
||||
}
|
||||
);
|
||||
account.Profile.Picture = CloudFileReferenceObject.FromProtoValue(file);
|
||||
}
|
||||
|
||||
if (request.BackgroundId is not null)
|
||||
{
|
||||
var file = await files.GetFileAsync(new GetFileRequest { Id = request.BackgroundId });
|
||||
if (account.Profile.Background is not null)
|
||||
await fileRefs.DeleteResourceReferencesAsync(
|
||||
new DeleteResourceReferencesRequest { ResourceId = account.Profile.ResourceIdentifier }
|
||||
);
|
||||
await fileRefs.CreateReferenceAsync(
|
||||
new CreateReferenceRequest
|
||||
{
|
||||
ResourceId = account.Profile.ResourceIdentifier,
|
||||
FileId = request.BackgroundId,
|
||||
Usage = "profile.background"
|
||||
}
|
||||
);
|
||||
account.Profile.Background = CloudFileReferenceObject.FromProtoValue(file);
|
||||
}
|
||||
|
||||
account.Name = request.Account.Name;
|
||||
account.Nick = request.Account.Nick;
|
||||
account.Profile = AccountProfile.FromProtoValue(request.Account.Profile);
|
||||
account.Language = request.Account.Language;
|
||||
|
||||
db.Accounts.Update(account);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
@@ -56,7 +95,7 @@ public class BotAccountReceiverGrpc(AppDatabase db, AccountService accounts)
|
||||
CreatedAt = account.CreatedAt.ToTimestamp(),
|
||||
UpdatedAt = account.UpdatedAt.ToTimestamp(),
|
||||
IsActive = true
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -69,9 +108,9 @@ public class BotAccountReceiverGrpc(AppDatabase db, AccountService accounts)
|
||||
var account = await accounts.GetBotAccount(automatedId);
|
||||
if (account is null)
|
||||
throw new RpcException(new Grpc.Core.Status(StatusCode.NotFound, "Account not found"));
|
||||
|
||||
|
||||
await accounts.DeleteAccount(account);
|
||||
|
||||
|
||||
return new DeleteBotAccountResponse();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user