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 }