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