Skip to content

Commit 293039d

Browse files
committed
Example of "forwarding" dispatcher.
1 parent 35ebb3d commit 293039d

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*
2+
* Copyright (c) 2008 Sonatype, Inc. All rights reserved.
3+
*
4+
* This program is licensed to you under the Apache License Version 2.0,
5+
* and you may not use this file except in compliance with the Apache License Version 2.0.
6+
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
7+
*
8+
* Unless required by applicable law or agreed to in writing,
9+
* software distributed under the Apache License Version 2.0 is distributed on an
10+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
12+
*/
13+
14+
package org.codehaus.plexus.components.secdispatcher.internal.dispatchers;
15+
16+
import org.codehaus.plexus.components.secdispatcher.Dispatcher;
17+
import org.codehaus.plexus.components.secdispatcher.DispatcherMeta;
18+
import org.codehaus.plexus.components.secdispatcher.MasterSource;
19+
import org.codehaus.plexus.components.secdispatcher.MasterSourceMeta;
20+
import org.codehaus.plexus.components.secdispatcher.SecDispatcher;
21+
import org.codehaus.plexus.components.secdispatcher.SecDispatcherException;
22+
23+
import javax.inject.Inject;
24+
import javax.inject.Named;
25+
import javax.inject.Singleton;
26+
import java.util.ArrayList;
27+
import java.util.Collection;
28+
import java.util.HashMap;
29+
import java.util.List;
30+
import java.util.Map;
31+
32+
/**
33+
* This dispatcher forwards requests fully to defined sources.
34+
*/
35+
@Singleton
36+
@Named(ForwardingDispatcher.NAME)
37+
public class ForwardingDispatcher implements Dispatcher, DispatcherMeta {
38+
public static final String NAME = "forwarding";
39+
40+
private static final String CONF_SOURCE = "source";
41+
42+
protected final Map<String, MasterSource> sources;
43+
44+
@Inject
45+
public ForwardingDispatcher(Map<String, MasterSource> sources) {
46+
this.sources = sources;
47+
}
48+
49+
@Override
50+
public String name() {
51+
return NAME;
52+
}
53+
54+
@Override
55+
public String displayName() {
56+
return "Forwarding Password Dispatcher";
57+
}
58+
59+
@Override
60+
public Collection<Field> fields() {
61+
return List.of(
62+
Field.builder(CONF_SOURCE)
63+
.optional(false)
64+
.description("Source of the password")
65+
.options(sources.entrySet().stream()
66+
.map(e -> {
67+
MasterSource ms = e.getValue();
68+
if (ms instanceof MasterSourceMeta m) {
69+
Field.Builder b =
70+
Field.builder(e.getKey()).description(m.description());
71+
if (m.configTemplate().isPresent()) {
72+
b.defaultValue(m.configTemplate().get());
73+
}
74+
return b.build();
75+
} else {
76+
return Field.builder(e.getKey())
77+
.description(e.getKey()
78+
+ "(Field not described, needs manual configuration)")
79+
.build();
80+
}
81+
})
82+
.toList())
83+
.build());
84+
}
85+
86+
@Override
87+
public EncryptPayload encrypt(String str, Map<String, String> attributes, Map<String, String> config)
88+
throws SecDispatcherException {
89+
throw new UnsupportedOperationException("Forwarding dispatcher does not support encryption");
90+
}
91+
92+
@Override
93+
public String decrypt(String str, Map<String, String> attributes, Map<String, String> config)
94+
throws SecDispatcherException {
95+
MasterSource masterSource = getPasswordSource(config);
96+
return masterSource.handle(str);
97+
}
98+
99+
@Override
100+
public SecDispatcher.ValidationResponse validateConfiguration(Map<String, String> config) {
101+
HashMap<SecDispatcher.ValidationResponse.Level, List<String>> report = new HashMap<>();
102+
ArrayList<SecDispatcher.ValidationResponse> subsystems = new ArrayList<>();
103+
boolean valid = false;
104+
String masterSource = config.get(CONF_SOURCE);
105+
if (masterSource == null) {
106+
report.computeIfAbsent(SecDispatcher.ValidationResponse.Level.ERROR, k -> new ArrayList<>())
107+
.add("Source configuration missing");
108+
} else {
109+
SecDispatcher.ValidationResponse masterSourceResponse = null;
110+
for (MasterSource masterPasswordSource : sources.values()) {
111+
masterSourceResponse = masterPasswordSource.validateConfiguration(masterSource);
112+
if (masterSourceResponse != null) {
113+
break;
114+
}
115+
}
116+
if (masterSourceResponse == null) {
117+
report.computeIfAbsent(SecDispatcher.ValidationResponse.Level.ERROR, k -> new ArrayList<>())
118+
.add("Configured Source configuration not handled");
119+
} else {
120+
subsystems.add(masterSourceResponse);
121+
if (!masterSourceResponse.isValid()) {
122+
report.computeIfAbsent(SecDispatcher.ValidationResponse.Level.ERROR, k -> new ArrayList<>())
123+
.add("Configured Source configuration invalid");
124+
} else {
125+
report.computeIfAbsent(SecDispatcher.ValidationResponse.Level.INFO, k -> new ArrayList<>())
126+
.add("Configured Source configuration valid");
127+
valid = true;
128+
}
129+
}
130+
}
131+
return new SecDispatcher.ValidationResponse(getClass().getSimpleName(), valid, report, subsystems);
132+
}
133+
134+
protected MasterSource getPasswordSource(Map<String, String> config) throws SecDispatcherException {
135+
String masterSource = config.get(CONF_SOURCE);
136+
if (masterSource == null) {
137+
throw new SecDispatcherException("Invalid configuration: Missing configuration " + CONF_SOURCE);
138+
}
139+
MasterSource source = sources.get(masterSource);
140+
if (source != null) {
141+
return source;
142+
}
143+
throw new SecDispatcherException("No source found the given masterSource: " + masterSource);
144+
}
145+
}

0 commit comments

Comments
 (0)