From 6a8a2e22a8272d2e3f1262eecd0a20909d9e17e4 Mon Sep 17 00:00:00 2001 From: cake Date: Sun, 4 Jan 2026 05:07:20 +0100 Subject: [PATCH] Changed group ban so it works differently. --- .../Hubs/LightlessHub.Groups.cs | 222 +++++++++++------- 1 file changed, 133 insertions(+), 89 deletions(-) diff --git a/LightlessSyncServer/LightlessSyncServer/Hubs/LightlessHub.Groups.cs b/LightlessSyncServer/LightlessSyncServer/Hubs/LightlessHub.Groups.cs index e5d63df..a9a0377 100644 --- a/LightlessSyncServer/LightlessSyncServer/Hubs/LightlessHub.Groups.cs +++ b/LightlessSyncServer/LightlessSyncServer/Hubs/LightlessHub.Groups.cs @@ -28,25 +28,69 @@ public partial class LightlessHub var (userHasRights, group) = await TryValidateGroupModeratorOrOwner(dto.Group.GID).ConfigureAwait(false); if (!userHasRights) return; - var (userExists, groupPair) = await TryValidateUserInGroup(dto.Group.GID, dto.User.UID).ConfigureAwait(false); - if (!userExists) return; + var targetUid = dto.User.UID?.Trim(); + if (string.IsNullOrWhiteSpace(targetUid)) return; - if (groupPair.IsModerator || string.Equals(group.OwnerUID, dto.User.UID, StringComparison.Ordinal)) return; + if (string.Equals(group.OwnerUID, targetUid, StringComparison.Ordinal)) + return; - var alias = string.IsNullOrEmpty(groupPair.GroupUser.Alias) ? "-" : groupPair.GroupUser.Alias; - var ban = new GroupBan() + var groupPair = await DbContext.GroupPairs + .Include(p => p.GroupUser) + .SingleOrDefaultAsync(p => p.GroupGID == dto.Group.GID && p.GroupUserUID == targetUid, cancellationToken: RequestAbortedToken).ConfigureAwait(false); + + if (groupPair?.IsModerator == true) + return; + + var now = DateTime.UtcNow; + + var existingBan = await DbContext.Set() + .SingleOrDefaultAsync(b => b.GroupGID == dto.Group.GID && b.BannedUserUID == targetUid, cancellationToken: RequestAbortedToken).ConfigureAwait(false); + + const string marker = " (Alias at time of ban:"; + string suffix; + + if (existingBan?.BannedReason is { } existingReason) { - BannedByUID = UserUID, - BannedReason = $"{reason} (Alias at time of ban: {alias})", - BannedOn = DateTime.UtcNow, - BannedUserUID = dto.User.UID, - GroupGID = dto.Group.GID, - }; + var idx = existingReason.IndexOf(marker, StringComparison.Ordinal); + suffix = idx >= 0 ? existingReason.Substring(startIndex: idx) : string.Empty; + } + else + { + var alias = groupPair?.GroupUser?.Alias; + alias = string.IsNullOrWhiteSpace(alias) ? "-" : alias; + suffix = $" (Alias at time of ban: {alias})"; + } - DbContext.Add(ban); - await DbContext.SaveChangesAsync().ConfigureAwait(false); + var baseReason = (reason ?? string.Empty).Trim(); + var finalReason = string.IsNullOrEmpty(suffix) ? baseReason : (baseReason + suffix); - await GroupRemoveUser(dto).ConfigureAwait(false); + if (existingBan != null) + { + existingBan.BannedByUID = UserUID; + existingBan.BannedReason = finalReason; + + DbContext.Update(existingBan); + } + else + { + var ban = new GroupBan + { + BannedByUID = UserUID, + BannedReason = finalReason, + BannedOn = now, + BannedUserUID = targetUid, + GroupGID = dto.Group.GID, + }; + + DbContext.Add(ban); + } + + await DbContext.SaveChangesAsync(RequestAbortedToken).ConfigureAwait(false); + + if (groupPair != null) + { + await GroupRemoveUser(dto).ConfigureAwait(false); + } _logger.LogCallInfo(LightlessHubLogger.Args(dto, "Success")); } @@ -326,7 +370,7 @@ public partial class LightlessHub await Clients.User(UserUID).Client_GroupSendFullInfo(new GroupFullInfoDto(newGroup.ToGroupData(), self.ToUserData(), newGroup.ToEnum(), initialPrefPermissions.ToEnum(), initialPair.ToEnum(), new(StringComparer.Ordinal), 1)) .ConfigureAwait(false); - + _logger.LogCallInfo(LightlessHubLogger.Args(gid)); return new GroupJoinDto(newGroup.ToGroupData(), passwd, initialPrefPermissions.ToEnum()); @@ -831,7 +875,7 @@ public partial class LightlessHub } var data = await DbContext.GroupProfiles - .Include(gp => gp.Group) + .Include(gp => gp.Group) .FirstOrDefaultAsync( g => g.Group.GID == dto.Group.GID || g.Group.Alias == dto.Group.AliasOrGID, cancellationToken @@ -862,85 +906,85 @@ public partial class LightlessHub [Authorize(Policy = "Identified")] public async Task GroupSetProfile(GroupProfileDto dto) { - _logger.LogCallInfo(LightlessHubLogger.Args(dto)); + _logger.LogCallInfo(LightlessHubLogger.Args(dto)); - var cancellationToken = RequestAbortedToken; + var cancellationToken = RequestAbortedToken; - if (dto.Group == null) return; + if (dto.Group == null) return; - var (hasRights, group) = await TryValidateGroupModeratorOrOwner(dto.Group.GID).ConfigureAwait(false); - if (!hasRights) return; + var (hasRights, group) = await TryValidateGroupModeratorOrOwner(dto.Group.GID).ConfigureAwait(false); + if (!hasRights) return; - var groupProfileDb = await DbContext.GroupProfiles - .Include(g => g.Group) - .FirstOrDefaultAsync(g => g.GroupGID == dto.Group.GID, cancellationToken) + var groupProfileDb = await DbContext.GroupProfiles + .Include(g => g.Group) + .FirstOrDefaultAsync(g => g.GroupGID == dto.Group.GID, cancellationToken) + .ConfigureAwait(false); + + ImageCheckService.ImageLoadResult profileResult = new(); + ImageCheckService.ImageLoadResult bannerResult = new(); + + //Avatar image validation + if (!string.IsNullOrEmpty(dto.PictureBase64)) + { + profileResult = await ImageCheckService.ValidateImageAsync(dto.PictureBase64, banner: false, RequestAbortedToken).ConfigureAwait(false); + + if (!profileResult.Success) + { + await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, profileResult.ErrorMessage).ConfigureAwait(false); + return; + } + } + + //Banner image validation + if (!string.IsNullOrEmpty(dto.BannerBase64)) + { + bannerResult = await ImageCheckService.ValidateImageAsync(dto.BannerBase64, banner: true, RequestAbortedToken).ConfigureAwait(false); + + if (!bannerResult.Success) + { + await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, bannerResult.ErrorMessage).ConfigureAwait(false); + return; + } + } + + var sanitizedProfileImage = profileResult?.Base64Image; + var sanitizedBannerImage = bannerResult?.Base64Image; + + if (groupProfileDb == null) + { + groupProfileDb = new GroupProfile + { + GroupGID = dto.Group.GID, + Group = group, + ProfileDisabled = dto.IsDisabled ?? false, + IsNSFW = dto.IsNsfw ?? false, + + }; + + groupProfileDb.UpdateProfileFromDto(dto, sanitizedProfileImage, sanitizedBannerImage); + await DbContext.GroupProfiles.AddAsync(groupProfileDb, cancellationToken).ConfigureAwait(false); + } + else + { + groupProfileDb.Group ??= group; + + groupProfileDb.UpdateProfileFromDto(dto, sanitizedProfileImage, sanitizedBannerImage); + } + + var userIds = await DbContext.GroupPairs + .Where(p => p.GroupGID == groupProfileDb.GroupGID) + .Select(p => p.GroupUserUID) + .ToListAsync(cancellationToken) + .ConfigureAwait(false); + + if (userIds.Count > 0) + { + var profileDto = groupProfileDb.ToDTO(); + await Clients.Users(userIds).Client_GroupSendProfile(profileDto) .ConfigureAwait(false); + } - ImageCheckService.ImageLoadResult profileResult = new(); - ImageCheckService.ImageLoadResult bannerResult = new(); - - //Avatar image validation - if (!string.IsNullOrEmpty(dto.PictureBase64)) - { - profileResult = await ImageCheckService.ValidateImageAsync(dto.PictureBase64, banner: false, RequestAbortedToken).ConfigureAwait(false); - - if (!profileResult.Success) - { - await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, profileResult.ErrorMessage).ConfigureAwait(false); - return; - } - } - - //Banner image validation - if (!string.IsNullOrEmpty(dto.BannerBase64)) - { - bannerResult = await ImageCheckService.ValidateImageAsync(dto.BannerBase64, banner: true, RequestAbortedToken).ConfigureAwait(false); - - if (!bannerResult.Success) - { - await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, bannerResult.ErrorMessage).ConfigureAwait(false); - return; - } - } - - var sanitizedProfileImage = profileResult?.Base64Image; - var sanitizedBannerImage = bannerResult?.Base64Image; - - if (groupProfileDb == null) - { - groupProfileDb = new GroupProfile - { - GroupGID = dto.Group.GID, - Group = group, - ProfileDisabled = dto.IsDisabled ?? false, - IsNSFW = dto.IsNsfw ?? false, - - }; - - groupProfileDb.UpdateProfileFromDto(dto, sanitizedProfileImage, sanitizedBannerImage); - await DbContext.GroupProfiles.AddAsync(groupProfileDb, cancellationToken).ConfigureAwait(false); - } - else - { - groupProfileDb.Group ??= group; - - groupProfileDb.UpdateProfileFromDto(dto, sanitizedProfileImage, sanitizedBannerImage); - } - - var userIds = await DbContext.GroupPairs - .Where(p => p.GroupGID == groupProfileDb.GroupGID) - .Select(p => p.GroupUserUID) - .ToListAsync(cancellationToken) - .ConfigureAwait(false); - - if (userIds.Count > 0) - { - var profileDto = groupProfileDb.ToDTO(); - await Clients.Users(userIds).Client_GroupSendProfile(profileDto) - .ConfigureAwait(false); - } - - await DbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false); + await DbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false); } [Authorize(Policy = "Identified")]