add rate limits
This commit is contained in:
parent
e15ce6ba8b
commit
c523d40342
4 changed files with 71 additions and 6 deletions
|
|
@ -14,6 +14,27 @@ public class Requests
|
|||
{
|
||||
public static ConcurrentDictionary<string, CreateHolder> createHolder = new();
|
||||
public static ConcurrentDictionary<string, (string, DateTimeOffset)> nonceHolder = new();
|
||||
public static ConcurrentDictionary<string, (int count, DateTime resetTime)> actionRateLimits = new();
|
||||
|
||||
public static bool IsActionRateLimited(string id)
|
||||
{
|
||||
if (ACTION_RATE_LIMIT <= 0) return false;
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
actionRateLimits.AddOrUpdate(id,
|
||||
_ => (1, now.AddMinutes(1)),
|
||||
(_, old) => {
|
||||
if (now > old.resetTime) return (1, now.AddMinutes(1));
|
||||
return (old.count + 1, old.resetTime);
|
||||
}
|
||||
);
|
||||
|
||||
if (actionRateLimits.TryGetValue(id, out var record) && record.count > ACTION_RATE_LIMIT)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static SemaphoreSlim createLock = new SemaphoreSlim(1, 1);
|
||||
|
||||
|
|
@ -625,6 +646,20 @@ public static async Task Auth(HttpContext context, Func<Task> next, IQueryCollec
|
|||
return;
|
||||
}
|
||||
|
||||
string[] actionRequests = {
|
||||
"user/dm/invite", "user/dm/invite/revoke", "user/dm/invite/decline", "user/dm/create",
|
||||
"dm/message/send", "dm/message/delete", "dm/message/react", "dm/key/update",
|
||||
"user/storage/public/update", "user/storage/private/update", "dm/read"
|
||||
};
|
||||
if (System.Array.IndexOf(actionRequests, serializedBody.string1) >= 0)
|
||||
{
|
||||
if (IsActionRateLimited(id))
|
||||
{
|
||||
await context.Response.WriteAsync(Encryption.Encryption.EncryptString("error:rate.limit", password));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SemaphoreSlim userLock = Utils.GetUserLock(id);
|
||||
await userLock.WaitAsync();
|
||||
try
|
||||
|
|
@ -733,6 +768,16 @@ public static async Task Auth(HttpContext context, Func<Task> next, IQueryCollec
|
|||
await context.Response.WriteAsync(Encryption.Encryption.EncryptString(await Room.Requests.GetDmMessages(id, msgGet.string1, msgGet.string3, msgGet.string2), password));
|
||||
break;
|
||||
}
|
||||
case "dm/read":
|
||||
{
|
||||
Universal2String readGet = JsonSerializer.Deserialize(
|
||||
serializedBody.string2,
|
||||
AppJsonSerializerContext.Default.Universal2String
|
||||
);
|
||||
await Account.Utils.UpdateUserDm(id, readGet.string1, "true", "");
|
||||
await context.Response.WriteAsync(Encryption.Encryption.EncryptString("success:dm.read", password));
|
||||
break;
|
||||
}
|
||||
case "dm/key/get":
|
||||
await context.Response.WriteAsync(
|
||||
Encryption.Encryption.EncryptString(
|
||||
|
|
@ -789,6 +834,12 @@ public static async Task Auth(HttpContext context, Func<Task> next, IQueryCollec
|
|||
return;
|
||||
}
|
||||
|
||||
if (IsActionRateLimited(id))
|
||||
{
|
||||
await context.Response.WriteAsync(Encryption.Encryption.EncryptString("error:rate.limit", password));
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] bodyBytes = await LarpixServer.Utils.Utils.LoadBodyBytes(context.Request.Body, LarpixServer.Utils.Utils.PUBLIC_STORAGE_LIMIT);
|
||||
byte[] fileBytes = await Utils.NonceDecryptBytes(id, password, bodyBytes, true);
|
||||
|
||||
|
|
|
|||
|
|
@ -432,7 +432,10 @@ public class Utils
|
|||
}
|
||||
|
||||
fileDm.string1 = dmId;
|
||||
if (timestamp != "")
|
||||
{
|
||||
fileDm.string2 = timestamp;
|
||||
}
|
||||
fileDm.string3 = isRead;
|
||||
|
||||
await Fs.WriteFile(dmPath, Encoding.UTF8.GetBytes(JsonSerializer.Serialize(fileDm, AppJsonSerializerContext.Default.Universal3String)));
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ public class Requests
|
|||
return Encoding.UTF8.GetString(await Fs.ReadFile(path));
|
||||
}
|
||||
|
||||
public static async Task<string> UpdateDmKey(string id, string dmId, string key)
|
||||
public static async Task<string> UpdateDmKey(string id, string dmId, string key) //nie powinno byc takich rzeczy jak ta, jak juz powinnismy tworzyc nowy klucz, np. 1 i pozniej w wiadomosci wpisywac Message.key = "1" i nim szyfrowac
|
||||
{
|
||||
if (!await IsMemberOfDm(id, dmId))
|
||||
{
|
||||
|
|
@ -414,7 +414,7 @@ public class Requests
|
|||
if (memberId == id)
|
||||
{
|
||||
await Account.Utils.UpdateUserDm(memberId, dmId, "true", msg.timestamp);
|
||||
await Utils.Utils.SendWsMessage(memberId, $"dm_message:{dmId}");
|
||||
await Utils.Utils.SendWsMessage(memberId, $"dm_message:{dmId}:read");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -430,7 +430,7 @@ public class Requests
|
|||
{
|
||||
userLock.Release();
|
||||
}
|
||||
await Utils.Utils.SendWsMessage(memberId, $"dm_message:{dmId}");
|
||||
await Utils.Utils.SendWsMessage(memberId, $"dm_message:{dmId}:unread");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -459,8 +459,10 @@ public class Requests
|
|||
);
|
||||
|
||||
if (msg.author != id) return "error:forbidden";
|
||||
if (msg.type == "larp.redacted") return "error:message.already.deleted";
|
||||
|
||||
msg.type = "larp.redacted";
|
||||
msg.reactions = "";
|
||||
msg.content = "{blah(larp.redacted)}";
|
||||
msg.attachment = "";
|
||||
msg.key = "";
|
||||
|
|
@ -474,7 +476,7 @@ public class Requests
|
|||
string memberId = Account.Utils.GetValidIdOrZero(memberWD);
|
||||
if (isLocal)
|
||||
{
|
||||
await Utils.Utils.SendWsMessage(memberId, $"dm_message:{dmId}");
|
||||
await Utils.Utils.SendWsMessage(memberId, $"dm_message:{dmId}:update");
|
||||
}
|
||||
}
|
||||
return "success:message.deleted";
|
||||
|
|
@ -501,6 +503,8 @@ public class Requests
|
|||
AppJsonSerializerContext.Default.Message
|
||||
);
|
||||
|
||||
if (msg.type == "larp.redacted") return "error:message.already.deleted";
|
||||
|
||||
msg.reactions = reactions ?? "";
|
||||
|
||||
await Fs.WriteFile(msgPath, Encoding.UTF8.GetBytes(JsonSerializer.Serialize(msg, AppJsonSerializerContext.Default.Message)));
|
||||
|
|
@ -512,7 +516,7 @@ public class Requests
|
|||
string memberId = Account.Utils.GetValidIdOrZero(memberWD);
|
||||
if (isLocal)
|
||||
{
|
||||
await Utils.Utils.SendWsMessage(memberId, $"dm_message:{dmId}");
|
||||
await Utils.Utils.SendWsMessage(memberId, $"dm_message:{dmId}:update");
|
||||
}
|
||||
}
|
||||
return "success:message.reacted";
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ public class Utils
|
|||
public static int LOCK_SIZE = 1000000;
|
||||
|
||||
public static int MAX_BODY_SIZE = 20971520; //20mb //2621440; //2.5mb
|
||||
public static int ACTION_RATE_LIMIT = 120;
|
||||
|
||||
public static int PRIVATE_STORAGE_LIMIT = 5242880;
|
||||
public static int PUBLIC_STORAGE_LIMIT = 10485760;
|
||||
|
|
@ -259,6 +260,12 @@ public class Utils
|
|||
PORT = int.Parse(port);
|
||||
}
|
||||
|
||||
string? actionRateLimitStr = Environment.GetEnvironmentVariable("ACTION_RATE_LIMIT");
|
||||
if (actionRateLimitStr != null && int.TryParse(actionRateLimitStr, out int parsedLimit))
|
||||
{
|
||||
ACTION_RATE_LIMIT = parsedLimit;
|
||||
}
|
||||
|
||||
VOICE_IPS.Clear();
|
||||
|
||||
port = Environment.GetEnvironmentVariable("VOICE_IPS");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue