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.panels;
20
21 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
22 import java.io.Serializable;
23 import java.util.ArrayList;
24 import java.util.Base64;
25 import java.util.Collection;
26 import java.util.Iterator;
27 import java.util.List;
28 import org.apache.commons.lang3.StringUtils;
29 import org.apache.syncope.client.console.SyncopeConsoleSession;
30 import org.apache.syncope.client.console.commons.DirectoryDataProvider;
31 import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
32 import org.apache.syncope.client.console.layout.UserFormLayoutInfo;
33 import org.apache.syncope.client.console.pages.BasePage;
34 import org.apache.syncope.client.console.panels.SAML2IdPsDirectoryPanel.SAML2IdPsProvider;
35 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
36 import org.apache.syncope.client.console.rest.ImplementationRestClient;
37 import org.apache.syncope.client.console.rest.SAML2IdPsRestClient;
38 import org.apache.syncope.client.console.rest.UserRestClient;
39 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.BooleanPropertyColumn;
40 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.KeyPropertyColumn;
41 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
42 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
43 import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksTogglePanel;
44 import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
45 import org.apache.syncope.client.console.wicket.markup.html.form.XMLEditorPanel;
46 import org.apache.syncope.client.console.wizards.SAML2IdPWizardBuilder;
47 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
48 import org.apache.syncope.client.console.wizards.any.UserTemplateWizardBuilder;
49 import org.apache.syncope.client.ui.commons.Constants;
50 import org.apache.syncope.client.ui.commons.panels.WizardModalPanel;
51 import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
52 import org.apache.syncope.client.ui.commons.wizards.any.AnyWrapper;
53 import org.apache.syncope.common.lib.SyncopeClientException;
54 import org.apache.syncope.common.lib.to.SAML2SP4UIIdPTO;
55 import org.apache.syncope.common.lib.to.UserTO;
56 import org.apache.syncope.common.lib.types.AnyTypeKind;
57 import org.apache.syncope.common.lib.types.SAML2SP4UIEntitlement;
58 import org.apache.wicket.MarkupContainer;
59 import org.apache.wicket.PageReference;
60 import org.apache.wicket.ajax.AjaxRequestTarget;
61 import org.apache.wicket.ajax.markup.html.AjaxLink;
62 import org.apache.wicket.event.Broadcast;
63 import org.apache.wicket.event.IEvent;
64 import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
65 import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
66 import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
67 import org.apache.wicket.model.CompoundPropertyModel;
68 import org.apache.wicket.model.IModel;
69 import org.apache.wicket.model.Model;
70 import org.apache.wicket.model.ResourceModel;
71 import org.apache.wicket.model.StringResourceModel;
72 import org.apache.wicket.spring.injection.annot.SpringBean;
73
74 public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
75 SAML2SP4UIIdPTO, SAML2SP4UIIdPTO, SAML2IdPsProvider, SAML2IdPsRestClient> {
76
77 private static final long serialVersionUID = 4792356089584116041L;
78
79 protected static final String PREF_SAML2_IDPS_PAGINATOR_ROWS = "saml2.idps.paginator.rows";
80
81 @SpringBean
82 protected AnyTypeRestClient anyTypeRestClient;
83
84 @SpringBean
85 protected UserRestClient userRestClient;
86
87 @SpringBean
88 protected ImplementationRestClient implementationRestClient;
89
90 protected final BaseModal<String> metadataModal = new BaseModal<>("outer");
91
92 protected final BaseModal<Serializable> templateModal;
93
94 public SAML2IdPsDirectoryPanel(final String id, final SAML2IdPsRestClient restClient, final PageReference pageRef) {
95 super(id, new Builder<SAML2SP4UIIdPTO, SAML2SP4UIIdPTO, SAML2IdPsRestClient>(restClient, pageRef) {
96
97 private static final long serialVersionUID = 8517982765290075155L;
98
99 @Override
100 protected WizardMgtPanel<SAML2SP4UIIdPTO> newInstance(final String id, final boolean wizardInModal) {
101 throw new UnsupportedOperationException();
102 }
103 }.disableCheckBoxes());
104
105 addNewItemPanelBuilder(new SAML2IdPWizardBuilder(
106 this, new SAML2SP4UIIdPTO(), implementationRestClient, restClient, pageRef), false);
107
108 modal.addSubmitButton();
109 modal.size(Modal.Size.Large);
110 modal.setWindowClosedCallback(target -> {
111 updateResultTable(target);
112 modal.show(false);
113 });
114
115 addOuterObject(metadataModal);
116 setWindowClosedReloadCallback(metadataModal);
117 metadataModal.size(Modal.Size.Large);
118
119 templateModal = new BaseModal<>("outer") {
120
121 private static final long serialVersionUID = 5787433530654262016L;
122
123 @Override
124 protected void onConfigure() {
125 super.onConfigure();
126 setFooterVisible(false);
127 }
128 };
129 templateModal.setWindowClosedCallback(target -> templateModal.show(false));
130 templateModal.size(Modal.Size.Large);
131 addOuterObject(templateModal);
132
133 initResultTable();
134
135 final ImportMetadata importMetadata = new ImportMetadata("importMetadata", container, pageRef);
136 addInnerObject(importMetadata);
137 AjaxLink<Void> importMetadataLink = new AjaxLink<>("add") {
138
139 private static final long serialVersionUID = -7978723352517770644L;
140
141 @Override
142 public void onClick(final AjaxRequestTarget target) {
143 importMetadata.toggle(target, true);
144 }
145 };
146 ((MarkupContainer) get("container:content")).addOrReplace(importMetadataLink);
147 }
148
149 @Override
150 protected SAML2IdPsProvider dataProvider() {
151 return new SAML2IdPsProvider(rows);
152 }
153
154 @Override
155 protected ActionLinksTogglePanel<SAML2SP4UIIdPTO> actionTogglePanel() {
156 return new ActionLinksTogglePanel<>(Constants.OUTER, pageRef) {
157
158 private static final long serialVersionUID = -7688359318035249200L;
159
160 @Override
161 public void updateHeader(final AjaxRequestTarget target, final Serializable modelObject) {
162 if (modelObject instanceof SAML2SP4UIIdPTO) {
163 setHeader(target, StringUtils.abbreviate(
164 ((SAML2SP4UIIdPTO) modelObject).getName(), HEADER_FIRST_ABBREVIATION));
165 } else {
166 super.updateHeader(target, modelObject);
167 }
168 }
169 };
170 }
171
172 @Override
173 protected String paginatorRowsKey() {
174 return PREF_SAML2_IDPS_PAGINATOR_ROWS;
175 }
176
177 @Override
178 protected Collection<ActionLink.ActionType> getBatches() {
179 return List.of();
180 }
181
182 @Override
183 protected List<IColumn<SAML2SP4UIIdPTO, String>> getColumns() {
184 List<IColumn<SAML2SP4UIIdPTO, String>> columns = new ArrayList<>();
185
186 columns.add(new KeyPropertyColumn<>(new ResourceModel("key"), "key", "key"));
187 columns.add(new PropertyColumn<>(new ResourceModel("name"), "name", "name"));
188 columns.add(new PropertyColumn<>(new ResourceModel("entityID"), "entityID", "entityID"));
189 columns.add(new PropertyColumn<>(
190 new ResourceModel("bindingType"), "bindingType", "bindingType"));
191 columns.add(new BooleanPropertyColumn<>(
192 new ResourceModel("logoutSupported"), "logoutSupported", "logoutSupported"));
193
194 return columns;
195 }
196
197 @Override
198 public ActionsPanel<SAML2SP4UIIdPTO> getActions(final IModel<SAML2SP4UIIdPTO> model) {
199 final ActionsPanel<SAML2SP4UIIdPTO> panel = super.getActions(model);
200
201 panel.add(new ActionLink<>() {
202
203 private static final long serialVersionUID = -7978723352517770645L;
204
205 @Override
206 public void onClick(final AjaxRequestTarget target, final SAML2SP4UIIdPTO ignore) {
207 SAML2SP4UIIdPTO object = restClient.read(model.getObject().getKey());
208 metadataModal.header(Model.of(object.getName() + " - Metadata"));
209 metadataModal.setContent(new XMLEditorPanel(
210 metadataModal,
211 Model.of(new String(Base64.getMimeDecoder().decode(object.getMetadata()))),
212 true,
213 pageRef));
214 metadataModal.show(true);
215 target.add(metadataModal);
216 }
217 }, ActionLink.ActionType.HTML, SAML2SP4UIEntitlement.IDP_READ);
218 panel.add(new ActionLink<>() {
219
220 private static final long serialVersionUID = -3722207913631435501L;
221
222 @Override
223 public void onClick(final AjaxRequestTarget target, final SAML2SP4UIIdPTO ignore) {
224 SAML2SP4UIIdPTO object = restClient.read(model.getObject().getKey());
225 send(SAML2IdPsDirectoryPanel.this, Broadcast.EXACT,
226 new AjaxWizard.EditItemActionEvent<>(object, target));
227 }
228 }, ActionLink.ActionType.EDIT, SAML2SP4UIEntitlement.IDP_UPDATE);
229 panel.add(new ActionLink<>() {
230
231 private static final long serialVersionUID = -3722207913631435501L;
232
233 @Override
234 public void onClick(final AjaxRequestTarget target, final SAML2SP4UIIdPTO ignore) {
235 final SAML2SP4UIIdPTO object = restClient.read(model.getObject().getKey());
236
237 UserTemplateWizardBuilder builder = new UserTemplateWizardBuilder(
238 object.getUserTemplate(),
239 anyTypeRestClient.read(AnyTypeKind.USER.name()).getClasses(),
240 new UserFormLayoutInfo(),
241 userRestClient,
242 pageRef) {
243
244 private static final long serialVersionUID = -7978723352517770634L;
245
246 @Override
247 protected Serializable onApplyInternal(final AnyWrapper<UserTO> modelObject) {
248 object.setUserTemplate(modelObject.getInnerObject());
249 restClient.update(object);
250
251 return modelObject;
252 }
253 };
254 templateModal.header(Model.of(StringUtils.capitalize(
255 new StringResourceModel("template.title", SAML2IdPsDirectoryPanel.this).getString())));
256 templateModal.setContent(builder.build(BaseModal.CONTENT_ID));
257 templateModal.show(true);
258 target.add(templateModal);
259
260 }
261 }, ActionLink.ActionType.TEMPLATE, SAML2SP4UIEntitlement.IDP_UPDATE);
262 panel.add(new ActionLink<>() {
263
264 private static final long serialVersionUID = -5467832321897812767L;
265
266 @Override
267 public void onClick(final AjaxRequestTarget target, final SAML2SP4UIIdPTO ignore) {
268 try {
269 restClient.delete(model.getObject().getKey());
270 SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
271 target.add(container);
272 } catch (SyncopeClientException e) {
273 LOG.error("While deleting object {}", model.getObject().getKey(), e);
274 SyncopeConsoleSession.get().onException(e);
275 }
276 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
277 }
278 }, ActionLink.ActionType.DELETE, SAML2SP4UIEntitlement.IDP_DELETE, true);
279
280 return panel;
281 }
282
283 @Override
284 public void onEvent(final IEvent<?> event) {
285 super.onEvent(event);
286
287 if (event.getPayload() instanceof AjaxWizard.NewItemEvent) {
288 AjaxWizard.NewItemEvent<?> newItemEvent = AjaxWizard.NewItemEvent.class.cast(event.getPayload());
289 WizardModalPanel<?> modalPanel = newItemEvent.getModalPanel();
290
291 if (newItemEvent instanceof AjaxWizard.NewItemActionEvent && modalPanel != null) {
292 IModel<Serializable> model = new CompoundPropertyModel<>(modalPanel.getItem());
293 templateModal.setFormModel(model);
294 templateModal.header(newItemEvent.getTitleModel());
295 newItemEvent.getTarget().ifPresent(target -> target.add(templateModal.setContent(modalPanel)));
296 templateModal.show(true);
297 } else if (newItemEvent instanceof AjaxWizard.NewItemCancelEvent) {
298 newItemEvent.getTarget().ifPresent(templateModal::close);
299 } else if (newItemEvent instanceof AjaxWizard.NewItemFinishEvent) {
300 newItemEvent.getTarget().ifPresent(templateModal::close);
301 }
302 }
303 }
304
305 protected final class SAML2IdPsProvider extends DirectoryDataProvider<SAML2SP4UIIdPTO> {
306
307 private static final long serialVersionUID = -185944053385660794L;
308
309 private final SortableDataProviderComparator<SAML2SP4UIIdPTO> comparator;
310
311 private SAML2IdPsProvider(final int paginatorRows) {
312 super(paginatorRows);
313
314 setSort("name", SortOrder.ASCENDING);
315 comparator = new SortableDataProviderComparator<>(this);
316 }
317
318 @Override
319 public Iterator<SAML2SP4UIIdPTO> iterator(final long first, final long count) {
320 List<SAML2SP4UIIdPTO> list = restClient.list();
321 list.sort(comparator);
322 return list.subList((int) first, (int) first + (int) count).iterator();
323 }
324
325 @Override
326 public long size() {
327 return restClient.list().size();
328 }
329
330 @Override
331 public IModel<SAML2SP4UIIdPTO> model(final SAML2SP4UIIdPTO object) {
332 return new CompoundPropertyModel<>(object);
333 }
334 }
335 }