CloudformationRulesDefinition.java

  1. /*
  2.  * Cloudformation Plugin for SonarQube
  3.  * Copyright (C) 2019 James Pether Sörling
  4.  * james@hack23.com
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 3 of the License, or (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public License
  17.  * along with this program; if not, write to the Free Software Foundation,
  18.  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  19.  */
  20. package com.hack23.sonar.cloudformation;

  21. import java.io.InputStream;
  22. import java.io.InputStreamReader;
  23. import java.nio.charset.StandardCharsets;
  24. import java.util.Set;

  25. import org.apache.commons.lang3.reflect.FieldUtils;
  26. import org.sonar.api.server.rule.RulesDefinition;
  27. import org.sonar.api.server.rule.RulesDefinitionXmlLoader;
  28. import org.sonar.api.utils.log.Logger;
  29. import org.sonar.api.utils.log.Loggers;

  30. /**
  31.  * The Class CloudformationRulesDefinition.
  32.  */
  33. public final class CloudformationRulesDefinition implements RulesDefinition {

  34.     /** The Constant LOGGER. */
  35.     private static final Logger LOGGER = Loggers.get(CloudformationRulesDefinition.class);

  36.     /** The Constant PATH_TO_RULES_XML. */
  37.     private static final String PATH_TO_RULES_XML = "/cloudformation-rules.xml";

  38.     /** The Constant PATH_TO_CHECKOV_CLOUDFORMATION_RULES_XML. */
  39.     private static final String PATH_TO_CHECKOV_CLOUDFORMATION_RULES_XML = "/cloudformation-checkov-cloudformation-rules.xml";

  40.     /** The Constant PATH_TO_CHECKOV_TERRAFOM_RULES_XML. */
  41.     private static final String PATH_TO_CHECKOV_TERRAFOM_RULES_XML = "/cloudformation-checkov-terraform-rules.xml";


  42.     /** The Constant KEY. */
  43.     public static final String KEY = "repo";

  44.     /** The Constant NAME. */
  45.     public static final String NAME = "repository";

  46.     /** The context. */
  47.     private Context context;

  48.     /** The xml loader. */
  49.     private final RulesDefinitionXmlLoader xmlLoader;

  50.     /**
  51.      * Instantiates a new cloudformation rules definition.
  52.      *
  53.      * @param xmlLoader the xml loader
  54.      */
  55.     public CloudformationRulesDefinition(final RulesDefinitionXmlLoader xmlLoader) {
  56.         super();
  57.         this.xmlLoader = xmlLoader;
  58.     }

  59.     /**
  60.      * Gets the context.
  61.      *
  62.      * @return the context
  63.      */
  64.     public Context getContext() {
  65.         return context;
  66.     }

  67.     /**
  68.      * Define rules for cloudformation.
  69.      *
  70.      * @param context the context
  71.      * @param repositoryKey the repository key
  72.      * @param repositoryName the repository name
  73.      * @param languageKey the language key
  74.      */
  75.     private void defineRulesForCloudformation(final Context context, final String repositoryKey, final String repositoryName,
  76.             final String languageKey) {
  77.         final NewRepository repository = context.createRepository(repositoryKey, languageKey).setName(repositoryName);

  78.         addRules(repository, this.getClass().getResourceAsStream(PATH_TO_RULES_XML));
  79.         addRules(repository, this.getClass().getResourceAsStream(PATH_TO_CHECKOV_CLOUDFORMATION_RULES_XML));
  80.         repository.done();
  81.     }


  82.     /**
  83.      * Define rules for terraform.
  84.      *
  85.      * @param context the context
  86.      * @param repositoryKey the repository key
  87.      * @param repositoryName the repository name
  88.      * @param languageKey the language key
  89.      */
  90.     private void defineRulesForTerraform(final Context context, final String repositoryKey, final String repositoryName,
  91.             final String languageKey) {
  92.         final NewRepository repository = context.createRepository(repositoryKey, languageKey).setName(repositoryName);
  93.         addRules(repository, this.getClass().getResourceAsStream(PATH_TO_CHECKOV_TERRAFOM_RULES_XML));
  94.         repository.done();
  95.     }


  96.     /**
  97.      * Adds the rules.
  98.      *
  99.      * @param repository the repository
  100.      * @param rulesXml the rules xml
  101.      */
  102.     private void addRules(final NewRepository repository, final InputStream rulesXml) {
  103.         if (rulesXml != null) {
  104.             xmlLoader.load(repository, new InputStreamReader(rulesXml,StandardCharsets.UTF_8));
  105.             for (final NewRule newRule : repository.rules()) {
  106.                 addNewRule(newRule);
  107.             }
  108.         }
  109.     }

  110.     /**
  111.      * Adds the new rule.
  112.      *
  113.      * @param newRule the new rule
  114.      */
  115.     private static void addNewRule(final NewRule newRule) {
  116.         try {
  117.             final Set<String> tags = (Set<String>) FieldUtils.readField(newRule, "tags", true);
  118.             for (final String tag : tags) {

  119.                 if (tag.contains("cweid-")) {
  120.                     newRule.addCwe(Integer.parseInt(tag.replace("cweid-", "")));
  121.                 }

  122.                 if (tag.contains("owasp-")) {
  123.                     newRule.addOwaspTop10(OwaspTop10.valueOf(tag.replace("owasp-", "").toUpperCase()));
  124.                 }
  125.             }
  126.         } catch (final IllegalAccessException e) {
  127.             LOGGER.warn("Problem parsing security tags", e);
  128.         }
  129.     }

  130.     /**
  131.      * Define.
  132.      *
  133.      * @param context the context
  134.      */
  135.     @Override
  136.     public void define(final Context context) {
  137.         this.context = context;
  138.         defineRulesForCloudformation(context, "cloudformation-plugin-cfn" ,"Cloudformation plugin(cfn) rules", "cloudformation");
  139.         defineRulesForTerraform(context, "cloudformation-plugin-terraform" ,"Cloudformation plugin(terrraform) Rules", "terraform");
  140.     }

  141. }