Skip to content

Commit 63d9dd3

Browse files
committed
Simplify and tidy up config
Tidy up model. Relocation: drop all that webdav mumbo-jumbo, and for now relocation is interpreted as Path, that if relative, is resolved from the relocated configuration directory.
1 parent b080ef6 commit 63d9dd3

File tree

5 files changed

+78
-57
lines changed

5 files changed

+78
-57
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public interface SecDispatcher {
2626
* The default path of configuration.
2727
* <p>
2828
* The character {@code ~} (tilde) may be present as first character ONLY and is
29-
* interpreted as "user home".
29+
* interpreted as "user.home" system property, and it MUST be followed by path separator.
3030
*/
3131
String DEFAULT_CONFIGURATION = "~/.m2/settings-security.xml";
3232

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import javax.inject.Named;
1818
import javax.inject.Singleton;
1919

20+
import java.nio.file.Paths;
2021
import java.util.HashMap;
2122
import java.util.Map;
2223
import java.util.Set;
@@ -170,7 +171,7 @@ private boolean isEncryptedString(String str) {
170171
private SettingsSecurity getConfiguration(boolean mandatory) throws SecDispatcherException {
171172
String location = System.getProperty(SYSTEM_PROPERTY_CONFIGURATION_LOCATION, getConfigurationFile());
172173
location = location.charAt(0) == '~' ? System.getProperty("user.home") + location.substring(1) : location;
173-
SettingsSecurity sec = SecUtil.read(location, true);
174+
SettingsSecurity sec = SecUtil.read(Paths.get(location), true);
174175
if (mandatory && sec == null)
175176
throw new SecDispatcherException("Please check that configuration file on path " + location + " exists");
176177

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

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717

1818
import java.io.IOException;
1919
import java.io.InputStream;
20-
import java.net.URL;
2120
import java.nio.file.Files;
2221
import java.nio.file.NoSuchFileException;
23-
import java.nio.file.Paths;
22+
import java.nio.file.Path;
2423
import java.util.HashMap;
24+
import java.util.LinkedHashSet;
2525
import java.util.List;
2626
import java.util.Map;
2727

@@ -40,21 +40,36 @@
4040
* @version $Id$
4141
*
4242
*/
43-
public class SecUtil {
43+
public final class SecUtil {
44+
private SecUtil() {}
4445

45-
public static final String PROTOCOL_DELIM = "://";
46-
public static final int PROTOCOL_DELIM_LEN = PROTOCOL_DELIM.length();
47-
public static final String[] URL_PROTOCOLS =
48-
new String[] {"http", "https", "dav", "file", "davs", "webdav", "webdavs", "dav+http", "dav+https"};
46+
private static final int MAX_RELOCATIONS = 5;
4947

50-
public static SettingsSecurity read(String location, boolean cycle) throws SecDispatcherException {
51-
if (location == null) throw new SecDispatcherException("location to read from is null");
48+
/**
49+
* Reads the configuration model up, optionally resolving relocation too.
50+
*/
51+
public static SettingsSecurity read(Path configurationFile, boolean followRelocation)
52+
throws SecDispatcherException {
53+
requireNonNull(configurationFile, "configurationFile must not be null");
54+
LinkedHashSet<Path> paths = new LinkedHashSet<>();
55+
return read(paths, configurationFile, followRelocation);
56+
}
57+
58+
private static SettingsSecurity read(LinkedHashSet<Path> paths, Path configurationFile, boolean follow)
59+
throws SecDispatcherException {
60+
if (!paths.add(configurationFile)) {
61+
throw new SecDispatcherException("Configuration relocation form a cycle: " + paths);
62+
}
63+
if (paths.size() > MAX_RELOCATIONS) {
64+
throw new SecDispatcherException("Configuration relocation is too deep: " + paths);
65+
}
5266
SettingsSecurity sec;
5367
try {
54-
try (InputStream in = toStream(location)) {
68+
try (InputStream in = Files.newInputStream(configurationFile)) {
5569
sec = new SecurityConfigurationStaxReader().read(in);
5670
}
57-
if (cycle && sec.getRelocation() != null) return read(sec.getRelocation(), true);
71+
if (follow && sec.getRelocation() != null)
72+
return read(paths, configurationFile.getParent().resolve(sec.getRelocation()), true);
5873
return sec;
5974
} catch (NoSuchFileException e) {
6075
return null;
@@ -65,21 +80,6 @@ public static SettingsSecurity read(String location, boolean cycle) throws SecDi
6580
}
6681
}
6782

68-
private static InputStream toStream(String resource) throws IOException {
69-
requireNonNull(resource, "resource is null");
70-
int ind = resource.indexOf(PROTOCOL_DELIM);
71-
if (ind > 1) {
72-
String protocol = resource.substring(0, ind);
73-
resource = resource.substring(ind + PROTOCOL_DELIM_LEN);
74-
for (String p : URL_PROTOCOLS) {
75-
if (protocol.regionMatches(true, 0, p, 0, p.length())) {
76-
return new URL(p + PROTOCOL_DELIM + resource).openStream();
77-
}
78-
}
79-
}
80-
return Files.newInputStream(Paths.get(resource));
81-
}
82-
8383
public static Map<String, String> getConfig(SettingsSecurity sec, String name) {
8484
if (sec != null && name != null) {
8585
List<Config> cl = sec.getConfigurations();

src/main/mdo/settings-security.mdo

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,91 +19,80 @@
1919
xml.schemaLocation="https://codehaus-plexus.github.io/xsd/plexus-sec-dispatcher-${version}.xsd">
2020

2121
<id>settings-security</id>
22-
2322
<name>SecurityConfiguration</name>
2423
<description>SecurityConfiguration</description>
25-
24+
2625
<defaults>
2726
<default>
2827
<key>package</key>
2928
<value>org.codehaus.plexus.components.secdispatcher.model</value>
3029
</default>
3130
</defaults>
32-
33-
<classes>
3431

32+
<classes>
3533
<class rootElement="true">
3634
<name>SettingsSecurity</name>
3735
<version>1.0.0+</version>
3836
<fields>
39-
4037
<field>
4138
<name>master</name>
4239
<version>1.0.0/2.1.0</version>
4340
<type>String</type>
4441
<description>encrypted master password</description>
4542
</field>
46-
4743
<field>
4844
<name>modelVersion</name>
4945
<version>3.0.0+</version>
5046
<type>String</type>
5147
<required>true</required>
5248
<description>The version of the model</description>
5349
</field>
54-
5550
<field>
5651
<name>masterSource</name>
5752
<version>3.0.0+</version>
5853
<type>String</type>
5954
<required>true</required>
60-
<description>The URI describing the source of the master password</description>
55+
<description>The masterSource describes the source of the master password</description>
6156
</field>
62-
6357
<field>
6458
<name>masterCipher</name>
6559
<version>3.0.0+</version>
6660
<type>String</type>
6761
<required>true</required>
68-
<description>The Cipher to be used</description>
62+
<description>The Cipher to be used for master password</description>
6963
</field>
70-
7164
<field>
7265
<name>relocation</name>
7366
<version>1.0.0+</version>
7467
<type>String</type>
7568
<required>false</required>
76-
<description>reference to the location of the security file</description>
69+
<description>Relocates configuration to given reference. Reference if relative, will be resolved from the relocated configuration directory</description>
7770
</field>
78-
7971
<field>
8072
<name>configurations</name>
8173
<version>1.0.0+</version>
82-
<description>named configurations</description>
74+
<description>Optional named Dispatcher configurations</description>
8375
<required>false</required>
8476
<association>
8577
<type>Config</type>
8678
<multiplicity>*</multiplicity>
8779
</association>
8880
</field>
89-
9081
</fields>
9182
</class>
9283

9384
<class>
9485
<name>Config</name>
9586
<version>1.0.0+</version>
96-
<description>Named configuration</description>
87+
<description>Named Dispatcher configuration</description>
9788
<fields>
98-
9989
<field>
10090
<name>name</name>
10191
<type>String</type>
10292
<required>true</required>
10393
<version>1.0.0+</version>
104-
<description>name of this configuration</description>
94+
<description>Name of Dispatcher configuration is meant for</description>
10595
</field>
106-
10796
<field>
10897
<name>properties</name>
10998
<version>1.0.0+</version>
@@ -113,35 +102,28 @@
113102
<multiplicity>*</multiplicity>
114103
</association>
115104
</field>
116-
117105
</fields>
118106
</class>
119-
120107
<class>
121108
<name>ConfigProperty</name>
122109
<version>1.0.0+</version>
123110
<description>generic property - name/value pair</description>
124-
125111
<fields>
126-
127112
<field>
128113
<name>name</name>
129114
<type>String</type>
130115
<required>true</required>
131116
<version>1.0.0+</version>
132117
<description>name of this property</description>
133118
</field>
134-
135119
<field>
136120
<name>value</name>
137121
<type>String</type>
138122
<required>true</required>
139123
<version>1.0.0+</version>
140124
<description>value of this property</description>
141125
</field>
142-
143126
</fields>
144127
</class>
145-
146128
</classes>
147129
</model>

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

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515

1616
import java.io.OutputStream;
1717
import java.nio.file.Files;
18+
import java.nio.file.Path;
1819
import java.nio.file.Paths;
1920
import java.util.Map;
2021

22+
import org.codehaus.plexus.components.secdispatcher.SecDispatcherException;
2123
import org.codehaus.plexus.components.secdispatcher.model.Config;
2224
import org.codehaus.plexus.components.secdispatcher.model.ConfigProperty;
2325
import org.codehaus.plexus.components.secdispatcher.model.SettingsSecurity;
@@ -27,6 +29,8 @@
2729

2830
import static org.junit.jupiter.api.Assertions.assertEquals;
2931
import static org.junit.jupiter.api.Assertions.assertNotNull;
32+
import static org.junit.jupiter.api.Assertions.assertThrows;
33+
import static org.junit.jupiter.api.Assertions.assertTrue;
3034

3135
/**
3236
*
@@ -41,6 +45,10 @@ public class SecUtilTest {
4145
String _propVal = "pval";
4246

4347
private void saveSec(String masterSource) throws Exception {
48+
saveSec("./target/sec1.xml", masterSource);
49+
}
50+
51+
private void saveSec(String path, String masterSource) throws Exception {
4452
SettingsSecurity sec = new SettingsSecurity();
4553

4654
sec.setRelocation(null);
@@ -56,7 +64,7 @@ private void saveSec(String masterSource) throws Exception {
5664

5765
sec.addConfiguration(conf);
5866

59-
try (OutputStream fos = Files.newOutputStream(Paths.get("./target/sec1.xml"))) {
67+
try (OutputStream fos = Files.newOutputStream(Paths.get(path))) {
6068
new SecurityConfigurationStaxWriter().write(fos, sec);
6169
}
6270
}
@@ -65,7 +73,7 @@ private void saveSec(String masterSource) throws Exception {
6573
public void prepare() throws Exception {
6674
System.setProperty(DefaultSecDispatcher.SYSTEM_PROPERTY_CONFIGURATION_LOCATION, "./target/sec.xml");
6775
SettingsSecurity sec = new SettingsSecurity();
68-
sec.setRelocation("./target/sec1.xml");
76+
sec.setRelocation("sec1.xml");
6977
try (OutputStream fos = Files.newOutputStream(Paths.get("./target/sec.xml"))) {
7078
new SecurityConfigurationStaxWriter().write(fos, sec);
7179
}
@@ -74,12 +82,42 @@ public void prepare() throws Exception {
7482

7583
@Test
7684
void testReadWithRelocation() throws Exception {
77-
SettingsSecurity sec = SecUtil.read("./target/sec.xml", true);
85+
SettingsSecurity sec = SecUtil.read(Paths.get("./target/sec.xml"), true);
7886
assertNotNull(sec);
7987
assertEquals("magic:mighty", sec.getMasterSource());
8088
Map<String, String> conf = SecUtil.getConfig(sec, _confName);
8189
assertNotNull(conf);
8290
assertNotNull(conf.get(_propName));
8391
assertEquals(_propVal, conf.get(_propName));
8492
}
93+
94+
@Test
95+
void testReadWithRelocationCycleSelf() throws Exception {
96+
Path sec1 = Paths.get("./target/sec-cycle-1.xml");
97+
SettingsSecurity s1 = new SettingsSecurity();
98+
s1.setRelocation("sec-cycle-1.xml");
99+
try (OutputStream fos = Files.newOutputStream(sec1)) {
100+
new SecurityConfigurationStaxWriter().write(fos, s1);
101+
}
102+
SecDispatcherException ex = assertThrows(SecDispatcherException.class, () -> SecUtil.read(sec1, true));
103+
assertTrue(ex.getMessage().contains("cycle"));
104+
}
105+
106+
@Test
107+
void testReadWithRelocationCycle() throws Exception {
108+
Path sec1 = Paths.get("./target/sec-cycle-1.xml");
109+
Path sec2 = Paths.get("./target/sec-cycle-2.xml");
110+
SettingsSecurity s1 = new SettingsSecurity();
111+
s1.setRelocation("sec-cycle-2.xml");
112+
try (OutputStream fos = Files.newOutputStream(sec1)) {
113+
new SecurityConfigurationStaxWriter().write(fos, s1);
114+
}
115+
SettingsSecurity s2 = new SettingsSecurity();
116+
s2.setRelocation("sec-cycle-1.xml");
117+
try (OutputStream fos = Files.newOutputStream(sec1)) {
118+
new SecurityConfigurationStaxWriter().write(fos, s2);
119+
}
120+
SecDispatcherException ex = assertThrows(SecDispatcherException.class, () -> SecUtil.read(sec1, true));
121+
assertTrue(ex.getMessage().contains("cycle"));
122+
}
85123
}

0 commit comments

Comments
 (0)