Added tags on call for user profile calls, added disabled on syncshell profiles. reworked the calls
This commit is contained in:
@@ -9,6 +9,8 @@ using LightlessSyncShared.Utils;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using SixLabors.ImageSharp;
|
||||||
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace LightlessSyncServer.Hubs;
|
namespace LightlessSyncServer.Hubs;
|
||||||
@@ -764,6 +766,11 @@ public partial class LightlessHub
|
|||||||
return new GroupProfileDto(dto.Group, Description: null, Tags: null, PictureBase64: null, IsNsfw: false, IsDisabled: false);
|
return new GroupProfileDto(dto.Group, Description: null, Tags: null, PictureBase64: null, IsNsfw: false, IsDisabled: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.ProfileDisabled)
|
||||||
|
{
|
||||||
|
return new GroupProfileDto(Group: dto.Group, Description: "This profile was permanently disabled", Tags: [], PictureBase64: null, IsNsfw: false, IsDisabled: true);
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return data.ToDTO();
|
return data.ToDTO();
|
||||||
@@ -792,6 +799,39 @@ public partial class LightlessHub
|
|||||||
cancellationToken)
|
cancellationToken)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(dto.PictureBase64))
|
||||||
|
{
|
||||||
|
byte[] imageData;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
imageData = Convert.FromBase64String(dto.PictureBase64);
|
||||||
|
}
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "The provided image is not a valid Base64 string.").ConfigureAwait(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryStream ms = new(imageData);
|
||||||
|
await using (ms.ConfigureAwait(false))
|
||||||
|
{
|
||||||
|
var format = await Image.DetectFormatAsync(ms, RequestAbortedToken).ConfigureAwait(false);
|
||||||
|
if (!format.FileExtensions.Contains("png", StringComparer.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your provided image file is not in PNG format").ConfigureAwait(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
using var image = Image.Load<Rgba32>(imageData);
|
||||||
|
|
||||||
|
if (image.Width > 512 || image.Height > 512 || (imageData.Length > 2000 * 1024))
|
||||||
|
{
|
||||||
|
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your provided image file is larger than 512x512 or more than 2MiB").ConfigureAwait(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (groupProfileDb == null)
|
if (groupProfileDb == null)
|
||||||
{
|
{
|
||||||
groupProfileDb = new GroupProfile
|
groupProfileDb = new GroupProfile
|
||||||
@@ -800,11 +840,18 @@ public partial class LightlessHub
|
|||||||
ProfileDisabled = false,
|
ProfileDisabled = false,
|
||||||
IsNSFW = dto.IsNsfw ?? false,
|
IsNSFW = dto.IsNsfw ?? false,
|
||||||
};
|
};
|
||||||
|
|
||||||
groupProfileDb.UpdateProfileFromDto(dto);
|
groupProfileDb.UpdateProfileFromDto(dto);
|
||||||
await DbContext.GroupProfiles.AddAsync(groupProfileDb, cancellationToken).ConfigureAwait(false);
|
await DbContext.GroupProfiles.AddAsync(groupProfileDb, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (groupProfileDb?.ProfileDisabled ?? false)
|
||||||
|
{
|
||||||
|
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your profile was permanently disabled and cannot be edited").ConfigureAwait(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
groupProfileDb.UpdateProfileFromDto(dto);
|
groupProfileDb.UpdateProfileFromDto(dto);
|
||||||
|
|
||||||
var userIds = await DbContext.GroupPairs
|
var userIds = await DbContext.GroupPairs
|
||||||
|
|||||||
@@ -826,16 +826,16 @@ public partial class LightlessHub
|
|||||||
|
|
||||||
if (!allUserPairs.Contains(user.User.UID, StringComparer.Ordinal) && !string.Equals(user.User.UID, UserUID, StringComparison.Ordinal))
|
if (!allUserPairs.Contains(user.User.UID, StringComparer.Ordinal) && !string.Equals(user.User.UID, UserUID, StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
return new UserProfileDto(user.User, false, null, null, "Due to the pause status you cannot access this users profile.");
|
return new UserProfileDto(user.User, false, null, null, "Due to the pause status you cannot access this users profile.", []);
|
||||||
}
|
}
|
||||||
|
|
||||||
var data = await DbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == user.User.UID, cancellationToken: RequestAbortedToken).ConfigureAwait(false);
|
var data = await DbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == user.User.UID, cancellationToken: RequestAbortedToken).ConfigureAwait(false);
|
||||||
if (data == null) return new UserProfileDto(user.User, false, null, null, null);
|
if (data == null) return new UserProfileDto(user.User, false, null, null, null, []);
|
||||||
|
|
||||||
if (data.FlaggedForReport) return new UserProfileDto(user.User, true, null, null, "This profile is flagged for report and pending evaluation");
|
if (data.FlaggedForReport) return new UserProfileDto(user.User, true, null, null, "This profile is flagged for report and pending evaluation", []);
|
||||||
if (data.ProfileDisabled) return new UserProfileDto(user.User, true, null, null, "This profile was permanently disabled");
|
if (data.ProfileDisabled) return new UserProfileDto(user.User, true, null, null, "This profile was permanently disabled", []);
|
||||||
|
|
||||||
return new UserProfileDto(user.User, false, data.IsNSFW, data.Base64ProfileImage, data.UserDescription);
|
return new UserProfileDto(user.User, false, data.IsNSFW, data.Base64ProfileImage, data.UserDescription, data.Tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(Policy = "Identified")]
|
[Authorize(Policy = "Identified")]
|
||||||
@@ -913,20 +913,20 @@ public partial class LightlessHub
|
|||||||
|
|
||||||
if (profile == null)
|
if (profile == null)
|
||||||
{
|
{
|
||||||
return new UserProfileDto(userData, false, null, null, null);
|
return new UserProfileDto(userData, false, null, null, null, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (profile.FlaggedForReport)
|
if (profile.FlaggedForReport)
|
||||||
{
|
{
|
||||||
return new UserProfileDto(userData, true, null, null, "This profile is flagged for report and pending evaluation");
|
return new UserProfileDto(userData, true, null, null, "This profile is flagged for report and pending evaluation", []);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (profile.ProfileDisabled)
|
if (profile.ProfileDisabled)
|
||||||
{
|
{
|
||||||
return new UserProfileDto(userData, true, null, null, "This profile was permanently disabled");
|
return new UserProfileDto(userData, true, null, null, "This profile was permanently disabled", []);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new UserProfileDto(userData, false, profile.IsNSFW, profile.Base64ProfileImage, profile.UserDescription);
|
return new UserProfileDto(userData, false, profile.IsNSFW, profile.Base64ProfileImage, profile.UserDescription, profile.Tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(Policy = "Identified")]
|
[Authorize(Policy = "Identified")]
|
||||||
@@ -1126,27 +1126,30 @@ public partial class LightlessHub
|
|||||||
{
|
{
|
||||||
_logger.LogCallInfo(LightlessHubLogger.Args(dto));
|
_logger.LogCallInfo(LightlessHubLogger.Args(dto));
|
||||||
|
|
||||||
|
var cancellationToken = RequestAbortedToken;
|
||||||
|
|
||||||
if (!string.Equals(dto.User.UID, UserUID, StringComparison.Ordinal)) throw new HubException("Cannot modify profile data for anyone but yourself");
|
if (!string.Equals(dto.User.UID, UserUID, StringComparison.Ordinal)) throw new HubException("Cannot modify profile data for anyone but yourself");
|
||||||
|
|
||||||
var existingData = await DbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == dto.User.UID, cancellationToken: RequestAbortedToken).ConfigureAwait(false);
|
var existingData = await DbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == dto.User.UID, cancellationToken: RequestAbortedToken).ConfigureAwait(false);
|
||||||
|
|
||||||
if (existingData?.FlaggedForReport ?? false)
|
//Image Check of size/format
|
||||||
{
|
|
||||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your profile is currently flagged for report and cannot be edited").ConfigureAwait(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (existingData?.ProfileDisabled ?? false)
|
|
||||||
{
|
|
||||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your profile was permanently disabled and cannot be edited").ConfigureAwait(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(dto.ProfilePictureBase64))
|
if (!string.IsNullOrEmpty(dto.ProfilePictureBase64))
|
||||||
{
|
{
|
||||||
byte[] imageData = Convert.FromBase64String(dto.ProfilePictureBase64);
|
byte[] imageData;
|
||||||
using MemoryStream ms = new(imageData);
|
try
|
||||||
var format = await Image.DetectFormatAsync(ms).ConfigureAwait(false);
|
{
|
||||||
|
imageData = Convert.FromBase64String(dto.ProfilePictureBase64);
|
||||||
|
}
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "The provided image is not a valid Base64 string.").ConfigureAwait(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryStream ms = new(imageData);
|
||||||
|
await using (ms.ConfigureAwait(false))
|
||||||
|
{
|
||||||
|
var format = await Image.DetectFormatAsync(ms, RequestAbortedToken).ConfigureAwait(false);
|
||||||
if (!format.FileExtensions.Contains("png", StringComparer.OrdinalIgnoreCase))
|
if (!format.FileExtensions.Contains("png", StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your provided image file is not in PNG format").ConfigureAwait(false);
|
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your provided image file is not in PNG format").ConfigureAwait(false);
|
||||||
@@ -1154,48 +1157,47 @@ public partial class LightlessHub
|
|||||||
}
|
}
|
||||||
using var image = Image.Load<Rgba32>(imageData);
|
using var image = Image.Load<Rgba32>(imageData);
|
||||||
|
|
||||||
if (image.Width > 256 || image.Height > 256 || (imageData.Length > 250 * 1024))
|
if (image.Width > 512 || image.Height > 512 || (imageData.Length > 2000 * 1024))
|
||||||
{
|
{
|
||||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your provided image file is larger than 256x256 or more than 250KiB.").ConfigureAwait(false);
|
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your provided image file is larger than 512x512 or more than 2MiB.").ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (existingData != null)
|
if (existingData != null)
|
||||||
{
|
{
|
||||||
if (string.Equals("", dto.ProfilePictureBase64, StringComparison.OrdinalIgnoreCase))
|
if (existingData.FlaggedForReport)
|
||||||
{
|
{
|
||||||
existingData.Base64ProfileImage = null;
|
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your profile is currently flagged for report and cannot be edited").ConfigureAwait(false);
|
||||||
}
|
return;
|
||||||
else if (dto.ProfilePictureBase64 != null)
|
|
||||||
{
|
|
||||||
existingData.Base64ProfileImage = dto.ProfilePictureBase64;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dto.IsNSFW != null)
|
if (existingData.ProfileDisabled)
|
||||||
{
|
{
|
||||||
existingData.IsNSFW = dto.IsNSFW.Value;
|
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your profile was permanently disabled and cannot be edited").ConfigureAwait(false);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dto.Description != null)
|
existingData.UpdateProfileFromDto(dto);
|
||||||
{
|
|
||||||
existingData.UserDescription = dto.Description;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UserProfileData userProfileData = new()
|
UserProfileData newUserProfileData = new()
|
||||||
{
|
{
|
||||||
UserUID = dto.User.UID,
|
UserUID = dto.User.UID,
|
||||||
Base64ProfileImage = dto.ProfilePictureBase64 ?? null,
|
Base64ProfileImage = dto.ProfilePictureBase64 ?? null,
|
||||||
UserDescription = dto.Description ?? null,
|
UserDescription = dto.Description ?? null,
|
||||||
IsNSFW = dto.IsNSFW ?? false
|
IsNSFW = dto.IsNSFW ?? false,
|
||||||
};
|
};
|
||||||
|
|
||||||
await DbContext.UserProfileData.AddAsync(userProfileData).ConfigureAwait(false);
|
newUserProfileData.UpdateProfileFromDto(dto);
|
||||||
|
|
||||||
|
await DbContext.UserProfileData.AddAsync(newUserProfileData, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
|
||||||
|
await DbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
|
||||||
var allPairedUsers = await GetAllPairedUnpausedUsers().ConfigureAwait(false);
|
var allPairedUsers = await GetAllPairedUnpausedUsers().ConfigureAwait(false);
|
||||||
var pairs = await GetOnlineUsers(allPairedUsers).ConfigureAwait(false);
|
var pairs = await GetOnlineUsers(allPairedUsers).ConfigureAwait(false);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using LightlessSync.API.Data.Enum;
|
using LightlessSync.API.Data.Enum;
|
||||||
using LightlessSync.API.Data.Extensions;
|
using LightlessSync.API.Data.Extensions;
|
||||||
using LightlessSync.API.Dto.Group;
|
using LightlessSync.API.Dto.Group;
|
||||||
|
using LightlessSync.API.Dto.User;
|
||||||
using LightlessSyncShared.Models;
|
using LightlessSyncShared.Models;
|
||||||
using static LightlessSyncServer.Hubs.LightlessHub;
|
using static LightlessSyncServer.Hubs.LightlessHub;
|
||||||
|
|
||||||
@@ -19,6 +20,16 @@ public static class Extensions
|
|||||||
if (dto.IsNsfw.HasValue) profile.IsNSFW = dto.IsNsfw.Value;
|
if (dto.IsNsfw.HasValue) profile.IsNSFW = dto.IsNsfw.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void UpdateProfileFromDto(this UserProfileData profile, UserProfileDto dto)
|
||||||
|
{
|
||||||
|
if (profile == null || dto == null) return;
|
||||||
|
|
||||||
|
profile.Base64ProfileImage = string.IsNullOrWhiteSpace(dto.ProfilePictureBase64) ? null : dto.ProfilePictureBase64;
|
||||||
|
if (dto.Tags != null) profile.Tags = dto.Tags;
|
||||||
|
if (dto.Description != null) profile.UserDescription = dto.Description;
|
||||||
|
if (dto.IsNSFW.HasValue) profile.IsNSFW = dto.IsNSFW.Value;
|
||||||
|
}
|
||||||
|
|
||||||
public static GroupProfileDto ToDTO(this GroupProfile groupProfile)
|
public static GroupProfileDto ToDTO(this GroupProfile groupProfile)
|
||||||
{
|
{
|
||||||
if (groupProfile == null)
|
if (groupProfile == null)
|
||||||
@@ -38,6 +49,25 @@ public static class Extensions
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static UserProfileDto ToDTO(this UserProfileData userProfileData)
|
||||||
|
{
|
||||||
|
if (userProfileData == null)
|
||||||
|
{
|
||||||
|
return new UserProfileDto(User: null, Disabled: false, IsNSFW: null, ProfilePictureBase64: null, Description: null, Tags: []);
|
||||||
|
}
|
||||||
|
|
||||||
|
var userData = userProfileData.User?.ToUserData();
|
||||||
|
|
||||||
|
return new UserProfileDto(
|
||||||
|
userData,
|
||||||
|
userProfileData.ProfileDisabled,
|
||||||
|
userProfileData.IsNSFW,
|
||||||
|
userProfileData.Base64ProfileImage,
|
||||||
|
userProfileData.UserDescription,
|
||||||
|
userProfileData.Tags
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static GroupData ToGroupData(this Group group)
|
public static GroupData ToGroupData(this Group group)
|
||||||
{
|
{
|
||||||
if (group == null)
|
if (group == null)
|
||||||
|
|||||||
Reference in New Issue
Block a user