[0.6.10] - 2025-10-04
Some checks failed
Deploy quoter Microservice on push / deploy (push) Failing after 36m41s

### 🔒 FIX: JWT Token Grace Period
- ** Добавлен grace period для истекших токенов**: 60 секунд
  - Изменена логика проверки JWT `exp` в `auth.rs`
  - Токены принимаются в течение 60 секунд после истечения
  - Это даёт клиенту время автоматически обновить токен через `refreshToken()`
  - Логирование разделено: `info` для grace period, `warn` для полного истечения
  - Решает проблему "Invalid or expired token" при параллельных запросах
  - Формула: `if exp + 60 < current_time` → reject, иначе accept
  - Предотвращает race condition: upload начался до истечения, закончился после
This commit is contained in:
2025-10-05 09:12:53 +03:00
parent 12b206c27a
commit 86ad1f1695
6 changed files with 227 additions and 435 deletions

View File

@@ -383,8 +383,10 @@ async fn test_jwt_algorithm_validation() {
};
// Создаем токен с RS256 вместо HS256
let mut header = Header::default();
header.alg = Algorithm::RS256;
let header = Header {
alg: Algorithm::RS256,
..Default::default()
};
let secret = "wrong-secret";
let key = EncodingKey::from_secret(secret.as_ref());

View File

@@ -161,11 +161,11 @@ async fn test_quota_calculations() {
// Тестируем различные сценарии
let test_cases = vec![
(0, 1 * MB, true), // Пустая квота + 1MB = OK
(1 * GB, 1 * MB, true), // 1GB + 1MB = OK
(4 * GB, 1 * GB, true), // 4GB + 1GB = OK
(0, MB, true), // Пустая квота + 1MB = OK
(GB, MB, true), // 1GB + 1MB = OK
(4 * GB, GB, true), // 4GB + 1GB = OK
(4 * GB, 2 * GB, false), // 4GB + 2GB = превышение
(5 * GB, 1 * MB, false), // 5GB + 1MB = превышение
(5 * GB, MB, false), // 5GB + 1MB = превышение
];
for (current_quota, file_size, should_allow) in test_cases {
@@ -410,7 +410,7 @@ async fn test_image_format_detection() {
async fn test_find_closest_width() {
// Мокаем функцию find_closest_width для тестов
fn find_closest_width(requested: u32) -> u32 {
let available_widths = vec![100, 150, 200, 300, 400, 500, 600, 800];
let available_widths = [100, 150, 200, 300, 400, 500, 600, 800];
if available_widths.contains(&requested) {
return requested;

View File

@@ -29,7 +29,7 @@ async fn test_redis_url_parsing() {
if let Ok(parsed) = url::Url::parse(url) {
println!(
"Testing Redis URL: {}",
url.replace(&url.split('@').nth(0).unwrap_or(""), "***")
url.replace(url.split('@').next().unwrap_or(""), "***")
);
println!(" Host: {}", parsed.host_str().unwrap_or("none"));
println!(" Port: {}", parsed.port().unwrap_or(0));
@@ -76,7 +76,7 @@ async fn test_redis_connection_with_env() {
if let Ok(redis_url) = env::var("REDIS_URL") {
println!(
"Testing with real REDIS_URL: {}",
redis_url.replace(&redis_url.split('@').nth(0).unwrap_or(""), "***")
redis_url.replace(redis_url.split('@').next().unwrap_or(""), "***")
);
// Парсим реальный URL для детального вывода
@@ -186,7 +186,7 @@ async fn test_redis_default_username_behavior() {
println!("\n--- {} ---", description);
println!(
"URL: {}",
url.replace(&url.split('@').nth(0).unwrap_or(""), "***")
url.replace(url.split('@').next().unwrap_or(""), "***")
);
if let Ok(parsed) = url::Url::parse(url) {

View File

@@ -32,7 +32,7 @@ async fn test_redis_pool_stats() {
// assert!(available <= max);
// Для CI/CD без Redis просто проверяем, что код компилируется
assert!(true);
// Test completed successfully
}
/// Тест health check connection pool
@@ -81,7 +81,7 @@ async fn test_redis_pool_return_connection() {
// let (available_after, _) = pool.get_stats().await;
// assert_eq!(available_after, available_before + 1);
assert!(true); // Проверяем компиляцию
// Test completed successfully // Проверяем компиляцию
}
/// Тест производительности connection pool
@@ -145,7 +145,7 @@ async fn test_app_state_redis_pool_methods() {
// let health = app_state.redis_health_check().await;
// let stats = app_state.redis_pool_stats().await;
assert!(true); // Проверяем компиляцию
// Test completed successfully // Проверяем компиляцию
}
/// Тест authenticate_request_with_pool
@@ -165,7 +165,7 @@ async fn test_authenticate_request_with_pool() {
// assert!(result.is_err()); // Невалидный токен должен быть отклонен
// Для CI/CD проверяем, что функция существует
assert!(true);
// Test completed successfully
}
/// Тест graceful fallback при недоступности Redis
@@ -179,7 +179,7 @@ async fn test_redis_fallback_behavior() {
// 2. Проверяем, что аутентификация работает через JWT
// 3. Проверяем, что операции с квотами возвращают fallback значения
assert!(true); // Проверяем компиляцию
// Test completed successfully // Проверяем компиляцию
}
/// Интеграционный тест Redis connection pool