diff --git a/LarpixServer/Account/Requests.cs b/LarpixServer/Account/Requests.cs index e4e785d..b77754c 100644 --- a/LarpixServer/Account/Requests.cs +++ b/LarpixServer/Account/Requests.cs @@ -31,7 +31,7 @@ public class Requests return; } - string id = Utils.GetIdFromUsernameWD(idQuery.ToString()); + string id = Utils.GetValidIdOrZero(idQuery.ToString()); string password = await Utils.GetPassword(id); secret = await Utils.NonceDecryptBody(id, password, secret); string auth = await Utils.Auth(id, password, secret); @@ -292,7 +292,7 @@ public class Requests return; } - string id = Utils.GetIdFromUsernameWD(idQuery.ToString()); + string id = Utils.GetValidIdOrZero(idQuery.ToString()); string password = await Utils.GetPassword(id); secret = await Utils.NonceDecryptBody(id, password, secret); string auth = await Utils.Auth(id, password, secret); @@ -353,7 +353,7 @@ public class Requests { return; } - id = Utils.GetIdFromUsernameWD(id.ToString()); + id = Utils.GetValidIdOrZero(id.ToString()); await context.Response.WriteAsync(await Utils.NameFromId(id) + $":{DOMAIN}"); return; @@ -367,7 +367,7 @@ public class Requests return; } - string id = Utils.GetIdFromUsernameWD(idQuery.ToString()); + string id = Utils.GetValidIdOrZero(idQuery.ToString()); string plainPass = await Utils.GetPassword(id); foreach (var kvp in nonceHolder) //clearowanie nieuzytych nonce { @@ -403,7 +403,7 @@ public class Requests return; } - string id = Utils.GetIdFromUsernameWD(idQuery.ToString()); + string id = Utils.GetValidIdOrZero(idQuery.ToString()); string body = await LoadBody(bodyReader); string password = await Utils.GetPassword(id); string newPass = await Utils.NonceDecryptBody(id, password, body, false); @@ -451,7 +451,7 @@ public class Requests return; } - string id = Utils.GetIdFromUsernameWD(idQuery.ToString()); + string id = Utils.GetValidIdOrZero(idQuery.ToString()); string body = await LoadBody(bodyReader); string password = await Utils.GetPassword(id); @@ -503,7 +503,7 @@ public class Requests { return; } - string id = Utils.GetIdFromUsernameWD(idQuery.ToString()); + string id = Utils.GetValidIdOrZero(idQuery.ToString()); string keysRaw = await Utils.GetUserKeys(id); if (string.IsNullOrEmpty(keysRaw)) { @@ -533,7 +533,7 @@ public class Requests { return; } - string id = Utils.GetIdFromUsernameWD(idQuery.ToString()); + string id = Utils.GetValidIdOrZero(idQuery.ToString()); byte[] entryByte = await Utils.GetUserPublicStorageEntry(id, entry); @@ -557,7 +557,7 @@ public class Requests return; } - string id = Utils.GetIdFromUsernameWD(idQuery.ToString()); + string id = Utils.GetValidIdOrZero(idQuery.ToString()); string body = await LoadBody(bodyReader); string password = await Utils.GetPassword(id); body = await Utils.NonceDecryptBody(id, password, body, false); diff --git a/LarpixServer/Account/Utils.cs b/LarpixServer/Account/Utils.cs index 308cdfc..56e879a 100644 --- a/LarpixServer/Account/Utils.cs +++ b/LarpixServer/Account/Utils.cs @@ -22,26 +22,38 @@ public class Utils { while (userLocks.Count >= LOCK_SIZE) { - if (!keyQueue.TryPeek(out var firstKey)) break; + if (!keyQueue.TryDequeue(out var firstKey)) break; - var sem = userLocks[firstKey]; - if (sem.Wait(0)) + if (userLocks.TryGetValue(firstKey, out var sem)) { - try + if (sem.Wait(0)) { - if (userLocks.TryRemove(firstKey, out _)) - keyQueue.TryDequeue(out _); + try + { + userLocks.TryRemove(firstKey, out _); + } + finally { sem.Release(); } + } + else + { + keyQueue.Enqueue(firstKey); + break; } - finally { sem.Release(); } - } - else - { - break; } } - var semLock = userLocks.GetOrAdd(id, _ => new SemaphoreSlim(1, 1)); - keyQueue.Enqueue(id); + if (!userLocks.TryGetValue(id, out var semLock)) + { + semLock = new SemaphoreSlim(1, 1); + if (userLocks.TryAdd(id, semLock)) + { + keyQueue.Enqueue(id); + } + else + { + semLock = userLocks[id]; + } + } return semLock; } @@ -51,6 +63,12 @@ public class Utils return colonIndex == -1 ? usernameWD : usernameWD.Substring(0, colonIndex); } + public static string GetValidIdOrZero(string input) + { + string idPart = GetIdFromUsernameWD(input); + return ulong.TryParse(idPart, out _) ? idPart : "0"; + } + public static string GetDmId(string id1, string domain1, string id2, string domain2) { string u1 = $"{id1};{domain1}"; diff --git a/LarpixServer/Federation/Receiver.cs b/LarpixServer/Federation/Receiver.cs index fd1b2c1..bb28e38 100644 --- a/LarpixServer/Federation/Receiver.cs +++ b/LarpixServer/Federation/Receiver.cs @@ -28,7 +28,20 @@ public class Receiver await context.Response.WriteAsync( await Account.Utils.IdFromName(serializedBody.string2) ); return; case "dm/invite/send": + { string[] ids = serializedBody.string2.Split(','); //0=receiver, 1=sender + if (ids.Length != 2 || string.IsNullOrEmpty(ids[0]) || !ulong.TryParse(ids[0], out _) || !Fs.Exists($"{ACCOUNTS_DATA_DIR}/{ids[0]}")) + { + await context.Response.WriteAsync("error:user.not.found"); + return; + } + + string dmIdCheck = Account.Utils.GetDmId(ids[0], DOMAIN, ids[1], domain); + if (Fs.Exists($"{ROOMS_DIR}/dms/{DOMAIN}/{dmIdCheck}")) + { + await context.Response.WriteAsync("error:dm.already.exists"); + return; + } if (!await Sender.HasSentDmInvite(ids[1], domain, ids[0])) { @@ -50,17 +63,22 @@ public class Receiver } finally { - userLock.Release(); } await context.Response.WriteAsync("success:user.invited"); - return; + } case "dm/invite/revoke": - ids = serializedBody.string2.Split(','); //0=receiver, 1=sender + { + string[] ids = serializedBody.string2.Split(','); //0=receiver, 1=sender + if (ids.Length != 2 || string.IsNullOrEmpty(ids[0]) || !ulong.TryParse(ids[0], out _) || !Fs.Exists($"{ACCOUNTS_DATA_DIR}/{ids[0]}")) + { + await context.Response.WriteAsync("error:user.not.found"); + return; + } - userLock = Account.Utils.GetUserLock(ids[0]); + SemaphoreSlim userLock = Account.Utils.GetUserLock(ids[0]); await userLock.WaitAsync(); try { @@ -77,19 +95,42 @@ public class Receiver await context.Response.WriteAsync("success:invite.revoked"); return; + } case "dm/invite/decline": - ids = serializedBody.string2.Split(','); //0=sender, 1=receiver - - string inviteSentFileDecline = ACCOUNTS_DATA_DIR + $"/{ids[0]}/dminvites/sent/{ids[1]};{domain}"; - if (Fs.Exists(inviteSentFileDecline)) + { + string[] ids = serializedBody.string2.Split(','); //0=sender, 1=receiver + if (ids.Length != 2 || string.IsNullOrEmpty(ids[0]) || !ulong.TryParse(ids[0], out _) || !Fs.Exists($"{ACCOUNTS_DATA_DIR}/{ids[0]}")) { - Fs.DeleteFile(inviteSentFileDecline); + await context.Response.WriteAsync("error:user.not.found"); + return; + } + + SemaphoreSlim userLock = Account.Utils.GetUserLock(ids[0]); + await userLock.WaitAsync(); + try + { + string inviteSentFileDecline = ACCOUNTS_DATA_DIR + $"/{ids[0]}/dminvites/sent/{ids[1]};{domain}"; + if (Fs.Exists(inviteSentFileDecline)) + { + Fs.DeleteFile(inviteSentFileDecline); + } + } + finally + { + userLock.Release(); } await context.Response.WriteAsync("success:invite.declined"); return; + } case "dm/invite/hassent": - ids = serializedBody.string2.Split(','); //0=sender, 1=receiver + { + string[] ids = serializedBody.string2.Split(','); //0=sender, 1=receiver + if (ids.Length != 2 || string.IsNullOrEmpty(ids[0]) || !ulong.TryParse(ids[0], out _) || !Fs.Exists($"{ACCOUNTS_DATA_DIR}/{ids[0]}")) + { + await context.Response.WriteAsync("false"); + return; + } string inviteSentFile = ACCOUNTS_DATA_DIR + $"/{ids[0]}/dminvites/sent/{ids[1]};{domain}"; if (!Fs.Exists(inviteSentFile)) @@ -100,43 +141,45 @@ public class Receiver await context.Response.WriteAsync( "true" ); return; + } case "dm/add": - ids = serializedBody.string2.Split(','); //0=creator (inv receiver), 1=inviter - - - //did i really sent an invite to this user???? idkkk maybeeeee yeahhh i did this - inviteSentFile = ACCOUNTS_DATA_DIR + $"/{ids[0]}/dminvites/sent/{ids[1]};{domain}"; - if (!Fs.Exists(inviteSentFile)) + { + string[] ids = serializedBody.string2.Split(','); //0=creator (inv receiver), 1=inviter + if (ids.Length != 2 || string.IsNullOrEmpty(ids[0]) || !ulong.TryParse(ids[0], out _) || !Fs.Exists($"{ACCOUNTS_DATA_DIR}/{ids[0]}")) { - await context.Response.WriteAsync( "error:no.invite.found" ); + await context.Response.WriteAsync("error:user.not.found"); return; } - Fs.DeleteFile(inviteSentFile); - //now full invite is deleted :333333333333333333333333333 - //we need to add to dm :33333333333333333333 - - userLock = Account.Utils.GetUserLock(ids[0]); + SemaphoreSlim userLock = Account.Utils.GetUserLock(ids[0]); await userLock.WaitAsync(); try { + //did i really sent an invite to this user???? idkkk maybeeeee yeahhh i did this + string inviteSentFile = ACCOUNTS_DATA_DIR + $"/{ids[0]}/dminvites/sent/{ids[1]};{domain}"; + if (!Fs.Exists(inviteSentFile)) + { + await context.Response.WriteAsync( "error:no.invite.found" ); + return; + } + Fs.DeleteFile(inviteSentFile); + //now full invite is deleted :333333333333333333333333333 + //we need to add to dm :33333333333333333333 + //best dmId creation ever string dmId = Account.Utils.GetDmId(ids[0], DOMAIN, ids[1], domain); - await Account.Utils.UpdateUserDm(ids[0], dmId, "false", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString()); - await context.Response.WriteAsync("success:dm.accepted"); return; - } finally { userLock.Release(); } - return; + } } return; diff --git a/LarpixServer/Room/Requests.cs b/LarpixServer/Room/Requests.cs index 2c3796a..8f25d65 100644 --- a/LarpixServer/Room/Requests.cs +++ b/LarpixServer/Room/Requests.cs @@ -66,7 +66,7 @@ public class Requests public static async Task DmInvite(string id, string targetId) { bool isLocal = Account.Utils.IsUserLocal(targetId, out string domain); - string tId = Account.Utils.GetIdFromUsernameWD(targetId); + string tId = Account.Utils.GetValidIdOrZero(targetId); string checkDmId = Account.Utils.GetDmId(id, DOMAIN, tId, domain); if (Fs.Exists($"{ROOMS_DIR}/dms/{DOMAIN}/{checkDmId}")) @@ -116,7 +116,7 @@ public class Requests public static async Task DmInviteRevoke(string id, string targetId) { bool isLocal = Account.Utils.IsUserLocal(targetId, out string domain); - string tId = Account.Utils.GetIdFromUsernameWD(targetId); + string tId = Account.Utils.GetValidIdOrZero(targetId); if (!isLocal) //federation { @@ -145,7 +145,7 @@ public class Requests public static async Task DmInviteDecline(string id, string targetId) { bool isLocal = Account.Utils.IsUserLocal(targetId, out string domain); - string tId = Account.Utils.GetIdFromUsernameWD(targetId); + string tId = Account.Utils.GetValidIdOrZero(targetId); if (!isLocal) //federation { @@ -183,7 +183,7 @@ public class Requests string targetId = serializedBody.string1; bool isUserLocal = Account.Utils.IsUserLocal(targetId, out string domain); - string id2 = Account.Utils.GetIdFromUsernameWD(targetId); + string id2 = Account.Utils.GetValidIdOrZero(targetId); if (id2 == "0" || string.IsNullOrEmpty(id2)) {