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.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.commons.DirectoryDataProvider;
30 import org.apache.syncope.client.console.commons.IdRepoConstants;
31 import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
32 import org.apache.syncope.client.console.layout.AnyLayout;
33 import org.apache.syncope.client.console.layout.AnyLayoutUtils;
34 import org.apache.syncope.client.console.layout.AnyLayoutWrapper;
35 import org.apache.syncope.client.console.pages.BasePage;
36 import org.apache.syncope.client.console.panels.RoleDirectoryPanel.RoleDataProvider;
37 import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
38 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
39 import org.apache.syncope.client.console.rest.RoleRestClient;
40 import org.apache.syncope.client.console.rest.UserRestClient;
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.ActionsPanel;
44 import org.apache.syncope.client.console.wicket.markup.html.form.JsonEditorPanel;
45 import org.apache.syncope.client.console.wizards.WizardMgtPanel;
46 import org.apache.syncope.client.console.wizards.role.RoleWrapper;
47 import org.apache.syncope.client.lib.SyncopeClient;
48 import org.apache.syncope.client.ui.commons.Constants;
49 import org.apache.syncope.client.ui.commons.panels.ModalPanel;
50 import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
51 import org.apache.syncope.common.lib.SyncopeClientException;
52 import org.apache.syncope.common.lib.SyncopeConstants;
53 import org.apache.syncope.common.lib.to.AnyTypeTO;
54 import org.apache.syncope.common.lib.to.RoleTO;
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.IdRepoEntitlement;
58 import org.apache.wicket.PageReference;
59 import org.apache.wicket.ajax.AjaxRequestTarget;
60 import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
61 import org.apache.wicket.event.Broadcast;
62 import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
63 import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
64 import org.apache.wicket.markup.html.WebPage;
65 import org.apache.wicket.markup.html.panel.Panel;
66 import org.apache.wicket.model.CompoundPropertyModel;
67 import org.apache.wicket.model.IModel;
68 import org.apache.wicket.model.PropertyModel;
69 import org.apache.wicket.model.ResourceModel;
70 import org.apache.wicket.model.StringResourceModel;
71 import org.apache.wicket.spring.injection.annot.SpringBean;
72
73 public class RoleDirectoryPanel extends DirectoryPanel<RoleTO, RoleWrapper, RoleDataProvider, RoleRestClient> {
74
75 private static final long serialVersionUID = -1100228004207271270L;
76
77 @SpringBean
78 protected AnyTypeRestClient anyTypeRestClient;
79
80 @SpringBean
81 protected AnyTypeClassRestClient anyTypeClassRestClient;
82
83 @SpringBean
84 protected UserRestClient userRestClient;
85
86 protected final BaseModal<String> utilityModal = new BaseModal<>(Constants.OUTER);
87
88 protected final BaseModal<Serializable> membersModal = new BaseModal<>(Constants.OUTER);
89
90 protected RoleDirectoryPanel(final String id, final Builder builder) {
91 super(id, builder);
92 MetaDataRoleAuthorizationStrategy.authorize(addAjaxLink, RENDER, IdRepoEntitlement.ROLE_CREATE);
93 setReadOnly(!SyncopeConsoleSession.get().owns(IdRepoEntitlement.ROLE_UPDATE));
94
95 disableCheckBoxes();
96 setShowResultPanel(true);
97
98 modal.size(Modal.Size.Large);
99 initResultTable();
100
101 addOuterObject(utilityModal);
102 setWindowClosedReloadCallback(utilityModal);
103 utilityModal.size(Modal.Size.Large);
104 utilityModal.addSubmitButton();
105
106 addOuterObject(membersModal);
107 membersModal.size(Modal.Size.Large);
108 }
109
110 @Override
111 protected RoleDataProvider dataProvider() {
112 return new RoleDataProvider(rows);
113 }
114
115 @Override
116 protected String paginatorRowsKey() {
117 return IdRepoConstants.PREF_ROLE_PAGINATOR_ROWS;
118 }
119
120 @Override
121 protected List<IColumn<RoleTO, String>> getColumns() {
122 final List<IColumn<RoleTO, String>> columns = new ArrayList<>();
123
124 columns.add(new PropertyColumn<>(
125 new ResourceModel(Constants.KEY_FIELD_NAME), Constants.KEY_FIELD_NAME, Constants.KEY_FIELD_NAME));
126 columns.add(new PropertyColumn<>(
127 new ResourceModel("entitlements", "Entitlements"), null, "entitlements"));
128 columns.add(new PropertyColumn<>(
129 new ResourceModel("realms"), null, "realms"));
130 columns.add(new PropertyColumn<>(
131 new ResourceModel("dynRealms"), null, "dynRealms"));
132 columns.add(new PropertyColumn<>(
133 new ResourceModel("privileges"), null, "privileges"));
134
135 return columns;
136 }
137
138 @Override
139 public ActionsPanel<RoleTO> getActions(final IModel<RoleTO> model) {
140 final ActionsPanel<RoleTO> panel = super.getActions(model);
141
142 panel.add(new ActionLink<>() {
143
144 private static final long serialVersionUID = -7978723352517770644L;
145
146 @Override
147 public void onClick(final AjaxRequestTarget target, final RoleTO ignore) {
148 send(RoleDirectoryPanel.this, Broadcast.EXACT,
149 new AjaxWizard.EditItemActionEvent<>(
150 new RoleWrapper(restClient.read(model.getObject().getKey())), target));
151 }
152 }, ActionLink.ActionType.EDIT, IdRepoEntitlement.ROLE_READ);
153
154 panel.add(new ActionLink<>() {
155
156 private static final long serialVersionUID = -7978723352517770644L;
157
158 @Override
159 public void onClick(final AjaxRequestTarget target, final RoleTO ignore) {
160 RoleTO clone = SerializationUtils.clone(model.getObject());
161 clone.setKey(null);
162 send(RoleDirectoryPanel.this, Broadcast.EXACT,
163 new AjaxWizard.NewItemActionEvent<>(new RoleWrapper(clone), target));
164 }
165 }, ActionLink.ActionType.CLONE, IdRepoEntitlement.ROLE_CREATE);
166
167 panel.add(new ActionLink<>() {
168
169 private static final long serialVersionUID = -7978723352517770644L;
170
171 @Override
172 public void onClick(final AjaxRequestTarget target, final RoleTO ignore) {
173 AnyTypeTO userType = anyTypeRestClient.read(AnyTypeKind.USER.name());
174
175 AnyLayout layout = AnyLayoutUtils.fetch(restClient, anyTypeRestClient.list());
176
177 ModalPanel anyPanel = new AnyPanel.Builder<>(
178 layout.getAnyPanelClass(), BaseModal.CONTENT_ID, userType, null, layout, false, pageRef).
179 build((id, anyTypeTO, realmTO, anyLayout, pageRef) -> {
180
181 String query = SyncopeClient.getUserSearchConditionBuilder().
182 inRoles(model.getObject().getKey()).query();
183
184 Panel panel = new UserDirectoryPanel.Builder(
185 anyTypeClassRestClient.list(anyTypeTO.getClasses()),
186 userRestClient,
187 anyTypeTO.getKey(),
188 pageRef).
189 setRealm(SyncopeConstants.ROOT_REALM).
190 setFiltered(true).
191 setFiql(query).
192 disableCheckBoxes().
193 addNewItemPanelBuilder(AnyLayoutUtils.newLayoutInfo(
194 new UserTO(),
195 anyTypeTO.getClasses(),
196 anyLayout.getUser(),
197 userRestClient,
198 pageRef), false).
199 setWizardInModal(false).build(id);
200
201 MetaDataRoleAuthorizationStrategy.authorize(
202 panel,
203 WebPage.RENDER,
204 IdRepoEntitlement.USER_SEARCH);
205
206 return panel;
207 });
208
209 membersModal.header(new StringResourceModel("role.members", RoleDirectoryPanel.this, model));
210 membersModal.setContent(anyPanel);
211 membersModal.show(true);
212 target.add(membersModal);
213 }
214 }, ActionLink.ActionType.MEMBERS, IdRepoEntitlement.USER_SEARCH);
215
216 panel.add(new ActionLink<>() {
217
218 private static final long serialVersionUID = -7978723352517770644L;
219
220 @Override
221 public void onClick(final AjaxRequestTarget target, final RoleTO ignore) {
222 AnyLayoutWrapper wrapper = new AnyLayoutWrapper(
223 model.getObject().getKey(),
224 AnyLayoutUtils.defaultIfEmpty(
225 restClient.readAnyLayout(model.getObject().getKey()), anyTypeRestClient.list()));
226
227 utilityModal.header(new ResourceModel("console.layout.info", "JSON Content"));
228 utilityModal.setContent(new JsonEditorPanel(
229 utilityModal, new PropertyModel<>(wrapper, "content"), false, pageRef) {
230
231 private static final long serialVersionUID = -8927036362466990179L;
232
233 @Override
234 public void onSubmit(final AjaxRequestTarget target) {
235 try {
236 restClient.setAnyLayout(wrapper.getKey(), wrapper.getContent());
237
238 SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
239 modal.show(false);
240 modal.close(target);
241 } catch (Exception e) {
242 LOG.error("While updating console layout for role {}", wrapper.getKey(), e);
243 SyncopeConsoleSession.get().onException(e);
244 }
245 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
246 }
247 });
248 utilityModal.show(true);
249 target.add(utilityModal);
250 }
251 }, ActionLink.ActionType.LAYOUT_EDIT, IdRepoEntitlement.ROLE_UPDATE);
252 panel.add(new ActionLink<>() {
253
254 private static final long serialVersionUID = -7978723352517770644L;
255
256 @Override
257 public void onClick(final AjaxRequestTarget target, final RoleTO ignore) {
258 try {
259 restClient.delete(model.getObject().getKey());
260
261 SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
262 target.add(container);
263 } catch (SyncopeClientException e) {
264 LOG.error("While deleting object {}", model.getObject().getKey(), e);
265 SyncopeConsoleSession.get().onException(e);
266 }
267 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
268 }
269 }, ActionLink.ActionType.DELETE, IdRepoEntitlement.ROLE_DELETE, true);
270
271 return panel;
272 }
273
274 @Override
275 protected Collection<ActionLink.ActionType> getBatches() {
276 return List.of(ActionLink.ActionType.DELETE);
277 }
278
279 protected class RoleDataProvider extends DirectoryDataProvider<RoleTO> {
280
281 private static final long serialVersionUID = 6267494272884913376L;
282
283 private final SortableDataProviderComparator<RoleTO> comparator;
284
285 public RoleDataProvider(final int paginatorRows) {
286 super(paginatorRows);
287 this.comparator = new SortableDataProviderComparator<>(this);
288 }
289
290 @Override
291 public Iterator<RoleTO> iterator(final long first, final long count) {
292 List<RoleTO> result = restClient.list();
293 result.sort(comparator);
294 return result.subList((int) first, (int) first + (int) count).iterator();
295 }
296
297 @Override
298 public long size() {
299 return restClient.list().size();
300 }
301
302 @Override
303 public IModel<RoleTO> model(final RoleTO object) {
304 return new CompoundPropertyModel<>(object);
305 }
306 }
307
308 public abstract static class Builder
309 extends DirectoryPanel.Builder<RoleTO, RoleWrapper, RoleRestClient> {
310
311 private static final long serialVersionUID = 5088962796986706805L;
312
313 public Builder(final RoleRestClient restClient, final PageReference pageRef) {
314 super(restClient, pageRef);
315 }
316
317 @Override
318 protected WizardMgtPanel<RoleWrapper> newInstance(final String id, final boolean wizardInModal) {
319 return new RoleDirectoryPanel(id, this);
320 }
321 }
322 }