add Rate Limiter & fix
This commit is contained in:
@@ -18,10 +18,7 @@ import io.vertx.ext.web.sstore.redis.RedisSessionStore;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import su.xserver.iikocon.config.AppConfig;
|
||||
import su.xserver.iikocon.handler.AdminHandler;
|
||||
import su.xserver.iikocon.handler.AuthHandler;
|
||||
import su.xserver.iikocon.handler.SecurityHandler;
|
||||
import su.xserver.iikocon.handler.SetupHandler;
|
||||
import su.xserver.iikocon.handler.*;
|
||||
import su.xserver.iikocon.iiko.IikoOlapClient;
|
||||
import su.xserver.iikocon.service.*;
|
||||
|
||||
@@ -63,12 +60,10 @@ public class MainVerticle extends AbstractVerticle {
|
||||
db = new DataBaseService(vertx, config.database);
|
||||
redis = new RedisService(vertx, config.redis);
|
||||
|
||||
// Инициализация сервисов
|
||||
userService = new UserService(db.getPool());
|
||||
restaurantService = new RestaurantService(db.getPool());
|
||||
settingsService = new SettingsService(db.getPool());
|
||||
|
||||
// Инициализация БД (создание таблицы users)
|
||||
userService.initDatabase().onFailure(err -> {
|
||||
log.error("Failed to initialize database", err);
|
||||
startPromise.fail(err);
|
||||
@@ -125,7 +120,7 @@ public class MainVerticle extends AbstractVerticle {
|
||||
|
||||
SecurityHandler securityHandlers = new SecurityHandler(settingsService);
|
||||
|
||||
// Обработчики безопасности (порядок важен)
|
||||
// Обработчики безопасности
|
||||
router.route().handler(securityHandlers.hostValidator());
|
||||
router.route().handler(securityHandlers.proxyHeadersHandler());
|
||||
router.route().handler(securityHandlers.cspHeader());
|
||||
@@ -161,6 +156,13 @@ public class MainVerticle extends AbstractVerticle {
|
||||
}
|
||||
});
|
||||
|
||||
// Rate Limiter Handler
|
||||
RedisRateLimiter limiter = new RedisRateLimiter(
|
||||
redis.getRedis(), 60, 60_000
|
||||
);
|
||||
|
||||
router.route().handler(limiter);
|
||||
|
||||
// Health Checks
|
||||
HealthCheckService healthCheckService = new HealthCheckService(vertx, redis, db);
|
||||
healthCheckService.registerHealthCheck(router);
|
||||
@@ -182,7 +184,6 @@ public class MainVerticle extends AbstractVerticle {
|
||||
rc.response().setStatusCode(403).end(new JsonObject().put("error", "Registration is disabled").encode());
|
||||
return;
|
||||
}
|
||||
// существующий код регистрации
|
||||
JsonObject body = rc.body().asJsonObject();
|
||||
String login = body.getString("login");
|
||||
String email = body.getString("email");
|
||||
@@ -197,7 +198,6 @@ public class MainVerticle extends AbstractVerticle {
|
||||
.onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
|
||||
}));
|
||||
|
||||
// В initRouter после настройки authHandler, до объявления /api/admin/*:
|
||||
router.route("/api/profile").handler(authHandler::requireAuth);
|
||||
router.get("/api/profile").handler(rc -> {
|
||||
Integer userId = rc.session().get("userId");
|
||||
@@ -218,29 +218,8 @@ public class MainVerticle extends AbstractVerticle {
|
||||
})
|
||||
.onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
|
||||
});
|
||||
router.put("/api/admin/language").handler(rc -> {
|
||||
Integer userId = rc.session().get("userId");
|
||||
JsonObject body = rc.body().asJsonObject();
|
||||
String language = body.getString("language");
|
||||
if (language == null || (!"en".equals(language) && !"ru".equals(language))) {
|
||||
rc.response().setStatusCode(400).end("Invalid language");
|
||||
return;
|
||||
}
|
||||
userService.updateLanguage(userId, language)
|
||||
.onSuccess(v -> {
|
||||
rc.session().put("language", language);
|
||||
rc.response().end(new JsonObject().put("success", true).encode());
|
||||
})
|
||||
.onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
|
||||
});
|
||||
|
||||
// Затем существующий блок router.route("/api/admin/*").handler(authHandler::requireAuth);
|
||||
router.route("/api/admin/*").handler(authHandler::requireAuth);
|
||||
// Добавить проверку роли для чувствительных эндпоинтов:
|
||||
// router.route("/api/settings/meta*").handler(AdminHandler::requireAdmin);
|
||||
// router.route("/api/admin/settings*").handler(AdminHandler::requireAdmin);
|
||||
// router.route("/api/admin/active-sessions").handler(AdminHandler::requireAdmin);
|
||||
|
||||
router.get("/api/admin/users").handler(rc -> userService.getAllUsers().onComplete(ar -> {
|
||||
if (ar.succeeded()) {
|
||||
rc.response()
|
||||
@@ -251,6 +230,7 @@ public class MainVerticle extends AbstractVerticle {
|
||||
}
|
||||
}));
|
||||
|
||||
router.route("/api/admin/users*").handler(AdminHandler::requireAdmin);
|
||||
router.post("/api/admin/users").handler(rc -> {
|
||||
JsonObject body = rc.body().asJsonObject();
|
||||
String login = body.getString("login");
|
||||
@@ -394,14 +374,12 @@ public class MainVerticle extends AbstractVerticle {
|
||||
.onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
|
||||
});
|
||||
|
||||
// Получение всех настроек
|
||||
router.get("/api/settings").handler(rc -> {
|
||||
settingsService.getPublicSettings()
|
||||
.onSuccess(settings -> rc.response().putHeader("Content-Type", "application/json").end(settings.encode()))
|
||||
.onFailure(err -> rc.response().setStatusCode(500).end());
|
||||
});
|
||||
|
||||
// Получить метаданные всех настроек (для построения формы)
|
||||
router.route("/api/admin/settings*").handler(AdminHandler::requireAdmin);
|
||||
router.get("/api/admin/settings/meta").handler(rc -> {
|
||||
settingsService.getMetadata()
|
||||
@@ -409,14 +387,12 @@ public class MainVerticle extends AbstractVerticle {
|
||||
.onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
|
||||
});
|
||||
|
||||
// Получить все настройки со значениями по умолчанию
|
||||
router.get("/api/admin/settings").handler(rc -> {
|
||||
settingsService.getAllWithDefaults()
|
||||
.onSuccess(settings -> rc.response().putHeader("Content-Type", "application/json").end(settings.encode()))
|
||||
.onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
|
||||
});
|
||||
|
||||
// Обновление настроек (админ)
|
||||
router.put("/api/admin/settings").handler(rc -> {
|
||||
JsonObject body = rc.body().asJsonObject();
|
||||
List<Future<Void>> futures = new ArrayList<>(); // явно указываем тип Future<Void>
|
||||
|
||||
Reference in New Issue
Block a user