Skip to content

Commit fa948b2

Browse files
committed
Drop relocation
1 parent 01ccc2a commit fa948b2

File tree

5 files changed

+90
-112
lines changed

5 files changed

+90
-112
lines changed

src/main/java/org/codehaus/plexus/components/secdispatcher/SecDispatcher.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313

1414
package org.codehaus.plexus.components.secdispatcher;
1515

16+
import java.io.IOException;
1617
import java.util.Map;
1718
import java.util.Set;
1819

20+
import org.codehaus.plexus.components.secdispatcher.model.SettingsSecurity;
21+
1922
/**
2023
* This component decrypts a string, passed to it
2124
*
@@ -53,7 +56,7 @@ public interface SecDispatcher {
5356
Set<String> availableCiphers();
5457

5558
/**
56-
* encrypt given plaintext string
59+
* Encrypt given plaintext string.
5760
*
5861
* @param str the plaintext to encrypt
5962
* @param attr the attributes, may be {@code null}
@@ -63,11 +66,28 @@ public interface SecDispatcher {
6366
String encrypt(String str, Map<String, String> attr) throws SecDispatcherException;
6467

6568
/**
66-
* decrypt given encrypted string
69+
* Decrypt given encrypted string.
6770
*
6871
* @param str the encrypted string
69-
* @return plaintext string
72+
* @return decrypted string
7073
* @throws SecDispatcherException in case of problem
7174
*/
7275
String decrypt(String str) throws SecDispatcherException;
76+
77+
/**
78+
* Reads the effective configuration, eventually creating new instance if not present.
79+
*
80+
* @param createIfMissing If {@code true}, it will create a new empty instance
81+
* @return the configuration, of {@code null} if it does not exist in {@code createIfMissing} is {@code false}
82+
* @throws IOException In case of IO problem
83+
*/
84+
SettingsSecurity readConfiguration(boolean createIfMissing) throws IOException;
85+
86+
/**
87+
* Writes the effective configuration.
88+
*
89+
* @param configuration The configuration to write, may not be {@code null}
90+
* @throws IOException In case of IO problem
91+
*/
92+
void writeConfiguration(SettingsSecurity configuration) throws IOException;
7393
}

src/main/java/org/codehaus/plexus/components/secdispatcher/internal/DefaultSecDispatcher.java

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
import javax.inject.Named;
1818
import javax.inject.Singleton;
1919

20+
import java.io.IOException;
21+
import java.nio.file.Path;
2022
import java.nio.file.Paths;
2123
import java.util.HashMap;
2224
import java.util.Map;
@@ -116,6 +118,21 @@ public String decrypt(String str) throws SecDispatcherException {
116118
}
117119
}
118120

121+
@Override
122+
public SettingsSecurity readConfiguration(boolean createIfMissing) throws IOException {
123+
SettingsSecurity configuration = getConfiguration(false);
124+
if (configuration == null && createIfMissing) {
125+
configuration = new SettingsSecurity();
126+
}
127+
return configuration;
128+
}
129+
130+
@Override
131+
public void writeConfiguration(SettingsSecurity configuration) throws IOException {
132+
requireNonNull(configuration, "configuration is null");
133+
SecUtil.writeWithBackup(getConfigurationPath(), configuration);
134+
}
135+
119136
private Map<String, String> prepareDispatcherConfig(String type) {
120137
HashMap<String, String> dispatcherConf = new HashMap<>();
121138
SettingsSecurity sec = getConfiguration(false);
@@ -168,14 +185,22 @@ private boolean isEncryptedString(String str) {
168185
return cipher.isEncryptedString(str);
169186
}
170187

171-
private SettingsSecurity getConfiguration(boolean mandatory) throws SecDispatcherException {
188+
private Path getConfigurationPath() {
172189
String location = System.getProperty(SYSTEM_PROPERTY_CONFIGURATION_LOCATION, getConfigurationFile());
173190
location = location.charAt(0) == '~' ? System.getProperty("user.home") + location.substring(1) : location;
174-
SettingsSecurity sec = SecUtil.read(Paths.get(location), true);
175-
if (mandatory && sec == null)
176-
throw new SecDispatcherException("Please check that configuration file on path " + location + " exists");
191+
return Paths.get(location);
192+
}
177193

178-
return sec;
194+
private SettingsSecurity getConfiguration(boolean mandatory) throws SecDispatcherException {
195+
Path path = getConfigurationPath();
196+
try {
197+
SettingsSecurity sec = SecUtil.read(path);
198+
if (mandatory && sec == null)
199+
throw new SecDispatcherException("Please check that configuration file on path " + path + " exists");
200+
return sec;
201+
} catch (IOException e) {
202+
throw new SecDispatcherException(e.getMessage(), e);
203+
}
179204
}
180205

181206
private String getMasterPassword(SettingsSecurity sec, boolean mandatory) throws SecDispatcherException {

src/main/java/org/codehaus/plexus/components/secdispatcher/internal/SecUtil.java

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,11 @@
2525
import java.nio.file.Path;
2626
import java.nio.file.StandardCopyOption;
2727
import java.util.HashMap;
28-
import java.util.LinkedHashSet;
2928
import java.util.List;
3029
import java.util.Map;
3130
import java.util.concurrent.ThreadLocalRandom;
3231

3332
import org.codehaus.plexus.components.secdispatcher.SecDispatcher;
34-
import org.codehaus.plexus.components.secdispatcher.SecDispatcherException;
3533
import org.codehaus.plexus.components.secdispatcher.model.Config;
3634
import org.codehaus.plexus.components.secdispatcher.model.ConfigProperty;
3735
import org.codehaus.plexus.components.secdispatcher.model.SettingsSecurity;
@@ -50,40 +48,21 @@
5048
public final class SecUtil {
5149
private SecUtil() {}
5250

53-
private static final int MAX_RELOCATIONS = 5;
54-
5551
/**
5652
* Reads the configuration model up, optionally resolving relocation too.
5753
*/
58-
public static SettingsSecurity read(Path configurationFile, boolean followRelocation)
59-
throws SecDispatcherException {
54+
public static SettingsSecurity read(Path configurationFile) throws IOException {
6055
requireNonNull(configurationFile, "configurationFile must not be null");
61-
LinkedHashSet<Path> paths = new LinkedHashSet<>();
62-
return read(paths, configurationFile, followRelocation);
63-
}
64-
65-
private static SettingsSecurity read(LinkedHashSet<Path> paths, Path configurationFile, boolean follow)
66-
throws SecDispatcherException {
67-
if (!paths.add(configurationFile)) {
68-
throw new SecDispatcherException("Configuration relocation form a cycle: " + paths);
69-
}
70-
if (paths.size() > MAX_RELOCATIONS) {
71-
throw new SecDispatcherException("Configuration relocation is too deep: " + paths);
72-
}
7356
SettingsSecurity sec;
7457
try {
7558
try (InputStream in = Files.newInputStream(configurationFile)) {
7659
sec = new SecurityConfigurationStaxReader().read(in);
7760
}
78-
if (follow && sec.getRelocation() != null)
79-
return read(paths, configurationFile.getParent().resolve(sec.getRelocation()), true);
8061
return sec;
8162
} catch (NoSuchFileException e) {
8263
return null;
83-
} catch (IOException e) {
84-
throw new SecDispatcherException("IO Problem", e);
8564
} catch (XMLStreamException e) {
86-
throw new SecDispatcherException("Parsing error", e);
65+
throw new IOException("Parsing error", e);
8766
}
8867
}
8968

@@ -113,16 +92,12 @@ public static Map<String, String> getConfig(SettingsSecurity sec, String name) {
11392
public static void write(Path target, SettingsSecurity configuration) throws IOException {
11493
requireNonNull(target, "file must not be null");
11594
requireNonNull(configuration, "sec must not be null");
116-
configuration.setModelVersion(SecDispatcher.class.getPackage().getImplementationVersion());
117-
configuration.setModelEncoding(StandardCharsets.UTF_8.name());
11895
writeFile(target, configuration, false);
11996
}
12097

12198
public static void writeWithBackup(Path target, SettingsSecurity configuration) throws IOException {
12299
requireNonNull(target, "file must not be null");
123100
requireNonNull(configuration, "sec must not be null");
124-
configuration.setModelVersion(SecDispatcher.class.getPackage().getImplementationVersion());
125-
configuration.setModelEncoding(StandardCharsets.UTF_8.name());
126101
writeFile(target, configuration, true);
127102
}
128103

@@ -135,6 +110,10 @@ private static void writeFile(Path target, SettingsSecurity configuration, boole
135110
Files.createDirectories(parent);
136111
Path tempFile = parent.resolve(target.getFileName() + "."
137112
+ Long.toUnsignedString(ThreadLocalRandom.current().nextLong()) + ".tmp");
113+
114+
configuration.setModelVersion(SecDispatcher.class.getPackage().getImplementationVersion());
115+
configuration.setModelEncoding(StandardCharsets.UTF_8.name());
116+
138117
try (OutputStream out = Files.newOutputStream(tempFile)) {
139118
new SecurityConfigurationStaxWriter().write(out, configuration);
140119
if (doBackup && Files.isRegularFile(target)) {

src/main/mdo/settings-security.mdo

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@
4040
<type>String</type>
4141
<description>encrypted master password</description>
4242
</field>
43+
<field>
44+
<name>relocation</name>
45+
<version>1.0.0/2.1.0</version>
46+
<type>String</type>
47+
<required>false</required>
48+
<description>Relocates configuration to given reference. Reference if relative, will be resolved from the relocated configuration directory</description>
49+
</field>
4350
<field>
4451
<name>modelVersion</name>
4552
<version>3.0.0+</version>
@@ -61,13 +68,6 @@
6168
<required>true</required>
6269
<description>The Cipher to be used for master password</description>
6370
</field>
64-
<field>
65-
<name>relocation</name>
66-
<version>1.0.0+</version>
67-
<type>String</type>
68-
<required>false</required>
69-
<description>Relocates configuration to given reference. Reference if relative, will be resolved from the relocated configuration directory</description>
70-
</field>
7171
<field>
7272
<name>configurations</name>
7373
<version>1.0.0+</version>

src/test/java/org/codehaus/plexus/components/secdispatcher/internal/SecUtilTest.java

Lines changed: 24 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,20 @@
1313

1414
package org.codehaus.plexus.components.secdispatcher.internal;
1515

16-
import java.io.OutputStream;
16+
import java.io.IOException;
1717
import java.nio.charset.StandardCharsets;
1818
import java.nio.file.Files;
1919
import java.nio.file.Path;
2020
import java.nio.file.Paths;
21-
import java.util.Map;
2221

23-
import org.codehaus.plexus.components.secdispatcher.SecDispatcher;
24-
import org.codehaus.plexus.components.secdispatcher.SecDispatcherException;
2522
import org.codehaus.plexus.components.secdispatcher.model.Config;
2623
import org.codehaus.plexus.components.secdispatcher.model.ConfigProperty;
2724
import org.codehaus.plexus.components.secdispatcher.model.SettingsSecurity;
28-
import org.codehaus.plexus.components.secdispatcher.model.io.stax.SecurityConfigurationStaxWriter;
2925
import org.junit.jupiter.api.BeforeEach;
3026
import org.junit.jupiter.api.Test;
3127

3228
import static org.junit.jupiter.api.Assertions.assertEquals;
3329
import static org.junit.jupiter.api.Assertions.assertNotNull;
34-
import static org.junit.jupiter.api.Assertions.assertThrows;
3530
import static org.junit.jupiter.api.Assertions.assertTrue;
3631

3732
/**
@@ -46,90 +41,49 @@ public class SecUtilTest {
4641
String _propName = "pname";
4742
String _propVal = "pval";
4843

49-
private void saveSec(String masterSource) throws Exception {
50-
saveSec("./target/sec1.xml", masterSource);
44+
private void saveSec(String masterSource) throws IOException {
45+
saveSec("./target/sec.xml", masterSource);
5146
}
5247

53-
private void saveSec(String path, String masterSource) throws Exception {
48+
private void saveSec(String path, String masterSource) throws IOException {
5449
SettingsSecurity sec = new SettingsSecurity();
55-
56-
sec.setModelEncoding(StandardCharsets.UTF_8.name());
57-
sec.setModelVersion(SecDispatcher.class.getPackage().getSpecificationVersion());
58-
sec.setRelocation(null);
5950
sec.setMasterSource(masterSource);
60-
6151
ConfigProperty cp = new ConfigProperty();
6252
cp.setName(_propName);
6353
cp.setValue(_propVal);
64-
6554
Config conf = new Config();
6655
conf.setName(_confName);
6756
conf.addProperty(cp);
68-
6957
sec.addConfiguration(conf);
70-
71-
try (OutputStream fos = Files.newOutputStream(Paths.get(path))) {
72-
new SecurityConfigurationStaxWriter().write(fos, sec);
73-
}
58+
SecUtil.write(Paths.get(path), sec);
7459
}
7560

7661
@BeforeEach
77-
public void prepare() throws Exception {
78-
System.setProperty(DefaultSecDispatcher.SYSTEM_PROPERTY_CONFIGURATION_LOCATION, "./target/sec.xml");
79-
SettingsSecurity sec = new SettingsSecurity();
80-
sec.setModelEncoding(StandardCharsets.UTF_8.name());
81-
sec.setModelVersion(SecDispatcher.class.getPackage().getSpecificationVersion());
82-
sec.setRelocation("sec1.xml");
83-
try (OutputStream fos = Files.newOutputStream(Paths.get("./target/sec.xml"))) {
84-
new SecurityConfigurationStaxWriter().write(fos, sec);
85-
}
62+
void prepare() throws IOException {
8663
saveSec("magic:mighty");
8764
}
8865

8966
@Test
90-
void testReadWithRelocation() throws Exception {
91-
SettingsSecurity sec = SecUtil.read(Paths.get("./target/sec.xml"), true);
92-
assertNotNull(sec);
93-
assertEquals("magic:mighty", sec.getMasterSource());
94-
Map<String, String> conf = SecUtil.getConfig(sec, _confName);
95-
assertNotNull(conf);
96-
assertNotNull(conf.get(_propName));
97-
assertEquals(_propVal, conf.get(_propName));
98-
}
99-
100-
@Test
101-
void testReadWithRelocationCycleSelf() throws Exception {
102-
Path sec1 = Paths.get("./target/sec-cycle-1.xml");
103-
SettingsSecurity s1 = new SettingsSecurity();
104-
s1.setModelEncoding(StandardCharsets.UTF_8.name());
105-
s1.setModelVersion(SecDispatcher.class.getPackage().getSpecificationVersion());
106-
s1.setRelocation("sec-cycle-1.xml");
107-
try (OutputStream fos = Files.newOutputStream(sec1)) {
108-
new SecurityConfigurationStaxWriter().write(fos, s1);
109-
}
110-
SecDispatcherException ex = assertThrows(SecDispatcherException.class, () -> SecUtil.read(sec1, true));
111-
assertTrue(ex.getMessage().contains("cycle"));
67+
void readWrite() throws IOException {
68+
Path path = Path.of("./target/sec.xml");
69+
SettingsSecurity config = SecUtil.read(path);
70+
assertNotNull(config);
71+
assertEquals(SettingsSecurity.class.getPackage().getSpecificationVersion(), config.getModelVersion());
72+
assertEquals(StandardCharsets.UTF_8.name(), config.getModelEncoding());
73+
assertEquals("magic:mighty", config.getMasterSource());
74+
SecUtil.write(path, config);
11275
}
11376

11477
@Test
115-
void testReadWithRelocationCycle() throws Exception {
116-
Path sec1 = Paths.get("./target/sec-cycle-1.xml");
117-
Path sec2 = Paths.get("./target/sec-cycle-2.xml");
118-
SettingsSecurity s1 = new SettingsSecurity();
119-
s1.setModelEncoding(StandardCharsets.UTF_8.name());
120-
s1.setModelVersion(SecDispatcher.class.getPackage().getSpecificationVersion());
121-
s1.setRelocation("sec-cycle-2.xml");
122-
try (OutputStream fos = Files.newOutputStream(sec1)) {
123-
new SecurityConfigurationStaxWriter().write(fos, s1);
124-
}
125-
SettingsSecurity s2 = new SettingsSecurity();
126-
s2.setModelEncoding(StandardCharsets.UTF_8.name());
127-
s2.setModelVersion(SecDispatcher.class.getPackage().getSpecificationVersion());
128-
s2.setRelocation("sec-cycle-1.xml");
129-
try (OutputStream fos = Files.newOutputStream(sec1)) {
130-
new SecurityConfigurationStaxWriter().write(fos, s2);
131-
}
132-
SecDispatcherException ex = assertThrows(SecDispatcherException.class, () -> SecUtil.read(sec1, true));
133-
assertTrue(ex.getMessage().contains("cycle"));
78+
void readWriteWithBackup() throws IOException {
79+
Path path = Path.of("./target/sec.xml");
80+
SettingsSecurity config = SecUtil.read(path);
81+
assertNotNull(config);
82+
assertEquals(SettingsSecurity.class.getPackage().getSpecificationVersion(), config.getModelVersion());
83+
assertEquals(StandardCharsets.UTF_8.name(), config.getModelEncoding());
84+
assertEquals("magic:mighty", config.getMasterSource());
85+
SecUtil.writeWithBackup(path, config);
86+
assertTrue(Files.exists(path));
87+
assertTrue(Files.exists(path.getParent().resolve(path.getFileName() + ".bak")));
13488
}
13589
}

0 commit comments

Comments
 (0)