This is an automated email from the ASF dual-hosted git repository. mmoayyed pushed a commit to branch 2_1_X in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/2_1_X by this push: new b04fa34 SYNCOPE-1511: History management for admin console UI (#141) b04fa34 is described below commit b04fa345655d87e74f07cbdba80b67e7d65ffec6 Author: Misagh Moayyed <mm1...@gmail.com> AuthorDate: Thu Dec 5 17:28:12 2019 +0400 SYNCOPE-1511: History management for admin console UI (#141) * initial draft of audit services * cntd with audit services design * add builder methods * clean up types * working on build failures; increased fit timeout * clean up API * clean up API * clean up API * update audit config for tests * clean up changes after review * audit tests for groups * initial pass at wicket * Merge branch '2_1_X' into SYNCOPE-1511-Wicket # Conflicts: # common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/AuditQuery.java # core/logic/src/main/java/org/apache/syncope/core/logic/AuditLogic.java # core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AuditDAO.java # core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAuditDAO.java # core/persistence-jpa/src/test/resources/domains/MasterContent.xml # core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AuditDataBinderImpl.java # core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AuditServiceImpl.java # fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuditITCase.java * clean up formatting * clean up formatting * clean up formatting * clean up formatting * clean up formatting * clean up formatting * clean up formatting * adjustments after code review * add view functionality to audit history * added view and restore functionality * add notes for restoring user based on audit * fix query syntax after merge * test restore functionality w/ serialization * clean up formatting * re-org api endpoint and audit entitlement for restore * clean up formatting * remove non-paged method; fix num of drop-down comparisons * additional cleanup after review * work thru issues with 'created' audit entries * remove audit records from content * add test case for any objects; clean up wicket panel refs * add additional audit tests for read/search ops * clean up audit tests * clean up audit tests * fix search query for any objects; specify type * add license to required files * clean up tests; wip * clean up tests --- .../console/audit/AuditHistoryDirectoryPanel.java | 323 +++++++++++++++++++++ .../client/console/audit/AuditHistoryModal.java | 54 ++++ .../client/console/audit/HistoryAuditDetails.java | 235 +++++++++++++++ .../syncope/client/console/commons/Constants.java | 2 + .../console/panels/AnyObjectDirectoryPanel.java | 23 +- .../client/console/panels/GroupDirectoryPanel.java | 21 ++ .../client/console/panels/UserDirectoryPanel.java | 24 +- .../console/rest/AuditHistoryRestClient.java | 58 ++++ .../wicket/markup/html/form/ActionLink.java | 1 + .../client/console/audit/AuditHistoryModal.html | 26 ++ .../AuditHistoryModal.properties} | 5 +- .../AuditHistoryModal_it.properties} | 5 +- .../AuditHistoryModal_ja.properties} | 5 +- .../AuditHistoryModal_pt_BR.properties} | 5 +- .../AuditHistoryModal_ru.properties} | 5 +- .../client/console/audit/HistoryAuditDetails.html | 29 ++ .../HistoryAuditDetails.properties} | 5 +- .../HistoryAuditDetails_it.properties} | 5 +- .../HistoryAuditDetails_ja.properties} | 5 +- .../HistoryAuditDetails_pt_BR.properties} | 5 +- .../HistoryAuditDetails_ru.properties} | 5 +- ...operties => AnyObjectDirectoryPanel.properties} | 3 +- ...rties => AnyObjectDirectoryPanel_it.properties} | 3 +- ...rties => AnyObjectDirectoryPanel_ja.properties} | 3 +- ...es => AnyObjectDirectoryPanel_pt_BR.properties} | 3 +- ...rties => AnyObjectDirectoryPanel_ru.properties} | 3 +- .../console/panels/GroupDirectoryPanel.properties | 1 + .../panels/GroupDirectoryPanel_it.properties | 1 + .../panels/GroupDirectoryPanel_ja.properties | 1 + .../panels/GroupDirectoryPanel_pt_BR.properties | 1 + .../panels/GroupDirectoryPanel_ru.properties | 1 + .../console/panels/UserDirectoryPanel.properties | 1 + .../panels/UserDirectoryPanel_it.properties | 1 + .../panels/UserDirectoryPanel_ja.properties | 1 + .../panels/UserDirectoryPanel_pt_BR.properties | 1 + .../panels/UserDirectoryPanel_ru.properties | 1 + .../markup/html/form/ActionsPanel.properties | 4 + .../markup/html/form/ActionsPanel_it.properties | 4 + .../markup/html/form/ActionsPanel_ja.properties | 4 + .../markup/html/form/ActionsPanel_pt_BR.properties | 4 + .../markup/html/form/ActionsPanel_ru.properties | 4 + .../src/test/resources/domains/MasterContent.xml | 25 +- .../src/test/resources/domains/MasterContent.xml | 27 +- .../provisioning/api/serialization/POJOHelper.java | 12 + .../provisioning/java/DefaultAuditManager.java | 5 + .../java/data/AuditDataBinderImpl.java | 6 +- .../org/apache/syncope/fit/core/AuditITCase.java | 86 +++++- 47 files changed, 997 insertions(+), 55 deletions(-) diff --git a/client/console/src/main/java/org/apache/syncope/client/console/audit/AuditHistoryDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/audit/AuditHistoryDirectoryPanel.java new file mode 100644 index 0000000..902576e --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/audit/AuditHistoryDirectoryPanel.java @@ -0,0 +1,323 @@ +/* + * 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 com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.client.console.SyncopeConsoleSession; +import org.apache.syncope.client.console.commons.Constants; +import org.apache.syncope.client.console.commons.DirectoryDataProvider; +import org.apache.syncope.client.console.pages.BasePage; +import org.apache.syncope.client.console.panels.AjaxDataTablePanel; +import org.apache.syncope.client.console.panels.DirectoryPanel; +import org.apache.syncope.client.console.panels.ModalPanel; +import org.apache.syncope.client.console.panels.MultilevelPanel; +import org.apache.syncope.client.console.rest.AnyObjectRestClient; +import org.apache.syncope.client.console.rest.AuditHistoryRestClient; +import org.apache.syncope.client.console.rest.GroupRestClient; +import org.apache.syncope.client.console.rest.UserRestClient; +import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn; +import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal; +import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink; +import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel; +import org.apache.syncope.common.lib.AnyOperations; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.patch.AnyObjectPatch; +import org.apache.syncope.common.lib.patch.GroupPatch; +import org.apache.syncope.common.lib.patch.UserPatch; +import org.apache.syncope.common.lib.to.AnyObjectTO; +import org.apache.syncope.common.lib.to.AnyTO; +import org.apache.syncope.common.lib.to.AuditEntryTO; +import org.apache.syncope.common.lib.to.GroupTO; +import org.apache.syncope.common.lib.to.ProvisioningResult; +import org.apache.syncope.common.lib.to.UserTO; +import org.apache.syncope.common.lib.types.AnyTypeKind; +import org.apache.syncope.common.lib.types.AuditElements; +import org.apache.syncope.common.lib.types.ClientExceptionType; +import org.apache.syncope.common.lib.types.StandardEntitlement; +import org.apache.wicket.PageReference; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; +import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn; +import org.apache.wicket.extensions.markup.html.repeater.util.SortParam; +import org.apache.wicket.model.CompoundPropertyModel; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.StringResourceModel; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; + +public class AuditHistoryDirectoryPanel extends + DirectoryPanel<AuditEntryTO, AuditEntryTO, + AuditHistoryDirectoryPanel.AuditHistoryProvider, AuditHistoryRestClient> + implements ModalPanel { + + private static final long serialVersionUID = -8248734710505211261L; + + private static final int TOTAL_AUDIT_HISTORY_COMPARISONS = 25; + + private static final ObjectMapper MAPPER = new ObjectMapper(); + + private final BaseModal<?> baseModal; + + private final MultilevelPanel multiLevelPanelRef; + + private final AnyTO anyTO; + + private final AnyTypeKind anyTypeKind; + + public AuditHistoryDirectoryPanel( + final BaseModal<?> baseModal, + final MultilevelPanel multiLevelPanelRef, + final PageReference pageRef, + final AnyTO anyTO) { + + super(MultilevelPanel.FIRST_LEVEL_ID, pageRef); + disableCheckBoxes(); + + this.baseModal = baseModal; + this.multiLevelPanelRef = multiLevelPanelRef; + this.anyTO = anyTO; + + anyTypeKind = AnyTypeKind.fromTOClass(anyTO.getClass()); + this.restClient = new AuditHistoryRestClient(); + initResultTable(); + } + + /** + * Restore an object based on the audit record. + * <p> + * Note that for user objects, the original audit record masks + * the password and the security answer; so we cannot use the audit + * record to resurrect the entry based on mask data. The method behavior + * below will reset the audit record such that the current security answer + * and the password for the object are always maintained, and such properties + * for the user cannot be restored using audit records. + * + * @param entryBean the entry bean + * @param anyTO the any to + * @return the response + */ + private static ProvisioningResult<? extends AnyTO> restore(final AuditEntryTO entryBean, + final AnyTO anyTO) { + try { + String json = getJSONFromAuditEntry(entryBean); + if (anyTO instanceof UserTO) { + UserTO userTO = MAPPER.readValue(json, UserTO.class); + UserPatch userPatch = AnyOperations.diff(userTO, anyTO, false); + userPatch.setPassword(null); + userPatch.setSecurityAnswer(null); + return new UserRestClient().update(anyTO.getETagValue(), userPatch); + } + if (anyTO instanceof GroupTO) { + GroupTO groupTO = MAPPER.readValue(json, GroupTO.class); + GroupPatch groupPatch = AnyOperations.diff(groupTO, anyTO, false); + return new GroupRestClient().update(anyTO.getETagValue(), groupPatch); + } + if (anyTO instanceof AnyObjectTO) { + AnyObjectTO anyObjectTO = MAPPER.readValue(json, AnyObjectTO.class); + AnyObjectPatch anyObjectPatch = AnyOperations.diff(anyObjectTO, anyTO, false); + return new AnyObjectRestClient().update(anyTO.getETagValue(), anyObjectPatch); + } + } catch (final Exception e) { + LOG.error("Could not restore object for {}", anyTO, e); + } + throw SyncopeClientException.build(ClientExceptionType.InvalidAnyObject); + } + + private static String getJSONFromAuditEntry(final AuditEntryTO entryBean) throws JsonProcessingException { + final String json; + if (entryBean.getBefore() == null) { + json = MAPPER.readTree(entryBean.getOutput()).get("entity").toPrettyString(); + } else { + json = entryBean.getBefore(); + } + return json; + } + + private static SortParam<String> getSortParam() { + return new SortParam<>("event_date", false); + } + + private static AuditElements.Result getQueryableAuditResult() { + return AuditElements.Result.SUCCESS; + } + + private static List<String> getQueryableAuditEvents() { + return Arrays.asList("create", "update"); + } + + @Override + protected AuditHistoryDirectoryPanel.AuditHistoryProvider dataProvider() { + return new AuditHistoryProvider(rows); + } + + @Override + protected String paginatorRowsKey() { + return Constants.PREF_AUDIT_HISTORY_PAGINATOR_ROWS; + } + + @Override + protected List<IColumn<AuditEntryTO, String>> getColumns() { + final List<IColumn<AuditEntryTO, String>> columns = new ArrayList<>(); + columns.add(new PropertyColumn<>( + new StringResourceModel("who", this), "who")); + columns.add(new DatePropertyColumn<>( + new StringResourceModel("date", this), null, "date")); + return columns; + } + + @Override + protected void resultTableCustomChanges( + final AjaxDataTablePanel.Builder<AuditEntryTO, String> resultTableBuilder) { + resultTableBuilder.setMultiLevelPanel(baseModal, multiLevelPanelRef); + } + + @Override + protected ActionsPanel<AuditEntryTO> getActions(final IModel<AuditEntryTO> model) { + final ActionsPanel<AuditEntryTO> panel = super.getActions(model); + final AuditEntryTO auditEntryTO = model.getObject(); + + panel.add(new ActionLink<AuditEntryTO>() { + private static final long serialVersionUID = -6745431735457245600L; + + @Override + public void onClick(final AjaxRequestTarget target, final AuditEntryTO modelObject) { + AuditHistoryDirectoryPanel.this.getTogglePanel().close(target); + viewAuditHistory(modelObject, target); + target.add(modal); + } + }, ActionLink.ActionType.VIEW, StandardEntitlement.AUDIT_READ); + + final String auditRestoreEntitlement; + switch (this.anyTypeKind) { + case USER: + auditRestoreEntitlement = StandardEntitlement.USER_UPDATE; + break; + case GROUP: + auditRestoreEntitlement = StandardEntitlement.GROUP_UPDATE; + break; + default: + auditRestoreEntitlement = StandardEntitlement.ANYTYPE_UPDATE; + break; + } + + panel.add(new ActionLink<AuditEntryTO>() { + + private static final long serialVersionUID = -6745431735457245600L; + + @Override + public void onClick(final AjaxRequestTarget target, final AuditEntryTO modelObject) { + try { + AuditHistoryDirectoryPanel.this.getTogglePanel().close(target); + ProvisioningResult<? extends AnyTO> result = restore(modelObject, anyTO); + anyTO.setLastChangeDate(new Date(Long.parseLong(result.getEntity().getETagValue()))); + target.add(container); + } catch (SyncopeClientException e) { + LOG.error("While restoring {}", anyTypeKind, e); + SyncopeConsoleSession.get().error(StringUtils.isBlank(e.getMessage()) + ? e.getClass().getName() : e.getMessage()); + } + ((BasePage) pageRef.getPage()).getNotificationPanel().refresh(target); + } + }, ActionLink.ActionType.RESTORE, auditRestoreEntitlement); + + return panel; + } + + @Override + protected Collection<ActionLink.ActionType> getBatches() { + return Collections.emptyList(); + } + + private void viewAuditHistory(final AuditEntryTO auditEntryBean, final AjaxRequestTarget target) { + List<AuditEntryTO> search = restClient.search(anyTO.getKey(), + 0, + TOTAL_AUDIT_HISTORY_COMPARISONS, + getSortParam(), + getQueryableAuditEvents(), + getQueryableAuditResult()); + + multiLevelPanelRef.next( + new StringResourceModel("audit.diff.view", this).getObject(), + new HistoryAuditDetails(modal, auditEntryBean, + getPage().getPageReference(), toAuditEntryTOs(search), anyTO, anyTypeKind), target); + } + + private List<AuditEntryTO> toAuditEntryTOs(final List<AuditEntryTO> search) { + return search + .stream() + .map(entry -> { + AuditEntryTO bean = new AuditEntryTO(); + bean.setKey(anyTO.getKey()); + bean.setBefore(entry.getBefore()); + bean.setDate(entry.getDate()); + bean.setEvent(entry.getEvent()); + bean.getInputs().addAll(entry.getInputs()); + bean.setLoggerName(entry.getLoggerName()); + bean.setOutput(entry.getOutput()); + bean.setResult(entry.getResult()); + bean.setSubCategory(entry.getSubCategory()); + bean.setThrowable(entry.getThrowable()); + bean.setWho(entry.getWho()); + return bean; + }) + .collect(Collectors.toList()); + } + + protected class AuditHistoryProvider extends DirectoryDataProvider<AuditEntryTO> { + private static final long serialVersionUID = 415113175628260864L; + + AuditHistoryProvider(final int paginatorRows) { + super(paginatorRows); + } + + @Override + public Iterator<? extends AuditEntryTO> iterator(final long first, final long count) { + return getAuditEntryBeans(first, count).iterator(); + } + + @Override + public long size() { + return restClient.count(anyTO.getKey(), getQueryableAuditEvents(), getQueryableAuditResult()); + } + + @Override + public IModel<AuditEntryTO> model(final AuditEntryTO auditEntryBean) { + return new CompoundPropertyModel<>(auditEntryBean); + } + + private List<AuditEntryTO> getAuditEntryBeans(final long first, final long count) { + int page = (int) first / paginatorRows; + return restClient.search(anyTO.getKey(), + Math.max(page, 0) + 1, + Long.valueOf(count).intValue(), + getSortParam(), + getQueryableAuditEvents(), + getQueryableAuditResult()); + } + } +} diff --git a/client/console/src/main/java/org/apache/syncope/client/console/audit/AuditHistoryModal.java b/client/console/src/main/java/org/apache/syncope/client/console/audit/AuditHistoryModal.java new file mode 100644 index 0000000..6b553f1 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/audit/AuditHistoryModal.java @@ -0,0 +1,54 @@ +/* + * 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 org.apache.syncope.client.console.panels.ModalPanel; +import org.apache.syncope.client.console.panels.MultilevelPanel; +import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal; +import org.apache.syncope.common.lib.to.AnyTO; +import org.apache.wicket.PageReference; +import org.apache.wicket.markup.html.panel.Panel; + +public class AuditHistoryModal<T extends AnyTO> extends Panel implements ModalPanel { + private static final long serialVersionUID = 1066124171682570080L; + + protected final AuditHistoryDirectoryPanel directoryPanel; + + public AuditHistoryModal( + final BaseModal<?> baseModal, + final PageReference pageReference, + final T entity) { + + super(BaseModal.CONTENT_ID); + + final MultilevelPanel mlp = new MultilevelPanel("history"); + mlp.setOutputMarkupId(true); + this.directoryPanel = getDirectoryPanel(mlp, baseModal, pageReference, entity); + add(mlp.setFirstLevel(this.directoryPanel)); + } + + protected AuditHistoryDirectoryPanel getDirectoryPanel( + final MultilevelPanel mlp, + final BaseModal<?> baseModal, + final PageReference pageReference, + final T entity) { + + return new AuditHistoryDirectoryPanel(baseModal, mlp, pageReference, entity); + } +} diff --git a/client/console/src/main/java/org/apache/syncope/client/console/audit/HistoryAuditDetails.java b/client/console/src/main/java/org/apache/syncope/client/console/audit/HistoryAuditDetails.java new file mode 100644 index 0000000..9628a05 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/audit/HistoryAuditDetails.java @@ -0,0 +1,235 @@ +/* + * 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 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.commons.Constants; +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.AjaxDropDownChoicePanel; +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.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; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +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); + } + } +} diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java index e37f8e3..0a2d7b3 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/Constants.java @@ -133,6 +133,8 @@ public final class Constants { public static final String PREF_RESOURCE_STATUS_PAGINATOR_ROWS = "resource.status.paginator.rows"; + public static final String PREF_AUDIT_HISTORY_PAGINATOR_ROWS = "audit.history.paginator.rows"; + public static final String PREF_CONNECTORS_PAGINATOR_ROWS = "connectors.paginator.rows"; public static final String PREF_NOTIFICATION_PAGINATOR_ROWS = "notification.paginator.rows"; diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java index 34eeed5..229af3d 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.java @@ -23,6 +23,7 @@ import java.util.List; import org.apache.commons.lang3.SerializationUtils; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.client.console.SyncopeConsoleSession; +import org.apache.syncope.client.console.audit.AuditHistoryModal; import org.apache.syncope.client.console.commons.Constants; import org.apache.syncope.client.console.notifications.NotificationTasks; import org.apache.syncope.client.console.pages.BasePage; @@ -188,7 +189,27 @@ public class AnyObjectDirectoryPanel extends AnyDirectoryPanel<AnyObjectTO, AnyO } }, ActionType.NOTIFICATION_TASKS, StandardEntitlement.TASK_LIST); } + panel.add(new ActionLink<AnyObjectTO>() { + private static final long serialVersionUID = -2878723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target, final AnyObjectTO ignore) { + IModel<AnyWrapper<AnyObjectTO>> formModel = new CompoundPropertyModel<>( + new AnyWrapper<>(new AnyObjectRestClient().read(model.getObject().getKey()))); + altDefaultModal.setFormModel(formModel); + target.add(altDefaultModal.setContent(new AuditHistoryModal<>( + altDefaultModal, + pageRef, + formModel.getObject().getInnerObject()))); + + altDefaultModal.header(new StringResourceModel("auditHistory.title", model)); + + altDefaultModal.show(true); + } + }, ActionType.VIEW_AUDIT_HISTORY, StandardEntitlement.AUDIT_LIST). + setRealms(realm, model.getObject().getDynRealms()); + panel.add(new ActionLink<AnyObjectTO>() { private static final long serialVersionUID = -7978723352517770646L; @@ -212,7 +233,7 @@ public class AnyObjectDirectoryPanel extends AnyDirectoryPanel<AnyObjectTO, AnyO return realm.startsWith(SyncopeConstants.ROOT_REALM); } }, ActionType.DELETE, AnyEntitlement.DELETE.getFor(type), true).setRealm(realm); - + return panel; } diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java index e7026c2..2556820 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/GroupDirectoryPanel.java @@ -25,6 +25,7 @@ import org.apache.commons.lang3.SerializationUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.apache.syncope.client.console.SyncopeConsoleSession; +import org.apache.syncope.client.console.audit.AuditHistoryModal; import org.apache.syncope.client.console.commons.Constants; import org.apache.syncope.client.console.layout.FormLayoutInfoUtils; import org.apache.syncope.client.console.notifications.NotificationTasks; @@ -363,6 +364,26 @@ public class GroupDirectoryPanel extends AnyDirectoryPanel<GroupTO, GroupRestCli }, ActionType.NOTIFICATION_TASKS, StandardEntitlement.TASK_LIST); panel.add(new ActionLink<GroupTO>() { + private static final long serialVersionUID = -2878723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target, final GroupTO ignore) { + IModel<GroupWrapper> formModel = new CompoundPropertyModel<>( + new GroupWrapper(new GroupRestClient().read(model.getObject().getKey()))); + target.add(altDefaultModal.setContent(new AuditHistoryModal<>( + altDefaultModal, + pageRef, + formModel.getObject().getInnerObject()))); + + altDefaultModal.header(new Model<>( + getString("auditHistory.title", new Model<>(new AnyWrapper<>(model.getObject()))))); + + altDefaultModal.show(true); + } + }, ActionType.VIEW_AUDIT_HISTORY, StandardEntitlement.AUDIT_LIST). + setRealms(realm, model.getObject().getDynRealms()); + + panel.add(new ActionLink<GroupTO>() { private static final long serialVersionUID = -7978723352517770644L; diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java index 18db27c..d36afbd 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserDirectoryPanel.java @@ -26,6 +26,7 @@ import java.util.List; import org.apache.commons.lang3.SerializationUtils; import org.apache.commons.lang3.StringUtils; import org.apache.syncope.client.console.SyncopeConsoleSession; +import org.apache.syncope.client.console.audit.AuditHistoryModal; import org.apache.syncope.client.console.commons.Constants; import org.apache.syncope.client.console.notifications.NotificationTasks; import org.apache.syncope.client.console.pages.BasePage; @@ -144,7 +145,7 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient @Override public ActionsPanel<UserTO> getActions(final IModel<UserTO> model) { final ActionsPanel<UserTO> panel = super.getActions(model); - + panel.add(new ActionLink<UserTO>() { private static final long serialVersionUID = -7978723352517770644L; @@ -350,6 +351,27 @@ public class UserDirectoryPanel extends AnyDirectoryPanel<UserTO, UserRestClient panel.add(new ActionLink<UserTO>() { + private static final long serialVersionUID = -1978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target, final UserTO ignore) { + IModel<UserWrapper> formModel = new CompoundPropertyModel<>( + new UserWrapper(new UserRestClient().read(model.getObject().getKey()))); + target.add(altDefaultModal.setContent(new AuditHistoryModal<>( + altDefaultModal, + pageRef, + formModel.getObject().getInnerObject()))); + + altDefaultModal.header(new Model<>( + getString("auditHistory.title", new Model<>(new AnyWrapper<>(model.getObject()))))); + + altDefaultModal.show(true); + } + }, ActionType.VIEW_AUDIT_HISTORY, StandardEntitlement.AUDIT_LIST). + setRealms(realm, model.getObject().getDynRealms()); + + panel.add(new ActionLink<UserTO>() { + private static final long serialVersionUID = -7978723352517770644L; @Override diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/AuditHistoryRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/AuditHistoryRestClient.java new file mode 100644 index 0000000..fd3da6a --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/AuditHistoryRestClient.java @@ -0,0 +1,58 @@ +/* + * 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.rest; + +import org.apache.syncope.common.lib.to.AuditEntryTO; +import org.apache.syncope.common.lib.types.AuditElements; +import org.apache.syncope.common.rest.api.beans.AuditQuery; +import org.apache.syncope.common.rest.api.service.AuditService; +import org.apache.wicket.extensions.markup.html.repeater.util.SortParam; + +import java.util.List; + +public class AuditHistoryRestClient extends BaseRestClient { + private static final long serialVersionUID = -381814125643246243L; + + public List<AuditEntryTO> search(final String key, + final int page, + final int size, + final SortParam<String> sort, + final List<String> events, + final AuditElements.Result result) { + AuditQuery query = new AuditQuery.Builder(key) + .size(size) + .page(page) + .events(events) + .result(result) + .orderBy(toOrderBy(sort)) + .build(); + return getService(AuditService.class).search(query).getResult(); + } + + public int count(final String key, + final List<String> events, + final AuditElements.Result result) { + AuditQuery query = new AuditQuery.Builder(key) + .events(events) + .result(result) + .build(); + return getService(AuditService.class).search(query).getTotalCount(); + } +} + diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java index d8dfba0..67afe12 100644 --- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/ActionLink.java @@ -104,6 +104,7 @@ public abstract class ActionLink<T extends Serializable> implements Serializable VIEW_DETAILS("read"), MANAGE_APPROVAL("edit"), EDIT_APPROVAL("edit"), + VIEW_AUDIT_HISTORY("read"), EXTERNAL_EDITOR("externalEditor"); private final String actionId; diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/audit/AuditHistoryModal.html b/client/console/src/main/resources/org/apache/syncope/client/console/audit/AuditHistoryModal.html new file mode 100644 index 0000000..48c38ea --- /dev/null +++ b/client/console/src/main/resources/org/apache/syncope/client/console/audit/AuditHistoryModal.html @@ -0,0 +1,26 @@ +<!-- +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. +--> +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org"> +<wicket:panel> + <div class="panel-group box-group"> + <wicket:child/> + </div> + <span wicket:id="history">[History]</span> +</wicket:panel> +</html> diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/audit/AuditHistoryModal.properties similarity index 89% copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties copy to client/console/src/main/resources/org/apache/syncope/client/console/audit/AuditHistoryModal.properties index 07164b4..e2abe89 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/audit/AuditHistoryModal.properties @@ -14,5 +14,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -any.edit=Edit ${anyTO.type} ${anyTO.name} -group.members=${right} members of ${left.name} +who=Who +date=Date +audit.diff.view=Configuration diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/audit/AuditHistoryModal_it.properties similarity index 89% copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties copy to client/console/src/main/resources/org/apache/syncope/client/console/audit/AuditHistoryModal_it.properties index 07164b4..e2abe89 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/audit/AuditHistoryModal_it.properties @@ -14,5 +14,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -any.edit=Edit ${anyTO.type} ${anyTO.name} -group.members=${right} members of ${left.name} +who=Who +date=Date +audit.diff.view=Configuration diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/audit/AuditHistoryModal_ja.properties similarity index 89% copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties copy to client/console/src/main/resources/org/apache/syncope/client/console/audit/AuditHistoryModal_ja.properties index 07164b4..e2abe89 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/audit/AuditHistoryModal_ja.properties @@ -14,5 +14,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -any.edit=Edit ${anyTO.type} ${anyTO.name} -group.members=${right} members of ${left.name} +who=Who +date=Date +audit.diff.view=Configuration diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/audit/AuditHistoryModal_pt_BR.properties similarity index 89% copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties copy to client/console/src/main/resources/org/apache/syncope/client/console/audit/AuditHistoryModal_pt_BR.properties index 07164b4..e2abe89 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/audit/AuditHistoryModal_pt_BR.properties @@ -14,5 +14,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -any.edit=Edit ${anyTO.type} ${anyTO.name} -group.members=${right} members of ${left.name} +who=Who +date=Date +audit.diff.view=Configuration diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/audit/AuditHistoryModal_ru.properties similarity index 89% copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties copy to client/console/src/main/resources/org/apache/syncope/client/console/audit/AuditHistoryModal_ru.properties index 07164b4..e2abe89 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/audit/AuditHistoryModal_ru.properties @@ -14,5 +14,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -any.edit=Edit ${anyTO.type} ${anyTO.name} -group.members=${right} members of ${left.name} +who=Who +date=Date +audit.diff.view=Configuration diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/audit/HistoryAuditDetails.html b/client/console/src/main/resources/org/apache/syncope/client/console/audit/HistoryAuditDetails.html new file mode 100644 index 0000000..da89934 --- /dev/null +++ b/client/console/src/main/resources/org/apache/syncope/client/console/audit/HistoryAuditDetails.html @@ -0,0 +1,29 @@ +<!-- +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. +--> +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org"> + <wicket:panel> + + <form wicket:id="form"> + <span wicket:id="compareDropdown"></span> + </form> + + <div wicket:id="content"></div> + + </wicket:panel> +</html> diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/audit/HistoryAuditDetails.properties similarity index 89% copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties copy to client/console/src/main/resources/org/apache/syncope/client/console/audit/HistoryAuditDetails.properties index 07164b4..b1406fe 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/audit/HistoryAuditDetails.properties @@ -14,5 +14,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -any.edit=Edit ${anyTO.type} ${anyTO.name} -group.members=${right} members of ${left.name} +history.view=History view +compare=Compare with +current=Current diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/audit/HistoryAuditDetails_it.properties similarity index 89% copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties copy to client/console/src/main/resources/org/apache/syncope/client/console/audit/HistoryAuditDetails_it.properties index 07164b4..e128bca 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/audit/HistoryAuditDetails_it.properties @@ -14,5 +14,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -any.edit=Edit ${anyTO.type} ${anyTO.name} -group.members=${right} members of ${left.name} +history.view=Storico vista +compare=paragonare con +current=presente diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/audit/HistoryAuditDetails_ja.properties similarity index 89% copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties copy to client/console/src/main/resources/org/apache/syncope/client/console/audit/HistoryAuditDetails_ja.properties index 07164b4..b1406fe 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/audit/HistoryAuditDetails_ja.properties @@ -14,5 +14,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -any.edit=Edit ${anyTO.type} ${anyTO.name} -group.members=${right} members of ${left.name} +history.view=History view +compare=Compare with +current=Current diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/audit/HistoryAuditDetails_pt_BR.properties similarity index 89% copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties copy to client/console/src/main/resources/org/apache/syncope/client/console/audit/HistoryAuditDetails_pt_BR.properties index 07164b4..b1406fe 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/audit/HistoryAuditDetails_pt_BR.properties @@ -14,5 +14,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -any.edit=Edit ${anyTO.type} ${anyTO.name} -group.members=${right} members of ${left.name} +history.view=History view +compare=Compare with +current=Current diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/audit/HistoryAuditDetails_ru.properties similarity index 89% copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties copy to client/console/src/main/resources/org/apache/syncope/client/console/audit/HistoryAuditDetails_ru.properties index 07164b4..b1406fe 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/audit/HistoryAuditDetails_ru.properties @@ -14,5 +14,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -any.edit=Edit ${anyTO.type} ${anyTO.name} -group.members=${right} members of ${left.name} +history.view=History view +compare=Compare with +current=Current diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.properties similarity index 89% copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties copy to client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.properties index 07164b4..441f190 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel.properties @@ -14,5 +14,4 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -any.edit=Edit ${anyTO.type} ${anyTO.name} -group.members=${right} members of ${left.name} +auditHistory.title=${type} ${name} history diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel_it.properties similarity index 89% copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties copy to client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel_it.properties index 07164b4..441f190 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel_it.properties @@ -14,5 +14,4 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -any.edit=Edit ${anyTO.type} ${anyTO.name} -group.members=${right} members of ${left.name} +auditHistory.title=${type} ${name} history diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel_ja.properties similarity index 89% copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties copy to client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel_ja.properties index 07164b4..441f190 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel_ja.properties @@ -14,5 +14,4 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -any.edit=Edit ${anyTO.type} ${anyTO.name} -group.members=${right} members of ${left.name} +auditHistory.title=${type} ${name} history diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel_pt_BR.properties similarity index 89% copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties copy to client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel_pt_BR.properties index 07164b4..441f190 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel_pt_BR.properties @@ -14,5 +14,4 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -any.edit=Edit ${anyTO.type} ${anyTO.name} -group.members=${right} members of ${left.name} +auditHistory.title=${type} ${name} history diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel_ru.properties similarity index 89% copy from client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties copy to client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel_ru.properties index 07164b4..441f190 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/AnyObjectDirectoryPanel_ru.properties @@ -14,5 +14,4 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -any.edit=Edit ${anyTO.type} ${anyTO.name} -group.members=${right} members of ${left.name} +auditHistory.title=${type} ${name} history diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties index 07164b4..7c1cb8c 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel.properties @@ -16,3 +16,4 @@ # under the License. any.edit=Edit ${anyTO.type} ${anyTO.name} group.members=${right} members of ${left.name} +auditHistory.title=${anyTO.type} ${anyTO.name} history diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_it.properties index bd97397..8566276 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_it.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_it.properties @@ -16,3 +16,4 @@ # under the License. any.edit=Modifica ${anyTO.type} ${anyTO.name} group.members=Membri ${right} di '${left.name}' +auditHistory.title=${anyTO.type} ${anyTO.name} history diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_ja.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_ja.properties index 0267d65..2f0982a 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_ja.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_ja.properties @@ -16,3 +16,4 @@ # under the License. any.edit=${anyTO.type} ${anyTO.name} \u3092\u7de8\u96c6 group.members=${left.name} \u306e ${right} \u30e1\u30f3\u30d0\u30fc +auditHistory.title=${anyTO.type} ${anyTO.name} history diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_pt_BR.properties index 9fb316d..b5730e2 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_pt_BR.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_pt_BR.properties @@ -16,3 +16,4 @@ # under the License. any.edit=Alterar ${anyTO.type} ${anyTO.name} group.members=${right} members of ${left.name} +auditHistory.title=${anyTO.type} ${anyTO.name} history diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_ru.properties index 94a1bd9..84e3f7b 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_ru.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/GroupDirectoryPanel_ru.properties @@ -17,3 +17,4 @@ # any.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c ${anyTO.type} ${anyTO.name} group.members=${right} \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0438 ${left.name} +auditHistory.title=${anyTO.type} ${anyTO.name} history diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties index 6acf5db..1d4db0d 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel.properties @@ -18,3 +18,4 @@ any.edit=Edit ${anyTO.type} ${anyTO.username} any.propagation.tasks=Propagation tasks for ${type} ${username} any.notification.tasks=Notification tasks for ${type} ${username} linkedAccounts.title=Manage user accounts +auditHistory.title=${anyTO.type} ${anyTO.username} history diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_it.properties index 38fa14d..ef6c91a 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_it.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_it.properties @@ -18,3 +18,4 @@ any.edit=Modifica ${anyTO.type} ${anyTO.username} any.propagation.tasks=Task di propagazione per ${type} ${username} any.notification.tasks=Task di notifica per ${type} ${username} linkedAccounts.title=Gestisci account utente +auditHistory.title=${anyTO.type} ${anyTO.username} history diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ja.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ja.properties index 9107368..a2193e2 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ja.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ja.properties @@ -18,3 +18,4 @@ any.edit=${anyTO.type} ${anyTO.username} \u3092\u7de8\u96c6 any.propagation.tasks=${type} ${username} \u306e\u4f1d\u64ad\u30bf\u30b9\u30af any.notification.tasks=${type} ${username} \u306e\u901a\u77e5\u30bf\u30b9\u30af linkedAccounts.title=\u30e6\u30fc\u30b6\u30fc\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u7ba1\u7406\u3059\u308b +auditHistory.title=${anyTO.type} ${anyTO.username} history diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_pt_BR.properties index 865e74d..84d5d86 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_pt_BR.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_pt_BR.properties @@ -18,3 +18,4 @@ any.edit=Alterar ${anyTO.type} ${anyTO.username} any.propagation.tasks=Propagation tasks for ${type} ${username} any.notification.tasks=Notification tasks for ${type} ${username} linkedAccounts.title=Gerenciar contas de usu\u00e1rio +auditHistory.title=${anyTO.type} ${anyTO.username} history diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ru.properties index 53e0e86..378c49a 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ru.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/UserDirectoryPanel_ru.properties @@ -19,3 +19,4 @@ any.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c ${anyTO.type} ${anyTO. any.propagation.tasks=\u0417\u0430\u0434\u0430\u0447\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0434\u043b\u044f ${type} ${username} any.notification.tasks=\u0417\u0430\u0434\u0430\u0447\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 \u0434\u043b\u044f ${type} ${username} linkedAccounts.title=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0443\u0447\u0435\u0442\u043d\u044b\u043c\u0438 \u0437\u0430\u043f\u0438\u0441\u044f\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 +auditHistory.title=${anyTO.type} ${anyTO.username} history diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel.properties index 333adca..be4d4d1 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel.properties @@ -280,3 +280,7 @@ manage_accounts.alt=manage accounts icon workflow_modeler.class=fa fa-picture-o workflow_modeler.title=workflow modeler workflow_modeler.alt=workflow modeler icon + +view_audit_history.class=fa fa-history +view_audit_history.title=history management +view_audit_history.alt=history management icon diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_it.properties index 760b241..fe1457a 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_it.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_it.properties @@ -275,3 +275,7 @@ reconciliation_pull.alt=reconciliation pull icon manage_accounts.class=fa fa-users manage_accounts.title=gestisci account manage_accounts.alt=manage accounts icon + +view_audit_history.class=fa fa-history +view_audit_history.title=storico modifiche +view_audit_history.alt=storico modifiche icon diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ja.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ja.properties index e2c053a..e23c35e 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ja.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ja.properties @@ -277,3 +277,7 @@ reconciliation_pull.alt=\u7167\u5408\u30d7\u30eb icon manage_accounts.class=fa fa-users manage_accounts.title=\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u7ba1\u7406\u3059\u308b manage_accounts.alt=\u30a2\u30ab\u30a6\u30f3\u30c8\u7ba1\u7406\u30a2\u30a4\u30b3\u30f3 + +view_audit_history.class=fa fa-history +view_audit_history.title=history management +view_audit_history.alt=history management icon diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_pt_BR.properties index 184d6b7..9ca5a2a 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_pt_BR.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_pt_BR.properties @@ -282,3 +282,7 @@ reconciliation_pull.alt=reconciliation pull icon manage_accounts.class=fa fa-users manage_accounts.title=manage accounts manage_accounts.alt=manage accounts icon + +view_audit_history.class=fa fa-history +view_audit_history.title=history management +view_audit_history.alt=history management icon diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ru.properties index d3ef6cc..e3ac79b 100644 --- a/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ru.properties +++ b/client/console/src/main/resources/org/apache/syncope/client/console/wicket/markup/html/form/ActionsPanel_ru.properties @@ -276,3 +276,7 @@ reconciliation_pull.alt=reconciliation pull icon manage_accounts.class=fa fa-users manage_accounts.title=manage accounts manage_accounts.alt=manage accounts icon + +view_audit_history.class=fa fa-history +view_audit_history.title=history management +view_audit_history.alt=history management icon diff --git a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml index d94cc30..5469e67 100644 --- a/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml +++ b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml @@ -2410,6 +2410,25 @@ $$ } <SyncopeLogger logName="syncope.audit.[LOGIC]:[SyncopeLogic]:[]:[isSelfRegAllowed]:[SUCCESS]" logLevel="DEBUG" logType="AUDIT"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[assign]:[FAILURE]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[assign]:[SUCCESS]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[create]:[FAILURE]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[create]:[SUCCESS]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[delete]:[FAILURE]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[delete]:[SUCCESS]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[deprovision]:[FAILURE]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[deprovision]:[SUCCESS]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[link]:[FAILURE]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[link]:[SUCCESS]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[provision]:[FAILURE]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[provision]:[SUCCESS]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[unassign]:[FAILURE]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[unassign]:[SUCCESS]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[unlink]:[FAILURE]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[unlink]:[SUCCESS]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[update]:[FAILURE]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[update]:[SUCCESS]" LOGLEVEL="DEBUG"/> + <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[assign]:[FAILURE]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[assign]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[confirmPasswordReset]:[FAILURE]" logLevel="DEBUG"/> @@ -2426,12 +2445,8 @@ $$ } <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[mustChangePassword]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[provision]:[FAILURE]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[provision]:[SUCCESS]" logLevel="DEBUG"/> - <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[read]:[FAILURE]" logLevel="DEBUG"/> - <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[read]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[requestPasswordReset]:[FAILURE]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[requestPasswordReset]:[SUCCESS]" logLevel="DEBUG"/> - <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[search]:[FAILURE]" logLevel="DEBUG"/> - <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[search]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[selfCreate]:[FAILURE]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[selfCreate]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[selfDelete]:[FAILURE]" logLevel="DEBUG"/> @@ -2459,8 +2474,6 @@ $$ } <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[GroupLogic]:[]:[own]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[GroupLogic]:[]:[provisionMembers]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[GroupLogic]:[]:[provision]:[SUCCESS]" logLevel="DEBUG"/> - <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[GroupLogic]:[]:[read]:[SUCCESS]" logLevel="DEBUG"/> - <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[GroupLogic]:[]:[search]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[GroupLogic]:[]:[unassign]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[GroupLogic]:[]:[unlink]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[GroupLogic]:[]:[update]:[SUCCESS]" logLevel="DEBUG"/> diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml index 76000f1..b04b552 100644 --- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml +++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml @@ -2561,7 +2561,26 @@ $$ } <SecurityQuestion id="887028ea-66fc-41e7-b397-620d7ea6dfbb" content="What's your mother's maiden name?"/> <SyncopeLogger logName="syncope.audit.[LOGIC]:[SyncopeLogic]:[]:[isSelfRegAllowed]:[SUCCESS]" logLevel="DEBUG" logType="AUDIT"/> - + + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[assign]:[FAILURE]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[assign]:[SUCCESS]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[create]:[FAILURE]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[create]:[SUCCESS]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[delete]:[FAILURE]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[delete]:[SUCCESS]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[deprovision]:[FAILURE]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[deprovision]:[SUCCESS]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[link]:[FAILURE]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[link]:[SUCCESS]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[provision]:[FAILURE]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[provision]:[SUCCESS]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[unassign]:[FAILURE]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[unassign]:[SUCCESS]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[unlink]:[FAILURE]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[unlink]:[SUCCESS]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[update]:[FAILURE]" LOGLEVEL="DEBUG"/> + <SYNCOPELOGGER LOGTYPE="AUDIT" LOGNAME="syncope.audit.[LOGIC]:[AnyObjectLogic]:[]:[update]:[SUCCESS]" LOGLEVEL="DEBUG"/> + <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[assign]:[FAILURE]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[assign]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[confirmPasswordReset]:[FAILURE]" logLevel="DEBUG"/> @@ -2578,12 +2597,8 @@ $$ } <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[mustChangePassword]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[provision]:[FAILURE]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[provision]:[SUCCESS]" logLevel="DEBUG"/> - <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[read]:[FAILURE]" logLevel="DEBUG"/> - <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[read]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[requestPasswordReset]:[FAILURE]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[requestPasswordReset]:[SUCCESS]" logLevel="DEBUG"/> - <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[search]:[FAILURE]" logLevel="DEBUG"/> - <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[search]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[selfCreate]:[FAILURE]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[selfCreate]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[UserLogic]:[]:[selfDelete]:[FAILURE]" logLevel="DEBUG"/> @@ -2611,8 +2626,6 @@ $$ } <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[GroupLogic]:[]:[own]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[GroupLogic]:[]:[provisionMembers]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[GroupLogic]:[]:[provision]:[SUCCESS]" logLevel="DEBUG"/> - <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[GroupLogic]:[]:[read]:[SUCCESS]" logLevel="DEBUG"/> - <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[GroupLogic]:[]:[search]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[GroupLogic]:[]:[unassign]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[GroupLogic]:[]:[unlink]:[SUCCESS]" logLevel="DEBUG"/> <SyncopeLogger logType="AUDIT" logName="syncope.audit.[LOGIC]:[GroupLogic]:[]:[update]:[SUCCESS]" logLevel="DEBUG"/> diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/POJOHelper.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/POJOHelper.java index af99906..c7b8faa 100644 --- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/POJOHelper.java +++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/serialization/POJOHelper.java @@ -64,6 +64,18 @@ public final class POJOHelper { return result; } + public static String serializeWithDefaultPrettyPrinter(final Object object) { + String result = null; + + try { + result = MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(object); + } catch (Exception e) { + LOG.error("During serialization", e); + } + + return result; + } + public static <T extends Object> T deserialize(final String serialized, final Class<T> reference) { T result = null; diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAuditManager.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAuditManager.java index d5b9df6..374c717 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAuditManager.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultAuditManager.java @@ -35,6 +35,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; +import java.util.Date; + @Transactional(readOnly = true) public class DefaultAuditManager implements AuditManager { @@ -52,6 +54,7 @@ public class DefaultAuditManager implements AuditManager { AuditEntry auditEntry = AuditEntryImpl.builder(). who(who). logger(new AuditLoggerName(type, category, subcategory, event, Result.SUCCESS)). + date(new Date()). build(); org.apache.syncope.core.persistence.api.entity.Logger syncopeLogger = loggerDAO.find(auditEntry.getLogger().toLoggerName()); @@ -64,6 +67,7 @@ public class DefaultAuditManager implements AuditManager { auditEntry = AuditEntryImpl.builder() .who(who) .logger(new AuditLoggerName(type, category, subcategory, event, Result.FAILURE)) + .date(new Date()) .build(); syncopeLogger = loggerDAO.find(auditEntry.getLogger().toLoggerName()); auditRequested = syncopeLogger != null && syncopeLogger.getLevel() == LoggerLevel.DEBUG; @@ -110,6 +114,7 @@ public class DefaultAuditManager implements AuditManager { before(before). output(throwable == null ? output : throwable.getMessage()). input(input). + date(new Date()). build(); org.apache.syncope.core.persistence.api.entity.Logger syncopeLogger = diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AuditDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AuditDataBinderImpl.java index de49702..4937503 100644 --- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AuditDataBinderImpl.java +++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AuditDataBinderImpl.java @@ -47,18 +47,18 @@ public class AuditDataBinderImpl implements AuditDataBinder { } if (auditEntry.getBefore() != null) { - auditEntryTO.setBefore(POJOHelper.serialize(auditEntry.getBefore())); + auditEntryTO.setBefore(POJOHelper.serializeWithDefaultPrettyPrinter(auditEntry.getBefore())); } if (auditEntry.getInput() != null) { auditEntryTO.getInputs().addAll(Arrays.stream(auditEntry.getInput()). filter(Objects::nonNull). - map(POJOHelper::serialize). + map(POJOHelper::serializeWithDefaultPrettyPrinter). collect(Collectors.toList())); } if (auditEntry.getOutput() != null) { - auditEntryTO.setOutput(POJOHelper.serialize(auditEntry.getOutput())); + auditEntryTO.setOutput(POJOHelper.serializeWithDefaultPrettyPrinter(auditEntry.getOutput())); } return auditEntryTO; diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuditITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuditITCase.java index 3b8b995..f4f075b 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuditITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/AuditITCase.java @@ -18,23 +18,33 @@ */ package org.apache.syncope.fit.core; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.Collections; import java.util.List; + +import org.apache.syncope.client.lib.SyncopeClient; +import org.apache.syncope.common.lib.SyncopeConstants; +import org.apache.syncope.common.lib.to.AnyObjectTO; import org.apache.syncope.common.lib.to.AuditEntryTO; import org.apache.syncope.common.lib.to.GroupTO; +import org.apache.syncope.common.lib.to.PagedResult; import org.apache.syncope.common.lib.to.UserTO; import org.apache.syncope.common.lib.types.AuditElements; +import org.apache.syncope.common.rest.api.beans.AnyQuery; import org.apache.syncope.common.rest.api.beans.AuditQuery; import org.apache.syncope.fit.AbstractITCase; import org.junit.jupiter.api.Test; public class AuditITCase extends AbstractITCase { + private static final int MAX_WAIT_SECONDS = 30; - private AuditEntryTO query(final AuditQuery query, final int maxWaitSeconds) { + private static AuditEntryTO query(final AuditQuery query, final int maxWaitSeconds, final boolean failIfEmpty) { int i = 0; List<AuditEntryTO> results = Collections.emptyList(); do { @@ -48,20 +58,40 @@ public class AuditITCase extends AbstractITCase { i++; } while (results.isEmpty() && i < maxWaitSeconds); if (results.isEmpty()) { - fail("Timeout when executing query for key " + query.getEntityKey()); + if (failIfEmpty) { + fail("Timeout when executing query for key " + query.getEntityKey()); + } + return null; } return results.get(0); } @Test + public void userReadAndSearchYieldsNoAudit() { + PagedResult<UserTO> users = userService.search( + new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).page(1).size(2).build()); + assertNotNull(users); + assertFalse(users.getResult().isEmpty()); + + for (UserTO user : users.getResult()) { + assertNotNull(userService.read(user.getKey())); + } + for (UserTO user : users.getResult()) { + AuditQuery query = new AuditQuery.Builder(user.getKey()).build(); + AuditEntryTO entry = query(query, MAX_WAIT_SECONDS, false); + assertNull(entry); + } + } + + @Test public void findByUser() { UserTO userTO = createUser(UserITCase.getUniqueSampleTO("au...@syncope.org")).getEntity(); assertNotNull(userTO.getKey()); AuditQuery query = new AuditQuery.Builder(userTO.getKey()).orderBy("event_date desc"). page(1).size(1).build(); - AuditEntryTO entry = query(query, 50); + AuditEntryTO entry = query(query, MAX_WAIT_SECONDS, true); assertEquals(userTO.getKey(), entry.getKey()); userService.delete(userTO.getKey()); } @@ -80,7 +110,7 @@ public class AuditITCase extends AbstractITCase { event("create"). result(AuditElements.Result.SUCCESS). build(); - AuditEntryTO entry = query(query, 50); + AuditEntryTO entry = query(query, MAX_WAIT_SECONDS, true); assertEquals(userTO.getKey(), entry.getKey()); userService.delete(userTO.getKey()); } @@ -92,8 +122,50 @@ public class AuditITCase extends AbstractITCase { AuditQuery query = new AuditQuery.Builder(groupTO.getKey()).orderBy("event_date desc"). page(1).size(1).build(); - AuditEntryTO entry = query(query, 50); + AuditEntryTO entry = query(query, MAX_WAIT_SECONDS, true); assertEquals(groupTO.getKey(), entry.getKey()); groupService.delete(groupTO.getKey()); } + + @Test + public void groupReadAndSearchYieldsNoAudit() { + PagedResult<GroupTO> groups = groupService.search( + new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM).build()); + assertNotNull(groups); + assertFalse(groups.getResult().isEmpty()); + for (GroupTO groupTO : groups.getResult()) { + assertNotNull(groupService.read(groupTO.getKey())); + } + for (GroupTO groupTO : groups.getResult()) { + AuditQuery query = new AuditQuery.Builder(groupTO.getKey()).build(); + AuditEntryTO entry = query(query, MAX_WAIT_SECONDS, false); + assertNull(entry); + } + } + + @Test + public void findByAnyObject() { + AnyObjectTO anyObjectTO = createAnyObject(AnyObjectITCase.getSampleTO("Italy")).getEntity(); + assertNotNull(anyObjectTO.getKey()); + AuditQuery query = new AuditQuery.Builder(anyObjectTO.getKey()).orderBy("event_date desc"). + page(1).size(1).build(); + AuditEntryTO entry = query(query, MAX_WAIT_SECONDS, true); + assertEquals(anyObjectTO.getKey(), entry.getKey()); + anyObjectService.delete(anyObjectTO.getKey()); + } + + @Test + public void anyObjectReadAndSearchYieldsNoAudit() { + PagedResult<AnyObjectTO> anyObjects = anyObjectService.search( + new AnyQuery.Builder().realm(SyncopeConstants.ROOT_REALM). + fiql(SyncopeClient.getAnyObjectSearchConditionBuilder(getUUIDString()).query()). + build()); + assertNotNull(anyObjects); + assertTrue(anyObjects.getResult().isEmpty()); + for (AnyObjectTO anyObjectTO : anyObjects.getResult()) { + AuditQuery query = new AuditQuery.Builder(anyObjectTO.getKey()).build(); + AuditEntryTO entry = query(query, MAX_WAIT_SECONDS, false); + assertNull(entry); + } + } }