All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.plugins.secrets.api.SecretMatcher Maven / Gradle / Ivy

/*
 * SonarQube Text Plugin
 * Copyright (C) 2021-2024 SonarSource SA
 * mailto:info AT sonarsource DOT com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the Sonar Source-Available License for more details.
 *
 * You should have received a copy of the Sonar Source-Available License
 * along with this program; if not, see https://sonarsource.com/license/ssal/
 */
package org.sonar.plugins.secrets.api;

import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
import org.sonar.plugins.common.DurationStatistics;
import org.sonar.plugins.common.InputFileContext;
import org.sonar.plugins.secrets.configuration.model.Rule;

/**
 * Checks if the file contains some secrets.
 */
public class SecretMatcher implements Matcher {

  private final String ruleId;
  private final String ruleMessage;
  private final PatternMatcher patternMatcher;
  private final AuxiliaryPatternMatcher auxiliaryPatternMatcher;
  private final Predicate preFilter;
  private final Predicate postFilter;
  private final DurationStatistics durationStatistics;

  SecretMatcher(String ruleId,
    String ruleMessage,
    PatternMatcher patternMatcher,
    AuxiliaryPatternMatcher auxiliaryPatternMatcher,
    Predicate preFilter,
    Predicate postFilter,
    DurationStatistics durationStatistics) {
    this.ruleId = ruleId;
    this.ruleMessage = ruleMessage;
    this.patternMatcher = patternMatcher;
    this.auxiliaryPatternMatcher = auxiliaryPatternMatcher;
    this.preFilter = preFilter;
    this.postFilter = postFilter;
    this.durationStatistics = durationStatistics;
  }

  /**
   * Creates a new SecretMatcher from provided Rule
   *
   * @param rule                       rule to extract matcher logic from
   * @param durationStatistics         instance to collect performance statistics
   * @param specificationConfiguration configuration of specification
   * @return a new SecretMatcher
   */
  public static SecretMatcher build(Rule rule, DurationStatistics durationStatistics, SpecificationConfiguration specificationConfiguration) {
    var patternMatcher = PatternMatcher.build(rule.getDetection().getMatching());
    Predicate preFilter = PreFilterFactory.createPredicate(rule.getDetection().getPre(), specificationConfiguration);
    Predicate postFilter = PostFilterFactory.createPredicate(rule.getDetection().getPost(), rule.getDetection().getMatching());
    var auxiliaryMatcher = AuxiliaryPatternMatcherFactory.build(rule.getDetection().getMatching());
    return new SecretMatcher(rule.getId(), rule.getMetadata().getMessage(), patternMatcher, auxiliaryMatcher, preFilter, postFilter, durationStatistics);
  }

  @Override
  public List findIn(InputFileContext fileContext) {
    boolean isRejectedOnPreFilter = durationStatistics.timed(
      getRuleId() + DurationStatistics.SUFFIX_PRE,
      () -> !preFilter.test(fileContext));
    if (isRejectedOnPreFilter) {
      return Collections.emptyList();
    }

    String content = fileContext.content();
    List secretsFilteredOnContext = durationStatistics.timed(
      getRuleId() + DurationStatistics.SUFFIX_MATCHER,
      () -> {
        List candidateSecrets = patternMatcher.findIn(content, getRuleId());
        return auxiliaryPatternMatcher.filter(candidateSecrets, fileContext, getRuleId());
      });

    return secretsFilteredOnContext.stream()
      .filter(match -> durationStatistics.timed(
        getRuleId() + DurationStatistics.SUFFIX_POST,
        () -> postFilter.test(match.getText())))
      .toList();
  }

  public String getRuleId() {
    return ruleId;
  }

  public String getMessageFromRule() {
    return ruleMessage;
  }

  Predicate getPostFilter() {
    return postFilter;
  }

  AuxiliaryPatternMatcher getAuxiliaryPatternMatcher() {
    return auxiliaryPatternMatcher;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy