Mare 0.9 (#27)
* add jwt expiry * update api * merge * start rework permissions * ok so in theory this compiles * make it work I guess * reuse some permissions * fix intermediate connectivity issues * fixes * whatever * some fixes I guess * fix some stuff * idk some random fixes I guess * change some defaults * update nuget * adjust order of operations * adjust deletion of account * remove todo --------- Co-authored-by: rootdarkarchon <root.darkarchon@outlook.com>
This commit is contained in:
@@ -7,9 +7,11 @@
|
|||||||
"Default": "Warning",
|
"Default": "Warning",
|
||||||
"Microsoft": "Warning",
|
"Microsoft": "Warning",
|
||||||
"Microsoft.Hosting.Lifetime": "Information",
|
"Microsoft.Hosting.Lifetime": "Information",
|
||||||
"MareSynchronosServer": "Information",
|
"Microsoft.EntityFramework": "Warning",
|
||||||
"MareSynchronosShared": "Information",
|
"MareSynchronosServer": "Debug",
|
||||||
"System.IO": "Information"
|
"MareSynchronosShared": "Debug",
|
||||||
|
"System.IO": "Information",
|
||||||
|
"MareSynchronosServer.Services.SystemInfoService": "Warning"
|
||||||
},
|
},
|
||||||
"File": {
|
"File": {
|
||||||
"BasePath": "logs",
|
"BasePath": "logs",
|
||||||
@@ -37,8 +39,8 @@
|
|||||||
],
|
],
|
||||||
"RedisConnectionString": "redis,password=secretredispassword",
|
"RedisConnectionString": "redis,password=secretredispassword",
|
||||||
"CdnFullUrl": "http://localhost:6200",
|
"CdnFullUrl": "http://localhost:6200",
|
||||||
"MaxExistingGroupsByUser": 3,
|
"MaxExistingGroupsByUser": 6,
|
||||||
"MaxJoinedGroupsByUser": 6,
|
"MaxJoinedGroupsByUser": 10,
|
||||||
"MaxGroupUserCount": 100,
|
"MaxGroupUserCount": 100,
|
||||||
"PurgeUnusedAccounts": false,
|
"PurgeUnusedAccounts": false,
|
||||||
"PurgeUnusedAccountsPeriodInDays": 14,
|
"PurgeUnusedAccountsPeriodInDays": 14,
|
||||||
|
|||||||
2
MareAPI
2
MareAPI
Submodule MareAPI updated: 820a432ad9...3c0f1e6eba
@@ -1,3 +1,3 @@
|
|||||||
namespace MareSynchronosServer.Authentication;
|
namespace MareSynchronosServer.Authentication;
|
||||||
|
|
||||||
public record SecretKeyAuthReply(bool Success, string Uid, bool TempBan, bool Permaban);
|
public record SecretKeyAuthReply(bool Success, string Uid, string PrimaryUid, bool TempBan, bool Permaban);
|
||||||
|
|||||||
@@ -50,24 +50,34 @@ public class SecretKeyAuthenticatorService
|
|||||||
_failedAuthorizations.Remove(ip, out _);
|
_failedAuthorizations.Remove(ip, out _);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return new(Success: false, Uid: null, TempBan: true, Permaban: false);
|
return new(Success: false, Uid: null, PrimaryUid: null, TempBan: true, Permaban: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
using var scope = _serviceScopeFactory.CreateScope();
|
using var scope = _serviceScopeFactory.CreateScope();
|
||||||
using var context = scope.ServiceProvider.GetService<MareDbContext>();
|
using var context = scope.ServiceProvider.GetService<MareDbContext>();
|
||||||
var authReply = await context.Auth.AsNoTracking().SingleOrDefaultAsync(u => u.HashedKey == hashedSecretKey).ConfigureAwait(false);
|
var authReply = await context.Auth.AsNoTracking().SingleOrDefaultAsync(u => u.HashedKey == hashedSecretKey).ConfigureAwait(false);
|
||||||
|
var isBanned = authReply?.IsBanned ?? false;
|
||||||
|
var primaryUid = authReply.PrimaryUserUID ?? authReply.UserUID;
|
||||||
|
|
||||||
SecretKeyAuthReply reply = new(authReply != null, authReply?.UserUID, false, authReply?.IsBanned ?? false);
|
if (authReply.PrimaryUserUID != null)
|
||||||
|
{
|
||||||
|
var primaryUser = await context.Auth.AsNoTracking().SingleOrDefaultAsync(u => u.UserUID == authReply.PrimaryUserUID).ConfigureAwait(false);
|
||||||
|
isBanned = isBanned || primaryUser.IsBanned;
|
||||||
|
}
|
||||||
|
|
||||||
|
SecretKeyAuthReply reply = new(authReply != null, authReply?.UserUID, authReply.PrimaryUserUID ?? authReply.UserUID, TempBan: false, isBanned);
|
||||||
|
|
||||||
if (reply.Success)
|
if (reply.Success)
|
||||||
{
|
{
|
||||||
_metrics.IncCounter(MetricsAPI.CounterAuthenticationSuccesses);
|
_metrics.IncCounter(MetricsAPI.CounterAuthenticationSuccesses);
|
||||||
|
_metrics.IncGauge(MetricsAPI.GaugeAuthenticationCacheEntries);
|
||||||
|
|
||||||
_cachedPositiveResponses[hashedSecretKey] = reply;
|
_cachedPositiveResponses[hashedSecretKey] = reply;
|
||||||
_ = Task.Run(async () =>
|
_ = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await Task.Delay(TimeSpan.FromMinutes(5)).ConfigureAwait(false);
|
await Task.Delay(TimeSpan.FromMinutes(5)).ConfigureAwait(false);
|
||||||
_cachedPositiveResponses.TryRemove(hashedSecretKey, out _);
|
_cachedPositiveResponses.TryRemove(hashedSecretKey, out _);
|
||||||
|
_metrics.DecGauge(MetricsAPI.GaugeAuthenticationCacheEntries);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -85,7 +95,7 @@ public class SecretKeyAuthenticatorService
|
|||||||
|
|
||||||
_logger.LogWarning("Failed authorization from {ip}", ip);
|
_logger.LogWarning("Failed authorization from {ip}", ip);
|
||||||
var whitelisted = _configurationService.GetValueOrDefault(nameof(MareConfigurationAuthBase.WhitelistedIps), new List<string>());
|
var whitelisted = _configurationService.GetValueOrDefault(nameof(MareConfigurationAuthBase.WhitelistedIps), new List<string>());
|
||||||
if (!whitelisted.Any(w => ip.Contains(w, StringComparison.OrdinalIgnoreCase)))
|
if (!whitelisted.Exists(w => ip.Contains(w, StringComparison.OrdinalIgnoreCase)))
|
||||||
{
|
{
|
||||||
if (_failedAuthorizations.TryGetValue(ip, out var auth))
|
if (_failedAuthorizations.TryGetValue(ip, out var auth))
|
||||||
{
|
{
|
||||||
@@ -97,6 +107,6 @@ public class SecretKeyAuthenticatorService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new(Success: false, Uid: null, TempBan: false, Permaban: false);
|
return new(Success: false, Uid: null, PrimaryUid: null, TempBan: false, Permaban: false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using StackExchange.Redis.Extensions.Core.Abstractions;
|
using StackExchange.Redis.Extensions.Core.Abstractions;
|
||||||
|
using System.Globalization;
|
||||||
using System.IdentityModel.Tokens.Jwt;
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -21,10 +22,10 @@ namespace MareSynchronosServer.Controllers;
|
|||||||
public class JwtController : Controller
|
public class JwtController : Controller
|
||||||
{
|
{
|
||||||
private readonly IHttpContextAccessor _accessor;
|
private readonly IHttpContextAccessor _accessor;
|
||||||
private readonly IRedisDatabase _redis;
|
|
||||||
private readonly MareDbContext _mareDbContext;
|
|
||||||
private readonly SecretKeyAuthenticatorService _secretKeyAuthenticatorService;
|
|
||||||
private readonly IConfigurationService<MareConfigurationAuthBase> _configuration;
|
private readonly IConfigurationService<MareConfigurationAuthBase> _configuration;
|
||||||
|
private readonly MareDbContext _mareDbContext;
|
||||||
|
private readonly IRedisDatabase _redis;
|
||||||
|
private readonly SecretKeyAuthenticatorService _secretKeyAuthenticatorService;
|
||||||
|
|
||||||
public JwtController(IHttpContextAccessor accessor, MareDbContext mareDbContext,
|
public JwtController(IHttpContextAccessor accessor, MareDbContext mareDbContext,
|
||||||
SecretKeyAuthenticatorService secretKeyAuthenticatorService,
|
SecretKeyAuthenticatorService secretKeyAuthenticatorService,
|
||||||
@@ -41,6 +42,33 @@ public class JwtController : Controller
|
|||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
[HttpPost(MareAuth.Auth_CreateIdent)]
|
[HttpPost(MareAuth.Auth_CreateIdent)]
|
||||||
public async Task<IActionResult> CreateToken(string auth, string charaIdent)
|
public async Task<IActionResult> CreateToken(string auth, string charaIdent)
|
||||||
|
{
|
||||||
|
return await AuthenticateInternal(auth, charaIdent).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Authorize(Policy = "Authenticated")]
|
||||||
|
[HttpGet("renewToken")]
|
||||||
|
public async Task<IActionResult> RenewToken()
|
||||||
|
{
|
||||||
|
var uid = HttpContext.User.Claims.Single(p => string.Equals(p.Type, MareClaimTypes.Uid, StringComparison.Ordinal))!.Value;
|
||||||
|
var ident = HttpContext.User.Claims.Single(p => string.Equals(p.Type, MareClaimTypes.CharaIdent, StringComparison.Ordinal))!.Value;
|
||||||
|
|
||||||
|
if (await _mareDbContext.Auth.Where(u => u.UserUID == uid || u.PrimaryUserUID == uid).AnyAsync(a => a.IsBanned))
|
||||||
|
{
|
||||||
|
await EnsureBan(uid, ident);
|
||||||
|
|
||||||
|
return Unauthorized("You are permanently banned.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (await IsIdentBanned(uid, ident))
|
||||||
|
{
|
||||||
|
return Unauthorized("Your character is banned from using the service.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return CreateJwtFromId(uid, ident);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<IActionResult> AuthenticateInternal(string auth, string charaIdent)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(auth)) return BadRequest("No Authkey");
|
if (string.IsNullOrEmpty(auth)) return BadRequest("No Authkey");
|
||||||
if (string.IsNullOrEmpty(charaIdent)) return BadRequest("No CharaIdent");
|
if (string.IsNullOrEmpty(charaIdent)) return BadRequest("No CharaIdent");
|
||||||
@@ -49,35 +77,71 @@ public class JwtController : Controller
|
|||||||
|
|
||||||
var authResult = await _secretKeyAuthenticatorService.AuthorizeAsync(ip, auth);
|
var authResult = await _secretKeyAuthenticatorService.AuthorizeAsync(ip, auth);
|
||||||
|
|
||||||
var isBanned = await _mareDbContext.BannedUsers.AsNoTracking().AnyAsync(u => u.CharacterIdentification == charaIdent).ConfigureAwait(false);
|
if (await IsIdentBanned(authResult.Uid, charaIdent))
|
||||||
if (isBanned)
|
|
||||||
{
|
{
|
||||||
var authToBan = _mareDbContext.Auth.SingleOrDefault(a => a.UserUID == authResult.Uid);
|
|
||||||
if (authToBan != null)
|
|
||||||
{
|
|
||||||
authToBan.IsBanned = true;
|
|
||||||
await _mareDbContext.SaveChangesAsync().ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Unauthorized("Your character is banned from using the service.");
|
return Unauthorized("Your character is banned from using the service.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!authResult.Success && !authResult.TempBan) return Unauthorized("The provided secret key is invalid. Verify your accounts existence and/or recover the secret key.");
|
if (!authResult.Success && !authResult.TempBan) return Unauthorized("The provided secret key is invalid. Verify your accounts existence and/or recover the secret key.");
|
||||||
if (!authResult.Success && authResult.TempBan) return Unauthorized("You are temporarily banned. Try connecting again in 5 minutes.");
|
if (!authResult.Success && authResult.TempBan) return Unauthorized("You are temporarily banned. Try connecting again in 5 minutes.");
|
||||||
if (authResult.Permaban)
|
if (authResult.Permaban)
|
||||||
|
{
|
||||||
|
await EnsureBan(authResult.Uid, charaIdent);
|
||||||
|
|
||||||
|
return Unauthorized("You are permanently banned.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var existingIdent = await _redis.GetAsync<string>("UID:" + authResult.Uid);
|
||||||
|
if (!string.IsNullOrEmpty(existingIdent)) return Unauthorized("Already logged in to this account. Reconnect in 60 seconds. If you keep seeing this issue, restart your game.");
|
||||||
|
|
||||||
|
return CreateJwtFromId(authResult.Uid, charaIdent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JwtSecurityToken CreateJwt(IEnumerable<Claim> authClaims)
|
||||||
|
{
|
||||||
|
var authSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_configuration.GetValue<string>(nameof(MareConfigurationAuthBase.Jwt))));
|
||||||
|
|
||||||
|
var token = new SecurityTokenDescriptor()
|
||||||
|
{
|
||||||
|
Subject = new ClaimsIdentity(authClaims),
|
||||||
|
SigningCredentials = new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256Signature),
|
||||||
|
Expires = new(long.Parse(authClaims.First(f => string.Equals(f.Type, MareClaimTypes.Expires, StringComparison.Ordinal)).Value!, CultureInfo.InvariantCulture), DateTimeKind.Utc),
|
||||||
|
};
|
||||||
|
|
||||||
|
var handler = new JwtSecurityTokenHandler();
|
||||||
|
return handler.CreateJwtSecurityToken(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IActionResult CreateJwtFromId(string uid, string charaIdent)
|
||||||
|
{
|
||||||
|
var token = CreateJwt(new List<Claim>()
|
||||||
|
{
|
||||||
|
new Claim(MareClaimTypes.Uid, uid),
|
||||||
|
new Claim(MareClaimTypes.CharaIdent, charaIdent),
|
||||||
|
new Claim(MareClaimTypes.Expires, DateTime.UtcNow.AddHours(6).Ticks.ToString(CultureInfo.InvariantCulture))
|
||||||
|
});
|
||||||
|
|
||||||
|
return Content(token.RawData);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task EnsureBan(string uid, string charaIdent)
|
||||||
{
|
{
|
||||||
if (!_mareDbContext.BannedUsers.Any(c => c.CharacterIdentification == charaIdent))
|
if (!_mareDbContext.BannedUsers.Any(c => c.CharacterIdentification == charaIdent))
|
||||||
{
|
{
|
||||||
_mareDbContext.BannedUsers.Add(new Banned()
|
_mareDbContext.BannedUsers.Add(new Banned()
|
||||||
{
|
{
|
||||||
CharacterIdentification = charaIdent,
|
CharacterIdentification = charaIdent,
|
||||||
Reason = "Autobanned CharacterIdent (" + authResult.Uid + ")",
|
Reason = "Autobanned CharacterIdent (" + uid + ")",
|
||||||
});
|
});
|
||||||
|
|
||||||
await _mareDbContext.SaveChangesAsync();
|
await _mareDbContext.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
var lodestone = await _mareDbContext.LodeStoneAuth.Include(a => a.User).FirstOrDefaultAsync(c => c.User.UID == authResult.Uid);
|
var primaryUser = await _mareDbContext.Auth.Include(a => a.User).FirstOrDefaultAsync(f => f.PrimaryUserUID == uid);
|
||||||
|
|
||||||
|
var toBanUid = primaryUser == null ? uid : primaryUser.UserUID;
|
||||||
|
|
||||||
|
var lodestone = await _mareDbContext.LodeStoneAuth.Include(a => a.User).FirstOrDefaultAsync(c => c.User.UID == toBanUid);
|
||||||
|
|
||||||
if (lodestone != null)
|
if (lodestone != null)
|
||||||
{
|
{
|
||||||
@@ -98,33 +162,21 @@ public class JwtController : Controller
|
|||||||
|
|
||||||
await _mareDbContext.SaveChangesAsync();
|
await _mareDbContext.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Unauthorized("You are permanently banned.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var existingIdent = await _redis.GetAsync<string>("UID:" + authResult.Uid);
|
private async Task<bool> IsIdentBanned(string uid, string charaIdent)
|
||||||
if (!string.IsNullOrEmpty(existingIdent)) return Unauthorized("Already logged in to this account. Reconnect in 60 seconds. If you keep seeing this issue, restart your game.");
|
|
||||||
|
|
||||||
var token = CreateToken(new List<Claim>()
|
|
||||||
{
|
{
|
||||||
new Claim(MareClaimTypes.Uid, authResult.Uid),
|
var isBanned = await _mareDbContext.BannedUsers.AsNoTracking().AnyAsync(u => u.CharacterIdentification == charaIdent).ConfigureAwait(false);
|
||||||
new Claim(MareClaimTypes.CharaIdent, charaIdent),
|
if (isBanned)
|
||||||
});
|
|
||||||
|
|
||||||
return Content(token.RawData);
|
|
||||||
}
|
|
||||||
|
|
||||||
private JwtSecurityToken CreateToken(IEnumerable<Claim> authClaims)
|
|
||||||
{
|
{
|
||||||
var authSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_configuration.GetValue<string>(nameof(MareConfigurationAuthBase.Jwt))));
|
var authToBan = _mareDbContext.Auth.SingleOrDefault(a => a.UserUID == uid);
|
||||||
|
if (authToBan != null)
|
||||||
var token = new SecurityTokenDescriptor()
|
|
||||||
{
|
{
|
||||||
Subject = new ClaimsIdentity(authClaims),
|
authToBan.IsBanned = true;
|
||||||
SigningCredentials = new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256Signature),
|
await _mareDbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var handler = new JwtSecurityTokenHandler();
|
return isBanned;
|
||||||
return handler.CreateJwtSecurityToken(token);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,8 +13,6 @@ namespace MareSynchronosServer.Hubs
|
|||||||
|
|
||||||
public Task Client_GroupDelete(GroupDto groupDto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_GroupDelete(GroupDto groupDto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_GroupPairChangePermissions(GroupPairUserPermissionDto permissionDto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
|
||||||
|
|
||||||
public Task Client_GroupPairChangeUserInfo(GroupPairUserInfoDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_GroupPairChangeUserInfo(GroupPairUserInfoDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_GroupPairJoined(GroupPairFullInfoDto groupPairInfoDto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_GroupPairJoined(GroupPairFullInfoDto groupPairInfoDto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
@@ -46,5 +44,8 @@ namespace MareSynchronosServer.Hubs
|
|||||||
public Task Client_UserUpdateProfile(UserDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_UserUpdateProfile(UserDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_UserUpdateSelfPairPermissions(UserPermissionsDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_UserUpdateSelfPairPermissions(UserPermissionsDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
public Task Client_UserUpdateDefaultPermissions(DefaultPermissionsDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
public Task Client_UpdateUserIndividualPairStatusDto(UserIndividualPairStatusDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
public Task Client_GroupChangeUserPairPermissions(GroupPairUserPermissionDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,6 +23,10 @@ public partial class MareHub
|
|||||||
var lodestone = await _dbContext.LodeStoneAuth.SingleOrDefaultAsync(a => a.User.UID == user.UID).ConfigureAwait(false);
|
var lodestone = await _dbContext.LodeStoneAuth.SingleOrDefaultAsync(a => a.User.UID == user.UID).ConfigureAwait(false);
|
||||||
var groupPairs = await _dbContext.GroupPairs.Where(g => g.GroupUserUID == user.UID).ToListAsync().ConfigureAwait(false);
|
var groupPairs = await _dbContext.GroupPairs.Where(g => g.GroupUserUID == user.UID).ToListAsync().ConfigureAwait(false);
|
||||||
var userProfileData = await _dbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == user.UID).ConfigureAwait(false);
|
var userProfileData = await _dbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == user.UID).ConfigureAwait(false);
|
||||||
|
var defaultpermissions = await _dbContext.UserDefaultPreferredPermissions.SingleOrDefaultAsync(u => u.UserUID == user.UID).ConfigureAwait(false);
|
||||||
|
var groupPermissions = await _dbContext.GroupPairPreferredPermissions.Where(u => u.UserUID == user.UID).ToListAsync().ConfigureAwait(false);
|
||||||
|
var individualPermissions = await _dbContext.Permissions.Where(u => u.UserUID == user.UID || u.OtherUserUID == user.UID).ToListAsync().ConfigureAwait(false);
|
||||||
|
var bannedEntries = await _dbContext.GroupBans.Where(u => u.BannedUserUID == user.UID).ToListAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
if (lodestone != null)
|
if (lodestone != null)
|
||||||
{
|
{
|
||||||
@@ -53,57 +57,33 @@ public partial class MareHub
|
|||||||
await UserLeaveGroup(new GroupDto(new GroupData(pair.GroupGID)), user.UID).ConfigureAwait(false);
|
await UserLeaveGroup(new GroupDto(new GroupData(pair.GroupGID)), user.UID).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (defaultpermissions != null)
|
||||||
|
{
|
||||||
|
_dbContext.UserDefaultPreferredPermissions.Remove(defaultpermissions);
|
||||||
|
}
|
||||||
|
_dbContext.GroupPairPreferredPermissions.RemoveRange(groupPermissions);
|
||||||
|
_dbContext.Permissions.RemoveRange(individualPermissions);
|
||||||
|
_dbContext.GroupBans.RemoveRange(bannedEntries);
|
||||||
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
_mareMetrics.IncCounter(MetricsAPI.CounterUsersRegisteredDeleted, 1);
|
_mareMetrics.IncCounter(MetricsAPI.CounterUsersRegisteredDeleted, 1);
|
||||||
|
|
||||||
_dbContext.ClientPairs.RemoveRange(otherPairData);
|
_dbContext.ClientPairs.RemoveRange(otherPairData);
|
||||||
_dbContext.Users.Remove(user);
|
_dbContext.Users.Remove(user);
|
||||||
_dbContext.Auth.Remove(auth);
|
_dbContext.Auth.Remove(auth);
|
||||||
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<List<PausedEntry>> GetAllPairedClientsWithPauseState(string? uid = null)
|
_cacheService.ClearCache(user.UID);
|
||||||
{
|
_cacheService.MarkAsStale(null, user.UID);
|
||||||
uid ??= UserUID;
|
|
||||||
|
|
||||||
var query = await (from userPair in _dbContext.ClientPairs
|
|
||||||
join otherUserPair in _dbContext.ClientPairs on userPair.OtherUserUID equals otherUserPair.UserUID
|
|
||||||
where otherUserPair.OtherUserUID == uid && userPair.UserUID == uid
|
|
||||||
select new
|
|
||||||
{
|
|
||||||
UID = Convert.ToString(userPair.OtherUserUID),
|
|
||||||
GID = "DIRECT",
|
|
||||||
PauseStateSelf = userPair.IsPaused,
|
|
||||||
PauseStateOther = otherUserPair.IsPaused,
|
|
||||||
})
|
|
||||||
.Union(
|
|
||||||
(from userGroupPair in _dbContext.GroupPairs
|
|
||||||
join otherGroupPair in _dbContext.GroupPairs on userGroupPair.GroupGID equals otherGroupPair.GroupGID
|
|
||||||
where
|
|
||||||
userGroupPair.GroupUserUID == uid
|
|
||||||
&& otherGroupPair.GroupUserUID != uid
|
|
||||||
select new
|
|
||||||
{
|
|
||||||
UID = Convert.ToString(otherGroupPair.GroupUserUID),
|
|
||||||
GID = Convert.ToString(otherGroupPair.GroupGID),
|
|
||||||
PauseStateSelf = userGroupPair.IsPaused,
|
|
||||||
PauseStateOther = otherGroupPair.IsPaused,
|
|
||||||
})
|
|
||||||
).AsNoTracking().ToListAsync().ConfigureAwait(false);
|
|
||||||
|
|
||||||
return query.GroupBy(g => g.UID, g => (g.GID, g.PauseStateSelf, g.PauseStateOther),
|
|
||||||
(key, g) => new PausedEntry
|
|
||||||
{
|
|
||||||
UID = key,
|
|
||||||
PauseStates = g.Select(p => new PauseState() { GID = string.Equals(p.GID, "DIRECT", StringComparison.Ordinal) ? null : p.GID, IsSelfPaused = p.PauseStateSelf, IsOtherPaused = p.PauseStateOther })
|
|
||||||
.ToList(),
|
|
||||||
}, StringComparer.Ordinal).ToList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<List<string>> GetAllPairedUnpausedUsers(string? uid = null)
|
private async Task<List<string>> GetAllPairedUnpausedUsers(string? uid = null)
|
||||||
{
|
{
|
||||||
uid ??= UserUID;
|
uid ??= UserUID;
|
||||||
var ret = await GetAllPairedClientsWithPauseState(uid).ConfigureAwait(false);
|
|
||||||
return ret.Where(k => !k.IsPaused).Select(k => k.UID).ToList();
|
return (await _cacheService.GetAllPairs(UserUID).ConfigureAwait(false))
|
||||||
|
.Where(u => !u.Value.OwnPermissions.IsPaused && u.Value.OtherPermissions != null && !u.Value.OtherPermissions.IsPaused)
|
||||||
|
.Select(u => u.Key).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Dictionary<string, string>> GetOnlineUsers(List<string> uids)
|
private async Task<Dictionary<string, string>> GetOnlineUsers(List<string> uids)
|
||||||
@@ -130,11 +110,9 @@ public partial class MareHub
|
|||||||
var pairIdent = await GetUserIdent(pair.GroupUserUID).ConfigureAwait(false);
|
var pairIdent = await GetUserIdent(pair.GroupUserUID).ConfigureAwait(false);
|
||||||
if (string.IsNullOrEmpty(pairIdent)) continue;
|
if (string.IsNullOrEmpty(pairIdent)) continue;
|
||||||
|
|
||||||
var pairs = await GetAllPairedClientsWithPauseState(pair.GroupUserUID).ConfigureAwait(false);
|
|
||||||
|
|
||||||
foreach (var groupUserPair in groupUsers.Where(g => !string.Equals(g.GroupUserUID, pair.GroupUserUID, StringComparison.Ordinal)))
|
foreach (var groupUserPair in groupUsers.Where(g => !string.Equals(g.GroupUserUID, pair.GroupUserUID, StringComparison.Ordinal)))
|
||||||
{
|
{
|
||||||
await UserGroupLeave(groupUserPair, pairs, pairIdent, pair.GroupUserUID).ConfigureAwait(false);
|
await UserGroupLeave(groupUserPair, pairIdent, pair.GroupUserUID).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,16 +172,12 @@ public partial class MareHub
|
|||||||
await _redis.AddAsync("UID:" + UserUID, UserCharaIdent, TimeSpan.FromSeconds(60), StackExchange.Redis.When.Always, StackExchange.Redis.CommandFlags.FireAndForget).ConfigureAwait(false);
|
await _redis.AddAsync("UID:" + UserUID, UserCharaIdent, TimeSpan.FromSeconds(60), StackExchange.Redis.When.Always, StackExchange.Redis.CommandFlags.FireAndForget).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task UserGroupLeave(GroupPair groupUserPair, List<PausedEntry> allUserPairs, string userIdent, string? uid = null)
|
private async Task UserGroupLeave(GroupPair groupUserPair, string userIdent, string? uid = null)
|
||||||
{
|
{
|
||||||
uid ??= UserUID;
|
uid ??= UserUID;
|
||||||
var userPair = allUserPairs.SingleOrDefault(p => string.Equals(p.UID, groupUserPair.GroupUserUID, StringComparison.Ordinal));
|
var allUserPairs = await _cacheService.GetAllPairs(uid).ConfigureAwait(false);
|
||||||
if (userPair != null)
|
if (!allUserPairs.TryGetValue(groupUserPair.GroupUserUID, out var info) || !info.IsSynced)
|
||||||
{
|
{
|
||||||
if (userPair.IsDirectlyPaused != PauseInfo.NoConnection) return;
|
|
||||||
if (userPair.IsPausedPerGroup is PauseInfo.Unpaused) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var groupUserIdent = await GetUserIdent(groupUserPair.GroupUserUID).ConfigureAwait(false);
|
var groupUserIdent = await GetUserIdent(groupUserPair.GroupUserUID).ConfigureAwait(false);
|
||||||
if (!string.IsNullOrEmpty(groupUserIdent))
|
if (!string.IsNullOrEmpty(groupUserIdent))
|
||||||
{
|
{
|
||||||
@@ -211,6 +185,7 @@ public partial class MareHub
|
|||||||
await Clients.User(groupUserPair.GroupUserUID).Client_UserSendOffline(new(new(uid))).ConfigureAwait(false);
|
await Clients.User(groupUserPair.GroupUserUID).Client_UserSendOffline(new(new(uid))).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task UserLeaveGroup(GroupDto dto, string userUid)
|
private async Task UserLeaveGroup(GroupDto dto, string userUid)
|
||||||
{
|
{
|
||||||
@@ -249,7 +224,7 @@ public partial class MareHub
|
|||||||
var user = await _dbContext.Users.SingleAsync(u => u.UID == groupHasMigrated.Item2).ConfigureAwait(false);
|
var user = await _dbContext.Users.SingleAsync(u => u.UID == groupHasMigrated.Item2).ConfigureAwait(false);
|
||||||
|
|
||||||
await Clients.Users(groupPairsWithoutSelf.Select(p => p.GroupUserUID)).Client_GroupSendInfo(new GroupInfoDto(group.ToGroupData(),
|
await Clients.Users(groupPairsWithoutSelf.Select(p => p.GroupUserUID)).Client_GroupSendInfo(new GroupInfoDto(group.ToGroupData(),
|
||||||
user.ToUserData(), group.GetGroupPermissions())).ConfigureAwait(false);
|
user.ToUserData(), group.ToEnum())).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -266,17 +241,20 @@ public partial class MareHub
|
|||||||
|
|
||||||
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
_cacheService.MarkAsStale(userUid, null);
|
||||||
|
|
||||||
_logger.LogCallInfo(MareHubLogger.Args(dto, "Success"));
|
_logger.LogCallInfo(MareHubLogger.Args(dto, "Success"));
|
||||||
|
|
||||||
await Clients.Users(groupPairsWithoutSelf.Select(p => p.GroupUserUID)).Client_GroupPairLeft(new GroupPairDto(dto.Group, groupPair.GroupUser.ToUserData())).ConfigureAwait(false);
|
await Clients.Users(groupPairsWithoutSelf.Select(p => p.GroupUserUID)).Client_GroupPairLeft(new GroupPairDto(dto.Group, groupPair.GroupUser.ToUserData())).ConfigureAwait(false);
|
||||||
|
|
||||||
var allUserPairs = await GetAllPairedClientsWithPauseState().ConfigureAwait(false);
|
|
||||||
|
|
||||||
var ident = await GetUserIdent(userUid).ConfigureAwait(false);
|
var ident = await GetUserIdent(userUid).ConfigureAwait(false);
|
||||||
|
|
||||||
foreach (var groupUserPair in groupPairsWithoutSelf)
|
foreach (var groupUserPair in groupPairsWithoutSelf)
|
||||||
{
|
{
|
||||||
await UserGroupLeave(groupUserPair, allUserPairs, ident, userUid).ConfigureAwait(false);
|
await UserGroupLeave(groupUserPair, ident, userUid).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public record UserQueryPermissionEntry(UserQueryEntry OtherUser, UserPermissionSet OwnPermissions, UserPermissionSet? OtherPermissions);
|
||||||
|
public record UserQueryEntry(string UID, bool IsPaired, string GID, string Alias);
|
||||||
}
|
}
|
||||||
@@ -53,9 +53,9 @@ public partial class MareHub
|
|||||||
if (!hasRights) return;
|
if (!hasRights) return;
|
||||||
|
|
||||||
group.InvitesEnabled = !dto.Permissions.HasFlag(GroupPermissions.DisableInvites);
|
group.InvitesEnabled = !dto.Permissions.HasFlag(GroupPermissions.DisableInvites);
|
||||||
group.DisableSounds = dto.Permissions.HasFlag(GroupPermissions.DisableSounds);
|
group.PreferDisableSounds = dto.Permissions.HasFlag(GroupPermissions.PreferDisableSounds);
|
||||||
group.DisableAnimations = dto.Permissions.HasFlag(GroupPermissions.DisableAnimations);
|
group.PreferDisableAnimations = dto.Permissions.HasFlag(GroupPermissions.PreferDisableAnimations);
|
||||||
group.DisableVFX = dto.Permissions.HasFlag(GroupPermissions.DisableVFX);
|
group.PreferDisableVFX = dto.Permissions.HasFlag(GroupPermissions.PreferDisableVFX);
|
||||||
|
|
||||||
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
@@ -71,47 +71,81 @@ public partial class MareHub
|
|||||||
var (inGroup, groupPair) = await TryValidateUserInGroup(dto.Group.GID).ConfigureAwait(false);
|
var (inGroup, groupPair) = await TryValidateUserInGroup(dto.Group.GID).ConfigureAwait(false);
|
||||||
if (!inGroup) return;
|
if (!inGroup) return;
|
||||||
|
|
||||||
var wasPaused = groupPair.IsPaused;
|
var groupPreferredPermissions = await _dbContext.GroupPairPreferredPermissions
|
||||||
groupPair.DisableSounds = dto.GroupPairPermissions.IsDisableSounds();
|
.SingleAsync(u => u.UserUID == UserUID && u.GroupGID == dto.Group.GID).ConfigureAwait(false);
|
||||||
groupPair.DisableAnimations = dto.GroupPairPermissions.IsDisableAnimations();
|
|
||||||
groupPair.IsPaused = dto.GroupPairPermissions.IsPaused();
|
|
||||||
groupPair.DisableVFX = dto.GroupPairPermissions.IsDisableVFX();
|
|
||||||
|
|
||||||
|
var wasPaused = groupPreferredPermissions.IsPaused;
|
||||||
|
groupPreferredPermissions.DisableSounds = dto.GroupPairPermissions.IsDisableSounds();
|
||||||
|
groupPreferredPermissions.DisableAnimations = dto.GroupPairPermissions.IsDisableAnimations();
|
||||||
|
groupPreferredPermissions.IsPaused = dto.GroupPairPermissions.IsPaused();
|
||||||
|
groupPreferredPermissions.DisableVFX = dto.GroupPairPermissions.IsDisableVFX();
|
||||||
|
|
||||||
|
// set the permissions for every group pair that is not sticky
|
||||||
|
var allPairs = (await _cacheService.GetAllPairs(UserUID).ConfigureAwait(false))
|
||||||
|
.Where(u => !u.Value.OwnPermissions.Sticky)
|
||||||
|
.ToDictionary(d => d.Key, d => d.Value, StringComparer.Ordinal);
|
||||||
|
|
||||||
|
var affectedGroupPairs = allPairs.Where(u => u.Value.GIDs.Contains(dto.GID, StringComparer.Ordinal)).ToList();
|
||||||
|
var groupUserUids = affectedGroupPairs.Select(g => g.Key).ToList();
|
||||||
|
var affectedPerms = await _dbContext.Permissions.Where(u => u.UserUID == UserUID
|
||||||
|
&& groupUserUids.Any(c => c == u.OtherUserUID))
|
||||||
|
.ToListAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
foreach (var perm in affectedPerms)
|
||||||
|
{
|
||||||
|
perm.DisableSounds = groupPreferredPermissions.DisableSounds;
|
||||||
|
perm.DisableAnimations = groupPreferredPermissions.DisableAnimations;
|
||||||
|
perm.IsPaused = groupPreferredPermissions.IsPaused;
|
||||||
|
perm.DisableVFX = groupPreferredPermissions.DisableVFX;
|
||||||
|
}
|
||||||
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
var groupPairs = _dbContext.GroupPairs.Include(p => p.GroupUser).Where(p => p.GroupGID == dto.Group.GID).ToList();
|
foreach (var item in affectedGroupPairs)
|
||||||
await Clients.Users(groupPairs.Select(p => p.GroupUserUID)).Client_GroupPairChangePermissions(dto).ConfigureAwait(false);
|
{
|
||||||
|
_cacheService.MarkAsStale(UserUID, item.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// send messages
|
||||||
|
UserPermissions permissions = UserPermissions.NoneSet;
|
||||||
|
permissions.SetPaused(groupPreferredPermissions.IsPaused);
|
||||||
|
permissions.SetDisableAnimations(groupPreferredPermissions.DisableAnimations);
|
||||||
|
permissions.SetDisableSounds(groupPreferredPermissions.DisableSounds);
|
||||||
|
permissions.SetDisableVFX(groupPreferredPermissions.DisableVFX);
|
||||||
|
|
||||||
|
// send apporpriate permission set to each user
|
||||||
|
await Clients.Users(affectedGroupPairs
|
||||||
|
.Select(k => k.Key))
|
||||||
|
.Client_UserUpdateOtherPairPermissions(new(new(UserUID), permissions)).ConfigureAwait(false);
|
||||||
|
|
||||||
|
await Clients.User(UserUID).Client_GroupChangeUserPairPermissions(dto).ConfigureAwait(false);
|
||||||
|
foreach (var item in affectedGroupPairs.Select(k => k.Key))
|
||||||
|
{
|
||||||
|
await Clients.User(UserUID).Client_UserUpdateSelfPairPermissions(new(new(item), permissions)).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
var allUserPairs = await GetAllPairedClientsWithPauseState().ConfigureAwait(false);
|
|
||||||
var self = await _dbContext.Users.SingleAsync(u => u.UID == UserUID).ConfigureAwait(false);
|
var self = await _dbContext.Users.SingleAsync(u => u.UID == UserUID).ConfigureAwait(false);
|
||||||
|
|
||||||
if (wasPaused == groupPair.IsPaused) return;
|
if (wasPaused == groupPreferredPermissions.IsPaused) return;
|
||||||
|
|
||||||
foreach (var groupUserPair in groupPairs.Where(u => !string.Equals(u.GroupUserUID, UserUID, StringComparison.Ordinal)).ToList())
|
foreach (var groupUserPair in affectedGroupPairs)
|
||||||
{
|
{
|
||||||
var userPair = allUserPairs.SingleOrDefault(p => string.Equals(p.UID, groupUserPair.GroupUserUID, StringComparison.Ordinal));
|
var groupUserIdent = await GetUserIdent(groupUserPair.Key).ConfigureAwait(false);
|
||||||
if (userPair != null)
|
|
||||||
{
|
|
||||||
if (userPair.IsDirectlyPaused != PauseInfo.NoConnection) continue;
|
|
||||||
if (userPair.IsPausedExcludingGroup(dto.Group.GID) is PauseInfo.Unpaused) continue;
|
|
||||||
if (userPair.IsOtherPausedForSpecificGroup(dto.Group.GID) is PauseInfo.Paused) continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var groupUserIdent = await GetUserIdent(groupUserPair.GroupUserUID).ConfigureAwait(false);
|
|
||||||
if (!string.IsNullOrEmpty(groupUserIdent))
|
if (!string.IsNullOrEmpty(groupUserIdent))
|
||||||
{
|
{
|
||||||
if (!groupPair.IsPaused)
|
// if we changed to paused and other was not paused before, we send offline
|
||||||
|
if (groupPreferredPermissions.IsPaused && !groupUserPair.Value.OtherPermissions.IsPaused)
|
||||||
{
|
{
|
||||||
await Clients.User(UserUID).Client_UserSendOnline(new(groupUserPair.ToUserData(), groupUserIdent)).ConfigureAwait(false);
|
await Clients.User(UserUID).Client_UserSendOffline(new(new(groupUserPair.Key, groupUserPair.Value.Alias))).ConfigureAwait(false);
|
||||||
await Clients.User(groupUserPair.GroupUserUID)
|
await Clients.User(groupUserPair.Key)
|
||||||
.Client_UserSendOnline(new(self.ToUserData(), UserCharaIdent)).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await Clients.User(UserUID).Client_UserSendOffline(new(groupUserPair.ToUserData())).ConfigureAwait(false);
|
|
||||||
await Clients.User(groupUserPair.GroupUserUID)
|
|
||||||
.Client_UserSendOffline(new(self.ToUserData())).ConfigureAwait(false);
|
.Client_UserSendOffline(new(self.ToUserData())).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
// if we changed to unpaused and other was not paused either we send online
|
||||||
|
else if (!groupPreferredPermissions.IsPaused && !groupUserPair.Value.OtherPermissions.IsPaused)
|
||||||
|
{
|
||||||
|
await Clients.User(UserUID).Client_UserSendOnline(new(new(groupUserPair.Key, groupUserPair.Value.Alias), groupUserIdent)).ConfigureAwait(false);
|
||||||
|
await Clients.User(groupUserPair.Key)
|
||||||
|
.Client_UserSendOnline(new(self.ToUserData(), UserCharaIdent)).ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,7 +176,7 @@ public partial class MareHub
|
|||||||
|
|
||||||
var groupPairs = await _dbContext.GroupPairs.Where(p => p.GroupGID == dto.Group.GID).Select(p => p.GroupUserUID).AsNoTracking().ToListAsync().ConfigureAwait(false);
|
var groupPairs = await _dbContext.GroupPairs.Where(p => p.GroupGID == dto.Group.GID).Select(p => p.GroupUserUID).AsNoTracking().ToListAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
await Clients.Users(groupPairs).Client_GroupSendInfo(new GroupInfoDto(group.ToGroupData(), newOwnerPair.GroupUser.ToUserData(), group.GetGroupPermissions())).ConfigureAwait(false);
|
await Clients.Users(groupPairs).Client_GroupSendInfo(new GroupInfoDto(group.ToGroupData(), newOwnerPair.GroupUser.ToUserData(), group.ToEnum())).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(Policy = "Identified")]
|
[Authorize(Policy = "Identified")]
|
||||||
@@ -179,25 +213,28 @@ public partial class MareHub
|
|||||||
|
|
||||||
_dbContext.GroupPairs.RemoveRange(notPinned);
|
_dbContext.GroupPairs.RemoveRange(notPinned);
|
||||||
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
foreach (var user in notPinned)
|
||||||
|
{
|
||||||
|
_cacheService.MarkAsStale(user.GroupUserUID, null);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var pair in notPinned)
|
foreach (var pair in notPinned)
|
||||||
{
|
{
|
||||||
await Clients.Users(groupPairs.Where(p => p.IsPinned).Select(g => g.GroupUserUID)).Client_GroupPairLeft(new GroupPairDto(dto.Group, pair.GroupUser.ToUserData())).ConfigureAwait(false);
|
await Clients.Users(groupPairs.Where(p => p.IsPinned || p.IsModerator).Select(g => g.GroupUserUID))
|
||||||
|
.Client_GroupPairLeft(new GroupPairDto(dto.Group, pair.GroupUser.ToUserData())).ConfigureAwait(false);
|
||||||
|
|
||||||
var pairIdent = await GetUserIdent(pair.GroupUserUID).ConfigureAwait(false);
|
var pairIdent = await GetUserIdent(pair.GroupUserUID).ConfigureAwait(false);
|
||||||
if (string.IsNullOrEmpty(pairIdent)) continue;
|
if (string.IsNullOrEmpty(pairIdent)) continue;
|
||||||
|
|
||||||
var allUserPairs = await GetAllPairedClientsWithPauseState(pair.GroupUserUID).ConfigureAwait(false);
|
|
||||||
|
|
||||||
foreach (var groupUserPair in groupPairs.Where(p => !string.Equals(p.GroupUserUID, pair.GroupUserUID, StringComparison.Ordinal)))
|
foreach (var groupUserPair in groupPairs.Where(p => !string.Equals(p.GroupUserUID, pair.GroupUserUID, StringComparison.Ordinal)))
|
||||||
{
|
{
|
||||||
await UserGroupLeave(groupUserPair, allUserPairs, pairIdent).ConfigureAwait(false);
|
await UserGroupLeave(groupUserPair, pairIdent, pair.GroupUserUID).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(Policy = "Identified")]
|
[Authorize(Policy = "Identified")]
|
||||||
public async Task<GroupPasswordDto> GroupCreate()
|
public async Task<GroupJoinDto> GroupCreate()
|
||||||
{
|
{
|
||||||
_logger.LogCallInfo();
|
_logger.LogCallInfo();
|
||||||
var existingGroupsByUser = await _dbContext.Groups.CountAsync(u => u.OwnerUID == UserUID).ConfigureAwait(false);
|
var existingGroupsByUser = await _dbContext.Groups.CountAsync(u => u.OwnerUID == UserUID).ConfigureAwait(false);
|
||||||
@@ -215,37 +252,52 @@ public partial class MareHub
|
|||||||
gid = "MSS-" + gid;
|
gid = "MSS-" + gid;
|
||||||
|
|
||||||
var passwd = StringUtils.GenerateRandomString(16);
|
var passwd = StringUtils.GenerateRandomString(16);
|
||||||
var sha = SHA256.Create();
|
using var sha = SHA256.Create();
|
||||||
var hashedPw = StringUtils.Sha256String(passwd);
|
var hashedPw = StringUtils.Sha256String(passwd);
|
||||||
|
|
||||||
|
UserDefaultPreferredPermission defaultPermissions = await _dbContext.UserDefaultPreferredPermissions.SingleAsync(u => u.UserUID == UserUID).ConfigureAwait(false);
|
||||||
|
|
||||||
Group newGroup = new()
|
Group newGroup = new()
|
||||||
{
|
{
|
||||||
GID = gid,
|
GID = gid,
|
||||||
HashedPassword = hashedPw,
|
HashedPassword = hashedPw,
|
||||||
InvitesEnabled = true,
|
InvitesEnabled = true,
|
||||||
OwnerUID = UserUID,
|
OwnerUID = UserUID,
|
||||||
|
PreferDisableAnimations = defaultPermissions.DisableGroupAnimations,
|
||||||
|
PreferDisableSounds = defaultPermissions.DisableGroupSounds,
|
||||||
|
PreferDisableVFX = defaultPermissions.DisableGroupVFX
|
||||||
};
|
};
|
||||||
|
|
||||||
GroupPair initialPair = new()
|
GroupPair initialPair = new()
|
||||||
{
|
{
|
||||||
GroupGID = newGroup.GID,
|
GroupGID = newGroup.GID,
|
||||||
GroupUserUID = UserUID,
|
GroupUserUID = UserUID,
|
||||||
IsPaused = false,
|
|
||||||
IsPinned = true,
|
IsPinned = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GroupPairPreferredPermission initialPrefPermissions = new()
|
||||||
|
{
|
||||||
|
UserUID = UserUID,
|
||||||
|
GroupGID = newGroup.GID,
|
||||||
|
DisableSounds = defaultPermissions.DisableGroupSounds,
|
||||||
|
DisableAnimations = defaultPermissions.DisableGroupAnimations,
|
||||||
|
DisableVFX = defaultPermissions.DisableGroupAnimations
|
||||||
|
};
|
||||||
|
|
||||||
await _dbContext.Groups.AddAsync(newGroup).ConfigureAwait(false);
|
await _dbContext.Groups.AddAsync(newGroup).ConfigureAwait(false);
|
||||||
await _dbContext.GroupPairs.AddAsync(initialPair).ConfigureAwait(false);
|
await _dbContext.GroupPairs.AddAsync(initialPair).ConfigureAwait(false);
|
||||||
|
await _dbContext.GroupPairPreferredPermissions.AddAsync(initialPrefPermissions).ConfigureAwait(false);
|
||||||
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
var self = await _dbContext.Users.SingleAsync(u => u.UID == UserUID).ConfigureAwait(false);
|
var self = await _dbContext.Users.SingleAsync(u => u.UID == UserUID).ConfigureAwait(false);
|
||||||
|
|
||||||
await Clients.User(UserUID).Client_GroupSendFullInfo(new GroupFullInfoDto(newGroup.ToGroupData(), self.ToUserData(), GroupPermissions.NoneSet, GroupUserPermissions.NoneSet, GroupUserInfo.None))
|
await Clients.User(UserUID).Client_GroupSendFullInfo(new GroupFullInfoDto(newGroup.ToGroupData(), self.ToUserData(),
|
||||||
|
newGroup.ToEnum(), initialPrefPermissions.ToEnum(), initialPair.ToEnum(), new(StringComparer.Ordinal)))
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
_logger.LogCallInfo(MareHubLogger.Args(gid));
|
_logger.LogCallInfo(MareHubLogger.Args(gid));
|
||||||
|
|
||||||
return new GroupPasswordDto(newGroup.ToGroupData(), passwd);
|
return new GroupJoinDto(newGroup.ToGroupData(), passwd, initialPrefPermissions.ToEnum());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(Policy = "Identified")]
|
[Authorize(Policy = "Identified")]
|
||||||
@@ -326,11 +378,39 @@ public partial class MareHub
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(Policy = "Identified")]
|
[Authorize(Policy = "Identified")]
|
||||||
public async Task<bool> GroupJoin(GroupPasswordDto dto)
|
public async Task<GroupJoinInfoDto> GroupJoin(GroupPasswordDto dto)
|
||||||
{
|
{
|
||||||
var aliasOrGid = dto.Group.GID.Trim();
|
var aliasOrGid = dto.Group.GID.Trim();
|
||||||
|
|
||||||
_logger.LogCallInfo(MareHubLogger.Args(dto.Group));
|
_logger.LogCallInfo(MareHubLogger.Args(dto));
|
||||||
|
|
||||||
|
var group = await _dbContext.Groups.Include(g => g.Owner).AsNoTracking().SingleOrDefaultAsync(g => g.GID == aliasOrGid || g.Alias == aliasOrGid).ConfigureAwait(false);
|
||||||
|
var groupGid = group?.GID ?? string.Empty;
|
||||||
|
var existingPair = await _dbContext.GroupPairs.AsNoTracking().SingleOrDefaultAsync(g => g.GroupGID == groupGid && g.GroupUserUID == UserUID).ConfigureAwait(false);
|
||||||
|
var hashedPw = StringUtils.Sha256String(dto.Password);
|
||||||
|
var existingUserCount = await _dbContext.GroupPairs.AsNoTracking().CountAsync(g => g.GroupGID == groupGid).ConfigureAwait(false);
|
||||||
|
var joinedGroups = await _dbContext.GroupPairs.CountAsync(g => g.GroupUserUID == UserUID).ConfigureAwait(false);
|
||||||
|
var isBanned = await _dbContext.GroupBans.AnyAsync(g => g.GroupGID == groupGid && g.BannedUserUID == UserUID).ConfigureAwait(false);
|
||||||
|
var oneTimeInvite = await _dbContext.GroupTempInvites.SingleOrDefaultAsync(g => g.GroupGID == groupGid && g.Invite == hashedPw).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (group == null
|
||||||
|
|| (!string.Equals(group.HashedPassword, hashedPw, StringComparison.Ordinal) && oneTimeInvite == null)
|
||||||
|
|| existingPair != null
|
||||||
|
|| existingUserCount >= _maxGroupUserCount
|
||||||
|
|| !group.InvitesEnabled
|
||||||
|
|| joinedGroups >= _maxJoinedGroupsByUser
|
||||||
|
|| isBanned)
|
||||||
|
return new GroupJoinInfoDto(null, null, GroupPermissions.NoneSet, false);
|
||||||
|
|
||||||
|
return new GroupJoinInfoDto(group.ToGroupData(), group.Owner.ToUserData(), group.ToEnum(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Authorize(Policy = "Identified")]
|
||||||
|
public async Task<bool> GroupJoinFinalize(GroupJoinDto dto)
|
||||||
|
{
|
||||||
|
var aliasOrGid = dto.Group.GID.Trim();
|
||||||
|
|
||||||
|
_logger.LogCallInfo(MareHubLogger.Args(dto));
|
||||||
|
|
||||||
var group = await _dbContext.Groups.Include(g => g.Owner).AsNoTracking().SingleOrDefaultAsync(g => g.GID == aliasOrGid || g.Alias == aliasOrGid).ConfigureAwait(false);
|
var group = await _dbContext.Groups.Include(g => g.Owner).AsNoTracking().SingleOrDefaultAsync(g => g.GID == aliasOrGid || g.Alias == aliasOrGid).ConfigureAwait(false);
|
||||||
var groupGid = group?.GID ?? string.Empty;
|
var groupGid = group?.GID ?? string.Empty;
|
||||||
@@ -350,6 +430,10 @@ public partial class MareHub
|
|||||||
|| isBanned)
|
|| isBanned)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// get all pairs before we join
|
||||||
|
var allUserPairs = (await _cacheService.GetAllPairs(UserUID).ConfigureAwait(false))
|
||||||
|
.ToDictionary(u => u.Key, u => u.Value, StringComparer.Ordinal);
|
||||||
|
|
||||||
if (oneTimeInvite != null)
|
if (oneTimeInvite != null)
|
||||||
{
|
{
|
||||||
_logger.LogCallInfo(MareHubLogger.Args(aliasOrGid, "TempInvite", oneTimeInvite.Invite));
|
_logger.LogCallInfo(MareHubLogger.Args(aliasOrGid, "TempInvite", oneTimeInvite.Invite));
|
||||||
@@ -360,47 +444,151 @@ public partial class MareHub
|
|||||||
{
|
{
|
||||||
GroupGID = group.GID,
|
GroupGID = group.GID,
|
||||||
GroupUserUID = UserUID,
|
GroupUserUID = UserUID,
|
||||||
DisableAnimations = false,
|
|
||||||
DisableSounds = false,
|
|
||||||
DisableVFX = false
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var preferredPermissions = await _dbContext.GroupPairPreferredPermissions.SingleOrDefaultAsync(u => u.UserUID == UserUID && u.GroupGID == group.GID).ConfigureAwait(false);
|
||||||
|
if (preferredPermissions == null)
|
||||||
|
{
|
||||||
|
GroupPairPreferredPermission newPerms = new()
|
||||||
|
{
|
||||||
|
GroupGID = group.GID,
|
||||||
|
UserUID = UserUID,
|
||||||
|
DisableSounds = dto.GroupUserPreferredPermissions.IsDisableSounds(),
|
||||||
|
DisableVFX = dto.GroupUserPreferredPermissions.IsDisableVFX(),
|
||||||
|
DisableAnimations = dto.GroupUserPreferredPermissions.IsDisableAnimations(),
|
||||||
|
IsPaused = false
|
||||||
|
};
|
||||||
|
|
||||||
|
_dbContext.Add(newPerms);
|
||||||
|
preferredPermissions = newPerms;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
preferredPermissions.DisableSounds = dto.GroupUserPreferredPermissions.IsDisableSounds();
|
||||||
|
preferredPermissions.DisableVFX = dto.GroupUserPreferredPermissions.IsDisableVFX();
|
||||||
|
preferredPermissions.DisableAnimations = dto.GroupUserPreferredPermissions.IsDisableAnimations();
|
||||||
|
preferredPermissions.IsPaused = false;
|
||||||
|
_dbContext.Update(preferredPermissions);
|
||||||
|
}
|
||||||
|
|
||||||
await _dbContext.GroupPairs.AddAsync(newPair).ConfigureAwait(false);
|
await _dbContext.GroupPairs.AddAsync(newPair).ConfigureAwait(false);
|
||||||
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
_logger.LogCallInfo(MareHubLogger.Args(aliasOrGid, "Success"));
|
_logger.LogCallInfo(MareHubLogger.Args(aliasOrGid, "Success"));
|
||||||
|
|
||||||
await Clients.User(UserUID).Client_GroupSendFullInfo(new GroupFullInfoDto(group.ToGroupData(), group.Owner.ToUserData(), group.GetGroupPermissions(), newPair.GetGroupPairPermissions(), newPair.GetGroupPairUserInfo())).ConfigureAwait(false);
|
var groupInfos = await _dbContext.GroupPairs.Where(u => u.GroupGID == group.GID && (u.IsPinned || u.IsModerator)).ToListAsync().ConfigureAwait(false);
|
||||||
|
await Clients.User(UserUID).Client_GroupSendFullInfo(new GroupFullInfoDto(group.ToGroupData(), group.Owner.ToUserData(),
|
||||||
|
group.ToEnum(), preferredPermissions.ToEnum(), newPair.ToEnum(),
|
||||||
|
groupInfos.ToDictionary(u => u.GroupUserUID, u => u.ToEnum(), StringComparer.Ordinal))).ConfigureAwait(false);
|
||||||
|
|
||||||
var self = _dbContext.Users.Single(u => u.UID == UserUID);
|
var self = _dbContext.Users.Single(u => u.UID == UserUID);
|
||||||
|
|
||||||
var groupPairs = await _dbContext.GroupPairs.Include(p => p.GroupUser).Where(p => p.GroupGID == group.GID && p.GroupUserUID != UserUID).ToListAsync().ConfigureAwait(false);
|
var groupPairs = await _dbContext.GroupPairs.Include(p => p.GroupUser).Where(p => p.GroupGID == group.GID && p.GroupUserUID != UserUID).ToListAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
await Clients.Users(groupPairs.Select(p => p.GroupUserUID))
|
_cacheService.MarkAsStale(UserUID, null);
|
||||||
.Client_GroupPairJoined(new GroupPairFullInfoDto(group.ToGroupData(), self.ToUserData(), newPair.GetGroupPairUserInfo(), newPair.GetGroupPairPermissions())).ConfigureAwait(false);
|
|
||||||
foreach (var pair in groupPairs)
|
foreach (var pair in groupPairs)
|
||||||
{
|
{
|
||||||
await Clients.User(UserUID).Client_GroupPairJoined(new GroupPairFullInfoDto(group.ToGroupData(), pair.ToUserData(), pair.GetGroupPairUserInfo(), pair.GetGroupPairPermissions())).ConfigureAwait(false);
|
_cacheService.MarkAsStale(UserUID, pair.GroupUserUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
var allUserPairs = await GetAllPairedClientsWithPauseState().ConfigureAwait(false);
|
var userPairsAfterJoin = await _cacheService.GetAllPairs(UserUID).ConfigureAwait(false);
|
||||||
|
|
||||||
foreach (var groupUserPair in groupPairs)
|
foreach (var pair in groupPairs)
|
||||||
{
|
{
|
||||||
var userPair = allUserPairs.Single(p => string.Equals(p.UID, groupUserPair.GroupUserUID, StringComparison.Ordinal));
|
var perms = userPairsAfterJoin.TryGetValue(pair.GroupUserUID, out var userinfo);
|
||||||
if (userPair.IsDirectlyPaused != PauseInfo.NoConnection) continue;
|
// check if we have had prior permissions to that pair, if not add them
|
||||||
if (userPair.IsPausedExcludingGroup(group.GID) is PauseInfo.Unpaused) continue;
|
var ownPermissionsToOther = userinfo?.OwnPermissions ?? null;
|
||||||
if (userPair.IsPausedPerGroup is PauseInfo.Paused) continue;
|
if (ownPermissionsToOther == null)
|
||||||
|
|
||||||
var groupUserIdent = await GetUserIdent(groupUserPair.GroupUserUID).ConfigureAwait(false);
|
|
||||||
if (!string.IsNullOrEmpty(groupUserIdent))
|
|
||||||
{
|
{
|
||||||
await Clients.User(UserUID).Client_UserSendOnline(new(groupUserPair.ToUserData(), groupUserIdent)).ConfigureAwait(false);
|
var existingPermissionsOnDb = await _dbContext.Permissions.SingleOrDefaultAsync(p => p.UserUID == UserUID && p.OtherUserUID == pair.GroupUserUID).ConfigureAwait(false);
|
||||||
await Clients.User(groupUserPair.GroupUserUID)
|
|
||||||
.Client_UserSendOnline(new(self.ToUserData(), UserCharaIdent)).ConfigureAwait(false);
|
if (existingPermissionsOnDb == null)
|
||||||
|
{
|
||||||
|
ownPermissionsToOther = new()
|
||||||
|
{
|
||||||
|
UserUID = UserUID,
|
||||||
|
OtherUserUID = pair.GroupUserUID,
|
||||||
|
DisableAnimations = preferredPermissions.DisableAnimations,
|
||||||
|
DisableSounds = preferredPermissions.DisableSounds,
|
||||||
|
DisableVFX = preferredPermissions.DisableVFX,
|
||||||
|
IsPaused = false,
|
||||||
|
Sticky = false
|
||||||
|
};
|
||||||
|
|
||||||
|
await _dbContext.Permissions.AddAsync(ownPermissionsToOther).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
existingPermissionsOnDb.DisableAnimations = preferredPermissions.DisableAnimations;
|
||||||
|
existingPermissionsOnDb.DisableSounds = preferredPermissions.DisableSounds;
|
||||||
|
existingPermissionsOnDb.DisableVFX = preferredPermissions.DisableVFX;
|
||||||
|
existingPermissionsOnDb.IsPaused = false;
|
||||||
|
existingPermissionsOnDb.Sticky = false;
|
||||||
|
|
||||||
|
_dbContext.Update(existingPermissionsOnDb);
|
||||||
|
|
||||||
|
ownPermissionsToOther = existingPermissionsOnDb;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (!ownPermissionsToOther.Sticky)
|
||||||
|
{
|
||||||
|
ownPermissionsToOther = await _dbContext.Permissions.SingleAsync(u => u.UserUID == UserUID && u.OtherUserUID == pair.GroupUserUID).ConfigureAwait(false);
|
||||||
|
|
||||||
|
// update the existing permission only if it was not set to sticky
|
||||||
|
ownPermissionsToOther.DisableAnimations = preferredPermissions.DisableAnimations;
|
||||||
|
ownPermissionsToOther.DisableVFX = preferredPermissions.DisableVFX;
|
||||||
|
ownPermissionsToOther.DisableSounds = preferredPermissions.DisableSounds;
|
||||||
|
ownPermissionsToOther.IsPaused = false;
|
||||||
|
|
||||||
|
_dbContext.Update(ownPermissionsToOther);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get others permissionset to self and eventually update it
|
||||||
|
var otherPermissionToSelf = userinfo?.OtherPermissions ?? null;
|
||||||
|
if (otherPermissionToSelf == null)
|
||||||
|
{
|
||||||
|
var otherPreferred = await _dbContext.GroupPairPreferredPermissions.SingleAsync(u => u.GroupGID == group.GID && u.UserUID == pair.GroupUserUID).ConfigureAwait(false);
|
||||||
|
otherPermissionToSelf = new()
|
||||||
|
{
|
||||||
|
UserUID = pair.GroupUserUID,
|
||||||
|
OtherUserUID = UserUID,
|
||||||
|
DisableAnimations = otherPreferred.DisableAnimations,
|
||||||
|
DisableSounds = otherPreferred.DisableSounds,
|
||||||
|
DisableVFX = otherPreferred.DisableVFX,
|
||||||
|
IsPaused = otherPreferred.IsPaused,
|
||||||
|
Sticky = false
|
||||||
|
};
|
||||||
|
|
||||||
|
await _dbContext.AddAsync(otherPermissionToSelf).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Clients.User(UserUID).Client_GroupPairJoined(new GroupPairFullInfoDto(group.ToGroupData(),
|
||||||
|
pair.ToUserData(), ownPermissionsToOther.ToUserPermissions(setSticky: ownPermissionsToOther.Sticky),
|
||||||
|
otherPermissionToSelf.ToUserPermissions(setSticky: false))).ConfigureAwait(false);
|
||||||
|
await Clients.User(pair.GroupUserUID).Client_GroupPairJoined(new GroupPairFullInfoDto(group.ToGroupData(),
|
||||||
|
self.ToUserData(), otherPermissionToSelf.ToUserPermissions(setSticky: false),
|
||||||
|
ownPermissionsToOther.ToUserPermissions(setSticky: false))).ConfigureAwait(false);
|
||||||
|
|
||||||
|
// if not paired prior and neither has the permissions set to paused, send online
|
||||||
|
if ((!allUserPairs.ContainsKey(pair.GroupUserUID) || (allUserPairs.ContainsKey(pair.GroupUserUID) && !allUserPairs[pair.GroupUserUID].IsSynced))
|
||||||
|
&& !otherPermissionToSelf.IsPaused && !ownPermissionsToOther.IsPaused)
|
||||||
|
{
|
||||||
|
var groupUserIdent = await GetUserIdent(pair.GroupUserUID).ConfigureAwait(false);
|
||||||
|
|
||||||
|
await Clients.User(UserUID).Client_UserSendOnline(new(pair.ToUserData(), groupUserIdent)).ConfigureAwait(false);
|
||||||
|
await Clients.User(pair.GroupUserUID).Client_UserSendOnline(new(self.ToUserData(), UserCharaIdent)).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_cacheService.MarkAsStale(UserUID, null);
|
||||||
|
foreach (var pair in groupPairs)
|
||||||
|
{
|
||||||
|
_cacheService.MarkAsStale(UserUID, pair.GroupUserUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,6 +614,11 @@ public partial class MareHub
|
|||||||
|
|
||||||
_dbContext.GroupPairs.Remove(groupPair);
|
_dbContext.GroupPairs.Remove(groupPair);
|
||||||
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
_cacheService.MarkAsStale(dto.User.UID, null);
|
||||||
|
foreach (var user in await _dbContext.GroupPairs.Where(u => u.GroupGID == dto.GID).ToListAsync().ConfigureAwait(false))
|
||||||
|
{
|
||||||
|
_cacheService.MarkAsStale(user.GroupUserUID, null);
|
||||||
|
}
|
||||||
|
|
||||||
var groupPairs = _dbContext.GroupPairs.Where(p => p.GroupGID == group.GID).AsNoTracking().ToList();
|
var groupPairs = _dbContext.GroupPairs.Where(p => p.GroupGID == group.GID).AsNoTracking().ToList();
|
||||||
await Clients.Users(groupPairs.Select(p => p.GroupUserUID)).Client_GroupPairLeft(dto).ConfigureAwait(false);
|
await Clients.Users(groupPairs.Select(p => p.GroupUserUID)).Client_GroupPairLeft(dto).ConfigureAwait(false);
|
||||||
@@ -435,11 +628,9 @@ public partial class MareHub
|
|||||||
|
|
||||||
await Clients.User(dto.User.UID).Client_GroupDelete(new GroupDto(dto.Group)).ConfigureAwait(false);
|
await Clients.User(dto.User.UID).Client_GroupDelete(new GroupDto(dto.Group)).ConfigureAwait(false);
|
||||||
|
|
||||||
var allUserPairs = await GetAllPairedClientsWithPauseState(dto.User.UID).ConfigureAwait(false);
|
|
||||||
|
|
||||||
foreach (var groupUserPair in groupPairs)
|
foreach (var groupUserPair in groupPairs)
|
||||||
{
|
{
|
||||||
await UserGroupLeave(groupUserPair, allUserPairs, userIdent, dto.User.UID).ConfigureAwait(false);
|
await UserGroupLeave(groupUserPair, userIdent, dto.User.UID).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,7 +645,7 @@ public partial class MareHub
|
|||||||
var (userIsOwner, _) = await TryValidateOwner(dto.Group.GID).ConfigureAwait(false);
|
var (userIsOwner, _) = await TryValidateOwner(dto.Group.GID).ConfigureAwait(false);
|
||||||
var (userIsModerator, _) = await TryValidateGroupModeratorOrOwner(dto.Group.GID).ConfigureAwait(false);
|
var (userIsModerator, _) = await TryValidateGroupModeratorOrOwner(dto.Group.GID).ConfigureAwait(false);
|
||||||
|
|
||||||
if (dto.GroupUserInfo.HasFlag(GroupUserInfo.IsPinned) && userIsModerator && !userPair.IsPinned)
|
if (dto.GroupUserInfo.HasFlag(GroupPairUserInfo.IsPinned) && userIsModerator && !userPair.IsPinned)
|
||||||
{
|
{
|
||||||
userPair.IsPinned = true;
|
userPair.IsPinned = true;
|
||||||
}
|
}
|
||||||
@@ -463,7 +654,7 @@ public partial class MareHub
|
|||||||
userPair.IsPinned = false;
|
userPair.IsPinned = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dto.GroupUserInfo.HasFlag(GroupUserInfo.IsModerator) && userIsOwner && !userPair.IsModerator)
|
if (dto.GroupUserInfo.HasFlag(GroupPairUserInfo.IsModerator) && userIsOwner && !userPair.IsModerator)
|
||||||
{
|
{
|
||||||
userPair.IsModerator = true;
|
userPair.IsModerator = true;
|
||||||
}
|
}
|
||||||
@@ -475,7 +666,7 @@ public partial class MareHub
|
|||||||
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
var groupPairs = await _dbContext.GroupPairs.AsNoTracking().Where(p => p.GroupGID == dto.Group.GID).Select(p => p.GroupUserUID).ToListAsync().ConfigureAwait(false);
|
var groupPairs = await _dbContext.GroupPairs.AsNoTracking().Where(p => p.GroupGID == dto.Group.GID).Select(p => p.GroupUserUID).ToListAsync().ConfigureAwait(false);
|
||||||
await Clients.Users(groupPairs).Client_GroupPairChangeUserInfo(new GroupPairUserInfoDto(dto.Group, dto.User, userPair.GetGroupPairUserInfo())).ConfigureAwait(false);
|
await Clients.Users(groupPairs).Client_GroupPairChangeUserInfo(new GroupPairUserInfoDto(dto.Group, dto.User, userPair.ToEnum())).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(Policy = "Identified")]
|
[Authorize(Policy = "Identified")]
|
||||||
@@ -484,22 +675,16 @@ public partial class MareHub
|
|||||||
_logger.LogCallInfo();
|
_logger.LogCallInfo();
|
||||||
|
|
||||||
var groups = await _dbContext.GroupPairs.Include(g => g.Group).Include(g => g.Group.Owner).Where(g => g.GroupUserUID == UserUID).AsNoTracking().ToListAsync().ConfigureAwait(false);
|
var groups = await _dbContext.GroupPairs.Include(g => g.Group).Include(g => g.Group.Owner).Where(g => g.GroupUserUID == UserUID).AsNoTracking().ToListAsync().ConfigureAwait(false);
|
||||||
|
var preferredPermissions = (await _dbContext.GroupPairPreferredPermissions.Where(u => u.UserUID == UserUID).ToListAsync().ConfigureAwait(false))
|
||||||
|
.Where(u => groups.Exists(k => string.Equals(k.GroupGID, u.GroupGID, StringComparison.Ordinal)))
|
||||||
|
.ToDictionary(u => groups.First(f => string.Equals(f.GroupGID, u.GroupGID, StringComparison.Ordinal)), u => u);
|
||||||
|
var groupInfos = await _dbContext.GroupPairs.Where(u => groups.Select(g => g.GroupGID).Contains(u.GroupGID) && (u.IsPinned || u.IsModerator))
|
||||||
|
.ToListAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
return groups.Select(g => new GroupFullInfoDto(g.Group.ToGroupData(), g.Group.Owner.ToUserData(),
|
return preferredPermissions.Select(g => new GroupFullInfoDto(g.Key.Group.ToGroupData(), g.Key.Group.Owner.ToUserData(),
|
||||||
g.Group.GetGroupPermissions(), g.GetGroupPairPermissions(), g.GetGroupPairUserInfo())).ToList();
|
g.Key.Group.ToEnum(), g.Value.ToEnum(), g.Key.ToEnum(),
|
||||||
}
|
groupInfos.Where(i => string.Equals(i.GroupGID, g.Key.GroupGID, StringComparison.Ordinal))
|
||||||
|
.ToDictionary(i => i.GroupUserUID, i => i.ToEnum(), StringComparer.Ordinal))).ToList();
|
||||||
[Authorize(Policy = "Identified")]
|
|
||||||
public async Task<List<GroupPairFullInfoDto>> GroupsGetUsersInGroup(GroupDto dto)
|
|
||||||
{
|
|
||||||
_logger.LogCallInfo(MareHubLogger.Args(dto));
|
|
||||||
|
|
||||||
var (inGroup, _) = await TryValidateUserInGroup(dto.Group.GID).ConfigureAwait(false);
|
|
||||||
if (!inGroup) return new List<GroupPairFullInfoDto>();
|
|
||||||
|
|
||||||
var group = await _dbContext.Groups.SingleAsync(g => g.GID == dto.Group.GID).ConfigureAwait(false);
|
|
||||||
var allPairs = await _dbContext.GroupPairs.Include(g => g.GroupUser).Where(g => g.GroupGID == dto.Group.GID && g.GroupUserUID != UserUID).AsNoTracking().ToListAsync().ConfigureAwait(false);
|
|
||||||
return allPairs.Select(p => new GroupPairFullInfoDto(group.ToGroupData(), p.GroupUser.ToUserData(), p.GetGroupPairUserInfo(), p.GetGroupPairPermissions())).ToList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(Policy = "Identified")]
|
[Authorize(Policy = "Identified")]
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Text.RegularExpressions;
|
|||||||
using MareSynchronos.API.Data;
|
using MareSynchronos.API.Data;
|
||||||
using MareSynchronos.API.Data.Enum;
|
using MareSynchronos.API.Data.Enum;
|
||||||
using MareSynchronos.API.Data.Extensions;
|
using MareSynchronos.API.Data.Extensions;
|
||||||
|
using MareSynchronos.API.Dto;
|
||||||
using MareSynchronos.API.Dto.User;
|
using MareSynchronos.API.Dto.User;
|
||||||
using MareSynchronosServer.Utils;
|
using MareSynchronosServer.Utils;
|
||||||
using MareSynchronosShared.Metrics;
|
using MareSynchronosShared.Metrics;
|
||||||
@@ -59,31 +60,80 @@ public partial class MareHub
|
|||||||
|
|
||||||
ClientPair wl = new ClientPair()
|
ClientPair wl = new ClientPair()
|
||||||
{
|
{
|
||||||
IsPaused = false,
|
|
||||||
OtherUser = otherUser,
|
OtherUser = otherUser,
|
||||||
User = user,
|
User = user,
|
||||||
};
|
};
|
||||||
await _dbContext.ClientPairs.AddAsync(wl).ConfigureAwait(false);
|
await _dbContext.ClientPairs.AddAsync(wl).ConfigureAwait(false);
|
||||||
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
_cacheService.MarkAsStale(UserUID, otherUser.UID);
|
||||||
|
|
||||||
|
var existingData = await _cacheService.GetPairData(UserUID, otherUser.UID).ConfigureAwait(false);
|
||||||
|
|
||||||
|
var permissions = existingData.OwnPermissions;
|
||||||
|
if (permissions == null || !permissions.Sticky)
|
||||||
|
{
|
||||||
|
var ownDefaultPermissions = await _dbContext.UserDefaultPreferredPermissions.AsNoTracking().SingleOrDefaultAsync(f => f.UserUID == UserUID).ConfigureAwait(false);
|
||||||
|
|
||||||
|
permissions = new UserPermissionSet()
|
||||||
|
{
|
||||||
|
User = user,
|
||||||
|
OtherUser = otherUser,
|
||||||
|
DisableAnimations = ownDefaultPermissions.DisableIndividualAnimations,
|
||||||
|
DisableSounds = ownDefaultPermissions.DisableIndividualSounds,
|
||||||
|
DisableVFX = ownDefaultPermissions.DisableIndividualVFX,
|
||||||
|
IsPaused = false,
|
||||||
|
Sticky = true
|
||||||
|
};
|
||||||
|
|
||||||
|
var existingDbPerms = await _dbContext.Permissions.SingleOrDefaultAsync(u => u.UserUID == UserUID && u.OtherUserUID == otherUser.UID).ConfigureAwait(false);
|
||||||
|
if (existingDbPerms == null)
|
||||||
|
{
|
||||||
|
await _dbContext.Permissions.AddAsync(permissions).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
existingDbPerms.DisableAnimations = permissions.DisableAnimations;
|
||||||
|
existingDbPerms.DisableSounds = permissions.DisableSounds;
|
||||||
|
existingDbPerms.DisableVFX = permissions.DisableVFX;
|
||||||
|
existingDbPerms.IsPaused = false;
|
||||||
|
existingDbPerms.Sticky = true;
|
||||||
|
|
||||||
|
_dbContext.Permissions.Update(existingDbPerms);
|
||||||
|
}
|
||||||
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
_cacheService.MarkAsStale(UserUID, otherUser.UID);
|
||||||
|
|
||||||
// get the opposite entry of the client pair
|
// get the opposite entry of the client pair
|
||||||
var otherEntry = OppositeEntry(otherUser.UID);
|
var otherEntry = OppositeEntry(otherUser.UID);
|
||||||
var otherIdent = await GetUserIdent(otherUser.UID).ConfigureAwait(false);
|
var otherIdent = await GetUserIdent(otherUser.UID).ConfigureAwait(false);
|
||||||
|
|
||||||
var ownPerm = UserPermissions.Paired;
|
var otherPermissions = existingData?.OtherPermissions ?? null;
|
||||||
var otherPerm = UserPermissions.NoneSet;
|
|
||||||
otherPerm.SetPaired(otherEntry != null);
|
var ownPerm = permissions.ToUserPermissions(setSticky: true);
|
||||||
otherPerm.SetPaused(otherEntry?.IsPaused ?? false);
|
var otherPerm = otherPermissions.ToUserPermissions();
|
||||||
var userPairResponse = new UserPairDto(otherUser.ToUserData(), ownPerm, otherPerm);
|
|
||||||
|
var userPairResponse = new UserPairDto(otherUser.ToUserData(),
|
||||||
|
otherEntry == null ? IndividualPairStatus.OneSided : IndividualPairStatus.Bidirectional,
|
||||||
|
ownPerm, otherPerm);
|
||||||
|
|
||||||
await Clients.User(user.UID).Client_UserAddClientPair(userPairResponse).ConfigureAwait(false);
|
await Clients.User(user.UID).Client_UserAddClientPair(userPairResponse).ConfigureAwait(false);
|
||||||
|
|
||||||
// check if other user is online
|
// check if other user is online
|
||||||
if (otherIdent == null || otherEntry == null) return;
|
if (otherIdent == null || otherEntry == null) return;
|
||||||
|
|
||||||
// send push with update to other user if other user is online
|
// send push with update to other user if other user is online
|
||||||
await Clients.User(otherUser.UID).Client_UserAddClientPair(new UserPairDto(user.ToUserData(), otherPerm, ownPerm)).ConfigureAwait(false);
|
await Clients.User(otherUser.UID)
|
||||||
|
.Client_UserUpdateOtherPairPermissions(new UserPermissionsDto(user.ToUserData(),
|
||||||
|
permissions.ToUserPermissions())).ConfigureAwait(false);
|
||||||
|
|
||||||
if (!otherPerm.IsPaused())
|
await Clients.User(otherUser.UID)
|
||||||
|
.Client_UpdateUserIndividualPairStatusDto(new(user.ToUserData(), IndividualPairStatus.Bidirectional))
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (!ownPerm.IsPaused() && !otherPerm.IsPaused())
|
||||||
{
|
{
|
||||||
await Clients.User(UserUID).Client_UserSendOnline(new(otherUser.ToUserData(), otherIdent)).ConfigureAwait(false);
|
await Clients.User(UserUID).Client_UserSendOnline(new(otherUser.ToUserData(), otherIdent)).ConfigureAwait(false);
|
||||||
await Clients.User(otherUser.UID).Client_UserSendOnline(new(user.ToUserData(), UserCharaIdent)).ConfigureAwait(false);
|
await Clients.User(otherUser.UID).Client_UserSendOnline(new(user.ToUserData(), UserCharaIdent)).ConfigureAwait(false);
|
||||||
@@ -113,60 +163,24 @@ public partial class MareHub
|
|||||||
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);
|
||||||
|
|
||||||
|
await SendOnlineToAllPairedUsers().ConfigureAwait(false);
|
||||||
|
|
||||||
return pairs.Select(p => new OnlineUserIdentDto(new UserData(p.Key), p.Value)).ToList();
|
return pairs.Select(p => new OnlineUserIdentDto(new UserData(p.Key), p.Value)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(Policy = "Identified")]
|
[Authorize(Policy = "Identified")]
|
||||||
public async Task<List<UserPairDto>> UserGetPairedClients()
|
public async Task<List<UserFullPairDto>> UserGetPairedClients()
|
||||||
{
|
{
|
||||||
_logger.LogCallInfo();
|
_logger.LogCallInfo();
|
||||||
|
|
||||||
var query =
|
var pairs = await _cacheService.GetAllPairs(UserUID).ConfigureAwait(false);
|
||||||
from userToOther in _dbContext.ClientPairs
|
return pairs.Select(p =>
|
||||||
join otherToUser in _dbContext.ClientPairs
|
|
||||||
on new
|
|
||||||
{
|
{
|
||||||
user = userToOther.UserUID,
|
return new UserFullPairDto(new UserData(p.Key, p.Value.Alias),
|
||||||
other = userToOther.OtherUserUID,
|
p.Value.ToIndividualPairStatus(),
|
||||||
} equals new
|
p.Value.GIDs.Where(g => !string.Equals(g, Constants.IndividualKeyword, StringComparison.OrdinalIgnoreCase)).ToList(),
|
||||||
{
|
p.Value.OwnPermissions.ToUserPermissions(setSticky: true),
|
||||||
user = otherToUser.OtherUserUID,
|
p.Value.OtherPermissions.ToUserPermissions());
|
||||||
other = otherToUser.UserUID,
|
|
||||||
} into leftJoin
|
|
||||||
from otherEntry in leftJoin.DefaultIfEmpty()
|
|
||||||
where
|
|
||||||
userToOther.UserUID == UserUID
|
|
||||||
select new
|
|
||||||
{
|
|
||||||
userToOther.OtherUser.Alias,
|
|
||||||
userToOther.IsPaused,
|
|
||||||
OtherIsPaused = otherEntry != null && otherEntry.IsPaused,
|
|
||||||
userToOther.OtherUserUID,
|
|
||||||
IsSynced = otherEntry != null,
|
|
||||||
DisableOwnAnimations = userToOther.DisableAnimations,
|
|
||||||
DisableOwnSounds = userToOther.DisableSounds,
|
|
||||||
DisableOwnVFX = userToOther.DisableVFX,
|
|
||||||
DisableOtherAnimations = otherEntry == null ? false : otherEntry.DisableAnimations,
|
|
||||||
DisableOtherSounds = otherEntry == null ? false : otherEntry.DisableSounds,
|
|
||||||
DisableOtherVFX = otherEntry == null ? false : otherEntry.DisableVFX
|
|
||||||
};
|
|
||||||
|
|
||||||
var results = await query.AsNoTracking().ToListAsync().ConfigureAwait(false);
|
|
||||||
|
|
||||||
return results.Select(c =>
|
|
||||||
{
|
|
||||||
var ownPerm = UserPermissions.Paired;
|
|
||||||
ownPerm.SetPaused(c.IsPaused);
|
|
||||||
ownPerm.SetDisableAnimations(c.DisableOwnAnimations);
|
|
||||||
ownPerm.SetDisableSounds(c.DisableOwnSounds);
|
|
||||||
ownPerm.SetDisableVFX(c.DisableOwnVFX);
|
|
||||||
var otherPerm = UserPermissions.NoneSet;
|
|
||||||
otherPerm.SetPaired(c.IsSynced);
|
|
||||||
otherPerm.SetPaused(c.OtherIsPaused);
|
|
||||||
otherPerm.SetDisableAnimations(c.DisableOtherAnimations);
|
|
||||||
otherPerm.SetDisableSounds(c.DisableOtherSounds);
|
|
||||||
otherPerm.SetDisableVFX(c.DisableOtherVFX);
|
|
||||||
return new UserPairDto(new(c.OtherUserUID, c.Alias), ownPerm, otherPerm);
|
|
||||||
}).ToList();
|
}).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,6 +265,9 @@ public partial class MareHub
|
|||||||
+ string.Join(Environment.NewLine, invalidFileSwapPaths.Select(p => "Invalid FileSwap Path: " + p)));
|
+ string.Join(Environment.NewLine, invalidFileSwapPaths.Select(p => "Invalid FileSwap Path: " + p)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var allPairs = await _cacheService.GetAllPairs(UserUID).ConfigureAwait(false);
|
||||||
|
allPairs.Where(p => !p.Value.OwnPermissions.IsPaused && p.Value.OtherPermissions != null && !p.Value.OtherPermissions.IsPaused).ToList();
|
||||||
|
|
||||||
var allPairedUsers = await GetAllPairedUnpausedUsers().ConfigureAwait(false);
|
var allPairedUsers = await GetAllPairedUnpausedUsers().ConfigureAwait(false);
|
||||||
var idents = await GetOnlineUsers(allPairedUsers).ConfigureAwait(false);
|
var idents = await GetOnlineUsers(allPairedUsers).ConfigureAwait(false);
|
||||||
|
|
||||||
@@ -276,53 +293,46 @@ public partial class MareHub
|
|||||||
await _dbContext.ClientPairs.SingleOrDefaultAsync(w => w.UserUID == UserUID && w.OtherUserUID == dto.User.UID).ConfigureAwait(false);
|
await _dbContext.ClientPairs.SingleOrDefaultAsync(w => w.UserUID == UserUID && w.OtherUserUID == dto.User.UID).ConfigureAwait(false);
|
||||||
if (callerPair == null) return;
|
if (callerPair == null) return;
|
||||||
|
|
||||||
bool callerHadPaused = callerPair.IsPaused;
|
var pairData = await _cacheService.GetPairData(UserUID, dto.User.UID).ConfigureAwait(false);
|
||||||
|
|
||||||
// delete from database, send update info to users pair list
|
// delete from database, send update info to users pair list
|
||||||
_dbContext.ClientPairs.Remove(callerPair);
|
_dbContext.ClientPairs.Remove(callerPair);
|
||||||
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
_cacheService.MarkAsStale(UserUID, dto.User.UID);
|
||||||
|
|
||||||
_logger.LogCallInfo(MareHubLogger.Args(dto, "Success"));
|
_logger.LogCallInfo(MareHubLogger.Args(dto, "Success"));
|
||||||
|
|
||||||
await Clients.User(UserUID).Client_UserRemoveClientPair(dto).ConfigureAwait(false);
|
await Clients.User(UserUID).Client_UserRemoveClientPair(dto).ConfigureAwait(false);
|
||||||
|
|
||||||
// check if opposite entry exists
|
// check if opposite entry exists
|
||||||
var oppositeClientPair = OppositeEntry(dto.User.UID);
|
if (!pairData.IndividuallyPaired) return;
|
||||||
if (oppositeClientPair == null) return;
|
|
||||||
|
|
||||||
// check if other user is online, if no then there is no need to do anything further
|
// check if other user is online, if no then there is no need to do anything further
|
||||||
var otherIdent = await GetUserIdent(dto.User.UID).ConfigureAwait(false);
|
var otherIdent = await GetUserIdent(dto.User.UID).ConfigureAwait(false);
|
||||||
if (otherIdent == null) return;
|
if (otherIdent == null) return;
|
||||||
|
|
||||||
// get own ident and
|
|
||||||
await Clients.User(dto.User.UID)
|
|
||||||
.Client_UserUpdateOtherPairPermissions(new UserPermissionsDto(new UserData(UserUID),
|
|
||||||
UserPermissions.NoneSet)).ConfigureAwait(false);
|
|
||||||
|
|
||||||
// if the other user had paused the user the state will be offline for either, do nothing
|
// if the other user had paused the user the state will be offline for either, do nothing
|
||||||
bool otherHadPaused = oppositeClientPair.IsPaused;
|
bool callerHadPaused = pairData.OwnPermissions?.IsPaused ?? false;
|
||||||
if (!callerHadPaused && otherHadPaused) return;
|
|
||||||
|
|
||||||
var allUsers = await GetAllPairedClientsWithPauseState().ConfigureAwait(false);
|
// send updated individual pair status
|
||||||
var pauseEntry = allUsers.SingleOrDefault(f => string.Equals(f.UID, dto.User.UID, StringComparison.Ordinal));
|
await Clients.User(dto.User.UID)
|
||||||
var isPausedInGroup = pauseEntry == null || pauseEntry.IsPausedPerGroup is PauseInfo.Paused or PauseInfo.NoConnection;
|
.Client_UpdateUserIndividualPairStatusDto(new(new(UserUID), IndividualPairStatus.OneSided))
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
// if neither user had paused each other and both are in unpaused groups, state will be online for both, do nothing
|
UserPermissionSet? otherPermissions = pairData.OtherPermissions;
|
||||||
if (!callerHadPaused && !otherHadPaused && !isPausedInGroup) return;
|
bool otherHadPaused = otherPermissions?.IsPaused ?? true;
|
||||||
|
|
||||||
|
// if the either had paused, do nothing
|
||||||
|
if (callerHadPaused && otherHadPaused) return;
|
||||||
|
|
||||||
|
var currentPairData = await _cacheService.GetPairData(UserUID, dto.User.UID).ConfigureAwait(false);
|
||||||
|
|
||||||
// if neither user had paused each other and either is not in an unpaused group with each other, change state to offline
|
// if neither user had paused each other and either is not in an unpaused group with each other, change state to offline
|
||||||
if (!callerHadPaused && !otherHadPaused && isPausedInGroup)
|
if (!currentPairData?.IsSynced ?? true)
|
||||||
{
|
{
|
||||||
await Clients.User(UserUID).Client_UserSendOffline(dto).ConfigureAwait(false);
|
await Clients.User(UserUID).Client_UserSendOffline(dto).ConfigureAwait(false);
|
||||||
await Clients.User(dto.User.UID).Client_UserSendOffline(new(new(UserUID))).ConfigureAwait(false);
|
await Clients.User(dto.User.UID).Client_UserSendOffline(new(new(UserUID))).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the caller had paused other but not the other has paused the caller and they are in an unpaused group together, change state to online
|
|
||||||
if (callerHadPaused && !otherHadPaused && !isPausedInGroup)
|
|
||||||
{
|
|
||||||
await Clients.User(UserUID).Client_UserSendOnline(new(dto.User, otherIdent)).ConfigureAwait(false);
|
|
||||||
await Clients.User(dto.User.UID).Client_UserSendOnline(new(new(UserUID), UserCharaIdent)).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(Policy = "Identified")]
|
[Authorize(Policy = "Identified")]
|
||||||
@@ -373,35 +383,49 @@ public partial class MareHub
|
|||||||
_logger.LogCallInfo(MareHubLogger.Args(dto));
|
_logger.LogCallInfo(MareHubLogger.Args(dto));
|
||||||
|
|
||||||
if (string.Equals(dto.User.UID, UserUID, StringComparison.Ordinal)) return;
|
if (string.Equals(dto.User.UID, UserUID, StringComparison.Ordinal)) return;
|
||||||
ClientPair pair = await _dbContext.ClientPairs.SingleOrDefaultAsync(w => w.UserUID == UserUID && w.OtherUserUID == dto.User.UID).ConfigureAwait(false);
|
UserPermissionSet prevPermissions = await _dbContext.Permissions.SingleOrDefaultAsync(w => w.UserUID == UserUID && w.OtherUserUID == dto.User.UID).ConfigureAwait(false);
|
||||||
if (pair == null) return;
|
if (prevPermissions == null) return; // you always should have permissions to another user
|
||||||
|
|
||||||
var pauseChange = pair.IsPaused != dto.Permissions.IsPaused();
|
var oldPairData = await _cacheService.GetPairData(UserUID, dto.User.UID).ConfigureAwait(false);
|
||||||
|
bool setSticky = false;
|
||||||
|
if (!oldPairData.GIDs.Contains(Constants.IndividualKeyword, StringComparer.Ordinal))
|
||||||
|
{
|
||||||
|
if (!oldPairData.OwnPermissions.Sticky && !dto.Permissions.IsSticky())
|
||||||
|
{
|
||||||
|
var defaultPermissions = await _dbContext.UserDefaultPreferredPermissions.SingleAsync(u => u.UserUID == UserUID).ConfigureAwait(false);
|
||||||
|
setSticky = defaultPermissions.IndividualIsSticky;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pair.IsPaused = dto.Permissions.IsPaused();
|
var pauseChange = prevPermissions.IsPaused != dto.Permissions.IsPaused();
|
||||||
pair.DisableAnimations = dto.Permissions.IsDisableAnimations();
|
|
||||||
pair.DisableSounds = dto.Permissions.IsDisableSounds();
|
prevPermissions.IsPaused = dto.Permissions.IsPaused();
|
||||||
pair.DisableVFX = dto.Permissions.IsDisableVFX();
|
prevPermissions.DisableAnimations = dto.Permissions.IsDisableAnimations();
|
||||||
_dbContext.Update(pair);
|
prevPermissions.DisableSounds = dto.Permissions.IsDisableSounds();
|
||||||
|
prevPermissions.DisableVFX = dto.Permissions.IsDisableVFX();
|
||||||
|
prevPermissions.Sticky = dto.Permissions.IsSticky() || setSticky;
|
||||||
|
_dbContext.Update(prevPermissions);
|
||||||
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
_cacheService.MarkAsStale(UserUID, dto.User.UID);
|
||||||
|
|
||||||
_logger.LogCallInfo(MareHubLogger.Args(dto, "Success"));
|
_logger.LogCallInfo(MareHubLogger.Args(dto, "Success"));
|
||||||
|
|
||||||
var otherEntry = OppositeEntry(dto.User.UID);
|
var permCopy = dto.Permissions;
|
||||||
|
permCopy.SetSticky(dto.Permissions.IsSticky() || setSticky);
|
||||||
|
|
||||||
await Clients.User(UserUID).Client_UserUpdateSelfPairPermissions(dto).ConfigureAwait(false);
|
await Clients.User(UserUID).Client_UserUpdateSelfPairPermissions(new UserPermissionsDto(dto.User, permCopy)).ConfigureAwait(false);
|
||||||
|
|
||||||
if (otherEntry != null)
|
|
||||||
{
|
|
||||||
await Clients.User(dto.User.UID).Client_UserUpdateOtherPairPermissions(new UserPermissionsDto(new UserData(UserUID), dto.Permissions)).ConfigureAwait(false);
|
await Clients.User(dto.User.UID).Client_UserUpdateOtherPairPermissions(new UserPermissionsDto(new UserData(UserUID), dto.Permissions)).ConfigureAwait(false);
|
||||||
|
|
||||||
if (pauseChange)
|
var newPairData = await _cacheService.GetPairData(UserUID, dto.User.UID).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (newPairData.OwnPermissions.IsPaused != oldPairData.OwnPermissions.IsPaused)
|
||||||
{
|
{
|
||||||
var otherCharaIdent = await GetUserIdent(pair.OtherUserUID).ConfigureAwait(false);
|
var otherCharaIdent = await GetUserIdent(dto.User.UID).ConfigureAwait(false);
|
||||||
|
var otherPermissions = newPairData.OtherPermissions;
|
||||||
|
|
||||||
if (UserCharaIdent == null || otherCharaIdent == null || otherEntry.IsPaused) return;
|
if (UserCharaIdent == null || otherCharaIdent == null || (otherPermissions?.IsPaused ?? true)) return;
|
||||||
|
|
||||||
if (dto.Permissions.IsPaused())
|
if (newPairData.OwnPermissions.IsPaused)
|
||||||
{
|
{
|
||||||
await Clients.User(UserUID).Client_UserSendOffline(dto).ConfigureAwait(false);
|
await Clients.User(UserUID).Client_UserSendOffline(dto).ConfigureAwait(false);
|
||||||
await Clients.User(dto.User.UID).Client_UserSendOffline(new(new(UserUID))).ConfigureAwait(false);
|
await Clients.User(dto.User.UID).Client_UserSendOffline(new(new(UserUID))).ConfigureAwait(false);
|
||||||
@@ -413,7 +437,6 @@ public partial class MareHub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[Authorize(Policy = "Identified")]
|
[Authorize(Policy = "Identified")]
|
||||||
public async Task UserSetProfile(UserProfileDto dto)
|
public async Task UserSetProfile(UserProfileDto dto)
|
||||||
@@ -498,6 +521,27 @@ public partial class MareHub
|
|||||||
await Clients.Caller.Client_UserUpdateProfile(new(dto.User)).ConfigureAwait(false);
|
await Clients.Caller.Client_UserUpdateProfile(new(dto.User)).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize(Policy = "Authenticated")]
|
||||||
|
public async Task UserUpdateDefaultPermissions(DefaultPermissionsDto defaultPermissions)
|
||||||
|
{
|
||||||
|
_logger.LogCallInfo(MareHubLogger.Args(defaultPermissions));
|
||||||
|
|
||||||
|
var permissions = await _dbContext.UserDefaultPreferredPermissions.SingleAsync(u => u.UserUID == UserUID).ConfigureAwait(false);
|
||||||
|
|
||||||
|
permissions.DisableGroupAnimations = defaultPermissions.DisableGroupAnimations;
|
||||||
|
permissions.DisableGroupSounds = defaultPermissions.DisableGroupSounds;
|
||||||
|
permissions.DisableGroupVFX = defaultPermissions.DisableGroupVFX;
|
||||||
|
permissions.DisableIndividualAnimations = defaultPermissions.DisableIndividualAnimations;
|
||||||
|
permissions.DisableIndividualSounds = defaultPermissions.DisableIndividualSounds;
|
||||||
|
permissions.DisableIndividualVFX = defaultPermissions.DisableIndividualVFX;
|
||||||
|
permissions.IndividualIsSticky = defaultPermissions.IndividualIsSticky;
|
||||||
|
|
||||||
|
_dbContext.Update(permissions);
|
||||||
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
await Clients.Caller.Client_UserUpdateDefaultPermissions(defaultPermissions).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
[GeneratedRegex(@"^([a-z0-9_ '+&,\.\-\{\}]+\/)+([a-z0-9_ '+&,\.\-\{\}]+\.[a-z]{3,4})$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ECMAScript)]
|
[GeneratedRegex(@"^([a-z0-9_ '+&,\.\-\{\}]+\/)+([a-z0-9_ '+&,\.\-\{\}]+\.[a-z]{3,4})$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ECMAScript)]
|
||||||
private static partial Regex GamePathRegex();
|
private static partial Regex GamePathRegex();
|
||||||
|
|
||||||
|
|||||||
@@ -7,10 +7,12 @@ using MareSynchronosServer.Utils;
|
|||||||
using MareSynchronosShared;
|
using MareSynchronosShared;
|
||||||
using MareSynchronosShared.Data;
|
using MareSynchronosShared.Data;
|
||||||
using MareSynchronosShared.Metrics;
|
using MareSynchronosShared.Metrics;
|
||||||
|
using MareSynchronosShared.Models;
|
||||||
using MareSynchronosShared.Services;
|
using MareSynchronosShared.Services;
|
||||||
using MareSynchronosShared.Utils;
|
using MareSynchronosShared.Utils;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using StackExchange.Redis.Extensions.Core.Abstractions;
|
using StackExchange.Redis.Extensions.Core.Abstractions;
|
||||||
|
|
||||||
namespace MareSynchronosServer.Hubs;
|
namespace MareSynchronosServer.Hubs;
|
||||||
@@ -28,13 +30,14 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
|
|||||||
private readonly int _maxJoinedGroupsByUser;
|
private readonly int _maxJoinedGroupsByUser;
|
||||||
private readonly int _maxGroupUserCount;
|
private readonly int _maxGroupUserCount;
|
||||||
private readonly IRedisDatabase _redis;
|
private readonly IRedisDatabase _redis;
|
||||||
|
private readonly UserPairCacheService _cacheService;
|
||||||
private readonly Uri _fileServerAddress;
|
private readonly Uri _fileServerAddress;
|
||||||
private readonly Version _expectedClientVersion;
|
private readonly Version _expectedClientVersion;
|
||||||
|
|
||||||
public MareHub(MareMetrics mareMetrics,
|
public MareHub(MareMetrics mareMetrics,
|
||||||
MareDbContext mareDbContext, ILogger<MareHub> logger, SystemInfoService systemInfoService,
|
MareDbContext mareDbContext, ILogger<MareHub> logger, SystemInfoService systemInfoService,
|
||||||
IConfigurationService<ServerConfiguration> configuration, IHttpContextAccessor contextAccessor,
|
IConfigurationService<ServerConfiguration> configuration, IHttpContextAccessor contextAccessor,
|
||||||
IRedisDatabase redisDb)
|
IRedisDatabase redisDb, UserPairCacheService cacheService)
|
||||||
{
|
{
|
||||||
_mareMetrics = mareMetrics;
|
_mareMetrics = mareMetrics;
|
||||||
_systemInfoService = systemInfoService;
|
_systemInfoService = systemInfoService;
|
||||||
@@ -46,6 +49,7 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
|
|||||||
_expectedClientVersion = configuration.GetValueOrDefault(nameof(ServerConfiguration.ExpectedClientVersion), new Version(0, 0, 0));
|
_expectedClientVersion = configuration.GetValueOrDefault(nameof(ServerConfiguration.ExpectedClientVersion), new Version(0, 0, 0));
|
||||||
_contextAccessor = contextAccessor;
|
_contextAccessor = contextAccessor;
|
||||||
_redis = redisDb;
|
_redis = redisDb;
|
||||||
|
_cacheService = cacheService;
|
||||||
_logger = new MareHubLogger(this, logger);
|
_logger = new MareHubLogger(this, logger);
|
||||||
_dbContext = mareDbContext;
|
_dbContext = mareDbContext;
|
||||||
}
|
}
|
||||||
@@ -64,7 +68,18 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
|
|||||||
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Information, "Welcome to Mare Synchronos \"" + _shardName + "\", Current Online Users: " + _systemInfoService.SystemInfoDto.OnlineUsers).ConfigureAwait(false);
|
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Information, "Welcome to Mare Synchronos \"" + _shardName + "\", Current Online Users: " + _systemInfoService.SystemInfoDto.OnlineUsers).ConfigureAwait(false);
|
||||||
await SendOnlineToAllPairedUsers().ConfigureAwait(false);
|
|
||||||
|
var defaultPermissions = await _dbContext.UserDefaultPreferredPermissions.SingleOrDefaultAsync(u => u.UserUID == UserUID).ConfigureAwait(false);
|
||||||
|
if (defaultPermissions == null)
|
||||||
|
{
|
||||||
|
defaultPermissions = new UserDefaultPreferredPermission()
|
||||||
|
{
|
||||||
|
UserUID = UserUID,
|
||||||
|
};
|
||||||
|
|
||||||
|
_dbContext.UserDefaultPreferredPermissions.Add(defaultPermissions);
|
||||||
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
return new ConnectionDto(new UserData(dbUser.UID, string.IsNullOrWhiteSpace(dbUser.Alias) ? null : dbUser.Alias))
|
return new ConnectionDto(new UserData(dbUser.UID, string.IsNullOrWhiteSpace(dbUser.Alias) ? null : dbUser.Alias))
|
||||||
{
|
{
|
||||||
@@ -78,7 +93,17 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
|
|||||||
ShardName = _shardName,
|
ShardName = _shardName,
|
||||||
MaxGroupsJoinedByUser = _maxJoinedGroupsByUser,
|
MaxGroupsJoinedByUser = _maxJoinedGroupsByUser,
|
||||||
MaxGroupUserCount = _maxGroupUserCount,
|
MaxGroupUserCount = _maxGroupUserCount,
|
||||||
FileServerAddress = _fileServerAddress
|
FileServerAddress = _fileServerAddress,
|
||||||
|
},
|
||||||
|
DefaultPreferredPermissions = new DefaultPermissionsDto()
|
||||||
|
{
|
||||||
|
DisableGroupAnimations = defaultPermissions.DisableGroupAnimations,
|
||||||
|
DisableGroupSounds = defaultPermissions.DisableGroupSounds,
|
||||||
|
DisableGroupVFX = defaultPermissions.DisableGroupVFX,
|
||||||
|
DisableIndividualAnimations = defaultPermissions.DisableIndividualAnimations,
|
||||||
|
DisableIndividualSounds = defaultPermissions.DisableIndividualSounds,
|
||||||
|
DisableIndividualVFX = defaultPermissions.DisableIndividualVFX,
|
||||||
|
IndividualIsSticky = defaultPermissions.IndividualIsSticky,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -119,11 +144,13 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
|
|||||||
_logger.LogCallWarning(MareHubLogger.Args(_contextAccessor.GetIpAddress(), exception.Message, exception.StackTrace));
|
_logger.LogCallWarning(MareHubLogger.Args(_contextAccessor.GetIpAddress(), exception.Message, exception.StackTrace));
|
||||||
|
|
||||||
await RemoveUserFromRedis().ConfigureAwait(false);
|
await RemoveUserFromRedis().ConfigureAwait(false);
|
||||||
|
_cacheService.ClearCache(UserUID);
|
||||||
|
|
||||||
await SendOfflineToAllPairedUsers().ConfigureAwait(false);
|
await SendOfflineToAllPairedUsers().ConfigureAwait(false);
|
||||||
|
|
||||||
_dbContext.RemoveRange(_dbContext.Files.Where(f => !f.Uploaded && f.UploaderUID == UserUID));
|
_dbContext.RemoveRange(_dbContext.Files.Where(f => !f.Uploaded && f.UploaderUID == UserUID));
|
||||||
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
await _dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
|
|
||||||
|
|||||||
@@ -21,20 +21,20 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
||||||
<PackageReference Include="Grpc.AspNetCore" Version="2.53.0" />
|
<PackageReference Include="Grpc.AspNetCore" Version="2.57.0" />
|
||||||
<PackageReference Include="Grpc.Net.Client" Version="2.53.0" />
|
<PackageReference Include="Grpc.Net.Client" Version="2.57.0" />
|
||||||
<PackageReference Include="IDisposableAnalyzers" Version="4.0.6">
|
<PackageReference Include="IDisposableAnalyzers" Version="4.0.7">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="lz4net" Version="1.0.15.93" />
|
<PackageReference Include="lz4net" Version="1.0.15.93" />
|
||||||
<PackageReference Include="Meziantou.Analyzer" Version="2.0.49">
|
<PackageReference Include="Meziantou.Analyzer" Version="2.0.93">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="7.0.0" />
|
||||||
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.30.0" />
|
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="7.0.2" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.0.1" />
|
<PackageReference Include="SixLabors.ImageSharp" Version="3.0.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public class Program
|
|||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
var hostBuilder = CreateHostBuilder(args);
|
var hostBuilder = CreateHostBuilder(args);
|
||||||
var host = hostBuilder.Build();
|
using var host = hostBuilder.Build();
|
||||||
using (var scope = host.Services.CreateScope())
|
using (var scope = host.Services.CreateScope())
|
||||||
{
|
{
|
||||||
var services = scope.ServiceProvider;
|
var services = scope.ServiceProvider;
|
||||||
@@ -38,7 +38,7 @@ public class Program
|
|||||||
|
|
||||||
metrics.SetGaugeTo(MetricsAPI.GaugeUsersRegistered, context.Users.AsNoTracking().Count());
|
metrics.SetGaugeTo(MetricsAPI.GaugeUsersRegistered, context.Users.AsNoTracking().Count());
|
||||||
metrics.SetGaugeTo(MetricsAPI.GaugePairs, context.ClientPairs.AsNoTracking().Count());
|
metrics.SetGaugeTo(MetricsAPI.GaugePairs, context.ClientPairs.AsNoTracking().Count());
|
||||||
metrics.SetGaugeTo(MetricsAPI.GaugePairsPaused, context.ClientPairs.AsNoTracking().Count(p => p.IsPaused));
|
metrics.SetGaugeTo(MetricsAPI.GaugePairsPaused, context.Permissions.AsNoTracking().Count(p => p.IsPaused));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ public class Program
|
|||||||
|
|
||||||
public static IHostBuilder CreateHostBuilder(string[] args)
|
public static IHostBuilder CreateHostBuilder(string[] args)
|
||||||
{
|
{
|
||||||
var loggerFactory = LoggerFactory.Create(builder =>
|
using var loggerFactory = LoggerFactory.Create(builder =>
|
||||||
{
|
{
|
||||||
builder.ClearProviders();
|
builder.ClearProviders();
|
||||||
builder.AddConsole();
|
builder.AddConsole();
|
||||||
|
|||||||
@@ -70,10 +70,9 @@ public class SystemInfoService : IHostedService, IDisposable
|
|||||||
|
|
||||||
_mareMetrics.SetGaugeTo(MetricsAPI.GaugeAuthorizedConnections, onlineUsers);
|
_mareMetrics.SetGaugeTo(MetricsAPI.GaugeAuthorizedConnections, onlineUsers);
|
||||||
_mareMetrics.SetGaugeTo(MetricsAPI.GaugePairs, db.ClientPairs.AsNoTracking().Count());
|
_mareMetrics.SetGaugeTo(MetricsAPI.GaugePairs, db.ClientPairs.AsNoTracking().Count());
|
||||||
_mareMetrics.SetGaugeTo(MetricsAPI.GaugePairsPaused, db.ClientPairs.AsNoTracking().Count(p => p.IsPaused));
|
_mareMetrics.SetGaugeTo(MetricsAPI.GaugePairsPaused, db.Permissions.AsNoTracking().Count(p => p.IsPaused));
|
||||||
_mareMetrics.SetGaugeTo(MetricsAPI.GaugeGroups, db.Groups.AsNoTracking().Count());
|
_mareMetrics.SetGaugeTo(MetricsAPI.GaugeGroups, db.Groups.AsNoTracking().Count());
|
||||||
_mareMetrics.SetGaugeTo(MetricsAPI.GaugeGroupPairs, db.GroupPairs.AsNoTracking().Count());
|
_mareMetrics.SetGaugeTo(MetricsAPI.GaugeGroupPairs, db.GroupPairs.AsNoTracking().Count());
|
||||||
_mareMetrics.SetGaugeTo(MetricsAPI.GaugeGroupPairsPaused, db.GroupPairs.AsNoTracking().Count(p => p.IsPaused));
|
|
||||||
_mareMetrics.SetGaugeTo(MetricsAPI.GaugeUsersRegistered, db.Users.AsNoTracking().Count());
|
_mareMetrics.SetGaugeTo(MetricsAPI.GaugeUsersRegistered, db.Users.AsNoTracking().Count());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,194 @@
|
|||||||
|
using MareSynchronos.API.Data;
|
||||||
|
using MareSynchronosShared.Data;
|
||||||
|
using MareSynchronosShared.Models;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
|
namespace MareSynchronosServer.Services;
|
||||||
|
|
||||||
|
public class UserPairCacheService : IHostedService
|
||||||
|
{
|
||||||
|
private readonly ConcurrentDictionary<string, Dictionary<string, UserInfo>> _cache;
|
||||||
|
private readonly ILogger<UserPairCacheService> _logger;
|
||||||
|
private readonly IDbContextFactory<MareDbContext> _dbContextFactory;
|
||||||
|
private readonly ConcurrentQueue<(string? UID, string? OtherUID)> _staleUserData;
|
||||||
|
public UserPairCacheService(ILogger<UserPairCacheService> logger, IDbContextFactory<MareDbContext> dbContextFactory)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_dbContextFactory = dbContextFactory;
|
||||||
|
_staleUserData = new();
|
||||||
|
_cache = new(StringComparer.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearCache(string uid)
|
||||||
|
{
|
||||||
|
_cache.TryRemove(uid, out _);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Dictionary<string, UserInfo>> GetAllPairs(string uid)
|
||||||
|
{
|
||||||
|
await WaitForProcessing(uid).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (!_cache.ContainsKey(uid))
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Building full cache: Did not find PairData for {uid}", uid);
|
||||||
|
|
||||||
|
using var dbContext = await _dbContextFactory.CreateDbContextAsync().ConfigureAwait(false);
|
||||||
|
_cache[uid] = await BuildFullCache(dbContext, uid).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _cache[uid];
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<UserInfo?> GetPairData(string uid, string otheruid)
|
||||||
|
{
|
||||||
|
await WaitForProcessing(uid, otheruid).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (!_cache.TryGetValue(uid, out var cachedInfos))
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Building full cache: Did not find PairData for {uid}:{otheruid}", uid, otheruid);
|
||||||
|
using var dbContext = await _dbContextFactory.CreateDbContextAsync().ConfigureAwait(false);
|
||||||
|
_cache[uid] = cachedInfos = await BuildFullCache(dbContext, uid).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cachedInfos.TryGetValue(otheruid, out var info))
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Building individual cache: Did not find PairData for {uid}:{otheruid}", uid, otheruid);
|
||||||
|
using var dbContext = await _dbContextFactory.CreateDbContextAsync().ConfigureAwait(false);
|
||||||
|
info = await BuildIndividualCache(dbContext, uid, otheruid).ConfigureAwait(false);
|
||||||
|
_cache[uid][otheruid] = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MarkAsStale(string? uid, string? otheruid)
|
||||||
|
{
|
||||||
|
if (!_staleUserData.Any(u => string.Equals(u.UID, uid, StringComparison.Ordinal)
|
||||||
|
&& string.Equals(u.OtherUID, otheruid, StringComparison.OrdinalIgnoreCase)))
|
||||||
|
{
|
||||||
|
_staleUserData.Enqueue((uid, otheruid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task StartAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
_ = ProcessStaleEntries();
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task StopAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Dictionary<string, UserInfo>> BuildFullCache(MareDbContext dbContext, string uid)
|
||||||
|
{
|
||||||
|
var pairs = await dbContext.GetAllPairsForUser(uid).ToListAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
return pairs.GroupBy(g => g.OtherUserUID, StringComparer.Ordinal)
|
||||||
|
.ToDictionary(g => g.Key, g =>
|
||||||
|
{
|
||||||
|
return new UserInfo(g.First().Alias,
|
||||||
|
g.SingleOrDefault(p => string.IsNullOrEmpty(p.GID))?.Synced ?? false,
|
||||||
|
g.Max(p => p.Synced),
|
||||||
|
g.Select(p => string.IsNullOrEmpty(p.GID) ? Constants.IndividualKeyword : p.GID).ToList(),
|
||||||
|
g.First().OwnPermissions,
|
||||||
|
g.First().OtherPermissions);
|
||||||
|
}, StringComparer.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<UserInfo?> BuildIndividualCache(MareDbContext dbContext, string uid, string otheruid)
|
||||||
|
{
|
||||||
|
var pairs = await dbContext.GetAllPairsForUser(uid).Where(u => u.OtherUserUID == otheruid).ToListAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (!pairs.Any()) return null;
|
||||||
|
|
||||||
|
var groups = pairs.Select(g => g.GID).ToList();
|
||||||
|
return new UserInfo(pairs[0].Alias,
|
||||||
|
pairs.SingleOrDefault(p => string.IsNullOrEmpty(p.GID))?.Synced ?? false,
|
||||||
|
pairs.Max(p => p.Synced),
|
||||||
|
pairs.Select(p => string.IsNullOrEmpty(p.GID) ? Constants.IndividualKeyword : p.GID).ToList(),
|
||||||
|
pairs[0].OwnPermissions,
|
||||||
|
pairs[0].OtherPermissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ProcessStaleEntries()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
await Task.Delay(250).ConfigureAwait(false);
|
||||||
|
if (_staleUserData.Any())
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Processing Stale Entries");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var dbContext = await _dbContextFactory.CreateDbContextAsync().ConfigureAwait(false);
|
||||||
|
while (_staleUserData.TryPeek(out var staleUserPair))
|
||||||
|
{
|
||||||
|
if (staleUserPair.UID == null)
|
||||||
|
{
|
||||||
|
foreach (var entry in _cache.Where(c => c.Value.ContainsKey(staleUserPair.OtherUID)).Select(k => k.Key).Distinct(StringComparer.Ordinal).ToList())
|
||||||
|
{
|
||||||
|
_logger.LogDebug("UID is null; Building Individual Cache for {user}:{user2}", staleUserPair.UID, entry);
|
||||||
|
_staleUserData.Enqueue(new(staleUserPair.OtherUID, entry));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (staleUserPair.OtherUID == null)
|
||||||
|
{
|
||||||
|
foreach (var entry in _cache.Where(c => c.Value.ContainsKey(staleUserPair.UID)).Select(k => k.Key).Distinct(StringComparer.Ordinal).ToList())
|
||||||
|
{
|
||||||
|
_logger.LogDebug("OtherUID is null; Building Individual Cache for {user}:{user2}", staleUserPair.UID, entry);
|
||||||
|
_staleUserData.Enqueue(new(staleUserPair.UID, entry));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_cache.ContainsKey(staleUserPair.UID))
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Building Individual Cache for {user}:{user2}", staleUserPair.UID, staleUserPair.OtherUID);
|
||||||
|
|
||||||
|
var userInfo = await BuildIndividualCache(dbContext, staleUserPair.UID, staleUserPair.OtherUID).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (userInfo == null) _cache[staleUserPair.UID].Remove(staleUserPair.OtherUID);
|
||||||
|
else _cache[staleUserPair.UID][staleUserPair.OtherUID] = userInfo;
|
||||||
|
|
||||||
|
if (_cache.ContainsKey(staleUserPair.OtherUID))
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Building Individual Cache for {user}:{user2}", staleUserPair.OtherUID, staleUserPair.UID);
|
||||||
|
var otherUserInfo = await BuildIndividualCache(dbContext, staleUserPair.OtherUID, staleUserPair.UID).ConfigureAwait(false);
|
||||||
|
if (otherUserInfo == null) _cache[staleUserPair.OtherUID].Remove(staleUserPair.UID);
|
||||||
|
else _cache[staleUserPair.OtherUID][staleUserPair.UID] = otherUserInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_staleUserData.TryDequeue(out _);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error during Stale entry processing");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task WaitForProcessing(string uid)
|
||||||
|
{
|
||||||
|
while (_staleUserData.Any(u => string.Equals(u.UID, uid, StringComparison.Ordinal)))
|
||||||
|
{
|
||||||
|
await Task.Delay(50).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task WaitForProcessing(string uid, string otheruid)
|
||||||
|
{
|
||||||
|
while (_staleUserData.Any(u => string.Equals(u.UID, uid, StringComparison.Ordinal) && string.Equals(u.OtherUID, otheruid, StringComparison.Ordinal)))
|
||||||
|
{
|
||||||
|
await Task.Delay(50).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record UserInfo(string Alias, bool IndividuallyPaired, bool IsSynced, List<string> GIDs, UserPermissionSet? OwnPermissions, UserPermissionSet? OtherPermissions);
|
||||||
|
}
|
||||||
@@ -5,8 +5,6 @@ using Microsoft.AspNetCore.SignalR;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using AspNetCoreRateLimit;
|
using AspNetCoreRateLimit;
|
||||||
using MareSynchronosShared.Data;
|
using MareSynchronosShared.Data;
|
||||||
using MareSynchronosShared.Protos;
|
|
||||||
using Grpc.Net.Client.Configuration;
|
|
||||||
using MareSynchronosShared.Metrics;
|
using MareSynchronosShared.Metrics;
|
||||||
using MareSynchronosServer.Services;
|
using MareSynchronosServer.Services;
|
||||||
using MareSynchronosShared.Utils;
|
using MareSynchronosShared.Utils;
|
||||||
@@ -92,7 +90,9 @@ public class Startup
|
|||||||
|
|
||||||
services.AddSingleton<ServerTokenGenerator>();
|
services.AddSingleton<ServerTokenGenerator>();
|
||||||
services.AddSingleton<SystemInfoService>();
|
services.AddSingleton<SystemInfoService>();
|
||||||
|
services.AddSingleton<UserPairCacheService>();
|
||||||
services.AddHostedService(provider => provider.GetService<SystemInfoService>());
|
services.AddHostedService(provider => provider.GetService<SystemInfoService>());
|
||||||
|
services.AddHostedService(p => p.GetService<UserPairCacheService>());
|
||||||
// configure services based on main server status
|
// configure services based on main server status
|
||||||
ConfigureServicesBasedOnShardType(services, mareConfig, isMainServer);
|
ConfigureServicesBasedOnShardType(services, mareConfig, isMainServer);
|
||||||
|
|
||||||
@@ -134,6 +134,7 @@ public class Startup
|
|||||||
.WithResolver(resolver);
|
.WithResolver(resolver);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// configure redis for SignalR
|
// configure redis for SignalR
|
||||||
var redisConnection = mareConfig.GetValue(nameof(ServerConfiguration.RedisConnectionString), string.Empty);
|
var redisConnection = mareConfig.GetValue(nameof(ServerConfiguration.RedisConnectionString), string.Empty);
|
||||||
signalRServiceBuilder.AddStackExchangeRedis(redisConnection, options => { });
|
signalRServiceBuilder.AddStackExchangeRedis(redisConnection, options => { });
|
||||||
@@ -185,6 +186,8 @@ public class Startup
|
|||||||
{
|
{
|
||||||
services.AddSingleton<SecretKeyAuthenticatorService>();
|
services.AddSingleton<SecretKeyAuthenticatorService>();
|
||||||
services.AddTransient<IAuthorizationHandler, UserRequirementHandler>();
|
services.AddTransient<IAuthorizationHandler, UserRequirementHandler>();
|
||||||
|
services.AddTransient<IAuthorizationHandler, ValidTokenRequirementHandler>();
|
||||||
|
services.AddTransient<IAuthorizationHandler, ValidTokenHubRequirementHandler>();
|
||||||
|
|
||||||
services.AddOptions<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme)
|
services.AddOptions<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme)
|
||||||
.Configure<IConfigurationService<MareConfigurationAuthBase>>((options, config) =>
|
.Configure<IConfigurationService<MareConfigurationAuthBase>>((options, config) =>
|
||||||
@@ -192,7 +195,7 @@ public class Startup
|
|||||||
options.TokenValidationParameters = new()
|
options.TokenValidationParameters = new()
|
||||||
{
|
{
|
||||||
ValidateIssuer = false,
|
ValidateIssuer = false,
|
||||||
ValidateLifetime = false,
|
ValidateLifetime = true,
|
||||||
ValidateAudience = false,
|
ValidateAudience = false,
|
||||||
ValidateIssuerSigningKey = true,
|
ValidateIssuerSigningKey = true,
|
||||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(config.GetValue<string>(nameof(MareConfigurationAuthBase.Jwt)))),
|
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(config.GetValue<string>(nameof(MareConfigurationAuthBase.Jwt)))),
|
||||||
@@ -215,18 +218,24 @@ public class Startup
|
|||||||
{
|
{
|
||||||
policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
|
policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
|
||||||
policy.RequireAuthenticatedUser();
|
policy.RequireAuthenticatedUser();
|
||||||
|
policy.AddRequirements(new ValidTokenRequirement());
|
||||||
});
|
});
|
||||||
options.AddPolicy("Identified", policy =>
|
options.AddPolicy("Identified", policy =>
|
||||||
{
|
{
|
||||||
policy.AddRequirements(new UserRequirement(UserRequirements.Identified));
|
policy.AddRequirements(new UserRequirement(UserRequirements.Identified));
|
||||||
|
policy.AddRequirements(new ValidTokenRequirement());
|
||||||
|
|
||||||
});
|
});
|
||||||
options.AddPolicy("Admin", policy =>
|
options.AddPolicy("Admin", policy =>
|
||||||
{
|
{
|
||||||
policy.AddRequirements(new UserRequirement(UserRequirements.Identified | UserRequirements.Administrator));
|
policy.AddRequirements(new UserRequirement(UserRequirements.Identified | UserRequirements.Administrator));
|
||||||
|
policy.AddRequirements(new ValidTokenRequirement());
|
||||||
|
|
||||||
});
|
});
|
||||||
options.AddPolicy("Moderator", policy =>
|
options.AddPolicy("Moderator", policy =>
|
||||||
{
|
{
|
||||||
policy.AddRequirements(new UserRequirement(UserRequirements.Identified | UserRequirements.Moderator | UserRequirements.Administrator));
|
policy.AddRequirements(new UserRequirement(UserRequirements.Identified | UserRequirements.Moderator | UserRequirements.Administrator));
|
||||||
|
policy.AddRequirements(new ValidTokenRequirement());
|
||||||
});
|
});
|
||||||
options.AddPolicy("Internal", new AuthorizationPolicyBuilder().RequireClaim(MareClaimTypes.Internal, "true").Build());
|
options.AddPolicy("Internal", new AuthorizationPolicyBuilder().RequireClaim(MareClaimTypes.Internal, "true").Build());
|
||||||
});
|
});
|
||||||
@@ -243,6 +252,15 @@ public class Startup
|
|||||||
}).UseSnakeCaseNamingConvention();
|
}).UseSnakeCaseNamingConvention();
|
||||||
options.EnableThreadSafetyChecks(false);
|
options.EnableThreadSafetyChecks(false);
|
||||||
}, mareConfig.GetValue(nameof(MareConfigurationBase.DbContextPoolSize), 1024));
|
}, mareConfig.GetValue(nameof(MareConfigurationBase.DbContextPoolSize), 1024));
|
||||||
|
services.AddDbContextFactory<MareDbContext>(options =>
|
||||||
|
{
|
||||||
|
options.UseNpgsql(Configuration.GetConnectionString("DefaultConnection"), builder =>
|
||||||
|
{
|
||||||
|
builder.MigrationsHistoryTable("_efmigrationshistory", "public");
|
||||||
|
builder.MigrationsAssembly("MareSynchronosShared");
|
||||||
|
}).UseSnakeCaseNamingConvention();
|
||||||
|
options.EnableThreadSafetyChecks(false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ConfigureMetrics(IServiceCollection services)
|
private static void ConfigureMetrics(IServiceCollection services)
|
||||||
@@ -267,8 +285,8 @@ public class Startup
|
|||||||
MetricsAPI.GaugeAvailableWorkerThreads,
|
MetricsAPI.GaugeAvailableWorkerThreads,
|
||||||
MetricsAPI.GaugeGroups,
|
MetricsAPI.GaugeGroups,
|
||||||
MetricsAPI.GaugeGroupPairs,
|
MetricsAPI.GaugeGroupPairs,
|
||||||
MetricsAPI.GaugeGroupPairsPaused,
|
|
||||||
MetricsAPI.GaugeUsersRegistered,
|
MetricsAPI.GaugeUsersRegistered,
|
||||||
|
MetricsAPI.GaugeAuthenticationCacheEntries,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
using MareSynchronos.API.Data.Enum;
|
using MareSynchronos.API.Data.Enum;
|
||||||
using MareSynchronos.API.Data.Extensions;
|
using MareSynchronos.API.Data.Extensions;
|
||||||
using MareSynchronosShared.Models;
|
using MareSynchronosShared.Models;
|
||||||
|
using static MareSynchronosServer.Services.UserPairCacheService;
|
||||||
|
|
||||||
|
namespace MareSynchronosServer.Utils;
|
||||||
|
|
||||||
namespace MareSynchronosServer.Utils
|
|
||||||
{
|
|
||||||
public static class Extensions
|
public static class Extensions
|
||||||
{
|
{
|
||||||
public static GroupData ToGroupData(this Group group)
|
public static GroupData ToGroupData(this Group group)
|
||||||
@@ -22,19 +23,26 @@ namespace MareSynchronosServer.Utils
|
|||||||
return new UserData(user.UID, user.Alias);
|
return new UserData(user.UID, user.Alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GroupPermissions GetGroupPermissions(this Group group)
|
public static IndividualPairStatus ToIndividualPairStatus(this UserInfo userInfo)
|
||||||
|
{
|
||||||
|
if (userInfo.IndividuallyPaired) return IndividualPairStatus.Bidirectional;
|
||||||
|
if (!userInfo.IndividuallyPaired && userInfo.GIDs.Contains(Constants.IndividualKeyword, StringComparer.Ordinal)) return IndividualPairStatus.OneSided;
|
||||||
|
return IndividualPairStatus.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GroupPermissions ToEnum(this Group group)
|
||||||
{
|
{
|
||||||
var permissions = GroupPermissions.NoneSet;
|
var permissions = GroupPermissions.NoneSet;
|
||||||
permissions.SetDisableAnimations(group.DisableAnimations);
|
permissions.SetPreferDisableAnimations(group.PreferDisableAnimations);
|
||||||
permissions.SetDisableSounds(group.DisableSounds);
|
permissions.SetPreferDisableSounds(group.PreferDisableSounds);
|
||||||
|
permissions.SetPreferDisableVFX(group.PreferDisableVFX);
|
||||||
permissions.SetDisableInvites(!group.InvitesEnabled);
|
permissions.SetDisableInvites(!group.InvitesEnabled);
|
||||||
permissions.SetDisableVFX(group.DisableVFX);
|
|
||||||
return permissions;
|
return permissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GroupUserPermissions GetGroupPairPermissions(this GroupPair groupPair)
|
public static GroupUserPreferredPermissions ToEnum(this GroupPairPreferredPermission groupPair)
|
||||||
{
|
{
|
||||||
var permissions = GroupUserPermissions.NoneSet;
|
var permissions = GroupUserPreferredPermissions.NoneSet;
|
||||||
permissions.SetDisableAnimations(groupPair.DisableAnimations);
|
permissions.SetDisableAnimations(groupPair.DisableAnimations);
|
||||||
permissions.SetDisableSounds(groupPair.DisableSounds);
|
permissions.SetDisableSounds(groupPair.DisableSounds);
|
||||||
permissions.SetPaused(groupPair.IsPaused);
|
permissions.SetPaused(groupPair.IsPaused);
|
||||||
@@ -42,12 +50,25 @@ namespace MareSynchronosServer.Utils
|
|||||||
return permissions;
|
return permissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GroupUserInfo GetGroupPairUserInfo(this GroupPair groupPair)
|
public static GroupPairUserInfo ToEnum(this GroupPair groupPair)
|
||||||
{
|
{
|
||||||
var groupUserInfo = GroupUserInfo.None;
|
var groupUserInfo = GroupPairUserInfo.None;
|
||||||
groupUserInfo.SetPinned(groupPair.IsPinned);
|
groupUserInfo.SetPinned(groupPair.IsPinned);
|
||||||
groupUserInfo.SetModerator(groupPair.IsModerator);
|
groupUserInfo.SetModerator(groupPair.IsModerator);
|
||||||
return groupUserInfo;
|
return groupUserInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static UserPermissions ToUserPermissions(this UserPermissionSet? permissions, bool setSticky = false)
|
||||||
|
{
|
||||||
|
if (permissions == null) return UserPermissions.NoneSet;
|
||||||
|
|
||||||
|
UserPermissions perm = UserPermissions.NoneSet;
|
||||||
|
perm.SetPaused(permissions.IsPaused);
|
||||||
|
perm.SetDisableAnimations(permissions.DisableAnimations);
|
||||||
|
perm.SetDisableSounds(permissions.DisableSounds);
|
||||||
|
perm.SetDisableVFX(permissions.DisableVFX);
|
||||||
|
if (setSticky)
|
||||||
|
perm.SetSticky(permissions.Sticky);
|
||||||
|
return perm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,9 +21,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Discord.Net" Version="3.10.0" />
|
<PackageReference Include="Discord.Net" Version="3.12.0" />
|
||||||
<PackageReference Include="Grpc.AspNetCore" Version="2.53.0" />
|
<PackageReference Include="Grpc.AspNetCore" Version="2.57.0" />
|
||||||
<PackageReference Include="Meziantou.Analyzer" Version="2.0.49">
|
<PackageReference Include="Meziantou.Analyzer" Version="2.0.93">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ public class MareDbContext : DbContext
|
|||||||
public DbSet<UserProfileData> UserProfileData { get; set; }
|
public DbSet<UserProfileData> UserProfileData { get; set; }
|
||||||
public DbSet<UserProfileDataReport> UserProfileReports { get; set; }
|
public DbSet<UserProfileDataReport> UserProfileReports { get; set; }
|
||||||
public DbSet<User> Users { get; set; }
|
public DbSet<User> Users { get; set; }
|
||||||
|
public DbSet<UserPermissionSet> Permissions { get; set; }
|
||||||
|
public DbSet<GroupPairPreferredPermission> GroupPairPreferredPermissions { get; set; }
|
||||||
|
public DbSet<UserDefaultPreferredPermission> UserDefaultPreferredPermissions { get; set; }
|
||||||
|
|
||||||
|
public IQueryable<UserPermissionQuery> GetAllPairsForUser(string uid) => FromExpression(() => GetAllPairsForUser(uid));
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
@@ -77,5 +82,21 @@ public class MareDbContext : DbContext
|
|||||||
modelBuilder.Entity<UserProfileData>().ToTable("user_profile_data");
|
modelBuilder.Entity<UserProfileData>().ToTable("user_profile_data");
|
||||||
modelBuilder.Entity<UserProfileData>().HasKey(c => c.UserUID);
|
modelBuilder.Entity<UserProfileData>().HasKey(c => c.UserUID);
|
||||||
modelBuilder.Entity<UserProfileDataReport>().ToTable("user_profile_data_reports");
|
modelBuilder.Entity<UserProfileDataReport>().ToTable("user_profile_data_reports");
|
||||||
|
modelBuilder.Entity<UserPermissionSet>().ToTable("user_permission_sets");
|
||||||
|
modelBuilder.Entity<UserPermissionSet>().HasKey(u => new { u.UserUID, u.OtherUserUID });
|
||||||
|
modelBuilder.Entity<UserPermissionSet>().HasIndex(c => c.UserUID);
|
||||||
|
modelBuilder.Entity<UserPermissionSet>().HasIndex(c => c.OtherUserUID);
|
||||||
|
modelBuilder.Entity<GroupPairPreferredPermission>().ToTable("group_pair_preferred_permissions");
|
||||||
|
modelBuilder.Entity<GroupPairPreferredPermission>().HasKey(u => new { u.UserUID, u.GroupGID });
|
||||||
|
modelBuilder.Entity<GroupPairPreferredPermission>().HasIndex(c => c.UserUID);
|
||||||
|
modelBuilder.Entity<GroupPairPreferredPermission>().HasIndex(c => c.GroupGID);
|
||||||
|
modelBuilder.Entity<UserDefaultPreferredPermission>().ToTable("user_default_preferred_permissions");
|
||||||
|
modelBuilder.Entity<UserDefaultPreferredPermission>().HasKey(u => u.UserUID);
|
||||||
|
modelBuilder.Entity<UserDefaultPreferredPermission>().HasIndex(u => u.UserUID);
|
||||||
|
modelBuilder.Entity<UserDefaultPreferredPermission>().HasOne(u => u.User);
|
||||||
|
modelBuilder.HasDbFunction(typeof(MareDbContext).GetMethod(nameof(GetAllPairsForUser), new[] { typeof(string) }))
|
||||||
|
.HasName("get_all_pairs_for_user");
|
||||||
|
modelBuilder.Entity<UserPermissionQuery>().HasNoKey();
|
||||||
|
modelBuilder.Entity<UserPermissionQuery>().ToTable("user_permission_query", t => t.ExcludeFromMigrations());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,13 +20,13 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ByteSize" Version="2.1.1" />
|
<PackageReference Include="ByteSize" Version="2.1.1" />
|
||||||
<PackageReference Include="EFCore.NamingConventions" Version="7.0.2" />
|
<PackageReference Include="EFCore.NamingConventions" Version="7.0.2" />
|
||||||
<PackageReference Include="Grpc.AspNetCore" Version="2.53.0" />
|
<PackageReference Include="Grpc.AspNetCore" Version="2.57.0" />
|
||||||
<PackageReference Include="IDisposableAnalyzers" Version="4.0.6">
|
<PackageReference Include="IDisposableAnalyzers" Version="4.0.7">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Karambolo.Extensions.Logging.File" Version="3.4.0" />
|
<PackageReference Include="Karambolo.Extensions.Logging.File" Version="3.5.0" />
|
||||||
<PackageReference Include="Meziantou.Analyzer" Version="2.0.49">
|
<PackageReference Include="Meziantou.Analyzer" Version="2.0.93">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
@@ -35,25 +35,25 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Core" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.Core" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.5" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.12" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="7.0.5" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="7.0.12" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="7.0.5" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="7.0.12" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.12" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.5" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.12" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.5">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.12">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="7.0.5" />
|
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="7.0.12" />
|
||||||
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.30.0" />
|
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="7.0.2" />
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.4" />
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.11" />
|
||||||
<PackageReference Include="prometheus-net" Version="7.0.0" />
|
<PackageReference Include="prometheus-net" Version="7.0.0" />
|
||||||
<PackageReference Include="prometheus-net.AspNetCore" Version="7.0.0" />
|
<PackageReference Include="prometheus-net.AspNetCore" Version="7.0.0" />
|
||||||
<PackageReference Include="StackExchange.Redis" Version="2.6.111" />
|
<PackageReference Include="StackExchange.Redis" Version="2.6.122" />
|
||||||
<PackageReference Include="StackExchange.Redis.Extensions.AspNetCore" Version="9.1.0" />
|
<PackageReference Include="StackExchange.Redis.Extensions.AspNetCore" Version="9.1.0" />
|
||||||
<PackageReference Include="StackExchange.Redis.Extensions.Core" Version="9.1.0" />
|
<PackageReference Include="StackExchange.Redis.Extensions.Core" Version="9.1.0" />
|
||||||
<PackageReference Include="StackExchange.Redis.Extensions.System.Text.Json" Version="9.1.0" />
|
<PackageReference Include="StackExchange.Redis.Extensions.System.Text.Json" Version="9.1.0" />
|
||||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.30.0" />
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.0.2" />
|
||||||
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
|
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ public class MetricsAPI
|
|||||||
public const string CounterAuthenticationCacheHits = "mare_auth_requests_cachehit";
|
public const string CounterAuthenticationCacheHits = "mare_auth_requests_cachehit";
|
||||||
public const string CounterAuthenticationFailures = "mare_auth_requests_fail";
|
public const string CounterAuthenticationFailures = "mare_auth_requests_fail";
|
||||||
public const string CounterAuthenticationSuccesses = "mare_auth_requests_success";
|
public const string CounterAuthenticationSuccesses = "mare_auth_requests_success";
|
||||||
|
public const string GaugeAuthenticationCacheEntries = "mare_auth_cache";
|
||||||
public const string GaugeGroups = "mare_groups";
|
public const string GaugeGroups = "mare_groups";
|
||||||
public const string GaugeGroupPairs = "mare_groups_pairs";
|
public const string GaugeGroupPairs = "mare_groups_pairs";
|
||||||
public const string GaugeGroupPairsPaused = "mare_groups_pairs_paused";
|
|
||||||
public const string GaugeFilesUniquePastHour = "mare_files_unique_past_hour";
|
public const string GaugeFilesUniquePastHour = "mare_files_unique_past_hour";
|
||||||
public const string GaugeFilesUniquePastHourSize = "mare_files_unique_past_hour_size";
|
public const string GaugeFilesUniquePastHourSize = "mare_files_unique_past_hour_size";
|
||||||
public const string GaugeFilesUniquePastDay = "mare_files_unique_past_day";
|
public const string GaugeFilesUniquePastDay = "mare_files_unique_past_day";
|
||||||
|
|||||||
805
MareSynchronosServer/MareSynchronosShared/Migrations/20230924190113_permissions.Designer.cs
generated
Normal file
805
MareSynchronosServer/MareSynchronosShared/Migrations/20230924190113_permissions.Designer.cs
generated
Normal file
@@ -0,0 +1,805 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using MareSynchronosShared.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace MareSynchronosServer.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(MareDbContext))]
|
||||||
|
[Migration("20230924190113_permissions")]
|
||||||
|
partial class permissions
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "7.0.5")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.Auth", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("HashedKey")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("hashed_key");
|
||||||
|
|
||||||
|
b.Property<bool>("IsBanned")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_banned");
|
||||||
|
|
||||||
|
b.Property<string>("PrimaryUserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("primary_user_uid");
|
||||||
|
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.HasKey("HashedKey")
|
||||||
|
.HasName("pk_auth");
|
||||||
|
|
||||||
|
b.HasIndex("PrimaryUserUID")
|
||||||
|
.HasDatabaseName("ix_auth_primary_user_uid");
|
||||||
|
|
||||||
|
b.HasIndex("UserUID")
|
||||||
|
.HasDatabaseName("ix_auth_user_uid");
|
||||||
|
|
||||||
|
b.ToTable("auth", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.Banned", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("CharacterIdentification")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)")
|
||||||
|
.HasColumnName("character_identification");
|
||||||
|
|
||||||
|
b.Property<string>("Reason")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("reason");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Timestamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasColumnType("bytea")
|
||||||
|
.HasColumnName("timestamp");
|
||||||
|
|
||||||
|
b.HasKey("CharacterIdentification")
|
||||||
|
.HasName("pk_banned_users");
|
||||||
|
|
||||||
|
b.ToTable("banned_users", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.BannedRegistrations", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("DiscordIdOrLodestoneAuth")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)")
|
||||||
|
.HasColumnName("discord_id_or_lodestone_auth");
|
||||||
|
|
||||||
|
b.HasKey("DiscordIdOrLodestoneAuth")
|
||||||
|
.HasName("pk_banned_registrations");
|
||||||
|
|
||||||
|
b.ToTable("banned_registrations", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.ClientPair", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.Property<string>("OtherUserUID")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("other_user_uid");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Timestamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasColumnType("bytea")
|
||||||
|
.HasColumnName("timestamp");
|
||||||
|
|
||||||
|
b.HasKey("UserUID", "OtherUserUID")
|
||||||
|
.HasName("pk_client_pairs");
|
||||||
|
|
||||||
|
b.HasIndex("OtherUserUID")
|
||||||
|
.HasDatabaseName("ix_client_pairs_other_user_uid");
|
||||||
|
|
||||||
|
b.HasIndex("UserUID")
|
||||||
|
.HasDatabaseName("ix_client_pairs_user_uid");
|
||||||
|
|
||||||
|
b.ToTable("client_pairs", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.FileCache", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Hash")
|
||||||
|
.HasMaxLength(40)
|
||||||
|
.HasColumnType("character varying(40)")
|
||||||
|
.HasColumnName("hash");
|
||||||
|
|
||||||
|
b.Property<long>("Size")
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("size");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Timestamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasColumnType("bytea")
|
||||||
|
.HasColumnName("timestamp");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UploadDate")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("upload_date");
|
||||||
|
|
||||||
|
b.Property<bool>("Uploaded")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("uploaded");
|
||||||
|
|
||||||
|
b.Property<string>("UploaderUID")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("uploader_uid");
|
||||||
|
|
||||||
|
b.HasKey("Hash")
|
||||||
|
.HasName("pk_file_caches");
|
||||||
|
|
||||||
|
b.HasIndex("UploaderUID")
|
||||||
|
.HasDatabaseName("ix_file_caches_uploader_uid");
|
||||||
|
|
||||||
|
b.ToTable("file_caches", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.ForbiddenUploadEntry", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Hash")
|
||||||
|
.HasMaxLength(40)
|
||||||
|
.HasColumnType("character varying(40)")
|
||||||
|
.HasColumnName("hash");
|
||||||
|
|
||||||
|
b.Property<string>("ForbiddenBy")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)")
|
||||||
|
.HasColumnName("forbidden_by");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Timestamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasColumnType("bytea")
|
||||||
|
.HasColumnName("timestamp");
|
||||||
|
|
||||||
|
b.HasKey("Hash")
|
||||||
|
.HasName("pk_forbidden_upload_entries");
|
||||||
|
|
||||||
|
b.ToTable("forbidden_upload_entries", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.Group", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("GID")
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasColumnType("character varying(20)")
|
||||||
|
.HasColumnName("gid");
|
||||||
|
|
||||||
|
b.Property<string>("Alias")
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("character varying(50)")
|
||||||
|
.HasColumnName("alias");
|
||||||
|
|
||||||
|
b.Property<string>("HashedPassword")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("hashed_password");
|
||||||
|
|
||||||
|
b.Property<bool>("InvitesEnabled")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("invites_enabled");
|
||||||
|
|
||||||
|
b.Property<string>("OwnerUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("owner_uid");
|
||||||
|
|
||||||
|
b.Property<bool>("PreferDisableAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("prefer_disable_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("PreferDisableSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("prefer_disable_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("PreferDisableVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("prefer_disable_vfx");
|
||||||
|
|
||||||
|
b.HasKey("GID")
|
||||||
|
.HasName("pk_groups");
|
||||||
|
|
||||||
|
b.HasIndex("OwnerUID")
|
||||||
|
.HasDatabaseName("ix_groups_owner_uid");
|
||||||
|
|
||||||
|
b.ToTable("groups", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupBan", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("GroupGID")
|
||||||
|
.HasColumnType("character varying(20)")
|
||||||
|
.HasColumnName("group_gid");
|
||||||
|
|
||||||
|
b.Property<string>("BannedUserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("banned_user_uid");
|
||||||
|
|
||||||
|
b.Property<string>("BannedByUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("banned_by_uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("BannedOn")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("banned_on");
|
||||||
|
|
||||||
|
b.Property<string>("BannedReason")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("banned_reason");
|
||||||
|
|
||||||
|
b.HasKey("GroupGID", "BannedUserUID")
|
||||||
|
.HasName("pk_group_bans");
|
||||||
|
|
||||||
|
b.HasIndex("BannedByUID")
|
||||||
|
.HasDatabaseName("ix_group_bans_banned_by_uid");
|
||||||
|
|
||||||
|
b.HasIndex("BannedUserUID")
|
||||||
|
.HasDatabaseName("ix_group_bans_banned_user_uid");
|
||||||
|
|
||||||
|
b.HasIndex("GroupGID")
|
||||||
|
.HasDatabaseName("ix_group_bans_group_gid");
|
||||||
|
|
||||||
|
b.ToTable("group_bans", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupPair", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("GroupGID")
|
||||||
|
.HasColumnType("character varying(20)")
|
||||||
|
.HasColumnName("group_gid");
|
||||||
|
|
||||||
|
b.Property<string>("GroupUserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("group_user_uid");
|
||||||
|
|
||||||
|
b.Property<bool>("IsModerator")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_moderator");
|
||||||
|
|
||||||
|
b.Property<bool>("IsPinned")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_pinned");
|
||||||
|
|
||||||
|
b.HasKey("GroupGID", "GroupUserUID")
|
||||||
|
.HasName("pk_group_pairs");
|
||||||
|
|
||||||
|
b.HasIndex("GroupGID")
|
||||||
|
.HasDatabaseName("ix_group_pairs_group_gid");
|
||||||
|
|
||||||
|
b.HasIndex("GroupUserUID")
|
||||||
|
.HasDatabaseName("ix_group_pairs_group_user_uid");
|
||||||
|
|
||||||
|
b.ToTable("group_pairs", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupPairPreferredPermission", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.Property<string>("GroupGID")
|
||||||
|
.HasColumnType("character varying(20)")
|
||||||
|
.HasColumnName("group_gid");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_vfx");
|
||||||
|
|
||||||
|
b.Property<bool>("IsPaused")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_paused");
|
||||||
|
|
||||||
|
b.HasKey("UserUID", "GroupGID")
|
||||||
|
.HasName("pk_group_pair_preferred_permissions");
|
||||||
|
|
||||||
|
b.HasIndex("GroupGID")
|
||||||
|
.HasDatabaseName("ix_group_pair_preferred_permissions_group_gid");
|
||||||
|
|
||||||
|
b.HasIndex("UserUID")
|
||||||
|
.HasDatabaseName("ix_group_pair_preferred_permissions_user_uid");
|
||||||
|
|
||||||
|
b.ToTable("group_pair_preferred_permissions", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupTempInvite", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("GroupGID")
|
||||||
|
.HasColumnType("character varying(20)")
|
||||||
|
.HasColumnName("group_gid");
|
||||||
|
|
||||||
|
b.Property<string>("Invite")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("invite");
|
||||||
|
|
||||||
|
b.Property<DateTime>("ExpirationDate")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("expiration_date");
|
||||||
|
|
||||||
|
b.HasKey("GroupGID", "Invite")
|
||||||
|
.HasName("pk_group_temp_invites");
|
||||||
|
|
||||||
|
b.HasIndex("GroupGID")
|
||||||
|
.HasDatabaseName("ix_group_temp_invites_group_gid");
|
||||||
|
|
||||||
|
b.HasIndex("Invite")
|
||||||
|
.HasDatabaseName("ix_group_temp_invites_invite");
|
||||||
|
|
||||||
|
b.ToTable("group_temp_invites", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.LodeStoneAuth", b =>
|
||||||
|
{
|
||||||
|
b.Property<decimal>("DiscordId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("numeric(20,0)")
|
||||||
|
.HasColumnName("discord_id");
|
||||||
|
|
||||||
|
b.Property<string>("HashedLodestoneId")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)")
|
||||||
|
.HasColumnName("hashed_lodestone_id");
|
||||||
|
|
||||||
|
b.Property<string>("LodestoneAuthString")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)")
|
||||||
|
.HasColumnName("lodestone_auth_string");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("StartedAt")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("started_at");
|
||||||
|
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.HasKey("DiscordId")
|
||||||
|
.HasName("pk_lodestone_auth");
|
||||||
|
|
||||||
|
b.HasIndex("UserUID")
|
||||||
|
.HasDatabaseName("ix_lodestone_auth_user_uid");
|
||||||
|
|
||||||
|
b.ToTable("lodestone_auth", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.User", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UID")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("uid");
|
||||||
|
|
||||||
|
b.Property<string>("Alias")
|
||||||
|
.HasMaxLength(15)
|
||||||
|
.HasColumnType("character varying(15)")
|
||||||
|
.HasColumnName("alias");
|
||||||
|
|
||||||
|
b.Property<bool>("IsAdmin")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_admin");
|
||||||
|
|
||||||
|
b.Property<bool>("IsModerator")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_moderator");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastLoggedIn")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("last_logged_in");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Timestamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasColumnType("bytea")
|
||||||
|
.HasColumnName("timestamp");
|
||||||
|
|
||||||
|
b.HasKey("UID")
|
||||||
|
.HasName("pk_users");
|
||||||
|
|
||||||
|
b.ToTable("users", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserDefaultPreferredPermission", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableGroupAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_group_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableGroupSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_group_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableGroupVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_group_vfx");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableIndividualAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_individual_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableIndividualSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_individual_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableIndividualVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_individual_vfx");
|
||||||
|
|
||||||
|
b.Property<bool>("IndividualIsSticky")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("individual_is_sticky");
|
||||||
|
|
||||||
|
b.Property<string>("UserUID1")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("user_uid1");
|
||||||
|
|
||||||
|
b.HasKey("UserUID")
|
||||||
|
.HasName("pk_user_default_preferred_permissions");
|
||||||
|
|
||||||
|
b.HasIndex("UserUID1")
|
||||||
|
.HasDatabaseName("ix_user_default_preferred_permissions_user_uid1");
|
||||||
|
|
||||||
|
b.ToTable("user_default_preferred_permissions", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserPermissionSet", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.Property<string>("OtherUserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("other_user_uid");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_vfx");
|
||||||
|
|
||||||
|
b.Property<bool>("IsPaused")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_paused");
|
||||||
|
|
||||||
|
b.Property<bool>("Sticky")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("sticky");
|
||||||
|
|
||||||
|
b.HasKey("UserUID", "OtherUserUID")
|
||||||
|
.HasName("pk_user_permission_sets");
|
||||||
|
|
||||||
|
b.HasIndex("OtherUserUID")
|
||||||
|
.HasDatabaseName("ix_user_permission_sets_other_user_uid");
|
||||||
|
|
||||||
|
b.HasIndex("UserUID")
|
||||||
|
.HasDatabaseName("ix_user_permission_sets_user_uid");
|
||||||
|
|
||||||
|
b.ToTable("user_permission_sets", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserProfileData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.Property<string>("Base64ProfileImage")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("base64profile_image");
|
||||||
|
|
||||||
|
b.Property<bool>("FlaggedForReport")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("flagged_for_report");
|
||||||
|
|
||||||
|
b.Property<bool>("IsNSFW")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_nsfw");
|
||||||
|
|
||||||
|
b.Property<bool>("ProfileDisabled")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("profile_disabled");
|
||||||
|
|
||||||
|
b.Property<string>("UserDescription")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("user_description");
|
||||||
|
|
||||||
|
b.HasKey("UserUID")
|
||||||
|
.HasName("pk_user_profile_data");
|
||||||
|
|
||||||
|
b.ToTable("user_profile_data", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserProfileDataReport", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("ReportDate")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("report_date");
|
||||||
|
|
||||||
|
b.Property<string>("ReportReason")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("report_reason");
|
||||||
|
|
||||||
|
b.Property<string>("ReportedUserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("reported_user_uid");
|
||||||
|
|
||||||
|
b.Property<string>("ReportingUserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("reporting_user_uid");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_user_profile_data_reports");
|
||||||
|
|
||||||
|
b.HasIndex("ReportedUserUID")
|
||||||
|
.HasDatabaseName("ix_user_profile_data_reports_reported_user_uid");
|
||||||
|
|
||||||
|
b.HasIndex("ReportingUserUID")
|
||||||
|
.HasDatabaseName("ix_user_profile_data_reports_reporting_user_uid");
|
||||||
|
|
||||||
|
b.ToTable("user_profile_data_reports", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.Auth", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "PrimaryUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("PrimaryUserUID")
|
||||||
|
.HasConstraintName("fk_auth_users_primary_user_temp_id");
|
||||||
|
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserUID")
|
||||||
|
.HasConstraintName("fk_auth_users_user_temp_id1");
|
||||||
|
|
||||||
|
b.Navigation("PrimaryUser");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.ClientPair", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "OtherUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("OtherUserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_client_pairs_users_other_user_temp_id2");
|
||||||
|
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_client_pairs_users_user_temp_id3");
|
||||||
|
|
||||||
|
b.Navigation("OtherUser");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.FileCache", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "Uploader")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UploaderUID")
|
||||||
|
.HasConstraintName("fk_file_caches_users_uploader_uid");
|
||||||
|
|
||||||
|
b.Navigation("Uploader");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.Group", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "Owner")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("OwnerUID")
|
||||||
|
.HasConstraintName("fk_groups_users_owner_temp_id9");
|
||||||
|
|
||||||
|
b.Navigation("Owner");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupBan", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "BannedBy")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("BannedByUID")
|
||||||
|
.HasConstraintName("fk_group_bans_users_banned_by_temp_id5");
|
||||||
|
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "BannedUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("BannedUserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_group_bans_users_banned_user_temp_id6");
|
||||||
|
|
||||||
|
b.HasOne("MareSynchronosShared.Models.Group", "Group")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("GroupGID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_group_bans_groups_group_temp_id");
|
||||||
|
|
||||||
|
b.Navigation("BannedBy");
|
||||||
|
|
||||||
|
b.Navigation("BannedUser");
|
||||||
|
|
||||||
|
b.Navigation("Group");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupPair", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.Group", "Group")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("GroupGID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_group_pairs_groups_group_temp_id2");
|
||||||
|
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "GroupUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("GroupUserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_group_pairs_users_group_user_temp_id8");
|
||||||
|
|
||||||
|
b.Navigation("Group");
|
||||||
|
|
||||||
|
b.Navigation("GroupUser");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupPairPreferredPermission", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.Group", "Group")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("GroupGID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_group_pair_preferred_permissions_groups_group_temp_id1");
|
||||||
|
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_group_pair_preferred_permissions_users_user_temp_id7");
|
||||||
|
|
||||||
|
b.Navigation("Group");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupTempInvite", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.Group", "Group")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("GroupGID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_group_temp_invites_groups_group_gid");
|
||||||
|
|
||||||
|
b.Navigation("Group");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.LodeStoneAuth", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserUID")
|
||||||
|
.HasConstraintName("fk_lodestone_auth_users_user_uid");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserDefaultPreferredPermission", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserUID1")
|
||||||
|
.HasConstraintName("fk_user_default_preferred_permissions_users_user_temp_id13");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserPermissionSet", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "OtherUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("OtherUserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_user_permission_sets_users_other_user_uid");
|
||||||
|
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_user_permission_sets_users_user_uid");
|
||||||
|
|
||||||
|
b.Navigation("OtherUser");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserProfileData", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_user_profile_data_users_user_uid");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserProfileDataReport", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "ReportedUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ReportedUserUID")
|
||||||
|
.HasConstraintName("fk_user_profile_data_reports_users_reported_user_uid");
|
||||||
|
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "ReportingUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ReportingUserUID")
|
||||||
|
.HasConstraintName("fk_user_profile_data_reports_users_reporting_user_uid");
|
||||||
|
|
||||||
|
b.Navigation("ReportedUser");
|
||||||
|
|
||||||
|
b.Navigation("ReportingUser");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,442 @@
|
|||||||
|
using MareSynchronosShared.Models;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace MareSynchronosServer.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class permissions : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "group_pair_preferred_permissions",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
group_gid = table.Column<string>(type: "character varying(20)", nullable: false),
|
||||||
|
user_uid = table.Column<string>(type: "character varying(10)", nullable: false),
|
||||||
|
is_paused = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
disable_animations = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
disable_sounds = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
disable_vfx = table.Column<bool>(type: "boolean", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_group_pair_preferred_permissions", x => new { x.user_uid, x.group_gid });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_group_pair_preferred_permissions_groups_group_temp_id1",
|
||||||
|
column: x => x.group_gid,
|
||||||
|
principalTable: "groups",
|
||||||
|
principalColumn: "gid",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_group_pair_preferred_permissions_users_user_temp_id7",
|
||||||
|
column: x => x.user_uid,
|
||||||
|
principalTable: "users",
|
||||||
|
principalColumn: "uid",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "user_default_preferred_permissions",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
user_uid = table.Column<string>(type: "text", nullable: false),
|
||||||
|
user_uid1 = table.Column<string>(type: "character varying(10)", nullable: true),
|
||||||
|
disable_individual_animations = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
disable_individual_sounds = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
disable_individual_vfx = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
disable_group_animations = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
disable_group_sounds = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
disable_group_vfx = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
individual_is_sticky = table.Column<bool>(type: "boolean", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_user_default_preferred_permissions", x => x.user_uid);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_user_default_preferred_permissions_users_user_temp_id13",
|
||||||
|
column: x => x.user_uid1,
|
||||||
|
principalTable: "users",
|
||||||
|
principalColumn: "uid");
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "user_permission_sets",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
user_uid = table.Column<string>(type: "character varying(10)", nullable: false),
|
||||||
|
other_user_uid = table.Column<string>(type: "character varying(10)", nullable: false),
|
||||||
|
sticky = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
is_paused = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
disable_animations = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
disable_vfx = table.Column<bool>(type: "boolean", nullable: false),
|
||||||
|
disable_sounds = table.Column<bool>(type: "boolean", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_user_permission_sets", x => new { x.user_uid, x.other_user_uid });
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_user_permission_sets_users_other_user_uid",
|
||||||
|
column: x => x.other_user_uid,
|
||||||
|
principalTable: "users",
|
||||||
|
principalColumn: "uid",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_user_permission_sets_users_user_uid",
|
||||||
|
column: x => x.user_uid,
|
||||||
|
principalTable: "users",
|
||||||
|
principalColumn: "uid",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.Sql(@"insert into user_permission_sets
|
||||||
|
select user1.user_uid as user_uid, user1.other_user_uid as other_user_uid,
|
||||||
|
true,
|
||||||
|
user1.is_paused as is_paused,
|
||||||
|
user1.disable_animations as disable_animations,
|
||||||
|
user1.disable_sounds as disable_sounds,
|
||||||
|
user1.disable_vfx as disable_vfx
|
||||||
|
from client_pairs as user1;");
|
||||||
|
|
||||||
|
migrationBuilder.Sql(@"insert into user_permission_sets
|
||||||
|
select gp.group_user_uid, gp2.group_user_uid,
|
||||||
|
false,
|
||||||
|
bool_and(gp.is_paused),
|
||||||
|
bool_and(g.disable_animations or gp.disable_animations),
|
||||||
|
bool_and(g.disable_sounds or gp.disable_sounds),
|
||||||
|
bool_and(g.disable_vfx or gp.disable_vfx)
|
||||||
|
from group_pairs gp
|
||||||
|
left join group_pairs gp2 on gp2.group_gid = gp.group_gid
|
||||||
|
left join groups g on g.gid = gp2.group_gid
|
||||||
|
where gp2.group_user_uid <> gp.group_user_uid
|
||||||
|
group by gp.group_user_uid, gp2.group_user_uid
|
||||||
|
on conflict do nothing;");
|
||||||
|
|
||||||
|
migrationBuilder.Sql(@"insert into group_pair_preferred_permissions
|
||||||
|
select group_gid
|
||||||
|
, group_user_uid
|
||||||
|
, gp.is_paused
|
||||||
|
, gp.disable_animations or g.disable_animations as disable_animations
|
||||||
|
, gp.disable_sounds or g.disable_sounds as disable_sounds
|
||||||
|
, gp.disable_vfx or g.disable_vfx as disable_vfx
|
||||||
|
from group_pairs as gp
|
||||||
|
left join groups g on g.gid = gp.group_gid");
|
||||||
|
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "fk_group_pairs_groups_group_temp_id1",
|
||||||
|
table: "group_pairs");
|
||||||
|
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "fk_group_pairs_users_group_user_temp_id7",
|
||||||
|
table: "group_pairs");
|
||||||
|
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "fk_groups_users_owner_temp_id8",
|
||||||
|
table: "groups");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "disable_animations",
|
||||||
|
table: "group_pairs");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "disable_sounds",
|
||||||
|
table: "group_pairs");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "disable_vfx",
|
||||||
|
table: "group_pairs");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "is_paused",
|
||||||
|
table: "group_pairs");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "allow_receiving_messages",
|
||||||
|
table: "client_pairs");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "disable_animations",
|
||||||
|
table: "client_pairs");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "disable_sounds",
|
||||||
|
table: "client_pairs");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "disable_vfx",
|
||||||
|
table: "client_pairs");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "is_paused",
|
||||||
|
table: "client_pairs");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "disable_vfx",
|
||||||
|
table: "groups",
|
||||||
|
newName: "prefer_disable_vfx");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "disable_sounds",
|
||||||
|
table: "groups",
|
||||||
|
newName: "prefer_disable_sounds");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "disable_animations",
|
||||||
|
table: "groups",
|
||||||
|
newName: "prefer_disable_animations");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_group_pair_preferred_permissions_group_gid",
|
||||||
|
table: "group_pair_preferred_permissions",
|
||||||
|
column: "group_gid");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_group_pair_preferred_permissions_user_uid",
|
||||||
|
table: "group_pair_preferred_permissions",
|
||||||
|
column: "user_uid");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_user_default_preferred_permissions_user_uid1",
|
||||||
|
table: "user_default_preferred_permissions",
|
||||||
|
column: "user_uid1");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_user_permission_sets_other_user_uid",
|
||||||
|
table: "user_permission_sets",
|
||||||
|
column: "other_user_uid");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_user_permission_sets_user_uid",
|
||||||
|
table: "user_permission_sets",
|
||||||
|
column: "user_uid");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "fk_group_pairs_groups_group_temp_id2",
|
||||||
|
table: "group_pairs",
|
||||||
|
column: "group_gid",
|
||||||
|
principalTable: "groups",
|
||||||
|
principalColumn: "gid",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "fk_group_pairs_users_group_user_temp_id8",
|
||||||
|
table: "group_pairs",
|
||||||
|
column: "group_user_uid",
|
||||||
|
principalTable: "users",
|
||||||
|
principalColumn: "uid",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "fk_groups_users_owner_temp_id9",
|
||||||
|
table: "groups",
|
||||||
|
column: "owner_uid",
|
||||||
|
principalTable: "users",
|
||||||
|
principalColumn: "uid");
|
||||||
|
|
||||||
|
migrationBuilder.Sql(@"create function get_all_pairs_for_user(req_uid text)
|
||||||
|
returns table(
|
||||||
|
user_uid varchar(10)
|
||||||
|
,other_user_uid varchar(10)
|
||||||
|
,alias varchar(15)
|
||||||
|
,gid varchar(20)
|
||||||
|
,synced bool
|
||||||
|
,ownperm_is_paused bool
|
||||||
|
,ownperm_sticky bool
|
||||||
|
,ownperm_disable_animations bool
|
||||||
|
,ownperm_disable_sounds bool
|
||||||
|
,ownperm_disable_vfx bool
|
||||||
|
,otherperm_is_paused bool
|
||||||
|
,otherperm_disable_animations bool
|
||||||
|
,otherperm_disable_sounds bool
|
||||||
|
,otherperm_disable_vfx bool)
|
||||||
|
as
|
||||||
|
$$
|
||||||
|
begin
|
||||||
|
return query(
|
||||||
|
WITH query1 AS (
|
||||||
|
SELECT user1.user_uid AS user_uid
|
||||||
|
,user1.other_user_uid AS other_user_uid
|
||||||
|
,NULL AS gid
|
||||||
|
,NOT (user2 IS NULL) AS synced
|
||||||
|
FROM client_pairs AS user1
|
||||||
|
LEFT JOIN client_pairs user2 ON user1.user_uid = user2.other_user_uid
|
||||||
|
AND user2.user_uid = user1.other_user_uid
|
||||||
|
WHERE user1.user_uid = req_uid
|
||||||
|
),
|
||||||
|
query2 AS (
|
||||||
|
SELECT gp.group_user_uid
|
||||||
|
,gp2.group_user_uid
|
||||||
|
,gp.group_gid
|
||||||
|
,true
|
||||||
|
FROM group_pairs gp
|
||||||
|
LEFT JOIN group_pairs gp2 ON gp2.group_gid = gp.group_gid
|
||||||
|
WHERE gp.group_user_uid = req_uid
|
||||||
|
AND gp2.group_user_uid <> req_uid
|
||||||
|
AND gp2.group_gid = gp.group_gid
|
||||||
|
)
|
||||||
|
|
||||||
|
SELECT pairs.user_uid
|
||||||
|
,pairs.other_user_uid
|
||||||
|
,u.alias
|
||||||
|
,cast(pairs.gid as varchar(20))
|
||||||
|
,pairs.synced
|
||||||
|
,ownperm.is_paused
|
||||||
|
,ownperm.sticky
|
||||||
|
,ownperm.disable_animations
|
||||||
|
,ownperm.disable_sounds
|
||||||
|
,ownperm.disable_vfx
|
||||||
|
,otherperm.is_paused
|
||||||
|
,otherperm.disable_animations
|
||||||
|
,otherperm.disable_sounds
|
||||||
|
,otherperm.disable_vfx
|
||||||
|
FROM (SELECT * FROM query1
|
||||||
|
union all
|
||||||
|
SELECT * FROM query2) AS pairs
|
||||||
|
LEFT JOIN users AS u ON pairs.other_user_uid = u.uid
|
||||||
|
LEFT JOIN user_permission_sets AS ownperm ON pairs.user_uid = ownperm.user_uid
|
||||||
|
AND pairs.other_user_uid = ownperm.other_user_uid
|
||||||
|
LEFT JOIN user_permission_sets AS otherperm ON pairs.user_uid = otherperm.other_user_uid
|
||||||
|
AND pairs.other_user_uid = otherperm.user_uid
|
||||||
|
WHERE pairs.user_uid = req_uid
|
||||||
|
AND u.uid = pairs.other_user_uid
|
||||||
|
AND (
|
||||||
|
(ownperm.user_uid = req_uid)
|
||||||
|
OR (otherperm.other_user_uid = req_uid)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
$$
|
||||||
|
language plpgsql;");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "fk_group_pairs_groups_group_temp_id2",
|
||||||
|
table: "group_pairs");
|
||||||
|
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "fk_group_pairs_users_group_user_temp_id8",
|
||||||
|
table: "group_pairs");
|
||||||
|
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "fk_groups_users_owner_temp_id9",
|
||||||
|
table: "groups");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "group_pair_preferred_permissions");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "user_default_preferred_permissions");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "user_permission_sets");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "prefer_disable_vfx",
|
||||||
|
table: "groups",
|
||||||
|
newName: "disable_vfx");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "prefer_disable_sounds",
|
||||||
|
table: "groups",
|
||||||
|
newName: "disable_sounds");
|
||||||
|
|
||||||
|
migrationBuilder.RenameColumn(
|
||||||
|
name: "prefer_disable_animations",
|
||||||
|
table: "groups",
|
||||||
|
newName: "disable_animations");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "disable_animations",
|
||||||
|
table: "group_pairs",
|
||||||
|
type: "boolean",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "disable_sounds",
|
||||||
|
table: "group_pairs",
|
||||||
|
type: "boolean",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "disable_vfx",
|
||||||
|
table: "group_pairs",
|
||||||
|
type: "boolean",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "is_paused",
|
||||||
|
table: "group_pairs",
|
||||||
|
type: "boolean",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "allow_receiving_messages",
|
||||||
|
table: "client_pairs",
|
||||||
|
type: "boolean",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "disable_animations",
|
||||||
|
table: "client_pairs",
|
||||||
|
type: "boolean",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "disable_sounds",
|
||||||
|
table: "client_pairs",
|
||||||
|
type: "boolean",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "disable_vfx",
|
||||||
|
table: "client_pairs",
|
||||||
|
type: "boolean",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "is_paused",
|
||||||
|
table: "client_pairs",
|
||||||
|
type: "boolean",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "fk_group_pairs_groups_group_temp_id1",
|
||||||
|
table: "group_pairs",
|
||||||
|
column: "group_gid",
|
||||||
|
principalTable: "groups",
|
||||||
|
principalColumn: "gid",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "fk_group_pairs_users_group_user_temp_id7",
|
||||||
|
table: "group_pairs",
|
||||||
|
column: "group_user_uid",
|
||||||
|
principalTable: "users",
|
||||||
|
principalColumn: "uid",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "fk_groups_users_owner_temp_id8",
|
||||||
|
table: "groups",
|
||||||
|
column: "owner_uid",
|
||||||
|
principalTable: "users",
|
||||||
|
principalColumn: "uid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
868
MareSynchronosServer/MareSynchronosShared/Migrations/20230926212023_AlterPermissions.Designer.cs
generated
Normal file
868
MareSynchronosServer/MareSynchronosShared/Migrations/20230926212023_AlterPermissions.Designer.cs
generated
Normal file
@@ -0,0 +1,868 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using MareSynchronosShared.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace MareSynchronosServer.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(MareDbContext))]
|
||||||
|
[Migration("20230926212023_AlterPermissions")]
|
||||||
|
partial class AlterPermissions
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "7.0.5")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.Auth", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("HashedKey")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("hashed_key");
|
||||||
|
|
||||||
|
b.Property<bool>("IsBanned")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_banned");
|
||||||
|
|
||||||
|
b.Property<string>("PrimaryUserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("primary_user_uid");
|
||||||
|
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.HasKey("HashedKey")
|
||||||
|
.HasName("pk_auth");
|
||||||
|
|
||||||
|
b.HasIndex("PrimaryUserUID")
|
||||||
|
.HasDatabaseName("ix_auth_primary_user_uid");
|
||||||
|
|
||||||
|
b.HasIndex("UserUID")
|
||||||
|
.HasDatabaseName("ix_auth_user_uid");
|
||||||
|
|
||||||
|
b.ToTable("auth", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.Banned", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("CharacterIdentification")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)")
|
||||||
|
.HasColumnName("character_identification");
|
||||||
|
|
||||||
|
b.Property<string>("Reason")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("reason");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Timestamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasColumnType("bytea")
|
||||||
|
.HasColumnName("timestamp");
|
||||||
|
|
||||||
|
b.HasKey("CharacterIdentification")
|
||||||
|
.HasName("pk_banned_users");
|
||||||
|
|
||||||
|
b.ToTable("banned_users", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.BannedRegistrations", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("DiscordIdOrLodestoneAuth")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)")
|
||||||
|
.HasColumnName("discord_id_or_lodestone_auth");
|
||||||
|
|
||||||
|
b.HasKey("DiscordIdOrLodestoneAuth")
|
||||||
|
.HasName("pk_banned_registrations");
|
||||||
|
|
||||||
|
b.ToTable("banned_registrations", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.ClientPair", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.Property<string>("OtherUserUID")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("other_user_uid");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Timestamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasColumnType("bytea")
|
||||||
|
.HasColumnName("timestamp");
|
||||||
|
|
||||||
|
b.HasKey("UserUID", "OtherUserUID")
|
||||||
|
.HasName("pk_client_pairs");
|
||||||
|
|
||||||
|
b.HasIndex("OtherUserUID")
|
||||||
|
.HasDatabaseName("ix_client_pairs_other_user_uid");
|
||||||
|
|
||||||
|
b.HasIndex("UserUID")
|
||||||
|
.HasDatabaseName("ix_client_pairs_user_uid");
|
||||||
|
|
||||||
|
b.ToTable("client_pairs", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.FileCache", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Hash")
|
||||||
|
.HasMaxLength(40)
|
||||||
|
.HasColumnType("character varying(40)")
|
||||||
|
.HasColumnName("hash");
|
||||||
|
|
||||||
|
b.Property<long>("Size")
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("size");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Timestamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasColumnType("bytea")
|
||||||
|
.HasColumnName("timestamp");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UploadDate")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("upload_date");
|
||||||
|
|
||||||
|
b.Property<bool>("Uploaded")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("uploaded");
|
||||||
|
|
||||||
|
b.Property<string>("UploaderUID")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("uploader_uid");
|
||||||
|
|
||||||
|
b.HasKey("Hash")
|
||||||
|
.HasName("pk_file_caches");
|
||||||
|
|
||||||
|
b.HasIndex("UploaderUID")
|
||||||
|
.HasDatabaseName("ix_file_caches_uploader_uid");
|
||||||
|
|
||||||
|
b.ToTable("file_caches", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.ForbiddenUploadEntry", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Hash")
|
||||||
|
.HasMaxLength(40)
|
||||||
|
.HasColumnType("character varying(40)")
|
||||||
|
.HasColumnName("hash");
|
||||||
|
|
||||||
|
b.Property<string>("ForbiddenBy")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)")
|
||||||
|
.HasColumnName("forbidden_by");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Timestamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasColumnType("bytea")
|
||||||
|
.HasColumnName("timestamp");
|
||||||
|
|
||||||
|
b.HasKey("Hash")
|
||||||
|
.HasName("pk_forbidden_upload_entries");
|
||||||
|
|
||||||
|
b.ToTable("forbidden_upload_entries", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.Group", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("GID")
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasColumnType("character varying(20)")
|
||||||
|
.HasColumnName("gid");
|
||||||
|
|
||||||
|
b.Property<string>("Alias")
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("character varying(50)")
|
||||||
|
.HasColumnName("alias");
|
||||||
|
|
||||||
|
b.Property<string>("HashedPassword")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("hashed_password");
|
||||||
|
|
||||||
|
b.Property<bool>("InvitesEnabled")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("invites_enabled");
|
||||||
|
|
||||||
|
b.Property<string>("OwnerUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("owner_uid");
|
||||||
|
|
||||||
|
b.Property<bool>("PreferDisableAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("prefer_disable_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("PreferDisableSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("prefer_disable_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("PreferDisableVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("prefer_disable_vfx");
|
||||||
|
|
||||||
|
b.HasKey("GID")
|
||||||
|
.HasName("pk_groups");
|
||||||
|
|
||||||
|
b.HasIndex("OwnerUID")
|
||||||
|
.HasDatabaseName("ix_groups_owner_uid");
|
||||||
|
|
||||||
|
b.ToTable("groups", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupBan", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("GroupGID")
|
||||||
|
.HasColumnType("character varying(20)")
|
||||||
|
.HasColumnName("group_gid");
|
||||||
|
|
||||||
|
b.Property<string>("BannedUserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("banned_user_uid");
|
||||||
|
|
||||||
|
b.Property<string>("BannedByUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("banned_by_uid");
|
||||||
|
|
||||||
|
b.Property<DateTime>("BannedOn")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("banned_on");
|
||||||
|
|
||||||
|
b.Property<string>("BannedReason")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("banned_reason");
|
||||||
|
|
||||||
|
b.HasKey("GroupGID", "BannedUserUID")
|
||||||
|
.HasName("pk_group_bans");
|
||||||
|
|
||||||
|
b.HasIndex("BannedByUID")
|
||||||
|
.HasDatabaseName("ix_group_bans_banned_by_uid");
|
||||||
|
|
||||||
|
b.HasIndex("BannedUserUID")
|
||||||
|
.HasDatabaseName("ix_group_bans_banned_user_uid");
|
||||||
|
|
||||||
|
b.HasIndex("GroupGID")
|
||||||
|
.HasDatabaseName("ix_group_bans_group_gid");
|
||||||
|
|
||||||
|
b.ToTable("group_bans", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupPair", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("GroupGID")
|
||||||
|
.HasColumnType("character varying(20)")
|
||||||
|
.HasColumnName("group_gid");
|
||||||
|
|
||||||
|
b.Property<string>("GroupUserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("group_user_uid");
|
||||||
|
|
||||||
|
b.Property<bool>("IsModerator")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_moderator");
|
||||||
|
|
||||||
|
b.Property<bool>("IsPinned")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_pinned");
|
||||||
|
|
||||||
|
b.HasKey("GroupGID", "GroupUserUID")
|
||||||
|
.HasName("pk_group_pairs");
|
||||||
|
|
||||||
|
b.HasIndex("GroupGID")
|
||||||
|
.HasDatabaseName("ix_group_pairs_group_gid");
|
||||||
|
|
||||||
|
b.HasIndex("GroupUserUID")
|
||||||
|
.HasDatabaseName("ix_group_pairs_group_user_uid");
|
||||||
|
|
||||||
|
b.ToTable("group_pairs", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupPairPreferredPermission", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.Property<string>("GroupGID")
|
||||||
|
.HasColumnType("character varying(20)")
|
||||||
|
.HasColumnName("group_gid");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_vfx");
|
||||||
|
|
||||||
|
b.Property<bool>("IsPaused")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_paused");
|
||||||
|
|
||||||
|
b.HasKey("UserUID", "GroupGID")
|
||||||
|
.HasName("pk_group_pair_preferred_permissions");
|
||||||
|
|
||||||
|
b.HasIndex("GroupGID")
|
||||||
|
.HasDatabaseName("ix_group_pair_preferred_permissions_group_gid");
|
||||||
|
|
||||||
|
b.HasIndex("UserUID")
|
||||||
|
.HasDatabaseName("ix_group_pair_preferred_permissions_user_uid");
|
||||||
|
|
||||||
|
b.ToTable("group_pair_preferred_permissions", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupTempInvite", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("GroupGID")
|
||||||
|
.HasColumnType("character varying(20)")
|
||||||
|
.HasColumnName("group_gid");
|
||||||
|
|
||||||
|
b.Property<string>("Invite")
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("character varying(64)")
|
||||||
|
.HasColumnName("invite");
|
||||||
|
|
||||||
|
b.Property<DateTime>("ExpirationDate")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("expiration_date");
|
||||||
|
|
||||||
|
b.HasKey("GroupGID", "Invite")
|
||||||
|
.HasName("pk_group_temp_invites");
|
||||||
|
|
||||||
|
b.HasIndex("GroupGID")
|
||||||
|
.HasDatabaseName("ix_group_temp_invites_group_gid");
|
||||||
|
|
||||||
|
b.HasIndex("Invite")
|
||||||
|
.HasDatabaseName("ix_group_temp_invites_invite");
|
||||||
|
|
||||||
|
b.ToTable("group_temp_invites", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.LodeStoneAuth", b =>
|
||||||
|
{
|
||||||
|
b.Property<decimal>("DiscordId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("numeric(20,0)")
|
||||||
|
.HasColumnName("discord_id");
|
||||||
|
|
||||||
|
b.Property<string>("HashedLodestoneId")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)")
|
||||||
|
.HasColumnName("hashed_lodestone_id");
|
||||||
|
|
||||||
|
b.Property<string>("LodestoneAuthString")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("character varying(100)")
|
||||||
|
.HasColumnName("lodestone_auth_string");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("StartedAt")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("started_at");
|
||||||
|
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.HasKey("DiscordId")
|
||||||
|
.HasName("pk_lodestone_auth");
|
||||||
|
|
||||||
|
b.HasIndex("UserUID")
|
||||||
|
.HasDatabaseName("ix_lodestone_auth_user_uid");
|
||||||
|
|
||||||
|
b.ToTable("lodestone_auth", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.User", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UID")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("uid");
|
||||||
|
|
||||||
|
b.Property<string>("Alias")
|
||||||
|
.HasMaxLength(15)
|
||||||
|
.HasColumnType("character varying(15)")
|
||||||
|
.HasColumnName("alias");
|
||||||
|
|
||||||
|
b.Property<bool>("IsAdmin")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_admin");
|
||||||
|
|
||||||
|
b.Property<bool>("IsModerator")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_moderator");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastLoggedIn")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("last_logged_in");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Timestamp")
|
||||||
|
.IsConcurrencyToken()
|
||||||
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
|
.HasColumnType("bytea")
|
||||||
|
.HasColumnName("timestamp");
|
||||||
|
|
||||||
|
b.HasKey("UID")
|
||||||
|
.HasName("pk_users");
|
||||||
|
|
||||||
|
b.ToTable("users", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserDefaultPreferredPermission", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableGroupAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_group_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableGroupSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_group_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableGroupVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_group_vfx");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableIndividualAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_individual_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableIndividualSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_individual_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableIndividualVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_individual_vfx");
|
||||||
|
|
||||||
|
b.Property<bool>("IndividualIsSticky")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("individual_is_sticky");
|
||||||
|
|
||||||
|
b.HasKey("UserUID")
|
||||||
|
.HasName("pk_user_default_preferred_permissions");
|
||||||
|
|
||||||
|
b.HasIndex("UserUID")
|
||||||
|
.HasDatabaseName("ix_user_default_preferred_permissions_user_uid");
|
||||||
|
|
||||||
|
b.ToTable("user_default_preferred_permissions", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserPermissionQuery", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Alias")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("alias");
|
||||||
|
|
||||||
|
b.Property<string>("GID")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("gid");
|
||||||
|
|
||||||
|
b.Property<string>("OtherUserUID")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("other_user_uid");
|
||||||
|
|
||||||
|
b.Property<bool>("OtherpermDisableAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("otherperm_disable_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("OtherpermDisableSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("otherperm_disable_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("OtherpermDisableVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("otherperm_disable_vfx");
|
||||||
|
|
||||||
|
b.Property<bool>("OtherpermIsPaused")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("otherperm_is_paused");
|
||||||
|
|
||||||
|
b.Property<bool>("OwnPermSticky")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("own_perm_sticky");
|
||||||
|
|
||||||
|
b.Property<bool>("OwnpermDisableAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("ownperm_disable_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("OwnpermDisableSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("ownperm_disable_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("OwnpermDisableVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("ownperm_disable_vfx");
|
||||||
|
|
||||||
|
b.Property<bool>("OwnpermIsPaused")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("ownperm_is_paused");
|
||||||
|
|
||||||
|
b.Property<bool>("Synced")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("synced");
|
||||||
|
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.ToTable("user_permission_query", null, t =>
|
||||||
|
{
|
||||||
|
t.ExcludeFromMigrations();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserPermissionSet", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.Property<string>("OtherUserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("other_user_uid");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_vfx");
|
||||||
|
|
||||||
|
b.Property<bool>("IsPaused")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_paused");
|
||||||
|
|
||||||
|
b.Property<bool>("Sticky")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("sticky");
|
||||||
|
|
||||||
|
b.HasKey("UserUID", "OtherUserUID")
|
||||||
|
.HasName("pk_user_permission_sets");
|
||||||
|
|
||||||
|
b.HasIndex("OtherUserUID")
|
||||||
|
.HasDatabaseName("ix_user_permission_sets_other_user_uid");
|
||||||
|
|
||||||
|
b.HasIndex("UserUID")
|
||||||
|
.HasDatabaseName("ix_user_permission_sets_user_uid");
|
||||||
|
|
||||||
|
b.ToTable("user_permission_sets", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserProfileData", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.Property<string>("Base64ProfileImage")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("base64profile_image");
|
||||||
|
|
||||||
|
b.Property<bool>("FlaggedForReport")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("flagged_for_report");
|
||||||
|
|
||||||
|
b.Property<bool>("IsNSFW")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_nsfw");
|
||||||
|
|
||||||
|
b.Property<bool>("ProfileDisabled")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("profile_disabled");
|
||||||
|
|
||||||
|
b.Property<string>("UserDescription")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("user_description");
|
||||||
|
|
||||||
|
b.HasKey("UserUID")
|
||||||
|
.HasName("pk_user_profile_data");
|
||||||
|
|
||||||
|
b.ToTable("user_profile_data", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserProfileDataReport", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("integer")
|
||||||
|
.HasColumnName("id");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||||
|
|
||||||
|
b.Property<DateTime>("ReportDate")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("report_date");
|
||||||
|
|
||||||
|
b.Property<string>("ReportReason")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("report_reason");
|
||||||
|
|
||||||
|
b.Property<string>("ReportedUserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("reported_user_uid");
|
||||||
|
|
||||||
|
b.Property<string>("ReportingUserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("reporting_user_uid");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_user_profile_data_reports");
|
||||||
|
|
||||||
|
b.HasIndex("ReportedUserUID")
|
||||||
|
.HasDatabaseName("ix_user_profile_data_reports_reported_user_uid");
|
||||||
|
|
||||||
|
b.HasIndex("ReportingUserUID")
|
||||||
|
.HasDatabaseName("ix_user_profile_data_reports_reporting_user_uid");
|
||||||
|
|
||||||
|
b.ToTable("user_profile_data_reports", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.Auth", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "PrimaryUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("PrimaryUserUID")
|
||||||
|
.HasConstraintName("fk_auth_users_primary_user_temp_id");
|
||||||
|
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserUID")
|
||||||
|
.HasConstraintName("fk_auth_users_user_temp_id1");
|
||||||
|
|
||||||
|
b.Navigation("PrimaryUser");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.ClientPair", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "OtherUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("OtherUserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_client_pairs_users_other_user_temp_id2");
|
||||||
|
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_client_pairs_users_user_temp_id3");
|
||||||
|
|
||||||
|
b.Navigation("OtherUser");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.FileCache", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "Uploader")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UploaderUID")
|
||||||
|
.HasConstraintName("fk_file_caches_users_uploader_uid");
|
||||||
|
|
||||||
|
b.Navigation("Uploader");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.Group", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "Owner")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("OwnerUID")
|
||||||
|
.HasConstraintName("fk_groups_users_owner_temp_id9");
|
||||||
|
|
||||||
|
b.Navigation("Owner");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupBan", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "BannedBy")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("BannedByUID")
|
||||||
|
.HasConstraintName("fk_group_bans_users_banned_by_temp_id5");
|
||||||
|
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "BannedUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("BannedUserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_group_bans_users_banned_user_temp_id6");
|
||||||
|
|
||||||
|
b.HasOne("MareSynchronosShared.Models.Group", "Group")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("GroupGID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_group_bans_groups_group_temp_id");
|
||||||
|
|
||||||
|
b.Navigation("BannedBy");
|
||||||
|
|
||||||
|
b.Navigation("BannedUser");
|
||||||
|
|
||||||
|
b.Navigation("Group");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupPair", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.Group", "Group")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("GroupGID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_group_pairs_groups_group_temp_id2");
|
||||||
|
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "GroupUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("GroupUserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_group_pairs_users_group_user_temp_id8");
|
||||||
|
|
||||||
|
b.Navigation("Group");
|
||||||
|
|
||||||
|
b.Navigation("GroupUser");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupPairPreferredPermission", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.Group", "Group")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("GroupGID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_group_pair_preferred_permissions_groups_group_temp_id1");
|
||||||
|
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_group_pair_preferred_permissions_users_user_temp_id7");
|
||||||
|
|
||||||
|
b.Navigation("Group");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupTempInvite", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.Group", "Group")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("GroupGID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_group_temp_invites_groups_group_gid");
|
||||||
|
|
||||||
|
b.Navigation("Group");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.LodeStoneAuth", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserUID")
|
||||||
|
.HasConstraintName("fk_lodestone_auth_users_user_uid");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserDefaultPreferredPermission", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_user_default_preferred_permissions_users_user_uid");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserPermissionSet", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "OtherUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("OtherUserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_user_permission_sets_users_other_user_uid");
|
||||||
|
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_user_permission_sets_users_user_uid");
|
||||||
|
|
||||||
|
b.Navigation("OtherUser");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserProfileData", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_user_profile_data_users_user_uid");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserProfileDataReport", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "ReportedUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ReportedUserUID")
|
||||||
|
.HasConstraintName("fk_user_profile_data_reports_users_reported_user_uid");
|
||||||
|
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "ReportingUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ReportingUserUID")
|
||||||
|
.HasConstraintName("fk_user_profile_data_reports_users_reporting_user_uid");
|
||||||
|
|
||||||
|
b.Navigation("ReportedUser");
|
||||||
|
|
||||||
|
b.Navigation("ReportingUser");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace MareSynchronosServer.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AlterPermissions : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "fk_user_default_preferred_permissions_users_user_temp_id13",
|
||||||
|
table: "user_default_preferred_permissions");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "ix_user_default_preferred_permissions_user_uid1",
|
||||||
|
table: "user_default_preferred_permissions");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "user_uid1",
|
||||||
|
table: "user_default_preferred_permissions");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<string>(
|
||||||
|
name: "user_uid",
|
||||||
|
table: "user_default_preferred_permissions",
|
||||||
|
type: "character varying(10)",
|
||||||
|
maxLength: 10,
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(string),
|
||||||
|
oldType: "text");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_user_default_preferred_permissions_user_uid",
|
||||||
|
table: "user_default_preferred_permissions",
|
||||||
|
column: "user_uid");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "fk_user_default_preferred_permissions_users_user_uid",
|
||||||
|
table: "user_default_preferred_permissions",
|
||||||
|
column: "user_uid",
|
||||||
|
principalTable: "users",
|
||||||
|
principalColumn: "uid",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "fk_user_default_preferred_permissions_users_user_uid",
|
||||||
|
table: "user_default_preferred_permissions");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "ix_user_default_preferred_permissions_user_uid",
|
||||||
|
table: "user_default_preferred_permissions");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<string>(
|
||||||
|
name: "user_uid",
|
||||||
|
table: "user_default_preferred_permissions",
|
||||||
|
type: "text",
|
||||||
|
nullable: false,
|
||||||
|
oldClrType: typeof(string),
|
||||||
|
oldType: "character varying(10)",
|
||||||
|
oldMaxLength: 10);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "user_uid1",
|
||||||
|
table: "user_default_preferred_permissions",
|
||||||
|
type: "character varying(10)",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_user_default_preferred_permissions_user_uid1",
|
||||||
|
table: "user_default_preferred_permissions",
|
||||||
|
column: "user_uid1");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "fk_user_default_preferred_permissions_users_user_temp_id13",
|
||||||
|
table: "user_default_preferred_permissions",
|
||||||
|
column: "user_uid1",
|
||||||
|
principalTable: "users",
|
||||||
|
principalColumn: "uid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ namespace MareSynchronosServer.Migrations
|
|||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "7.0.4")
|
.HasAnnotation("ProductVersion", "7.0.5")
|
||||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
@@ -101,26 +101,6 @@ namespace MareSynchronosServer.Migrations
|
|||||||
.HasColumnType("character varying(10)")
|
.HasColumnType("character varying(10)")
|
||||||
.HasColumnName("other_user_uid");
|
.HasColumnName("other_user_uid");
|
||||||
|
|
||||||
b.Property<bool>("AllowReceivingMessages")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("allow_receiving_messages");
|
|
||||||
|
|
||||||
b.Property<bool>("DisableAnimations")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("disable_animations");
|
|
||||||
|
|
||||||
b.Property<bool>("DisableSounds")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("disable_sounds");
|
|
||||||
|
|
||||||
b.Property<bool>("DisableVFX")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("disable_vfx");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPaused")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("is_paused");
|
|
||||||
|
|
||||||
b.Property<byte[]>("Timestamp")
|
b.Property<byte[]>("Timestamp")
|
||||||
.IsConcurrencyToken()
|
.IsConcurrencyToken()
|
||||||
.ValueGeneratedOnAddOrUpdate()
|
.ValueGeneratedOnAddOrUpdate()
|
||||||
@@ -214,18 +194,6 @@ namespace MareSynchronosServer.Migrations
|
|||||||
.HasColumnType("character varying(50)")
|
.HasColumnType("character varying(50)")
|
||||||
.HasColumnName("alias");
|
.HasColumnName("alias");
|
||||||
|
|
||||||
b.Property<bool>("DisableAnimations")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("disable_animations");
|
|
||||||
|
|
||||||
b.Property<bool>("DisableSounds")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("disable_sounds");
|
|
||||||
|
|
||||||
b.Property<bool>("DisableVFX")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("disable_vfx");
|
|
||||||
|
|
||||||
b.Property<string>("HashedPassword")
|
b.Property<string>("HashedPassword")
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("hashed_password");
|
.HasColumnName("hashed_password");
|
||||||
@@ -238,6 +206,18 @@ namespace MareSynchronosServer.Migrations
|
|||||||
.HasColumnType("character varying(10)")
|
.HasColumnType("character varying(10)")
|
||||||
.HasColumnName("owner_uid");
|
.HasColumnName("owner_uid");
|
||||||
|
|
||||||
|
b.Property<bool>("PreferDisableAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("prefer_disable_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("PreferDisableSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("prefer_disable_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("PreferDisableVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("prefer_disable_vfx");
|
||||||
|
|
||||||
b.HasKey("GID")
|
b.HasKey("GID")
|
||||||
.HasName("pk_groups");
|
.HasName("pk_groups");
|
||||||
|
|
||||||
@@ -294,26 +274,10 @@ namespace MareSynchronosServer.Migrations
|
|||||||
.HasColumnType("character varying(10)")
|
.HasColumnType("character varying(10)")
|
||||||
.HasColumnName("group_user_uid");
|
.HasColumnName("group_user_uid");
|
||||||
|
|
||||||
b.Property<bool>("DisableAnimations")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("disable_animations");
|
|
||||||
|
|
||||||
b.Property<bool>("DisableSounds")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("disable_sounds");
|
|
||||||
|
|
||||||
b.Property<bool>("DisableVFX")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("disable_vfx");
|
|
||||||
|
|
||||||
b.Property<bool>("IsModerator")
|
b.Property<bool>("IsModerator")
|
||||||
.HasColumnType("boolean")
|
.HasColumnType("boolean")
|
||||||
.HasColumnName("is_moderator");
|
.HasColumnName("is_moderator");
|
||||||
|
|
||||||
b.Property<bool>("IsPaused")
|
|
||||||
.HasColumnType("boolean")
|
|
||||||
.HasColumnName("is_paused");
|
|
||||||
|
|
||||||
b.Property<bool>("IsPinned")
|
b.Property<bool>("IsPinned")
|
||||||
.HasColumnType("boolean")
|
.HasColumnType("boolean")
|
||||||
.HasColumnName("is_pinned");
|
.HasColumnName("is_pinned");
|
||||||
@@ -330,6 +294,44 @@ namespace MareSynchronosServer.Migrations
|
|||||||
b.ToTable("group_pairs", (string)null);
|
b.ToTable("group_pairs", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupPairPreferredPermission", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.Property<string>("GroupGID")
|
||||||
|
.HasColumnType("character varying(20)")
|
||||||
|
.HasColumnName("group_gid");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_vfx");
|
||||||
|
|
||||||
|
b.Property<bool>("IsPaused")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_paused");
|
||||||
|
|
||||||
|
b.HasKey("UserUID", "GroupGID")
|
||||||
|
.HasName("pk_group_pair_preferred_permissions");
|
||||||
|
|
||||||
|
b.HasIndex("GroupGID")
|
||||||
|
.HasDatabaseName("ix_group_pair_preferred_permissions_group_gid");
|
||||||
|
|
||||||
|
b.HasIndex("UserUID")
|
||||||
|
.HasDatabaseName("ix_group_pair_preferred_permissions_user_uid");
|
||||||
|
|
||||||
|
b.ToTable("group_pair_preferred_permissions", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("MareSynchronosShared.Models.GroupTempInvite", b =>
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupTempInvite", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("GroupGID")
|
b.Property<string>("GroupGID")
|
||||||
@@ -427,6 +429,156 @@ namespace MareSynchronosServer.Migrations
|
|||||||
b.ToTable("users", (string)null);
|
b.ToTable("users", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserDefaultPreferredPermission", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasMaxLength(10)
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableGroupAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_group_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableGroupSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_group_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableGroupVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_group_vfx");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableIndividualAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_individual_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableIndividualSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_individual_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableIndividualVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_individual_vfx");
|
||||||
|
|
||||||
|
b.Property<bool>("IndividualIsSticky")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("individual_is_sticky");
|
||||||
|
|
||||||
|
b.HasKey("UserUID")
|
||||||
|
.HasName("pk_user_default_preferred_permissions");
|
||||||
|
|
||||||
|
b.HasIndex("UserUID")
|
||||||
|
.HasDatabaseName("ix_user_default_preferred_permissions_user_uid");
|
||||||
|
|
||||||
|
b.ToTable("user_default_preferred_permissions", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserPermissionQuery", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Alias")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("alias");
|
||||||
|
|
||||||
|
b.Property<string>("GID")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("gid");
|
||||||
|
|
||||||
|
b.Property<string>("OtherUserUID")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("other_user_uid");
|
||||||
|
|
||||||
|
b.Property<bool>("OtherpermDisableAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("otherperm_disable_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("OtherpermDisableSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("otherperm_disable_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("OtherpermDisableVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("otherperm_disable_vfx");
|
||||||
|
|
||||||
|
b.Property<bool>("OtherpermIsPaused")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("otherperm_is_paused");
|
||||||
|
|
||||||
|
b.Property<bool>("OwnPermSticky")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("own_perm_sticky");
|
||||||
|
|
||||||
|
b.Property<bool>("OwnpermDisableAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("ownperm_disable_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("OwnpermDisableSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("ownperm_disable_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("OwnpermDisableVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("ownperm_disable_vfx");
|
||||||
|
|
||||||
|
b.Property<bool>("OwnpermIsPaused")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("ownperm_is_paused");
|
||||||
|
|
||||||
|
b.Property<bool>("Synced")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("synced");
|
||||||
|
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.ToTable("user_permission_query", null, t =>
|
||||||
|
{
|
||||||
|
t.ExcludeFromMigrations();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserPermissionSet", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("UserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("user_uid");
|
||||||
|
|
||||||
|
b.Property<string>("OtherUserUID")
|
||||||
|
.HasColumnType("character varying(10)")
|
||||||
|
.HasColumnName("other_user_uid");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableAnimations")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_animations");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableSounds")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_sounds");
|
||||||
|
|
||||||
|
b.Property<bool>("DisableVFX")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("disable_vfx");
|
||||||
|
|
||||||
|
b.Property<bool>("IsPaused")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("is_paused");
|
||||||
|
|
||||||
|
b.Property<bool>("Sticky")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("sticky");
|
||||||
|
|
||||||
|
b.HasKey("UserUID", "OtherUserUID")
|
||||||
|
.HasName("pk_user_permission_sets");
|
||||||
|
|
||||||
|
b.HasIndex("OtherUserUID")
|
||||||
|
.HasDatabaseName("ix_user_permission_sets_other_user_uid");
|
||||||
|
|
||||||
|
b.HasIndex("UserUID")
|
||||||
|
.HasDatabaseName("ix_user_permission_sets_user_uid");
|
||||||
|
|
||||||
|
b.ToTable("user_permission_sets", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("MareSynchronosShared.Models.UserProfileData", b =>
|
modelBuilder.Entity("MareSynchronosShared.Models.UserProfileData", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("UserUID")
|
b.Property<string>("UserUID")
|
||||||
@@ -549,7 +701,7 @@ namespace MareSynchronosServer.Migrations
|
|||||||
b.HasOne("MareSynchronosShared.Models.User", "Owner")
|
b.HasOne("MareSynchronosShared.Models.User", "Owner")
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("OwnerUID")
|
.HasForeignKey("OwnerUID")
|
||||||
.HasConstraintName("fk_groups_users_owner_temp_id8");
|
.HasConstraintName("fk_groups_users_owner_temp_id9");
|
||||||
|
|
||||||
b.Navigation("Owner");
|
b.Navigation("Owner");
|
||||||
});
|
});
|
||||||
@@ -589,20 +741,41 @@ namespace MareSynchronosServer.Migrations
|
|||||||
.HasForeignKey("GroupGID")
|
.HasForeignKey("GroupGID")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasConstraintName("fk_group_pairs_groups_group_temp_id1");
|
.HasConstraintName("fk_group_pairs_groups_group_temp_id2");
|
||||||
|
|
||||||
b.HasOne("MareSynchronosShared.Models.User", "GroupUser")
|
b.HasOne("MareSynchronosShared.Models.User", "GroupUser")
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("GroupUserUID")
|
.HasForeignKey("GroupUserUID")
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasConstraintName("fk_group_pairs_users_group_user_temp_id7");
|
.HasConstraintName("fk_group_pairs_users_group_user_temp_id8");
|
||||||
|
|
||||||
b.Navigation("Group");
|
b.Navigation("Group");
|
||||||
|
|
||||||
b.Navigation("GroupUser");
|
b.Navigation("GroupUser");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupPairPreferredPermission", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.Group", "Group")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("GroupGID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_group_pair_preferred_permissions_groups_group_temp_id1");
|
||||||
|
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_group_pair_preferred_permissions_users_user_temp_id7");
|
||||||
|
|
||||||
|
b.Navigation("Group");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("MareSynchronosShared.Models.GroupTempInvite", b =>
|
modelBuilder.Entity("MareSynchronosShared.Models.GroupTempInvite", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("MareSynchronosShared.Models.Group", "Group")
|
b.HasOne("MareSynchronosShared.Models.Group", "Group")
|
||||||
@@ -625,6 +798,39 @@ namespace MareSynchronosServer.Migrations
|
|||||||
b.Navigation("User");
|
b.Navigation("User");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserDefaultPreferredPermission", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_user_default_preferred_permissions_users_user_uid");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("MareSynchronosShared.Models.UserPermissionSet", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "OtherUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("OtherUserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_user_permission_sets_users_other_user_uid");
|
||||||
|
|
||||||
|
b.HasOne("MareSynchronosShared.Models.User", "User")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("UserUID")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_user_permission_sets_users_user_uid");
|
||||||
|
|
||||||
|
b.Navigation("OtherUser");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("MareSynchronosShared.Models.UserProfileData", b =>
|
modelBuilder.Entity("MareSynchronosShared.Models.UserProfileData", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("MareSynchronosShared.Models.User", "User")
|
b.HasOne("MareSynchronosShared.Models.User", "User")
|
||||||
|
|||||||
@@ -10,11 +10,6 @@ public class ClientPair
|
|||||||
[MaxLength(10)]
|
[MaxLength(10)]
|
||||||
public string OtherUserUID { get; set; }
|
public string OtherUserUID { get; set; }
|
||||||
public User OtherUser { get; set; }
|
public User OtherUser { get; set; }
|
||||||
public bool IsPaused { get; set; }
|
|
||||||
public bool AllowReceivingMessages { get; set; } = false;
|
|
||||||
[Timestamp]
|
[Timestamp]
|
||||||
public byte[] Timestamp { get; set; }
|
public byte[] Timestamp { get; set; }
|
||||||
public bool DisableSounds { get; set; } = false;
|
|
||||||
public bool DisableAnimations { get; set; } = false;
|
|
||||||
public bool DisableVFX { get; set; } = false;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class Group
|
|||||||
public string Alias { get; set; }
|
public string Alias { get; set; }
|
||||||
public bool InvitesEnabled { get; set; }
|
public bool InvitesEnabled { get; set; }
|
||||||
public string HashedPassword { get; set; }
|
public string HashedPassword { get; set; }
|
||||||
public bool DisableSounds { get; set; }
|
public bool PreferDisableSounds { get; set; }
|
||||||
public bool DisableAnimations { get; set; }
|
public bool PreferDisableAnimations { get; set; }
|
||||||
public bool DisableVFX { get; set; }
|
public bool PreferDisableVFX { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,6 @@ public class GroupPair
|
|||||||
public Group Group { get; set; }
|
public Group Group { get; set; }
|
||||||
public string GroupUserUID { get; set; }
|
public string GroupUserUID { get; set; }
|
||||||
public User GroupUser { get; set; }
|
public User GroupUser { get; set; }
|
||||||
public bool IsPaused { get; set; }
|
|
||||||
public bool IsPinned { get; set; }
|
public bool IsPinned { get; set; }
|
||||||
public bool IsModerator { get; set; }
|
public bool IsModerator { get; set; }
|
||||||
public bool DisableSounds { get; set; }
|
|
||||||
public bool DisableAnimations { get; set; }
|
|
||||||
public bool DisableVFX { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
namespace MareSynchronosShared.Models;
|
||||||
|
|
||||||
|
public class GroupPairPreferredPermission
|
||||||
|
{
|
||||||
|
public string GroupGID { get; set; }
|
||||||
|
public Group Group { get; set; }
|
||||||
|
public string UserUID { get; set; }
|
||||||
|
public User User { get; set; }
|
||||||
|
public bool IsPaused { get; set; }
|
||||||
|
public bool DisableAnimations { get; set; }
|
||||||
|
public bool DisableSounds { get; set; }
|
||||||
|
public bool DisableVFX { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace MareSynchronosShared.Models;
|
||||||
|
|
||||||
|
public class UserDefaultPreferredPermission
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
[MaxLength(10)]
|
||||||
|
[ForeignKey("User")]
|
||||||
|
public string UserUID { get; set; }
|
||||||
|
public User User { get; set; }
|
||||||
|
|
||||||
|
public bool DisableIndividualAnimations { get; set; } = false;
|
||||||
|
public bool DisableIndividualSounds { get; set; } = false;
|
||||||
|
public bool DisableIndividualVFX { get; set; } = false;
|
||||||
|
public bool DisableGroupAnimations { get; set; } = false;
|
||||||
|
public bool DisableGroupSounds { get; set; } = false;
|
||||||
|
public bool DisableGroupVFX { get; set; } = false;
|
||||||
|
public bool IndividualIsSticky { get; set; } = false;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
namespace MareSynchronosShared.Models;
|
||||||
|
|
||||||
|
public class UserPermissionQuery
|
||||||
|
{
|
||||||
|
public string UserUID { get; set; }
|
||||||
|
public string OtherUserUID { get; set; }
|
||||||
|
public string Alias { get; set; }
|
||||||
|
public string GID { get; set; }
|
||||||
|
public bool Synced { get; set; }
|
||||||
|
public bool OwnpermIsPaused { get; set; }
|
||||||
|
public bool OwnpermSticky { get; set; }
|
||||||
|
public bool OwnpermDisableAnimations { get; set; }
|
||||||
|
public bool OwnpermDisableSounds { get; set; }
|
||||||
|
public bool OwnpermDisableVFX { get; set; }
|
||||||
|
public bool? OtherpermIsPaused { get; set; }
|
||||||
|
public bool? OtherpermDisableAnimations { get; set; }
|
||||||
|
public bool? OtherpermDisableSounds { get; set; }
|
||||||
|
public bool? OtherpermDisableVFX { get; set; }
|
||||||
|
|
||||||
|
public UserPermissionSet OwnPermissions => new UserPermissionSet
|
||||||
|
{
|
||||||
|
UserUID = UserUID,
|
||||||
|
OtherUserUID = OtherUserUID,
|
||||||
|
IsPaused = OwnpermIsPaused,
|
||||||
|
DisableAnimations = OwnpermDisableAnimations,
|
||||||
|
DisableSounds = OwnpermDisableSounds,
|
||||||
|
DisableVFX = OwnpermDisableVFX,
|
||||||
|
Sticky = OwnpermSticky
|
||||||
|
};
|
||||||
|
|
||||||
|
public UserPermissionSet? OtherPermissions => !Synced ? null : new UserPermissionSet
|
||||||
|
{
|
||||||
|
UserUID = OtherUserUID,
|
||||||
|
OtherUserUID = UserUID,
|
||||||
|
IsPaused = OtherpermIsPaused ?? false,
|
||||||
|
DisableAnimations = OtherpermDisableAnimations ?? false,
|
||||||
|
DisableSounds = OtherpermDisableSounds ?? false,
|
||||||
|
DisableVFX = OtherpermDisableVFX ?? false,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace MareSynchronosShared.Models;
|
||||||
|
|
||||||
|
public class UserPermissionSet
|
||||||
|
{
|
||||||
|
[NotNull]
|
||||||
|
public string UserUID { get; set; }
|
||||||
|
public User User { get; set; }
|
||||||
|
[NotNull]
|
||||||
|
public string OtherUserUID { get; set; }
|
||||||
|
public User OtherUser { get; set; }
|
||||||
|
public bool Sticky { get; set; } = false;
|
||||||
|
public bool IsPaused { get; set; } = false;
|
||||||
|
public bool DisableAnimations { get; set; } = false;
|
||||||
|
public bool DisableVFX { get; set; } = false;
|
||||||
|
public bool DisableSounds { get; set; } = false;
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.SignalR;
|
||||||
|
using MareSynchronosShared.Utils;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace MareSynchronosShared.RequirementHandlers;
|
||||||
|
|
||||||
|
public class ValidTokenRequirementHandler : AuthorizationHandler<ValidTokenRequirement>
|
||||||
|
{
|
||||||
|
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ValidTokenRequirement requirement)
|
||||||
|
{
|
||||||
|
var expirationClaimValue = context.User.Claims.Single(r => string.Equals(r.Type, MareClaimTypes.Expires, StringComparison.Ordinal))?.Value;
|
||||||
|
if (expirationClaimValue == null)
|
||||||
|
{
|
||||||
|
context.Fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime expirationDate = new(long.Parse(expirationClaimValue, CultureInfo.InvariantCulture), DateTimeKind.Utc);
|
||||||
|
if (expirationDate < DateTime.UtcNow)
|
||||||
|
{
|
||||||
|
context.Fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Succeed(requirement);
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ValidTokenHubRequirementHandler : AuthorizationHandler<ValidTokenRequirement, HubInvocationContext>
|
||||||
|
{
|
||||||
|
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ValidTokenRequirement requirement, HubInvocationContext resource)
|
||||||
|
{
|
||||||
|
var expirationClaimValue = context.User.Claims.Single(r => string.Equals(r.Type, MareClaimTypes.Expires, StringComparison.Ordinal))?.Value;
|
||||||
|
if (expirationClaimValue == null)
|
||||||
|
{
|
||||||
|
context.Fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime expirationDate = new(long.Parse(expirationClaimValue, CultureInfo.InvariantCulture), DateTimeKind.Utc);
|
||||||
|
if (expirationDate < DateTime.UtcNow)
|
||||||
|
{
|
||||||
|
context.Fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Succeed(requirement);
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
|
||||||
|
namespace MareSynchronosShared.RequirementHandlers;
|
||||||
|
|
||||||
|
public class ValidTokenRequirement : IAuthorizationRequirement { }
|
||||||
@@ -5,4 +5,5 @@ public static class MareClaimTypes
|
|||||||
public const string Uid = "uid";
|
public const string Uid = "uid";
|
||||||
public const string CharaIdent = "character_identification";
|
public const string CharaIdent = "character_identification";
|
||||||
public const string Internal = "internal";
|
public const string Internal = "internal";
|
||||||
|
public const string Expires = "expiration_date";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,6 +100,16 @@ public static class SharedDbFunctions
|
|||||||
await dbContext.SaveChangesAsync().ConfigureAwait(false);
|
await dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var defaultPermissions = await dbContext.UserDefaultPreferredPermissions.Where(u => u.UserUID == user.UID).ToListAsync().ConfigureAwait(false);
|
||||||
|
var groupPermissions = await dbContext.GroupPairPreferredPermissions.Where(u => u.UserUID == user.UID).ToListAsync().ConfigureAwait(false);
|
||||||
|
var individualPermissions = await dbContext.Permissions.Where(u => u.UserUID == user.UID || u.OtherUserUID == user.UID).ToListAsync().ConfigureAwait(false);
|
||||||
|
var bannedinGroups = await dbContext.GroupBans.Where(u => u.BannedUserUID == user.UID).ToListAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
dbContext.GroupPairPreferredPermissions.RemoveRange(groupPermissions);
|
||||||
|
dbContext.UserDefaultPreferredPermissions.RemoveRange(defaultPermissions);
|
||||||
|
dbContext.Permissions.RemoveRange(individualPermissions);
|
||||||
|
dbContext.GroupBans.RemoveRange(bannedinGroups);
|
||||||
|
|
||||||
_logger.LogInformation("User purged: {uid}", user.UID);
|
_logger.LogInformation("User purged: {uid}", user.UID);
|
||||||
|
|
||||||
dbContext.Auth.Remove(auth);
|
dbContext.Auth.Remove(auth);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="lz4net" Version="1.0.15.93" />
|
<PackageReference Include="lz4net" Version="1.0.15.93" />
|
||||||
<PackageReference Include="Meziantou.Analyzer" Version="2.0.49">
|
<PackageReference Include="Meziantou.Analyzer" Version="2.0.93">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ public class RequestQueueService : IHostedService
|
|||||||
_userQueueRequests[i] = null;
|
_userQueueRequests[i] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_queue.Any()) return;
|
if (!_queue.Any() && !_priorityQueue.Any()) return;
|
||||||
|
|
||||||
if (_userQueueRequests[i] == null)
|
if (_userQueueRequests[i] == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public class Startup
|
|||||||
o.TokenValidationParameters = new()
|
o.TokenValidationParameters = new()
|
||||||
{
|
{
|
||||||
ValidateIssuer = false,
|
ValidateIssuer = false,
|
||||||
ValidateLifetime = false,
|
ValidateLifetime = true,
|
||||||
ValidateAudience = false,
|
ValidateAudience = false,
|
||||||
ValidateIssuerSigningKey = true,
|
ValidateIssuerSigningKey = true,
|
||||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(s.GetValue<string>(nameof(MareConfigurationAuthBase.Jwt)))),
|
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(s.GetValue<string>(nameof(MareConfigurationAuthBase.Jwt)))),
|
||||||
|
|||||||
Reference in New Issue
Block a user