View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
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.text.MessageFormat;
24  import java.util.ArrayList;
25  import java.util.Collection;
26  import java.util.Collections;
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.audit.AuditHistoryModal;
31  import org.apache.syncope.client.console.commons.ConnectorDataProvider;
32  import org.apache.syncope.client.console.commons.IdRepoConstants;
33  import org.apache.syncope.client.console.pages.BasePage;
34  import org.apache.syncope.client.console.rest.AuditRestClient;
35  import org.apache.syncope.client.console.rest.ConnectorRestClient;
36  import org.apache.syncope.client.console.rest.ResourceRestClient;
37  import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
38  import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
39  import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
40  import org.apache.syncope.client.console.wizards.WizardMgtPanel;
41  import org.apache.syncope.client.console.wizards.resources.ConnectorWizardBuilder;
42  import org.apache.syncope.client.console.wizards.resources.ResourceWizardBuilder;
43  import org.apache.syncope.client.ui.commons.Constants;
44  import org.apache.syncope.client.ui.commons.wizards.AjaxWizard;
45  import org.apache.syncope.common.lib.SyncopeClientException;
46  import org.apache.syncope.common.lib.to.ConnInstanceTO;
47  import org.apache.syncope.common.lib.to.ResourceTO;
48  import org.apache.syncope.common.lib.types.AuditElements;
49  import org.apache.syncope.common.lib.types.IdMEntitlement;
50  import org.apache.syncope.common.lib.types.IdRepoEntitlement;
51  import org.apache.wicket.PageReference;
52  import org.apache.wicket.ajax.AjaxRequestTarget;
53  import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
54  import org.apache.wicket.event.IEvent;
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.ResourceModel;
61  import org.apache.wicket.spring.injection.annot.SpringBean;
62  
63  public class ConnectorDirectoryPanel extends
64          DirectoryPanel<Serializable, Serializable, ConnectorDataProvider, ConnectorRestClient> {
65  
66      private static final long serialVersionUID = 2041468935602350821L;
67  
68      @SpringBean
69      protected AuditRestClient auditRestClient;
70  
71      @SpringBean
72      protected ResourceRestClient resourceRestClient;
73  
74      protected String keyword;
75  
76      protected ConnectorDirectoryPanel(final String id, final ConnectorDirectoryPanel.Builder builder) {
77          super(id, builder);
78  
79          if (SyncopeConsoleSession.get().owns("CONNECTOR_CREATE")) {
80              MetaDataRoleAuthorizationStrategy.authorizeAll(addAjaxLink, RENDER);
81          } else {
82              MetaDataRoleAuthorizationStrategy.unauthorizeAll(addAjaxLink, RENDER);
83          }
84  
85          setShowResultPanel(false);
86          modal.size(Modal.Size.Large);
87          initResultTable();
88      }
89  
90      @Override
91      public void onEvent(final IEvent<?> event) {
92          if (event.getPayload() instanceof ConnectorSearchEvent) {
93              ConnectorSearchEvent payload = (ConnectorSearchEvent) event.getPayload();
94              AjaxRequestTarget target = payload.getTarget();
95              if (StringUtils.isNotBlank(payload.getKeyword())) {
96                  keyword = payload.getKeyword().toLowerCase();
97              }
98              updateResultTable(target);
99          } else {
100             super.onEvent(event);
101         }
102     }
103 
104     @Override
105     protected ConnectorDataProvider dataProvider() {
106         dataProvider = new ConnectorDataProvider(restClient, rows, pageRef, keyword);
107         return dataProvider;
108     }
109 
110     public ConnectorDataProvider getDataProvider() {
111         return dataProvider;
112     }
113 
114     @Override
115     protected String paginatorRowsKey() {
116         return IdRepoConstants.PREF_PARAMETERS_PAGINATOR_ROWS;
117     }
118 
119     @Override
120     protected List<IColumn<Serializable, String>> getColumns() {
121         final List<IColumn<Serializable, String>> columns = new ArrayList<>();
122         columns.add(new PropertyColumn<>(
123                 new ResourceModel("displayName"), "displayNameSortParam", "displayName"));
124         columns.add(new PropertyColumn<>(
125                 new ResourceModel("connectorName"), "connectorNameSortParam", "connectorName"));
126         return columns;
127     }
128 
129     @Override
130     protected Collection<ActionLink.ActionType> getBatches() {
131         return Collections.singletonList(ActionLink.ActionType.DELETE);
132     }
133 
134     @Override
135     public ActionsPanel<Serializable> getActions(final IModel<Serializable> model) {
136         final ActionsPanel<Serializable> panel = super.getActions(model);
137 
138         panel.add(new ActionLink<>() {
139 
140             private static final long serialVersionUID = 8345646188740279483L;
141 
142             @Override
143             public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
144                 final ResourceTO modelObject = new ResourceTO();
145                 modelObject.setConnector(((ConnInstanceTO) model.getObject()).getKey());
146                 modelObject.setConnectorDisplayName(((ConnInstanceTO) model.getObject()).getDisplayName());
147 
148                 final IModel<ResourceTO> model = new CompoundPropertyModel<>(modelObject);
149                 modal.setFormModel(model.getObject());
150 
151                 target.add(modal.setContent(new ResourceWizardBuilder(
152                         modelObject, resourceRestClient, restClient, pageRef).
153                         build(BaseModal.CONTENT_ID, AjaxWizard.Mode.CREATE)));
154 
155                 modal.header(new Model<>(MessageFormat.format(getString("resource.new"),
156                         model.getObject().getKey())));
157                 modal.show(true);
158 
159                 target.add(modal);
160             }
161 
162         }, ActionLink.ActionType.CREATE_RESOURCE, String.format("%s", IdMEntitlement.RESOURCE_CREATE));
163 
164         panel.add(new ActionLink<>() {
165 
166             private static final long serialVersionUID = 8200500789152854321L;
167 
168             @Override
169             public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
170                 ConnInstanceTO connInstance = restClient.read(((ConnInstanceTO) model.getObject()).getKey());
171 
172                 final IModel<ConnInstanceTO> model = new CompoundPropertyModel<>(connInstance);
173                 modal.setFormModel(model);
174 
175                 target.add(modal.setContent(new ConnectorWizardBuilder(connInstance, restClient, pageRef).
176                         build(BaseModal.CONTENT_ID,
177                                 SyncopeConsoleSession.get().
178                                         owns(IdMEntitlement.CONNECTOR_UPDATE, connInstance.getAdminRealm())
179                                 ? AjaxWizard.Mode.EDIT
180                                 : AjaxWizard.Mode.READONLY)));
181 
182                 modal.header(
183                         new Model<>(MessageFormat.format(getString("connector.edit"), connInstance.getDisplayName())));
184                 modal.show(true);
185 
186             }
187         }, ActionLink.ActionType.EDIT, String.format("%s,%s", IdMEntitlement.CONNECTOR_READ,
188                 IdMEntitlement.CONNECTOR_UPDATE));
189 
190         panel.add(new ActionLink<>() {
191 
192             private static final long serialVersionUID = 1085863437941911947L;
193 
194             @Override
195             public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
196                 ConnInstanceTO modelObject = restClient.read(((ConnInstanceTO) model.getObject()).getKey());
197 
198                 target.add(altDefaultModal.setContent(new AuditHistoryModal<>(
199                         AuditElements.EventCategoryType.LOGIC,
200                         "ConnectorLogic",
201                         modelObject,
202                         IdMEntitlement.CONNECTOR_UPDATE,
203                         auditRestClient) {
204 
205                     private static final long serialVersionUID = -3225348282675513648L;
206 
207                     @Override
208                     protected void restore(final String json, final AjaxRequestTarget target) {
209                         try {
210                             ConnInstanceTO updated = MAPPER.readValue(json, ConnInstanceTO.class);
211                             restClient.update(updated);
212 
213                             SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
214                         } catch (Exception e) {
215                             LOG.error("While restoring connector {}", ((ConnInstanceTO) model.getObject()).getKey(), e);
216                             SyncopeConsoleSession.get().onException(e);
217                         }
218                         ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
219                     }
220                 }));
221 
222                 altDefaultModal.header(
223                         new Model<>(MessageFormat.format(getString("connector.menu.history"),
224                                 ((ConnInstanceTO) model.getObject()).getDisplayName())));
225 
226                 altDefaultModal.show(true);
227             }
228 
229         }, ActionLink.ActionType.VIEW_AUDIT_HISTORY,
230                 String.format("%s,%s", IdMEntitlement.CONNECTOR_READ, IdRepoEntitlement.AUDIT_LIST));
231 
232         panel.add(new ActionLink<>() {
233 
234             private static final long serialVersionUID = -1544718936080799146L;
235 
236             @Override
237             public void onClick(final AjaxRequestTarget target, final Serializable ignore) {
238                 try {
239                     restClient.delete(((ConnInstanceTO) model.getObject()).getKey());
240                     target.appendJavaScript(String.format("jsPlumb.remove('%s');",
241                             ((ConnInstanceTO) model.getObject()).getKey()));
242 
243                     SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
244                 } catch (SyncopeClientException e) {
245                     LOG.error("While deleting resource {}", ((ConnInstanceTO) model.getObject()).getKey(), e);
246                     SyncopeConsoleSession.get().onException(e);
247                 }
248                 ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target);
249             }
250 
251         }, ActionLink.ActionType.DELETE, IdMEntitlement.CONNECTOR_DELETE, true);
252 
253         return panel;
254     }
255 
256     public static class ConnectorSearchEvent implements Serializable {
257 
258         private static final long serialVersionUID = -282052400565266028L;
259 
260         private final AjaxRequestTarget target;
261 
262         private final String keyword;
263 
264         public ConnectorSearchEvent(final AjaxRequestTarget target, final String keyword) {
265             this.target = target;
266             this.keyword = keyword;
267         }
268 
269         public AjaxRequestTarget getTarget() {
270             return target;
271         }
272 
273         public String getKeyword() {
274             return keyword;
275         }
276     }
277 
278     public static class Builder extends DirectoryPanel.Builder<Serializable, Serializable, ConnectorRestClient> {
279 
280         private static final long serialVersionUID = 6128427903964630093L;
281 
282         public Builder(final ConnectorRestClient restClient, final PageReference pageRef) {
283             super(restClient, pageRef);
284             setShowResultPage(false);
285         }
286 
287         @Override
288         protected WizardMgtPanel<Serializable> newInstance(final String id, final boolean wizardInModal) {
289             return new ConnectorDirectoryPanel(id, this);
290         }
291     }
292 }