[backend/core] Improve user deletes (ISH-222)
This commit is contained in:
parent
3ef83a1cd3
commit
806bfca099
2 changed files with 57 additions and 20 deletions
|
@ -39,6 +39,9 @@ public class BackgroundTaskQueue()
|
||||||
case FilterExpiryJobData filterExpiryJob:
|
case FilterExpiryJobData filterExpiryJob:
|
||||||
await ProcessFilterExpiry(filterExpiryJob, scope, token);
|
await ProcessFilterExpiry(filterExpiryJob, scope, token);
|
||||||
break;
|
break;
|
||||||
|
case UserDeleteJobData userDeleteJob:
|
||||||
|
await ProcessUserDelete(userDeleteJob, scope, token);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,12 +216,59 @@ public class BackgroundTaskQueue()
|
||||||
db.Remove(filter);
|
db.Remove(filter);
|
||||||
await db.SaveChangesAsync(token);
|
await db.SaveChangesAsync(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task ProcessUserDelete(
|
||||||
|
UserDeleteJobData jobData,
|
||||||
|
IServiceProvider scope,
|
||||||
|
CancellationToken token
|
||||||
|
)
|
||||||
|
{
|
||||||
|
var db = scope.GetRequiredService<DatabaseContext>();
|
||||||
|
var queue = scope.GetRequiredService<QueueService>();
|
||||||
|
var logger = scope.GetRequiredService<ILogger<BackgroundTaskQueue>>();
|
||||||
|
var followupTaskSvc = scope.GetRequiredService<FollowupTaskService>();
|
||||||
|
|
||||||
|
logger.LogDebug("Processing delete for user {id}", jobData.UserId);
|
||||||
|
|
||||||
|
var user = await db.Users.FirstOrDefaultAsync(p => p.Id == jobData.UserId, token);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
logger.LogDebug("Failed to delete user {id}: id not found in database", jobData.UserId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileIds = await db.DriveFiles.Where(p => p.User == user).Select(p => p.Id).ToListAsync(token);
|
||||||
|
logger.LogDebug("Removing {count} files for user {id}", fileIds.Count, user.Id);
|
||||||
|
foreach (var id in fileIds)
|
||||||
|
{
|
||||||
|
await queue.BackgroundTaskQueue.EnqueueAsync(new DriveFileDeleteJobData
|
||||||
|
{
|
||||||
|
DriveFileId = id, Expire = false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
db.Remove(user);
|
||||||
|
await db.SaveChangesAsync(token);
|
||||||
|
|
||||||
|
await followupTaskSvc.ExecuteTask("UpdateInstanceUserCounter", async provider =>
|
||||||
|
{
|
||||||
|
var bgDb = provider.GetRequiredService<DatabaseContext>();
|
||||||
|
var bgInstanceSvc = provider.GetRequiredService<InstanceService>();
|
||||||
|
var dbInstance = await bgInstanceSvc.GetUpdatedInstanceMetadataAsync(user);
|
||||||
|
await bgDb.Instances.Where(p => p.Id == dbInstance.Id)
|
||||||
|
.ExecuteUpdateAsync(p => p.SetProperty(i => i.UsersCount, i => i.UsersCount - 1),
|
||||||
|
cancellationToken: token);
|
||||||
|
});
|
||||||
|
|
||||||
|
logger.LogDebug("User {id} deleted successfully", jobData.UserId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonDerivedType(typeof(DriveFileDeleteJobData), "driveFileDelete")]
|
[JsonDerivedType(typeof(DriveFileDeleteJobData), "driveFileDelete")]
|
||||||
[JsonDerivedType(typeof(PollExpiryJobData), "pollExpiry")]
|
[JsonDerivedType(typeof(PollExpiryJobData), "pollExpiry")]
|
||||||
[JsonDerivedType(typeof(MuteExpiryJobData), "muteExpiry")]
|
[JsonDerivedType(typeof(MuteExpiryJobData), "muteExpiry")]
|
||||||
[JsonDerivedType(typeof(FilterExpiryJobData), "filterExpiry")]
|
[JsonDerivedType(typeof(FilterExpiryJobData), "filterExpiry")]
|
||||||
|
[JsonDerivedType(typeof(UserDeleteJobData), "userDelete")]
|
||||||
public abstract class BackgroundTaskJobData;
|
public abstract class BackgroundTaskJobData;
|
||||||
|
|
||||||
public class DriveFileDeleteJobData : BackgroundTaskJobData
|
public class DriveFileDeleteJobData : BackgroundTaskJobData
|
||||||
|
@ -240,4 +290,9 @@ public class MuteExpiryJobData : BackgroundTaskJobData
|
||||||
public class FilterExpiryJobData : BackgroundTaskJobData
|
public class FilterExpiryJobData : BackgroundTaskJobData
|
||||||
{
|
{
|
||||||
[JR] [J("filterId")] public required long FilterId { get; set; }
|
[JR] [J("filterId")] public required long FilterId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UserDeleteJobData : BackgroundTaskJobData
|
||||||
|
{
|
||||||
|
[JR] [J("userId")] public required string UserId { get; set; }
|
||||||
}
|
}
|
|
@ -459,10 +459,7 @@ public class UserService(
|
||||||
|
|
||||||
public async Task DeleteUserAsync(ASActor actor)
|
public async Task DeleteUserAsync(ASActor actor)
|
||||||
{
|
{
|
||||||
var user = await db.Users
|
var user = await db.Users.FirstOrDefaultAsync(p => p.Uri == actor.Id && p.Host != null);
|
||||||
.Include(user => user.Avatar)
|
|
||||||
.Include(user => user.Banner)
|
|
||||||
.FirstOrDefaultAsync(p => p.Uri == actor.Id && p.Host != null);
|
|
||||||
|
|
||||||
if (user == null)
|
if (user == null)
|
||||||
{
|
{
|
||||||
|
@ -470,22 +467,7 @@ public class UserService(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
db.Remove(user);
|
await queueSvc.BackgroundTaskQueue.EnqueueAsync(new UserDeleteJobData { UserId = user.Id });
|
||||||
await db.SaveChangesAsync();
|
|
||||||
|
|
||||||
_ = followupTaskSvc.ExecuteTask("UpdateInstanceUserCounter", async provider =>
|
|
||||||
{
|
|
||||||
var bgDb = provider.GetRequiredService<DatabaseContext>();
|
|
||||||
var bgInstanceSvc = provider.GetRequiredService<InstanceService>();
|
|
||||||
var dbInstance = await bgInstanceSvc.GetUpdatedInstanceMetadataAsync(user);
|
|
||||||
await bgDb.Instances.Where(p => p.Id == dbInstance.Id)
|
|
||||||
.ExecuteUpdateAsync(p => p.SetProperty(i => i.UsersCount, i => i.UsersCount - 1));
|
|
||||||
});
|
|
||||||
|
|
||||||
if (user.Avatar != null)
|
|
||||||
await driveSvc.RemoveFile(user.Avatar);
|
|
||||||
if (user.Banner != null)
|
|
||||||
await driveSvc.RemoveFile(user.Banner);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateOauthTokenMetadata(OauthToken token)
|
public void UpdateOauthTokenMetadata(OauthToken token)
|
||||||
|
|
Loading…
Add table
Reference in a new issue