1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.client.console.wizards;
20
21 import java.io.Serializable;
22 import java.util.List;
23 import java.util.concurrent.Callable;
24 import java.util.concurrent.Future;
25 import java.util.stream.Collectors;
26 import org.apache.commons.lang3.StringUtils;
27 import org.apache.commons.lang3.tuple.Pair;
28 import org.apache.syncope.client.console.SyncopeConsoleSession;
29 import org.apache.syncope.client.console.SyncopeWebApplication;
30 import org.apache.syncope.client.console.panels.OIDCProvidersDirectoryPanel;
31 import org.apache.syncope.client.console.rest.ImplementationRestClient;
32 import org.apache.syncope.client.console.rest.OIDCProviderRestClient;
33 import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel;
34 import org.apache.syncope.client.console.wizards.mapping.ItemTransformersTogglePanel;
35 import org.apache.syncope.client.console.wizards.mapping.JEXLTransformersTogglePanel;
36 import org.apache.syncope.client.console.wizards.mapping.OIDCProviderMappingPanel;
37 import org.apache.syncope.client.ui.commons.Constants;
38 import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
39 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxCheckBoxPanel;
40 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxPalettePanel;
41 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
42 import org.apache.syncope.client.ui.commons.wizards.AjaxWizardBuilder;
43 import org.apache.syncope.common.lib.OIDCScopeConstants;
44 import org.apache.syncope.common.lib.to.ImplementationTO;
45 import org.apache.syncope.common.lib.to.OIDCC4UIProviderTO;
46 import org.apache.syncope.common.lib.types.OIDCClientImplementationType;
47 import org.apache.wicket.PageReference;
48 import org.apache.wicket.ajax.AjaxRequestTarget;
49 import org.apache.wicket.extensions.wizard.WizardModel;
50 import org.apache.wicket.extensions.wizard.WizardStep;
51 import org.apache.wicket.markup.html.WebMarkupContainer;
52 import org.apache.wicket.model.IModel;
53 import org.apache.wicket.model.LoadableDetachableModel;
54 import org.apache.wicket.model.Model;
55 import org.apache.wicket.model.PropertyModel;
56 import org.apache.wicket.model.StringResourceModel;
57 import org.apache.wicket.model.util.ListModel;
58 import org.apache.wicket.validation.validator.UrlValidator;
59
60 public class OIDCProviderWizardBuilder extends AjaxWizardBuilder<OIDCC4UIProviderTO> {
61
62 private static final long serialVersionUID = -3310772400714122768L;
63
64 protected final OIDCProvidersDirectoryPanel directoryPanel;
65
66 protected final ImplementationRestClient implementationRestClient;
67
68 protected final OIDCProviderRestClient oidcProviderRestClient;
69
70 protected final IModel<List<String>> opActions = new LoadableDetachableModel<>() {
71
72 private static final long serialVersionUID = 5275935387613157437L;
73
74 @Override
75 protected List<String> load() {
76 return implementationRestClient.list(OIDCClientImplementationType.OP_ACTIONS).stream().
77 map(ImplementationTO::getKey).sorted().collect(Collectors.toList());
78 }
79 };
80
81 public OIDCProviderWizardBuilder(
82 final OIDCProvidersDirectoryPanel directoryPanel,
83 final OIDCC4UIProviderTO defaultItem,
84 final ImplementationRestClient implementationRestClient,
85 final OIDCProviderRestClient oidcProviderRestClient,
86 final PageReference pageRef) {
87
88 super(defaultItem, pageRef);
89 this.directoryPanel = directoryPanel;
90 this.implementationRestClient = implementationRestClient;
91 this.oidcProviderRestClient = oidcProviderRestClient;
92 }
93
94 @Override
95 protected Serializable onApplyInternal(final OIDCC4UIProviderTO modelObject) {
96 if (modelObject.getKey() == null) {
97 if (modelObject.getHasDiscovery()) {
98 oidcProviderRestClient.createFromDiscovery(modelObject);
99 } else {
100 oidcProviderRestClient.create(modelObject);
101 }
102
103 } else {
104 oidcProviderRestClient.update(modelObject);
105 }
106 return modelObject;
107 }
108
109 @Override
110 protected WizardModel buildModelSteps(final OIDCC4UIProviderTO modelObject, final WizardModel wizardModel) {
111 wizardModel.add(new OP(modelObject));
112 wizardModel.add(new OPContinue(modelObject, modelObject.getKey() != null));
113
114 Mapping mapping = new Mapping();
115 mapping.setOutputMarkupId(true);
116
117 ItemTransformersTogglePanel mapItemTransformers = new ItemTransformersTogglePanel(mapping, pageRef);
118 addOuterObject(mapItemTransformers);
119 JEXLTransformersTogglePanel jexlTransformers = new JEXLTransformersTogglePanel(mapping, pageRef);
120 addOuterObject(jexlTransformers);
121 mapping.add(new OIDCProviderMappingPanel("mapping", modelObject, mapItemTransformers, jexlTransformers));
122
123 wizardModel.add(mapping);
124
125 return wizardModel;
126 }
127
128 @Override
129 protected long getMaxWaitTimeInSeconds() {
130 return SyncopeWebApplication.get().getMaxWaitTimeInSeconds();
131 }
132
133 @Override
134 protected void sendError(final Exception exception) {
135 SyncopeConsoleSession.get().onException(exception);
136 }
137
138 @Override
139 protected void sendWarning(final String message) {
140 SyncopeConsoleSession.get().warn(message);
141 }
142
143 @Override
144 protected Future<Pair<Serializable, Serializable>> execute(
145 final Callable<Pair<Serializable, Serializable>> future) {
146
147 return SyncopeConsoleSession.get().execute(future);
148 }
149
150 public class OP extends WizardStep {
151
152 private static final long serialVersionUID = 7127421283216134900L;
153
154 public OP(final OIDCC4UIProviderTO opTO) {
155 AjaxTextFieldPanel name = new AjaxTextFieldPanel(
156 "name", "name", new PropertyModel<>(opTO, "name"), false);
157 name.addRequiredLabel();
158 name.setEnabled(true);
159 add(name);
160
161 AjaxTextFieldPanel clientID = new AjaxTextFieldPanel(
162 "clientID", "clientID", new PropertyModel<>(opTO, "clientID"), false);
163 clientID.addRequiredLabel();
164 clientID.setEnabled(true);
165 add(clientID);
166
167 AjaxTextFieldPanel clientSecret = new AjaxTextFieldPanel(
168 "clientSecret", "clientSecret", new PropertyModel<>(opTO, "clientSecret"), false);
169 clientSecret.addRequiredLabel();
170 clientSecret.setEnabled(true);
171 add(clientSecret);
172
173 AjaxCheckBoxPanel createUnmatching = new AjaxCheckBoxPanel(
174 "createUnmatching", "createUnmatching", new PropertyModel<>(opTO, "createUnmatching"),
175 false);
176 add(createUnmatching);
177
178 AjaxCheckBoxPanel selfRegUnmatching = new AjaxCheckBoxPanel(
179 "selfRegUnmatching", "selfRegUnmatching", new PropertyModel<>(opTO, "selfRegUnmatching"),
180 false);
181 add(selfRegUnmatching);
182
183 AjaxCheckBoxPanel updateMatching = new AjaxCheckBoxPanel(
184 "updateMatching", "updateMatching", new PropertyModel<>(opTO, "updateMatching"), false);
185 add(updateMatching);
186
187 AjaxPalettePanel<String> actions = new AjaxPalettePanel.Builder<String>().
188 setName(new StringResourceModel("actions", directoryPanel).getString()).
189 setAllowMoveAll(true).setAllowOrder(true).
190 build("actions",
191 new PropertyModel<>(opTO, "actions"),
192 new ListModel<>(opActions.getObject()));
193 actions.setOutputMarkupId(true);
194 add(actions);
195 }
196 }
197
198 public static class OPContinue extends WizardStep {
199
200 private static final long serialVersionUID = -7087008312629522790L;
201
202 public OPContinue(final OIDCC4UIProviderTO opTO, final boolean readOnly) {
203 this.setOutputMarkupId(true);
204
205 WebMarkupContainer content = new WebMarkupContainer("content");
206 content.setOutputMarkupId(true);
207 add(content);
208
209 UrlValidator urlValidator = new UrlValidator();
210
211 AjaxTextFieldPanel issuer = new AjaxTextFieldPanel(
212 "issuer", "issuer", new PropertyModel<>(opTO, "issuer"));
213 issuer.addValidator(urlValidator);
214 issuer.addRequiredLabel();
215 content.add(issuer.setReadOnly(readOnly));
216
217 AjaxCheckBoxPanel hasDiscovery = new AjaxCheckBoxPanel(
218 "hasDiscovery", "hasDiscovery", new PropertyModel<>(opTO, "hasDiscovery"));
219 content.add(hasDiscovery);
220
221 AjaxTextFieldPanel authorizationEndpoint = new AjaxTextFieldPanel("authorizationEndpoint",
222 "authorizationEndpoint", new PropertyModel<>(opTO, "authorizationEndpoint"));
223 authorizationEndpoint.addRequiredLabel();
224 authorizationEndpoint.addValidator(urlValidator);
225 content.add(authorizationEndpoint.setReadOnly(readOnly));
226
227 AjaxTextFieldPanel userinfoEndpoint = new AjaxTextFieldPanel("userinfoEndpoint",
228 "userinfoEndpoint", new PropertyModel<>(opTO, "userinfoEndpoint"));
229 userinfoEndpoint.addValidator(urlValidator);
230 content.add(userinfoEndpoint.setReadOnly(readOnly));
231
232 AjaxTextFieldPanel tokenEndpoint = new AjaxTextFieldPanel("tokenEndpoint",
233 "tokenEndpoint", new PropertyModel<>(opTO, "tokenEndpoint"));
234 tokenEndpoint.addRequiredLabel();
235 tokenEndpoint.addValidator(urlValidator);
236 content.add(tokenEndpoint.setReadOnly(readOnly));
237
238 AjaxTextFieldPanel jwksUri = new AjaxTextFieldPanel("jwksUri",
239 "jwksUri", new PropertyModel<>(opTO, "jwksUri"));
240 jwksUri.addRequiredLabel();
241 jwksUri.addValidator(urlValidator);
242 content.add(jwksUri.setReadOnly(readOnly));
243
244 AjaxTextFieldPanel endSessionEndpoint = new AjaxTextFieldPanel("endSessionEndpoint",
245 "endSessionEndpoint", new PropertyModel<>(opTO, "endSessionEndpoint"));
246 endSessionEndpoint.addValidator(urlValidator);
247 content.add(endSessionEndpoint.setReadOnly(readOnly));
248
249 WebMarkupContainer visibleParams = new WebMarkupContainer("visibleParams");
250 visibleParams.setOutputMarkupPlaceholderTag(true);
251 visibleParams.add(authorizationEndpoint);
252 visibleParams.add(userinfoEndpoint);
253 visibleParams.add(tokenEndpoint);
254 visibleParams.add(jwksUri);
255 visibleParams.add(endSessionEndpoint);
256 content.add(visibleParams);
257
258 showHide(hasDiscovery, visibleParams);
259
260 hasDiscovery.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
261
262 private static final long serialVersionUID = -1107858522700306810L;
263
264 @Override
265 protected void onUpdate(final AjaxRequestTarget target) {
266 showHide(hasDiscovery, visibleParams);
267 target.add(visibleParams);
268 }
269 });
270
271 AjaxTextFieldPanel value = new AjaxTextFieldPanel("panel", "scopes", new Model<>());
272 value.setChoices(OIDCScopeConstants.ALL_STANDARD_SCOPES);
273 content.add(new MultiFieldPanel.Builder<String>(
274 new PropertyModel<>(opTO, "scopes")).build("scopes", "scopes", value));
275 }
276 }
277
278 private static void showHide(final AjaxCheckBoxPanel hasDiscovery, final WebMarkupContainer visibleParams) {
279 visibleParams.setVisible("false".equals(hasDiscovery.getField().getValue()));
280 }
281
282
283
284
285 private static final class Mapping extends WizardStep {
286
287 private static final long serialVersionUID = 3454904947720856253L;
288
289 Mapping() {
290 setTitleModel(Model.of("Mapping"));
291 setSummaryModel(Model.of(StringUtils.EMPTY));
292 }
293 }
294 }