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.util.ArrayList;
23  import java.util.Collection;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.stream.Stream;
27  import org.apache.syncope.client.console.SyncopeConsoleSession;
28  import org.apache.syncope.client.console.commons.AMConstants;
29  import org.apache.syncope.client.console.commons.DirectoryDataProvider;
30  import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
31  import org.apache.syncope.client.console.panels.AMSessionDirectoryPanel.AMSessionProvider;
32  import org.apache.syncope.client.console.panels.AMSessionPanel.AMSessionSearchEvent;
33  import org.apache.syncope.client.console.rest.AMSessionRestClient;
34  import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn;
35  import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.KeyPropertyColumn;
36  import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
37  import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
38  import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
39  import org.apache.syncope.client.console.wicket.markup.html.form.JsonEditorPanel;
40  import org.apache.syncope.client.ui.commons.Constants;
41  import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
42  import org.apache.syncope.common.lib.AMSession;
43  import org.apache.syncope.common.lib.SyncopeClientException;
44  import org.apache.wicket.PageReference;
45  import org.apache.wicket.ajax.AjaxRequestTarget;
46  import org.apache.wicket.event.IEvent;
47  import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
48  import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
49  import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
50  import org.apache.wicket.model.CompoundPropertyModel;
51  import org.apache.wicket.model.IModel;
52  import org.apache.wicket.model.Model;
53  import org.apache.wicket.model.ResourceModel;
54  import org.apache.wicket.model.StringResourceModel;
55  
56  public class AMSessionDirectoryPanel
57          extends DirectoryPanel<AMSession, AMSession, AMSessionProvider, AMSessionRestClient> {
58  
59      private static final long serialVersionUID = 24083331272114L;
60  
61      private final String listEntitlement;
62  
63      private final String deleteEntitlement;
64  
65      private final BaseModal<String> viewModal;
66  
67      private String keyword;
68  
69      public AMSessionDirectoryPanel(
70              final String id,
71              final AMSessionRestClient restClient,
72              final String listEntitlement,
73              final String deleteEntitlement,
74              final PageReference pageRef) {
75  
76          super(id, restClient, pageRef);
77  
78          this.listEntitlement = listEntitlement;
79          this.deleteEntitlement = deleteEntitlement;
80          this.restClient = restClient;
81  
82          disableCheckBoxes();
83  
84          viewModal = new BaseModal<>(Constants.OUTER) {
85  
86              private static final long serialVersionUID = 389935548143327858L;
87  
88              @Override
89              protected void onConfigure() {
90                  super.onConfigure();
91                  setFooterVisible(false);
92              }
93          };
94          viewModal.size(Modal.Size.Extra_large);
95          viewModal.setWindowClosedCallback(target -> viewModal.show(false));
96          addOuterObject(viewModal);
97  
98          initResultTable();
99      }
100 
101     @Override
102     protected List<IColumn<AMSession, String>> getColumns() {
103         List<IColumn<AMSession, String>> columns = new ArrayList<>();
104 
105         columns.add(new KeyPropertyColumn<>(
106                 new StringResourceModel(Constants.KEY_FIELD_NAME, this), Constants.KEY_FIELD_NAME));
107         columns.add(new DatePropertyColumn<>(
108                 new ResourceModel("authenticationDate"), "authenticationDate", "authenticationDate"));
109         columns.add(new PropertyColumn<>(
110                 new ResourceModel("principal"), "principal", "principal"));
111         return columns;
112     }
113 
114     @Override
115     protected ActionsPanel<AMSession> getActions(final IModel<AMSession> model) {
116         ActionsPanel<AMSession> panel = super.getActions(model);
117 
118         panel.add(new ActionLink<>() {
119 
120             private static final long serialVersionUID = 22687128346032L;
121 
122             @Override
123             public void onClick(final AjaxRequestTarget target, final AMSession ignore) {
124                 viewModal.header(new ResourceModel("details"));
125                 target.add(viewModal.setContent(
126                     new JsonEditorPanel(viewModal, Model.of(model.getObject().getJson()), true, pageRef)));
127                 viewModal.show(true);
128             }
129         }, ActionLink.ActionType.VIEW, listEntitlement);
130 
131         panel.add(new ActionLink<>() {
132 
133             private static final long serialVersionUID = -4608353559809323466L;
134 
135             @Override
136             public void onClick(final AjaxRequestTarget target, final AMSession ignore) {
137                 AMSession session = model.getObject();
138                 try {
139                     restClient.delete(session.getKey());
140                     SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
141                     target.add(container);
142                 } catch (SyncopeClientException e) {
143                     LOG.error("While deleting {}", session.getKey(), e);
144                     SyncopeConsoleSession.get().onException(e);
145                 }
146                 ((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(target);
147             }
148         }, ActionLink.ActionType.DELETE, deleteEntitlement, true);
149 
150         return panel;
151     }
152 
153     @Override
154     protected Collection<ActionLink.ActionType> getBatches() {
155         return List.of();
156     }
157 
158     @Override
159     protected AMSessionProvider dataProvider() {
160         return new AMSessionProvider(rows);
161     }
162 
163     @Override
164     protected String paginatorRowsKey() {
165         return AMConstants.PREF_WASESSION_PAGINATOR_ROWS;
166     }
167 
168     @Override
169     public void onEvent(final IEvent<?> event) {
170         if (event.getPayload() instanceof AMSessionSearchEvent) {
171             AMSessionSearchEvent payload = AMSessionSearchEvent.class.cast(event.getPayload());
172             keyword = payload.getKeyword();
173 
174             updateResultTable(payload.getTarget());
175         } else {
176             super.onEvent(event);
177         }
178     }
179 
180     protected final class AMSessionProvider extends DirectoryDataProvider<AMSession> {
181 
182         private static final long serialVersionUID = 18002870965042L;
183 
184         private final SortableDataProviderComparator<AMSession> comparator;
185 
186         public AMSessionProvider(final int paginatorRows) {
187             super(paginatorRows);
188             setSort("authenticationDate", SortOrder.ASCENDING);
189             comparator = new SortableDataProviderComparator<>(this);
190         }
191 
192         private Stream<AMSession> filtered() {
193             Stream<AMSession> stream = restClient.list().stream();
194             return keyword == null
195                     ? stream
196                     : stream.filter(s -> s.getJson().contains(keyword));
197         }
198 
199         @Override
200         public Iterator<? extends AMSession> iterator(final long first, final long count) {
201             return filtered().skip(first).limit(count).sorted(comparator).iterator();
202         }
203 
204         @Override
205         public long size() {
206             return filtered().count();
207         }
208 
209         @Override
210         public IModel<AMSession> model(final AMSession waSession) {
211             return new CompoundPropertyModel<>(waSession);
212         }
213     }
214 }