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.stream.Collectors;
24 import org.apache.commons.lang3.StringUtils;
25 import org.apache.syncope.client.console.SyncopeWebApplication;
26 import org.apache.syncope.client.console.panels.BeanPanel;
27 import org.apache.syncope.client.console.rest.AuthModuleRestClient;
28 import org.apache.syncope.client.console.wizards.mapping.AuthModuleMappingPanel;
29 import org.apache.syncope.client.ui.commons.Constants;
30 import org.apache.syncope.client.ui.commons.ajax.form.IndicatorAjaxFormComponentUpdatingBehavior;
31 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxCheckBoxPanel;
32 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
33 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxSpinnerFieldPanel;
34 import org.apache.syncope.client.ui.commons.markup.html.form.AjaxTextFieldPanel;
35 import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
36 import org.apache.syncope.common.lib.auth.AuthModuleConf;
37 import org.apache.syncope.common.lib.auth.GoogleMfaAuthModuleConf;
38 import org.apache.syncope.common.lib.to.AuthModuleTO;
39 import org.apache.syncope.common.lib.types.AuthModuleState;
40 import org.apache.wicket.PageReference;
41 import org.apache.wicket.ajax.AjaxEventBehavior;
42 import org.apache.wicket.ajax.AjaxRequestTarget;
43 import org.apache.wicket.extensions.wizard.WizardModel;
44 import org.apache.wicket.extensions.wizard.WizardStep;
45 import org.apache.wicket.model.IModel;
46 import org.apache.wicket.model.LoadableDetachableModel;
47 import org.apache.wicket.model.Model;
48 import org.apache.wicket.model.PropertyModel;
49 import org.springframework.util.ClassUtils;
50
51 public class AuthModuleWizardBuilder extends BaseAjaxWizardBuilder<AuthModuleTO> {
52
53 private static final long serialVersionUID = -6163230263062920394L;
54
55 protected final LoadableDetachableModel<List<String>> authModuleConfs = new LoadableDetachableModel<>() {
56
57 private static final long serialVersionUID = 5275935387613157437L;
58
59 @Override
60 protected List<String> load() {
61 return SyncopeWebApplication.get().getLookup().getClasses(AuthModuleConf.class).stream().
62 map(Class::getName).sorted().collect(Collectors.toList());
63 }
64 };
65
66 protected final AuthModuleRestClient authModuleRestClient;
67
68 protected final Model<Class<? extends AuthModuleConf>> authModuleConfClass = Model.of();
69
70 public AuthModuleWizardBuilder(
71 final AuthModuleTO defaultItem,
72 final AuthModuleRestClient authModuleRestClient,
73 final PageReference pageRef) {
74
75 super(defaultItem, pageRef);
76 this.authModuleRestClient = authModuleRestClient;
77 }
78
79 @Override
80 protected Serializable onApplyInternal(final AuthModuleTO modelObject) {
81 if (mode == AjaxWizard.Mode.CREATE) {
82 authModuleRestClient.create(modelObject);
83 } else {
84 authModuleRestClient.update(modelObject);
85 }
86 return modelObject;
87 }
88
89 @Override
90 protected WizardModel buildModelSteps(final AuthModuleTO modelObject, final WizardModel wizardModel) {
91 wizardModel.add(new Profile(modelObject, authModuleConfs, authModuleConfClass));
92 wizardModel.add(new Configuration(modelObject));
93 wizardModel.add(new GoogleMfaAuthModuleConfLDAP(modelObject, authModuleConfClass));
94 wizardModel.add(new Mapping(modelObject));
95 return wizardModel;
96 }
97
98 protected static class Profile extends WizardStep {
99
100 private static final long serialVersionUID = -3043839139187792810L;
101
102 Profile(
103 final AuthModuleTO authModule,
104 final LoadableDetachableModel<List<String>> authModuleConfs,
105 final Model<Class<? extends AuthModuleConf>> authModuleConfClass) {
106
107 boolean isNew = authModule.getConf() == null;
108 if (!isNew) {
109 authModuleConfClass.setObject(authModule.getConf().getClass());
110 }
111
112 AjaxTextFieldPanel key = new AjaxTextFieldPanel(
113 Constants.KEY_FIELD_NAME, Constants.KEY_FIELD_NAME,
114 new PropertyModel<>(authModule, Constants.KEY_FIELD_NAME));
115 key.addRequiredLabel();
116 key.setEnabled(isNew);
117 add(key);
118
119 AjaxTextFieldPanel description = new AjaxTextFieldPanel(
120 Constants.DESCRIPTION_FIELD_NAME, getString(Constants.DESCRIPTION_FIELD_NAME),
121 new PropertyModel<>(authModule, Constants.DESCRIPTION_FIELD_NAME));
122 add(description);
123
124 AjaxDropDownChoicePanel<AuthModuleState> state = new AjaxDropDownChoicePanel<>(
125 "state", getString("state"), new PropertyModel<>(authModule, "state"));
126 state.setChoices(List.of(AuthModuleState.values()));
127 state.addRequiredLabel();
128 state.setNullValid(false);
129 add(state);
130
131 add(new AjaxSpinnerFieldPanel.Builder<Integer>().build(
132 "order",
133 "order",
134 Integer.class,
135 new PropertyModel<>(authModule, "order")).addRequiredLabel());
136
137 AjaxDropDownChoicePanel<String> conf = new AjaxDropDownChoicePanel<>("conf", getString("type"), isNew
138 ? Model.of()
139 : Model.of(authModule.getConf().getClass().getName()));
140 conf.setChoices(authModuleConfs.getObject());
141 conf.addRequiredLabel();
142 conf.setNullValid(false);
143 conf.setEnabled(isNew);
144 conf.add(new AjaxEventBehavior(Constants.ON_CHANGE) {
145
146 private static final long serialVersionUID = -7133385027739964990L;
147
148 @SuppressWarnings("unchecked")
149 @Override
150 protected void onEvent(final AjaxRequestTarget target) {
151 try {
152 Class<? extends AuthModuleConf> clazz =
153 (Class<? extends AuthModuleConf>) ClassUtils.resolveClassName(
154 conf.getModelObject(), ClassUtils.getDefaultClassLoader());
155
156 authModule.setConf(clazz.getConstructor().newInstance());
157 authModuleConfClass.setObject(clazz);
158 } catch (Exception e) {
159 LOG.error("Cannot instantiate {}", conf.getModelObject(), e);
160 }
161 }
162 });
163 add(conf);
164 }
165 }
166
167 protected class Configuration extends WizardStep {
168
169 private static final long serialVersionUID = -785981096328637758L;
170
171 Configuration(final AuthModuleTO authModule) {
172 add(new BeanPanel<>("bean", new PropertyModel<>(authModule, "conf"), pageRef, "ldap").
173 setRenderBodyOnly(true));
174 }
175 }
176
177 protected class GoogleMfaAuthModuleConfLDAP extends WizardStep implements WizardModel.ICondition {
178
179 private static final long serialVersionUID = 5328049907748683944L;
180
181 private final Model<Class<? extends AuthModuleConf>> authModuleConfClass;
182
183 GoogleMfaAuthModuleConfLDAP(
184 final AuthModuleTO authModule,
185 final Model<Class<? extends AuthModuleConf>> authModuleConfClass) {
186
187 this.authModuleConfClass = authModuleConfClass;
188
189 PropertyModel<GoogleMfaAuthModuleConf.LDAP> beanPanelModel = new PropertyModel<>(authModule, "conf.ldap");
190
191 AjaxCheckBoxPanel enable = new AjaxCheckBoxPanel("enable", "enableLDAP", new IModel<Boolean>() {
192
193 private static final long serialVersionUID = -7126718045816207110L;
194
195 @Override
196 public Boolean getObject() {
197 return beanPanelModel.getObject() != null;
198 }
199
200 @Override
201 public void setObject(final Boolean object) {
202
203 }
204 });
205 enable.getField().add(new IndicatorAjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
206
207 private static final long serialVersionUID = -1107858522700306810L;
208
209 @Override
210 protected void onUpdate(final AjaxRequestTarget target) {
211 if (beanPanelModel.getObject() == null) {
212 beanPanelModel.setObject(new GoogleMfaAuthModuleConf.LDAP());
213 } else {
214 beanPanelModel.setObject(null);
215 }
216 target.add(GoogleMfaAuthModuleConfLDAP.this);
217 }
218 });
219 add(enable);
220
221 add(new BeanPanel<>("bean", beanPanelModel, pageRef).setRenderBodyOnly(true));
222 setOutputMarkupId(true);
223 }
224
225 @Override
226 public boolean evaluate() {
227 return GoogleMfaAuthModuleConf.class.equals(authModuleConfClass.getObject());
228 }
229 }
230
231 protected static final class Mapping extends WizardStep {
232
233 private static final long serialVersionUID = 3454904947720856253L;
234
235 Mapping(final AuthModuleTO authModule) {
236 setTitleModel(Model.of("Mapping"));
237 setSummaryModel(Model.of(StringUtils.EMPTY));
238 add(new AuthModuleMappingPanel("mapping", authModule));
239 }
240 }
241 }