2019-03-13 12:49:28 +03:00
|
|
|
package ru.gravit.launchserver.components;
|
2018-09-17 10:07:32 +03:00
|
|
|
|
2019-01-15 06:35:39 +03:00
|
|
|
import ru.gravit.launcher.NeedGarbageCollection;
|
|
|
|
import ru.gravit.launchserver.LaunchServer;
|
2019-03-13 12:49:28 +03:00
|
|
|
import ru.gravit.launchserver.auth.AuthException;
|
|
|
|
import ru.gravit.launchserver.auth.provider.AuthProvider;
|
|
|
|
import ru.gravit.launchserver.socket.Client;
|
2019-04-04 15:10:28 +03:00
|
|
|
import ru.gravit.launchserver.websocket.json.auth.AuthResponse;
|
2019-01-15 06:35:39 +03:00
|
|
|
|
2018-12-20 18:45:01 +03:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
|
2019-03-13 12:49:28 +03:00
|
|
|
public class AuthLimiterComponent extends Component implements NeedGarbageCollection {
|
|
|
|
@Override
|
|
|
|
public void preInit(LaunchServer launchServer) {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void init(LaunchServer launchServer) {
|
|
|
|
launchServer.authHookManager.registerPreHook(this::preAuthHook);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void postInit(LaunchServer launchServer) {
|
|
|
|
|
|
|
|
}
|
2019-04-03 16:27:40 +03:00
|
|
|
|
2019-03-13 12:49:28 +03:00
|
|
|
public void preAuthHook(AuthResponse.AuthContext context, Client client) throws AuthException {
|
2019-04-03 16:27:40 +03:00
|
|
|
if (isLimit(context.ip)) {
|
2019-03-13 12:49:28 +03:00
|
|
|
AuthProvider.authError(message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-17 10:07:32 +03:00
|
|
|
static class AuthEntry {
|
|
|
|
public int value;
|
|
|
|
|
|
|
|
public long ts;
|
|
|
|
|
|
|
|
public AuthEntry(int i, long l) {
|
|
|
|
value = i;
|
|
|
|
ts = l;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean equals(Object obj) {
|
|
|
|
if (this == obj)
|
2018-09-22 17:33:00 +03:00
|
|
|
return true;
|
2018-09-17 10:07:32 +03:00
|
|
|
if (obj == null)
|
2018-09-22 17:33:00 +03:00
|
|
|
return false;
|
2018-09-17 10:07:32 +03:00
|
|
|
if (!(obj instanceof AuthEntry))
|
2018-09-22 17:33:00 +03:00
|
|
|
return false;
|
2018-09-17 10:07:32 +03:00
|
|
|
AuthEntry other = (AuthEntry) obj;
|
|
|
|
if (ts != other.ts)
|
2018-09-22 17:33:00 +03:00
|
|
|
return false;
|
2018-09-17 10:07:32 +03:00
|
|
|
return value == other.value;
|
|
|
|
}
|
2018-09-22 17:33:00 +03:00
|
|
|
|
2018-09-17 10:07:32 +03:00
|
|
|
@Override
|
|
|
|
public int hashCode() {
|
|
|
|
final int prime = 31;
|
|
|
|
int result = 1;
|
|
|
|
result = prime * result + (int) (ts ^ ts >>> 32);
|
|
|
|
result = prime * result + value;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return String.format("AuthEntry {value=%s, ts=%s}", value, ts);
|
|
|
|
}
|
|
|
|
}
|
2018-09-22 17:33:00 +03:00
|
|
|
|
2018-10-13 11:01:10 +03:00
|
|
|
|
2018-09-17 10:07:32 +03:00
|
|
|
public static final long TIMEOUT = 10 * 60 * 1000; //10 минут
|
2019-03-13 12:49:28 +03:00
|
|
|
public int rateLimit;
|
|
|
|
public int rateLimitMilis;
|
|
|
|
public String message;
|
|
|
|
|
2019-03-15 21:47:47 +03:00
|
|
|
public transient HashMap<String, AuthEntry> map = new HashMap<>();
|
|
|
|
public List<String> excludeIps = new ArrayList<>();
|
2018-09-17 10:07:32 +03:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void garbageCollection() {
|
|
|
|
long time = System.currentTimeMillis();
|
|
|
|
long max_timeout = Math.max(rateLimitMilis, TIMEOUT);
|
|
|
|
map.entrySet().removeIf(e -> e.getValue().ts + max_timeout < time);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isLimit(String ip) {
|
2018-12-20 18:45:01 +03:00
|
|
|
if (excludeIps.contains(ip)) return false;
|
2018-09-17 10:07:32 +03:00
|
|
|
if (map.containsKey(ip)) {
|
|
|
|
AuthEntry rate = map.get(ip);
|
|
|
|
long currenttime = System.currentTimeMillis();
|
|
|
|
if (rate.ts + rateLimitMilis < currenttime) rate.value = 0;
|
|
|
|
if (rate.value >= rateLimit && rateLimit > 0) {
|
|
|
|
rate.value++;
|
|
|
|
rate.ts = currenttime;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
rate.value++;
|
|
|
|
rate.ts = currenttime;
|
|
|
|
return false;
|
|
|
|
}
|
2018-09-22 17:33:00 +03:00
|
|
|
map.put(ip, new AuthEntry(1, System.currentTimeMillis()));
|
|
|
|
return false;
|
2018-09-17 10:07:32 +03:00
|
|
|
}
|
|
|
|
}
|