mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-11-15 11:39:11 +03:00
[FEATURE] RegLimiterComponent
This commit is contained in:
parent
2d887c86a9
commit
07dd7bcfc8
5 changed files with 108 additions and 1 deletions
|
@ -62,6 +62,7 @@
|
||||||
import pro.gravit.launchserver.binary.ProguardConf;
|
import pro.gravit.launchserver.binary.ProguardConf;
|
||||||
import pro.gravit.launchserver.components.AuthLimiterComponent;
|
import pro.gravit.launchserver.components.AuthLimiterComponent;
|
||||||
import pro.gravit.launchserver.components.Component;
|
import pro.gravit.launchserver.components.Component;
|
||||||
|
import pro.gravit.launchserver.components.RegLimiterComponent;
|
||||||
import pro.gravit.launchserver.config.LaunchServerRuntimeConfig;
|
import pro.gravit.launchserver.config.LaunchServerRuntimeConfig;
|
||||||
import pro.gravit.launchserver.dao.UserService;
|
import pro.gravit.launchserver.dao.UserService;
|
||||||
import pro.gravit.launchserver.dao.provider.DaoProvider;
|
import pro.gravit.launchserver.dao.provider.DaoProvider;
|
||||||
|
@ -761,6 +762,11 @@ private void generateConfigIfNotExists(boolean testEnv) throws IOException {
|
||||||
authLimiterComponent.rateLimitMilis = 8000;
|
authLimiterComponent.rateLimitMilis = 8000;
|
||||||
authLimiterComponent.message = "Превышен лимит авторизаций";
|
authLimiterComponent.message = "Превышен лимит авторизаций";
|
||||||
newConfig.components.put("authLimiter", authLimiterComponent);
|
newConfig.components.put("authLimiter", authLimiterComponent);
|
||||||
|
RegLimiterComponent regLimiterComponent = new RegLimiterComponent();
|
||||||
|
regLimiterComponent.rateLimit = 3;
|
||||||
|
regLimiterComponent.rateLimitMilis = 1000 * 60 * 60 * 10; //Блок на 10 часов
|
||||||
|
regLimiterComponent.message = "Превышен лимит регистраций";
|
||||||
|
newConfig.components.put("regLimiter", regLimiterComponent);
|
||||||
|
|
||||||
// Set server address
|
// Set server address
|
||||||
String address;
|
String address;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
import pro.gravit.launchserver.auth.AuthException;
|
import pro.gravit.launchserver.auth.AuthException;
|
||||||
import pro.gravit.launchserver.dao.User;
|
import pro.gravit.launchserver.dao.User;
|
||||||
|
import pro.gravit.launchserver.manangers.hook.AuthHookManager;
|
||||||
import pro.gravit.utils.helper.SecurityHelper;
|
import pro.gravit.utils.helper.SecurityHelper;
|
||||||
|
|
||||||
public class HibernateAuthProvider extends AuthProvider {
|
public class HibernateAuthProvider extends AuthProvider {
|
||||||
|
@ -12,9 +13,17 @@ public class HibernateAuthProvider extends AuthProvider {
|
||||||
public AuthProviderResult auth(String login, String password, String ip) throws Exception {
|
public AuthProviderResult auth(String login, String password, String ip) throws Exception {
|
||||||
User user = srv.config.dao.userService.findUserByUsername(login);
|
User user = srv.config.dao.userService.findUserByUsername(login);
|
||||||
if(user == null && autoReg)
|
if(user == null && autoReg)
|
||||||
|
{
|
||||||
|
AuthHookManager.RegContext context = new AuthHookManager.RegContext(login, password, ip, false);
|
||||||
|
if(AuthHookManager.registraion.hook(context))
|
||||||
{
|
{
|
||||||
user = srv.config.dao.userService.registerNewUser(login, password);
|
user = srv.config.dao.userService.registerNewUser(login, password);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new AuthException("Registration canceled. Try again later");
|
||||||
|
}
|
||||||
|
}
|
||||||
if(user == null || !user.verifyPassword(password))
|
if(user == null || !user.verifyPassword(password))
|
||||||
{
|
{
|
||||||
if(user ==null) throw new AuthException("Username incorrect");
|
if(user ==null) throw new AuthException("Username incorrect");
|
||||||
|
|
|
@ -10,6 +10,7 @@ public abstract class Component {
|
||||||
public static void registerComponents() {
|
public static void registerComponents() {
|
||||||
if (!registredComp) {
|
if (!registredComp) {
|
||||||
providers.register("authLimiter", AuthLimiterComponent.class);
|
providers.register("authLimiter", AuthLimiterComponent.class);
|
||||||
|
providers.register("regLimiter", RegLimiterComponent.class);
|
||||||
providers.register("commandRemover", CommandRemoverComponent.class);
|
providers.register("commandRemover", CommandRemoverComponent.class);
|
||||||
registredComp = true;
|
registredComp = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
package pro.gravit.launchserver.components;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.NeedGarbageCollection;
|
||||||
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
|
import pro.gravit.launchserver.manangers.hook.AuthHookManager;
|
||||||
|
import pro.gravit.utils.HookException;
|
||||||
|
import pro.gravit.utils.HookSet;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class RegLimiterComponent extends Component implements NeedGarbageCollection, AutoCloseable {
|
||||||
|
|
||||||
|
public static final long TIMEOUT = 12 * 60 * 60 * 1000; //12 часов
|
||||||
|
public transient LaunchServer launchServer;
|
||||||
|
public int rateLimit;
|
||||||
|
public int rateLimitMilis;
|
||||||
|
public String message;
|
||||||
|
public transient HookSet.Hook<AuthHookManager.RegContext> hook;
|
||||||
|
|
||||||
|
public transient HashMap<String, AuthLimiterComponent.AuthEntry> map = new HashMap<>();
|
||||||
|
public List<String> excludeIps = new ArrayList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preInit(LaunchServer launchServer) {
|
||||||
|
this.launchServer = launchServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(LaunchServer launchServer) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postInit(LaunchServer launchServer) {
|
||||||
|
launchServer.authHookManager.registraion.registerHook(context -> {
|
||||||
|
if (isLimit(context.ip)) {
|
||||||
|
throw new HookException(message);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@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) {
|
||||||
|
if (excludeIps.contains(ip)) return false;
|
||||||
|
if (map.containsKey(ip)) {
|
||||||
|
AuthLimiterComponent.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;
|
||||||
|
}
|
||||||
|
map.put(ip, new AuthLimiterComponent.AuthEntry(1, System.currentTimeMillis()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws Exception {
|
||||||
|
if(hook != null)
|
||||||
|
launchServer.authHookManager.registraion.unregisterHook(hook);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
import pro.gravit.launchserver.socket.response.auth.JoinServerResponse;
|
import pro.gravit.launchserver.socket.response.auth.JoinServerResponse;
|
||||||
import pro.gravit.launchserver.socket.response.auth.SetProfileResponse;
|
import pro.gravit.launchserver.socket.response.auth.SetProfileResponse;
|
||||||
import pro.gravit.utils.BiHookSet;
|
import pro.gravit.utils.BiHookSet;
|
||||||
|
import pro.gravit.utils.HookSet;
|
||||||
|
|
||||||
public class AuthHookManager {
|
public class AuthHookManager {
|
||||||
public BiHookSet<AuthResponse.AuthContext, Client> preHook = new BiHookSet<>();
|
public BiHookSet<AuthResponse.AuthContext, Client> preHook = new BiHookSet<>();
|
||||||
|
@ -13,4 +14,18 @@ public class AuthHookManager {
|
||||||
public BiHookSet<CheckServerResponse, Client> checkServerHook = new BiHookSet<>();
|
public BiHookSet<CheckServerResponse, Client> checkServerHook = new BiHookSet<>();
|
||||||
public BiHookSet<JoinServerResponse, Client> joinServerHook = new BiHookSet<>();
|
public BiHookSet<JoinServerResponse, Client> joinServerHook = new BiHookSet<>();
|
||||||
public BiHookSet<SetProfileResponse, Client> setProfileHook = new BiHookSet<>();
|
public BiHookSet<SetProfileResponse, Client> setProfileHook = new BiHookSet<>();
|
||||||
|
public static class RegContext
|
||||||
|
{
|
||||||
|
public String login;
|
||||||
|
public String password;
|
||||||
|
public String ip;
|
||||||
|
public boolean trustContext;
|
||||||
|
public RegContext(String login, String password, String ip, boolean trustContext) {
|
||||||
|
this.login = login;
|
||||||
|
this.password = password;
|
||||||
|
this.ip = ip;
|
||||||
|
this.trustContext = trustContext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public HookSet<RegContext> registraion;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue