blob: 5e47d7cca151452dba2ead6336b59a0879c6c320 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.syncope.client.console.audit;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.syncope.client.console.panels.AbstractModalPanel;
import org.apache.syncope.client.console.panels.MultilevelPanel;
import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
import org.apache.syncope.client.console.wicket.markup.html.form.JsonDiffPanel;
import org.apache.syncope.client.console.wicket.markup.html.form.JsonEditorPanel;
import org.apache.syncope.client.ui.commons.Constants;
import org.apache.syncope.client.ui.commons.markup.html.form.AjaxDropDownChoicePanel;
import org.apache.syncope.common.lib.to.AnyTO;
import org.apache.syncope.common.lib.to.AuditEntryTO;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;
public class HistoryAuditDetails extends MultilevelPanel.SecondLevel {
private static final String KEY_CURRENT = "current";
private static final long serialVersionUID = -7400543686272100483L;
private static final ObjectMapper MAPPER = new ObjectMapper();
private final AuditEntryTO selected;
private final List<AuditEntryTO> availableTOs;
private final AnyTypeKind anyTypeKind;
private AbstractModalPanel<String> jsonPanel;
private final AnyTO currentTO;
public HistoryAuditDetails(final BaseModal<?> baseModal, final AuditEntryTO selected,
final PageReference pageRef, final List<AuditEntryTO> availableTOs,
final AnyTO currentTO, final AnyTypeKind anyTypeKind) {
super();
this.availableTOs = availableTOs.stream()
.filter(object -> !selected.equals(object) && selected.getBefore() != null)
.collect(Collectors.toList());
this.selected = selected;
this.anyTypeKind = anyTypeKind;
this.currentTO = currentTO;
addCurrentInstanceConf();
Form<?> form = initDropdownDiffConfForm();
add(form);
form.setVisible(!this.availableTOs.isEmpty());
showConfigurationSinglePanel();
}
private void showConfigurationSinglePanel() {
Pair<String, String> info = getJSONInfo(selected);
jsonPanel = new JsonEditorPanel(null, new PropertyModel<>(info, "right"), true, null) {
private static final long serialVersionUID = -8927036362466990179L;
@Override
public void onSubmit(final AjaxRequestTarget target) {
modal.close(target);
}
};
jsonPanel.setOutputMarkupId(true);
addOrReplace(jsonPanel);
}
private void showConfigurationDiffPanel(final List<AuditEntryTO> entries) {
List<Pair<String, String>> infos = new ArrayList<>();
entries.forEach(entry -> infos.add(getJSONInfo(entry)));
jsonPanel = new JsonDiffPanel(null, new PropertyModel<>(infos.get(0), "value"),
new PropertyModel<>(infos.get(1), "value"), null) {
private static final long serialVersionUID = -8927036362466990179L;
@Override
public void onSubmit(final AjaxRequestTarget target) {
modal.close(target);
}
};
replace(jsonPanel);
}
private String getSanitizedTOAsJSON(final AnyTO anyTO) throws Exception {
if (this.anyTypeKind == AnyTypeKind.USER) {
UserTO userTO = (UserTO) anyTO;
userTO.setPassword(null);
userTO.setSecurityAnswer(null);
return MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(userTO);
}
return MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(anyTO);
}
private Pair<String, String> getJSONInfo(final AuditEntryTO auditEntryBean) {
try {
final String content;
if (auditEntryBean.getBefore() == null) {
content = MAPPER.readTree(auditEntryBean.getOutput()).get("entity").toPrettyString();
} else {
content = auditEntryBean.getBefore();
}
AnyTO userTO = MAPPER.readValue(content, anyTypeKind.getTOClass());
String json = getSanitizedTOAsJSON(userTO);
return Pair.of(auditEntryBean.getKey(), json);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static <T extends AuditEntryTO> Map<String, String> getDropdownNamesMap(final List<T> entries) {
Map<String, String> map = new LinkedHashMap<>();
for (AuditEntryTO audit : entries) {
String value = audit.getWho()
+ " - " + SyncopeConsoleSession.get().getDateFormat().format(audit.getDate());
if (audit.getKey().equalsIgnoreCase(KEY_CURRENT)) {
value += " - " + audit.getKey();
}
map.put(audit.getKey(), value);
}
return map;
}
private Form<?> initDropdownDiffConfForm() {
final Form<AuditEntryTO> form = new Form<>("form");
form.setModel(new CompoundPropertyModel<>(selected));
form.setOutputMarkupId(true);
final Map<String, String> namesMap = getDropdownNamesMap(availableTOs);
List<String> keys = new ArrayList<>(namesMap.keySet());
final AjaxDropDownChoicePanel<String> dropdownElem = new AjaxDropDownChoicePanel<>(
"compareDropdown",
getString("compare"),
new PropertyModel<>(selected, "key"),
false);
dropdownElem.setChoices(keys);
dropdownElem.setChoiceRenderer(new IChoiceRenderer<String>() {
private static final long serialVersionUID = -6265603675261014912L;
@Override
public Object getDisplayValue(final String value) {
return namesMap.get(value) == null ? value : namesMap.get(value);
}
@Override
public String getIdValue(final String value, final int i) {
return value;
}
@Override
public String getObject(
final String id, final IModel<? extends List<? extends String>> choices) {
return id;
}
});
dropdownElem.setNullValid(false);
dropdownElem.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) {
private static final long serialVersionUID = -1107858522700306810L;
@Override
protected void onUpdate(final AjaxRequestTarget target) {
List<AuditEntryTO> elemsToCompare = new ArrayList<>();
elemsToCompare.add(selected);
final String selectedKey = dropdownElem.getModelObject();
if (selectedKey != null) {
if (!selectedKey.isEmpty()) {
AuditEntryTO confToCompare = availableTOs.stream().
filter(object -> object.getKey().equals(selectedKey)).findAny().orElse(null);
elemsToCompare.add(confToCompare);
showConfigurationDiffPanel(elemsToCompare);
} else {
showConfigurationSinglePanel();
}
}
target.add(jsonPanel);
}
});
form.add(dropdownElem);
return form;
}
private void addCurrentInstanceConf() {
try {
AuditEntryTO entryBean = new AuditEntryTO();
entryBean.setKey(KEY_CURRENT);
entryBean.setWho(currentTO.getCreator());
entryBean.setDate(currentTO.getCreationDate());
entryBean.setBefore(MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(currentTO));
availableTOs.add(entryBean);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
}