vernedeng commented on code in PR #9012: URL: https://github.com/apache/inlong/pull/9012#discussion_r1353874926
########## inlong-tubemq/tubemq-manager/src/main/java/org/apache/inlong/tubemq/manager/service/TopicServiceImpl.java: ########## @@ -111,25 +117,143 @@ public TubeMQResult queryGroupExist(QueryConsumerGroupReq req) { return TubeMQResult.errorResult(TubeMQErrorConst.NO_SUCH_GROUP); } + /** + * Requests and retrieves topic view information from a TubeMQ cluster. + * + * @param clusterId The ID of the TubeMQ cluster. + * @param topicName The name of the topic to retrieve information for. + * @return The TopicView object containing topic information. + * @throws IllegalArgumentException If any validation checks fail. + * @throws RuntimeException If an exception occurs during the request. + */ @Override public TopicView requestTopicViewInfo(Long clusterId, String topicName) { MasterEntry masterNode = masterService.getMasterNode(clusterId); - String url = TubeConst.SCHEMA + masterNode.getIp() + ":" + masterNode.getWebPort() - + TubeConst.TOPIC_VIEW; - if (StringUtils.isNotBlank(topicName)) { - url = StringUtils.join(url, TubeConst.TOPIC_NAME, topicName); - } + validateMasterEntry(masterNode, clusterId); + validateTopicName(topicName, clusterId); + + String url = buildTopicViewURL(masterNode, topicName, clusterId); HttpGet httpget = new HttpGet(url); try (CloseableHttpResponse response = httpclient.execute(httpget)) { - return gson.fromJson(new InputStreamReader(response.getEntity().getContent(), - StandardCharsets.UTF_8), - TopicView.class); + return parseTopicViewResponse(response); } catch (Exception ex) { - log.error("exception caught while requesting group status", ex); + handleRequestException(clusterId, topicName, ex); throw new RuntimeException(ex.getMessage()); } } + /** + * Validates if the provided MasterEntry is valid. + * + * @param masterNode The MasterEntry to validate. + * @param clusterId The ID of the TubeMQ cluster. + * @throws IllegalArgumentException If the MasterEntry is invalid. + */ + private void validateMasterEntry(MasterEntry masterNode, Long clusterId) { + if (masterNode == null || StringUtils.isBlank(masterNode.getIp()) || masterNode.getWebPort() <= 0) { + log.error("Invalid MasterEntry: ClusterId = {}", clusterId); + throw new IllegalArgumentException("Invalid MasterEntry."); + } + } + + /** + * Validates if the provided topic name is valid. + * + * @param topicName The topic name to validate. + * @param clusterId The ID of the TubeMQ cluster. + * @throws IllegalArgumentException If the topic name is invalid. + */ + private void validateTopicName(String topicName, Long clusterId) { + if (StringUtils.isBlank(topicName) || containsDangerousChars(topicName) + || topicName.length() > MAX_TOPIC_NAME_LENGTH) { + log.error("Invalid topicName: ClusterId = {}, TopicName = {}", clusterId, topicName); + throw new IllegalArgumentException("Invalid topicName."); + } + } + + /** + * Builds the URL for requesting topic view information. + * + * @param masterNode The MasterEntry representing the TubeMQ master node. + * @param topicName The name of the topic. + * @param clusterId The ID of the TubeMQ cluster. + * @return The constructed URL. + * @throws IllegalArgumentException If the URL is invalid. + */ + private String buildTopicViewURL(MasterEntry masterNode, String topicName, Long clusterId) { + String url = TubeConst.SCHEMA + masterNode.getIp() + ":" + masterNode.getWebPort() + TubeConst.TOPIC_VIEW; + if (!isValidURL(url)) { + log.error("Invalid URL: ClusterId = {}, URL = {}", clusterId, url); + throw new IllegalArgumentException("Invalid URL."); + } + return url + TubeConst.TOPIC_NAME + topicName; + } + + /** + * Parses the response to obtain a TopicView object. + * + * @param response The HTTP response containing topic view information. + * @return The parsed TopicView object. + * @throws Exception If an exception occurs during parsing. + */ + private TopicView parseTopicViewResponse(CloseableHttpResponse response) throws Exception { + return gson.fromJson(new InputStreamReader(response.getEntity().getContent(), StandardCharsets.UTF_8), + TopicView.class); + } + + /** + * Handles exceptions that occur during the request. + * + * @param clusterId The ID of the TubeMQ cluster. + * @param topicName The name of the topic. + * @param ex The exception that occurred. + */ + private void handleRequestException(Long clusterId, String topicName, Exception ex) { + log.error("Exception caught while requesting topic view: ClusterId = {}, TopicName = {}", clusterId, topicName, + ex); + } + + /** + * Checks if the input string contains dangerous characters or keywords that may pose security risks, + * such as those commonly associated with SSRF attacks. + * + * @param input The input string to be checked for dangerous characters or keywords. + * @return True if the input contains dangerous characters or keywords, otherwise false. + */ + private boolean containsDangerousChars(String input) { + input = input.toLowerCase(); + String[] dangerousKeywords = Review Comment: make these keywords as constant array -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@inlong.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org