55import io .kafbat .ui .service .ClustersStorage ;
66import java .net .URLDecoder ;
77import java .nio .charset .StandardCharsets ;
8+ import java .util .Set ;
89import java .util .regex .Pattern ;
910import lombok .RequiredArgsConstructor ;
1011import org .jetbrains .annotations .NotNull ;
@@ -23,6 +24,10 @@ public class ReadOnlyModeFilter implements WebFilter {
2324 private static final Pattern CLUSTER_NAME_REGEX =
2425 Pattern .compile ("/api/clusters/(?<clusterName>[^/]++)" );
2526
27+ private static final Set <Pattern > SAFE_ENDPOINTS = Set .of (
28+ Pattern .compile ("/api/clusters/[^/]+/topics/[^/]+/(smartfilters)$" )
29+ );
30+
2631 private final ClustersStorage clustersStorage ;
2732
2833 @ NotNull
@@ -35,10 +40,12 @@ public Mono<Void> filter(ServerWebExchange exchange, @NotNull WebFilterChain cha
3540
3641 var path = exchange .getRequest ().getPath ().pathWithinApplication ().value ();
3742 var decodedPath = URLDecoder .decode (path , StandardCharsets .UTF_8 );
43+
3844 var matcher = CLUSTER_NAME_REGEX .matcher (decodedPath );
3945 if (!matcher .find ()) {
4046 return chain .filter (exchange );
4147 }
48+
4249 var clusterName = matcher .group ("clusterName" );
4350 var kafkaCluster = clustersStorage .getClusterByName (clusterName )
4451 .orElseThrow (
@@ -49,6 +56,15 @@ public Mono<Void> filter(ServerWebExchange exchange, @NotNull WebFilterChain cha
4956 return chain .filter (exchange );
5057 }
5158
59+ var isSafeEndpoint = SAFE_ENDPOINTS
60+ .stream ()
61+ .parallel ()
62+ .anyMatch (endpoint -> endpoint .matcher (decodedPath ).matches ());
63+
64+ if (isSafeEndpoint ) {
65+ return chain .filter (exchange );
66+ }
67+
5268 return Mono .error (ReadOnlyModeException ::new );
5369 }
5470}
0 commit comments