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.clientapps;
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.Collection;
25 import java.util.Iterator;
26 import java.util.List;
27 import org.apache.commons.lang3.SerializationUtils;
28 import org.apache.syncope.client.console.SyncopeConsoleSession;
29 import org.apache.syncope.client.console.audit.AuditHistoryModal;
30 import org.apache.syncope.client.console.commons.AMConstants;
31 import org.apache.syncope.client.console.commons.DirectoryDataProvider;
32 import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
33 import org.apache.syncope.client.console.pages.BasePage;
34 import org.apache.syncope.client.console.panels.DirectoryPanel;
35 import org.apache.syncope.client.console.panels.ModalDirectoryPanel;
36 import org.apache.syncope.client.console.rest.AuditRestClient;
37 import org.apache.syncope.client.console.rest.ClientAppRestClient;
38 import org.apache.syncope.client.console.rest.PolicyRestClient;
39 import org.apache.syncope.client.console.rest.RealmRestClient;
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.ActionLink.ActionType;
44 import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
45 import org.apache.syncope.client.ui.commons.Constants;
46 import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
47 import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
48 import org.apache.syncope.common.lib.SyncopeClientException;
49 import org.apache.syncope.common.lib.to.ClientAppTO;
50 import org.apache.syncope.common.lib.types.AMEntitlement;
51 import org.apache.syncope.common.lib.types.AuditElements;
52 import org.apache.syncope.common.lib.types.ClientAppType;
53 import org.apache.syncope.common.lib.types.IdRepoEntitlement;
54 import org.apache.wicket.PageReference;
55 import org.apache.wicket.ajax.AjaxRequestTarget;
56 import org.apache.wicket.event.Broadcast;
57 import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
58 import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
59 import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
60 import org.apache.wicket.model.CompoundPropertyModel;
61 import org.apache.wicket.model.IModel;
62 import org.apache.wicket.model.Model;
63 import org.apache.wicket.model.StringResourceModel;
64 import org.apache.wicket.spring.injection.annot.SpringBean;
65
66 public abstract class ClientAppDirectoryPanel<T extends ClientAppTO>
67 extends DirectoryPanel<T, T, DirectoryDataProvider<T>, ClientAppRestClient> {
68
69 private static final long serialVersionUID = 4100100988730985059L;
70
71 @SpringBean
72 protected PolicyRestClient policyRestClient;
73
74 @SpringBean
75 protected ClientAppRestClient clientAppRestClient;
76
77 @SpringBean
78 protected RealmRestClient realmRestClient;
79
80 @SpringBean
81 protected AuditRestClient auditRestClient;
82
83 protected final ClientAppType type;
84
85 protected final BaseModal<T> propertiesModal;
86
87 protected final BaseModal<Serializable> historyModal;
88
89 public ClientAppDirectoryPanel(
90 final String id,
91 final ClientAppRestClient restClient,
92 final ClientAppType type,
93 final PageReference pageRef) {
94
95 super(id, restClient, pageRef, true);
96 this.type = type;
97
98 modal.addSubmitButton();
99 modal.size(Modal.Size.Large);
100 modal.setWindowClosedCallback(target -> {
101 updateResultTable(target);
102 modal.show(false);
103 });
104 setFooterVisibility(true);
105
106 propertiesModal = new BaseModal<>(Constants.OUTER) {
107
108 private static final long serialVersionUID = 389935548143327858L;
109
110 @Override
111 protected void onConfigure() {
112 super.onConfigure();
113 setFooterVisible(false);
114 }
115 };
116 propertiesModal.size(Modal.Size.Large);
117 propertiesModal.setWindowClosedCallback(target -> propertiesModal.show(false));
118 addOuterObject(propertiesModal);
119
120 disableCheckBoxes();
121
122 historyModal = new BaseModal<>(Constants.OUTER);
123 historyModal.size(Modal.Size.Large);
124 addOuterObject(historyModal);
125 }
126
127 @Override
128 protected List<IColumn<T, String>> getColumns() {
129 List<IColumn<T, String>> columns = new ArrayList<>();
130
131 columns.add(new KeyPropertyColumn<>(
132 new StringResourceModel(Constants.KEY_FIELD_NAME, this), Constants.KEY_FIELD_NAME));
133 columns.add(new PropertyColumn<>(
134 new StringResourceModel(Constants.NAME_FIELD_NAME, this),
135 Constants.NAME_FIELD_NAME, Constants.NAME_FIELD_NAME));
136 columns.add(new PropertyColumn<>(
137 new StringResourceModel("clientAppId", this), "clientAppId", "clientAppId"));
138
139 addCustomColumnFields(columns);
140
141 return columns;
142 }
143
144 protected void addCustomColumnFields(final List<IColumn<T, String>> columns) {
145 }
146
147 @Override
148 public ActionsPanel<T> getActions(final IModel<T> model) {
149 ActionsPanel<T> panel = super.getActions(model);
150
151 panel.add(new ActionLink<>() {
152
153 private static final long serialVersionUID = -3722207913631435501L;
154
155 @Override
156 public void onClick(final AjaxRequestTarget target, final ClientAppTO ignore) {
157 send(ClientAppDirectoryPanel.this, Broadcast.EXACT,
158 new AjaxWizard.EditItemActionEvent<>(
159 restClient.read(type, model.getObject().getKey()), target));
160 }
161 }, ActionLink.ActionType.EDIT, AMEntitlement.CLIENTAPP_UPDATE);
162
163 panel.add(new ActionLink<>() {
164
165 private static final long serialVersionUID = -3722207913631435501L;
166
167 @Override
168 public void onClick(final AjaxRequestTarget target, final ClientAppTO ignore) {
169 model.setObject(restClient.read(type, model.getObject().getKey()));
170 modal.setContent(new UsernameAttributeProviderModalPanelBuilder<>(
171 type, model.getObject(), modal, clientAppRestClient, pageRef).
172 build(actualId, 1, AjaxWizard.Mode.EDIT));
173 modal.header(new Model<>(getString("usernameAttributeProviderConf.title", model)));
174 modal.show(true);
175 target.add(modal);
176 }
177 }, ActionLink.ActionType.COMPOSE, AMEntitlement.CLIENTAPP_UPDATE);
178
179 panel.add(new ActionLink<>() {
180
181 private static final long serialVersionUID = -3722207913631435501L;
182
183 @Override
184 public void onClick(final AjaxRequestTarget target, final ClientAppTO ignore) {
185 model.setObject(restClient.read(type, model.getObject().getKey()));
186 target.add(propertiesModal.setContent(new ModalDirectoryPanel<>(
187 propertiesModal,
188 new ClientAppPropertiesDirectoryPanel<>(
189 "panel", restClient, propertiesModal, type, model, pageRef),
190 pageRef)));
191 propertiesModal.header(new Model<>(getString("properties.title", model)));
192 propertiesModal.show(true);
193 }
194 }, ActionLink.ActionType.TYPE_EXTENSIONS, AMEntitlement.CLIENTAPP_UPDATE);
195
196 panel.add(new ActionLink<>() {
197
198 private static final long serialVersionUID = -5432034353017728756L;
199
200 @Override
201 public void onClick(final AjaxRequestTarget target, final ClientAppTO ignore) {
202 model.setObject(restClient.read(type, model.getObject().getKey()));
203
204 target.add(historyModal.setContent(new AuditHistoryModal<>(
205 AuditElements.EventCategoryType.LOGIC,
206 "ClientAppLogic",
207 model.getObject(),
208 AMEntitlement.CLIENTAPP_UPDATE,
209 auditRestClient) {
210
211 private static final long serialVersionUID = -3712506022627033811L;
212
213 @Override
214 protected void restore(final String json, final AjaxRequestTarget target) {
215 try {
216 ClientAppTO updated = MAPPER.readValue(json, ClientAppTO.class);
217 restClient.update(type, updated);
218
219 SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
220 } catch (Exception e) {
221 LOG.error("While restoring ClientApp {}", ((ClientAppTO) model.getObject()).getKey(), e);
222 SyncopeConsoleSession.get().onException(e);
223 }
224 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
225 }
226 }));
227
228 historyModal.header(new Model<>(getString("auditHistory.title", new Model<>(model.getObject()))));
229
230 historyModal.show(true);
231 }
232 }, ActionLink.ActionType.VIEW_AUDIT_HISTORY, String.format("%s,%s", AMEntitlement.CLIENTAPP_READ,
233 IdRepoEntitlement.AUDIT_LIST));
234
235 panel.add(new ActionLink<>() {
236
237 private static final long serialVersionUID = -3722207913631435501L;
238
239 @Override
240 public void onClick(final AjaxRequestTarget target, final ClientAppTO ignore) {
241 ClientAppTO clone = SerializationUtils.clone(model.getObject());
242 clone.setKey(null);
243 clone.setClientAppId(null);
244 send(ClientAppDirectoryPanel.this, Broadcast.EXACT,
245 new AjaxWizard.EditItemActionEvent<>(clone, target));
246 }
247 }, ActionLink.ActionType.CLONE, AMEntitlement.CLIENTAPP_CREATE);
248
249 panel.add(new ActionLink<>() {
250
251 private static final long serialVersionUID = -3722207913631435501L;
252
253 @Override
254 public void onClick(final AjaxRequestTarget target, final ClientAppTO ignore) {
255 T clientAppTO = model.getObject();
256 try {
257 restClient.delete(type, clientAppTO.getKey());
258
259 SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
260 target.add(container);
261 } catch (SyncopeClientException e) {
262 LOG.error("While deleting {}", clientAppTO.getKey(), e);
263 SyncopeConsoleSession.get().onException(e);
264 }
265 ((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(target);
266 }
267 }, ActionLink.ActionType.DELETE, AMEntitlement.CLIENTAPP_DELETE, true);
268
269 return panel;
270 }
271
272 @Override
273 protected Collection<ActionType> getBatches() {
274 return List.of();
275 }
276
277 @Override
278 protected ClientAppDataProvider dataProvider() {
279 return new ClientAppDataProvider(rows);
280 }
281
282 @Override
283 protected String paginatorRowsKey() {
284 return AMConstants.PREF_CLIENTAPP_PAGINATOR_ROWS;
285 }
286
287 protected class ClientAppDataProvider extends DirectoryDataProvider<T> {
288
289 private static final long serialVersionUID = 4725679400450513556L;
290
291 private final SortableDataProviderComparator<T> comparator;
292
293 ClientAppDataProvider(final int paginatorRows) {
294 super(paginatorRows);
295
296 setSort(Constants.NAME_FIELD_NAME, SortOrder.ASCENDING);
297 comparator = new SortableDataProviderComparator<>(this);
298 }
299
300 @Override
301 public Iterator<T> iterator(final long first, final long count) {
302 List<T> list = restClient.list(type);
303 list.sort(comparator);
304 return list.subList((int) first, (int) first + (int) count).iterator();
305 }
306
307 @Override
308 public long size() {
309 return restClient.list(type).size();
310 }
311
312 @Override
313 public IModel<T> model(final T object) {
314 return new CompoundPropertyModel<>(object);
315 }
316 }
317 }