content: /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.camel.component.jasypt.springboot;
  
  import org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig;
  import org.jasypt.exceptions.EncryptionInitializationException;
  import org.jasypt.iv.IvGenerator;
  import org.jasypt.iv.NoIvGenerator;
  import org.jasypt.iv.RandomIvGenerator;
  
  import java.util.Arrays;
  import java.util.HashSet;
  import java.util.Set;
  
  import static org.apache.camel.util.ObjectHelper.isNotEmpty;
  import static org.apache.camel.util.StringHelper.after;
  
  public class JasyptEncryptedPropertiesUtils {
  
      private static final String SYSTEM_ENVIRONMENT_PREFIX = "sysenv:";
  
      private static final String SYSTEM_PROPERTIES_PREFIX = "sys:";
  
      /**
       * Algorithms that mandatory require initialization vector
       */
      static final Set<String> ALGORITHMS_THAT_REQUIRE_IV = new HashSet<>(Arrays.asList("PBEWITHHMACSHA1ANDAES_128",
              "PBEWITHHMACSHA1ANDAES_256", "PBEWITHHMACSHA224ANDAES_128", "PBEWITHHMACSHA224ANDAES_256",
              "PBEWITHHMACSHA256ANDAES_128", "PBEWITHHMACSHA256ANDAES_256", "PBEWITHHMACSHA384ANDAES_128",
              "PBEWITHHMACSHA384ANDAES_256", "PBEWITHHMACSHA512ANDAES_128", "PBEWITHHMACSHA512ANDAES_256"));
  
      /**
       * test if algorithm requires an initialization vector
       *
       * @param algorithm
       *            the algorithm to test
       *
       * @return true if the algorithm requires initialization vector, false otherwise
       */
      static boolean isIVNeeded(String algorithm) {
          if (isNotBlank(algorithm)) {
              return ALGORITHMS_THAT_REQUIRE_IV.contains(algorithm.toUpperCase());
          }
          return false;
      }
  
      /**
       * Checks if a CharSequence is empty (""), null or whitespace only.
       *
       * @param cs
       *            the CharSequence to check, may be null
       *
       * @return true if the CharSequence is null, empty or whitespace only
       */
      static boolean isBlank(final CharSequence cs) {
          final int strLen = cs == null ? 0 : cs.length();
          if (strLen == 0) {
              return true;
          }
          for (int i = 0; i < strLen; i++) {
              if (!Character.isWhitespace(cs.charAt(i))) {
                  return false;
              }
          }
          return true;
      }
  
      /**
       * Checks if a CharSequence is not empty (""), not null or not whitespace only.
       *
       * @param cs
       *            the CharSequence to check, may be null
       *
       * @return true if the CharSequence is not null, not empty or not whitespace only
       */
      static boolean isNotBlank(final CharSequence cs) {
          return !isBlank(cs);
      }
  
      static void parsePassword(EnvironmentStringPBEConfig environmentStringPBEConfig,
              JasyptEncryptedPropertiesConfiguration configuration) {
          String passwordReference = configuration.getPassword();
          if (isNotEmpty(passwordReference) && passwordReference.startsWith(SYSTEM_ENVIRONMENT_PREFIX)) {
              environmentStringPBEConfig.setPasswordEnvName(after(passwordReference, SYSTEM_ENVIRONMENT_PREFIX));
              return;
          }
          if (isNotEmpty(passwordReference) && passwordReference.startsWith(SYSTEM_PROPERTIES_PREFIX)) {
              environmentStringPBEConfig.setPasswordSysPropertyName(after(passwordReference, SYSTEM_PROPERTIES_PREFIX));
              return;
          }
          environmentStringPBEConfig.setPassword(passwordReference);
      }
  
      static IvGenerator getIVGenerator(JasyptEncryptedPropertiesConfiguration configuration) {
          String ivGeneratorClassName = configuration.getIvGeneratorClassName();
          String algorithm = configuration.getAlgorithm();
          if (isBlank(ivGeneratorClassName)) {
              if (isIVNeeded(algorithm)) {
                  return configuration.getRandomIvGeneratorAlgorithm() != null
                          ? new RandomIvGenerator(configuration.getRandomIvGeneratorAlgorithm())
                          : new RandomIvGenerator();
              } else {
                  return new NoIvGenerator();
              }
          }
          IvGenerator ivGenerator = loadClass(ivGeneratorClassName);
          return ivGenerator;
      }
  
      /**
       * search and load the class identified by className parameter
       *
       * @param className
       *            fully qualified class name to be loaded
       *
       * @return a new instance of type className
       */
      static <T> T loadClass(String className) {
          try {
              final Class clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
              return (T) clazz.getDeclaredConstructor().newInstance();
          } catch (Exception e) {
              throw new EncryptionInitializationException(e);
          }
      }
  }
  