View Javadoc
1   /*-
2    * #%L
3    * Secured Properties
4    * ===============================================================
5    * Copyright (C) 2016 Brabenetz Harald, Austria
6    * ===============================================================
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   *
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  package net.brabenetz.lib.securedproperties;
21  
22  import net.brabenetz.lib.securedproperties.config.Config;
23  import net.brabenetz.lib.securedproperties.config.ConfigInitializer;
24  import net.brabenetz.lib.securedproperties.config.ConfigInitializers;
25  import net.brabenetz.lib.securedproperties.core.Algorithm;
26  import net.brabenetz.lib.securedproperties.core.SupportedAlgorithm;
27  import org.apache.commons.lang3.ArrayUtils;
28  import org.apache.commons.lang3.SystemUtils;
29  import org.slf4j.Logger;
30  import org.slf4j.LoggerFactory;
31  
32  import java.io.File;
33  import java.util.Arrays;
34  
35  /**
36   * Configuration Object to control the behavior of {@link SecuredProperties}.
37   */
38  public class SecuredPropertiesConfig implements Config {
39  
40      private static final Logger LOG = LoggerFactory.getLogger(SecuredPropertiesConfig.class);
41  
42      private static final int DEFAULT_SALT_LENGTH = 11;
43  
44      /** The place of your secret file. default is '$HOME/.secret/securedProperties.key'. */
45      private File secretFile;
46      /** The salt length to make sure that properties with the same value result in different encrypted strings. */
47      private int saltLength = DEFAULT_SALT_LENGTH;
48      /** The allowed encryption algorithms for auto-create the secret-key like 'AES_256' or 'DESede_168'. */
49      private Algorithm[] allowedAlgorithm = new Algorithm[] {
50              SupportedAlgorithm.AES_256,
51              SupportedAlgorithm.AES_192,
52              SupportedAlgorithm.AES_128,
53              SupportedAlgorithm.DESede_168,
54              SupportedAlgorithm.DESede_112
55      };
56  
57      /** If the secret Key should be created automatically if missing, or an Exception should be shown instead. */
58      private boolean autoCreateSecretKey = true;
59  
60      /**
61       * Return the SecretFile location which is needed to decrypt and encrypt your property-values.
62       * <p>
63       * Default is $HOME/.secret/securedProperties.key
64       */
65      public File getSecretFile() {
66          if (secretFile == null) {
67              final String secretFilePath = SystemUtils.USER_HOME + "/.secret/securedProperties.key";
68              LOG.debug("No secretFilePath configured. Use default location: {}", secretFilePath);
69              secretFile = new File(secretFilePath);
70          }
71          return secretFile;
72      }
73  
74      public int getSaltLength() {
75          return saltLength;
76      }
77  
78      public boolean isAutoCreateSecretKey() {
79          return autoCreateSecretKey;
80      }
81  
82      public Algorithm[] getAllowedAlgorithm() {
83          return allowedAlgorithm;
84      }
85  
86      /**
87       * Similar to Spring-Boot, Externalize your configuration so that you can work with the same application code in different environments.
88       * <p>
89       * <ol>
90       * <li>Application property Files './application.properties'. If the File doesn't exist, it will be ignored.</li>
91       * <li>Application property Files './config/application.properties'. If the File doesn't exist, it will be ignored.</li>
92       * <li>OS environment variables.</li>
93       * <li>Java System properties (System.getProperties()).</li>
94       * </ol>
95       * The last one has the highest priority and will overwrite properties before.
96       * <p>
97       * The Properties which can be configured can be found in {@link net.brabenetz.lib.securedproperties.config.ConfigKey}.<br>
98       * The default prefix is "SECURED_PROPERTIES" and the keys must be configured formatted as:
99       * <ul>
100      * <li><b>UPPER_CASE:</b> Like "SECURED_PROPERTIES_SECRET_FILE" is used for <b>OS environment variables</b>.</li>
101      * <li><b>kebab-case:</b> Like "secured-properties.secret-file" is used for <b>System-Properties</b> and <b>Property-Files</b></li>
102      * </ul>
103      *
104      * @see "https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html"
105      * @return this for fluent style.
106      */
107     public SecuredPropertiesConfig initDefault() {
108         return init(ConfigInitializers.propertyFile(new File("./application.properties")),
109                 ConfigInitializers.propertyFile(new File("./config/application.properties")),
110                 ConfigInitializers.envProperties(),
111                 ConfigInitializers.systemProperties());
112     }
113 
114     /**
115      * The generic variant of {@link #initDefault()}. Just put your {@link ConfigInitializer}s into it in the order you want.
116      * <p>
117      * The last one has the highest priority and will overwrite properties before.
118      *
119      * @param configInitializers your {@link ConfigInitializer}s. See {@link ConfigInitializers}.
120      * @return this for fluent style.
121      */
122     public SecuredPropertiesConfig init(final ConfigInitializer... configInitializers) {
123         Arrays.asList(configInitializers).forEach(configInit -> configInit.init(this));
124         return this;
125     }
126 
127     /**
128      * Overwrite the default location "%user_home%/.secret/securedProperties.key" for the secret key to encrypt and decrypt values.
129      *
130      * @param newSecretFile the secret File
131      * @return this for fluent style.
132      */
133     @Override
134     public SecuredPropertiesConfig withSecretFile(final File newSecretFile) {
135         secretFile = newSecretFile;
136         return this;
137     }
138 
139     @Override
140     public SecuredPropertiesConfig withSaltLength(final int newSaltLength) {
141         saltLength = newSaltLength;
142         return this;
143     }
144 
145     @Override
146     public SecuredPropertiesConfig withAllowedAlgorithm(final Algorithm... newAllowedAlgorithm) {
147         allowedAlgorithm = newAllowedAlgorithm;
148         return this;
149     }
150 
151     public SecuredPropertiesConfig addAllowedAlgorithm(final Algorithm... addedAllowedAlgorithm) {
152         allowedAlgorithm = ArrayUtils.addAll(allowedAlgorithm, addedAllowedAlgorithm);
153         return this;
154     }
155 
156     @Override
157     public SecuredPropertiesConfig withAutoCreateSecretKey(final boolean autoCreate) {
158         autoCreateSecretKey = autoCreate;
159         return this;
160     }
161 
162 }