fix+refactor: 代码审查修复(11 项安全/并发缺陷)+ log.debug → log.info(21 处)
代码审查修复:
- MybatisPlusConfig: video_process_job 加入 IGNORED_TABLES(修复回调路径多租户过滤导致全部回调静默丢失)
- TokenFilter: catch(Exception) 替代 catch(NumberFormatException),防止空指针泄漏为 500
- VideoController: createJob 空指针防护 + handleCallback 共享密钥校验(X-Callback-Secret)
- VideoProcessService: handleCallback 显式校验 companyId 非空;triggerAi 失败改为 error 级日志
- ExtractionService/QaService: validateAndGetTask 显式校验 companyId(纵深防御)
- TaskClaimService: reclaim 增加原子 WHERE status='REJECTED';claim 异常时释放 Redis 锁
- TaskService: reassign 校验 targetUserId 属于同一租户
- AuthService: user:sessions:{userId} Set 设置滑动 TTL,防止 Token 无限累积
- ExportService/SourceService: RustFS + DB 非原子操作增加失败回滚清理
- SourceService: getOriginalFilename 使用 Paths.get().getFileName() 防路径遍历
日志规范:
- 11 个 Service 类 21 处 log.debug 替换为 log.info
This commit is contained in:
@@ -19,8 +19,9 @@ public class MybatisPlusConfig {
|
||||
|
||||
// Tables that do NOT need tenant isolation (either global or tenant root tables)
|
||||
private static final List<String> IGNORED_TABLES = Arrays.asList(
|
||||
"sys_company", // the tenant root table itself
|
||||
"sys_config" // has company_id=NULL for global defaults; service handles this manually
|
||||
"sys_company", // the tenant root table itself
|
||||
"sys_config", // has company_id=NULL for global defaults; service handles this manually
|
||||
"video_process_job" // accessed by unauthenticated callback endpoint; service validates companyId manually
|
||||
);
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -81,7 +81,7 @@ public class TokenFilter extends OncePerRequestFilter {
|
||||
request.setAttribute("__token_principal__", principal);
|
||||
|
||||
filterChain.doFilter(request, response);
|
||||
} catch (NumberFormatException e) {
|
||||
} catch (Exception e) {
|
||||
log.error("解析 Token 数据失败: {}", e.getMessage());
|
||||
writeUnauthorized(response, "令牌数据格式错误");
|
||||
} finally {
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
package com.label.common.storage;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
|
||||
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
|
||||
import software.amazon.awssdk.core.sync.RequestBody;
|
||||
import software.amazon.awssdk.regions.Region;
|
||||
import software.amazon.awssdk.services.s3.S3Client;
|
||||
import software.amazon.awssdk.services.s3.model.*;
|
||||
import software.amazon.awssdk.services.s3.model.CreateBucketRequest;
|
||||
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
|
||||
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
|
||||
import software.amazon.awssdk.services.s3.model.HeadBucketRequest;
|
||||
import software.amazon.awssdk.services.s3.model.NoSuchBucketException;
|
||||
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
|
||||
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
|
||||
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class RustFsClient {
|
||||
|
||||
Reference in New Issue
Block a user