diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java index a07aaf1154d..6f8b21c7538 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/gui/api/page/PageBase.java @@ -553,11 +553,17 @@ public void showMainPopup(AjaxRequestTarget target) { getMainPopup().show(target); } - public void hideMainPopup(AjaxRequestTarget target) { - getMainPopup().close(target); - } + public void showMainPopup(Component body, IModel title, AjaxRequestTarget target) { + setMainPopupContent(body); + setMainPopupTitle(title); + showMainPopup(target); + } + + public void hideMainPopup(AjaxRequestTarget target) { + getMainPopup().close(target); + } - private VisibleEnableBehaviour createUserStatusBehaviour(final boolean visibleIfLoggedIn) { + private VisibleEnableBehaviour createUserStatusBehaviour(final boolean visibleIfLoggedIn) { return new VisibleEnableBehaviour() { @Override @@ -698,6 +704,7 @@ public void showResult(OperationResult result, String errorMessageKey, boolean s } + protected String createComponentPath(String... components) { return StringUtils.join(components, ":"); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentTablePanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentTablePanel.html index 38a69b95673..64fb8b609b2 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentTablePanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentTablePanel.html @@ -19,7 +19,6 @@
-
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentTablePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentTablePanel.java index a22c66c4299..47f90b45174 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentTablePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/assignment/AssignmentTablePanel.java @@ -34,6 +34,7 @@ import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.web.component.dialog.ConfirmationDialog; +import com.evolveum.midpoint.web.component.dialog.ConfirmationPanel; import com.evolveum.midpoint.web.component.menu.cog.InlineMenu; import com.evolveum.midpoint.web.component.menu.cog.InlineMenuItem; import com.evolveum.midpoint.web.component.menu.cog.InlineMenuItemAction; @@ -41,6 +42,7 @@ import com.evolveum.midpoint.web.page.admin.users.dto.UserDtoStatus; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; +import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox; import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; @@ -77,8 +79,6 @@ public class AssignmentTablePanel extends BasePanel getUserDefinition() { }; AssignableSelectionPage.prepareDialog(assignWindow, assignableSelectionContext, this, "AssignmentTablePanel.modal.title.selectAssignment", ID_ASSIGNMENTS); add(assignWindow); - - ModalWindow deleteDialog = new ConfirmationDialog(ID_MODAL_DELETE_ASSIGNMENT, - createStringResource("AssignmentTablePanel.modal.title.confirmDeletion"), - new AbstractReadOnlyModel() { - - @Override - public String getObject() { - return createStringResource("AssignmentTablePanel.modal.message.delete", - getSelectedAssignments().size()).getString(); - } - }) { - - @Override - public void yesPerformed(AjaxRequestTarget target) { - close(target); - deleteAssignmentConfirmedPerformed(target, getSelectedAssignments()); - } - }; - add(deleteDialog); } private List createAssignmentMenu() { @@ -329,7 +310,11 @@ private void showModalWindow(String id, AjaxRequestTarget target) { window.show(target); } - private void showAssignablePopupPerformed(AjaxRequestTarget target, Class type, + protected void showModalWindow(Component body, IModel title, AjaxRequestTarget target) { + getPageBase().showMainPopup(body, title, target); + } + + private void showAssignablePopupPerformed(AjaxRequestTarget target, Class type, QName searchParameter) { assignableSelectionContext.setType(type); assignableSelectionContext.setSearchParameter(searchParameter); @@ -350,9 +335,31 @@ private void deleteAssignmentPerformed(AjaxRequestTarget target) { return; } - showModalWindow(ID_MODAL_DELETE_ASSIGNMENT, target); + showModalWindow(getDeleteAssignmentPopupContent(), createStringResource("AssignmentTablePanel.modal.title.confirmDeletion"), target); } + private Component getDeleteAssignmentPopupContent(){ + return new ConfirmationPanel(getPageBase().getMainPopupBodyId(), + new AbstractReadOnlyModel() { + + @Override + public String getObject() { + return createStringResource("AssignmentTablePanel.modal.message.delete", + getSelectedAssignments().size()).getString(); + } + }) { + + @Override + public void yesPerformed(AjaxRequestTarget target) { + ModalWindow modalWindow = findParent(ModalWindow.class); + if (modalWindow != null) { + modalWindow.close(target); + deleteAssignmentConfirmedPerformed(target, getSelectedAssignments()); + } + } + }; + } + private void deleteAssignmentConfirmedPerformed(AjaxRequestTarget target, List toDelete) { List assignments = getAssignmentModel().getObject(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/AbstractObjectTabPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/AbstractObjectTabPanel.java index d301578cef6..91eeaec0100 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/AbstractObjectTabPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/objectdetails/AbstractObjectTabPanel.java @@ -138,9 +138,7 @@ protected void showModalWindow(String id, AjaxRequestTarget target) { } protected void showModalWindow(Component body, IModel title, AjaxRequestTarget target) { - getPageBase().setMainPopupContent(body); - getPageBase().setMainPopupTitle(title); - getPageBase().showMainPopup(target); + getPageBase().showMainPopup(body, title, target); target.add(getFeedbackPanel()); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressPanel.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressPanel.html index 2ef3036db5c..bc1e735c222 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressPanel.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressPanel.html @@ -47,6 +47,7 @@ diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressPanel.java index fb1c16463a9..8b69ab44f8e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressPanel.java @@ -21,10 +21,12 @@ import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.web.component.AjaxSubmitButton; import com.evolveum.midpoint.web.component.form.Form; +import com.evolveum.midpoint.web.page.admin.PageAdminObjectDetails; import com.evolveum.midpoint.web.page.admin.server.dto.OperationResultStatusIcon; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultStatusType; import org.apache.wicket.AttributeModifier; +import org.apache.wicket.Page; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; @@ -221,8 +223,30 @@ protected void onError(AjaxRequestTarget target, target.add(page.getFeedbackPanel()); } }; - progressReporter.registerAbortButton(abortButton); - progressForm.add(abortButton); + + progressReporter.registerAbortButton(abortButton); + progressForm.add(abortButton); + + AjaxSubmitButton backButton = new AjaxSubmitButton("back", + createStringResource("pageAdminFocus.button.back")) { + + @Override + protected void onSubmit(AjaxRequestTarget target, + org.apache.wicket.markup.html.form.Form form) { + Page page = getPage(); + if (page != null && page instanceof PageAdminObjectDetails){ + setResponsePage(((PageAdminObjectDetails) page).getDefaultBackPage()); + } + } + + @Override + protected void onError(AjaxRequestTarget target, + org.apache.wicket.markup.html.form.Form form) { + target.add(page.getFeedbackPanel()); + } + }; + progressReporter.registerBackButton(backButton); + progressForm.add(backButton); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressReporter.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressReporter.java index e657d6a2012..8bf078947e3 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressReporter.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/progress/ProgressReporter.java @@ -65,6 +65,7 @@ public class ProgressReporter implements Serializable { // links to wicket artefacts on parent page private AjaxSubmitButton abortButton; + private AjaxSubmitButton backButton; private ProgressReportingAwarePage parentPage; private ProgressPanel progressPanel; private Behavior refreshingBehavior = null; // behavior is attached to the progress panel @@ -213,6 +214,7 @@ public void run() { if (abortEnabled) { showAbortButton(target); } + showBackButton(target); result.recordInProgress(); // to disable showing not-final results (why does it work? and why is the result shown otherwise?) @@ -266,6 +268,13 @@ public void registerAbortButton(AjaxSubmitButton abortButton) { this.abortButton = abortButton; } + public void registerBackButton(AjaxSubmitButton backButton) { + backButton.setOutputMarkupId(true); + backButton.setOutputMarkupPlaceholderTag(true); + backButton.setVisible(false); + this.backButton = backButton; + } + /** * You have to call this method when Abort button is pressed */ @@ -288,7 +297,7 @@ public void onAbortSubmit(AjaxRequestTarget target) { hideAbortButton(target); } - private void hideAbortButton(AjaxRequestTarget target) { + public void hideAbortButton(AjaxRequestTarget target) { abortButton.setVisible(false); target.add(abortButton); } @@ -298,6 +307,11 @@ public void showAbortButton(AjaxRequestTarget target) { target.add(abortButton); } + public void showBackButton(AjaxRequestTarget target) { + backButton.setVisible(true); + target.add(backButton); + } + // ================= Other methods ================= diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchFactory.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchFactory.java index d81e163a83d..29588a0d536 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchFactory.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchFactory.java @@ -47,14 +47,55 @@ public class SearchFactory { SEARCHABLE_OBJECTS.put(RoleType.class, Arrays.asList( new ItemPath(RoleType.F_NAME), new ItemPath(RoleType.F_DISPLAY_NAME), -// new ItemPath(RoleType.F_OWNER_REF), - new ItemPath(RoleType.F_REQUESTABLE), new ItemPath(RoleType.F_ROLE_TYPE))); + SEARCHABLE_OBJECTS.put(ConnectorHostType.class, Arrays.asList( + new ItemPath(ConnectorHostType.F_HOSTNAME) + )); + SEARCHABLE_OBJECTS.put(ConnectorType.class, Arrays.asList( + new ItemPath(ConnectorType.F_CONNECTOR_BUNDLE), + new ItemPath(ConnectorType.F_CONNECTOR_VERSION), + new ItemPath(ConnectorType.F_CONNECTOR_TYPE) + )); + SEARCHABLE_OBJECTS.put(AbstractRoleType.class, Arrays.asList( + new ItemPath(RoleType.F_REQUESTABLE) + )); + SEARCHABLE_OBJECTS.put(OrgType.class, Arrays.asList( + new ItemPath(OrgType.F_DISPLAY_NAME), + new ItemPath(OrgType.F_COST_CENTER), + new ItemPath(OrgType.F_IDENTIFIER), + new ItemPath(OrgType.F_ORG_TYPE), + new ItemPath(OrgType.F_TENANT), + new ItemPath(OrgType.F_LOCALITY) + )); + SEARCHABLE_OBJECTS.put(GenericObjectType.class, Arrays.asList( + new ItemPath(GenericObjectType.F_OBJECT_TYPE) + )); + SEARCHABLE_OBJECTS.put(NodeType.class, Arrays.asList( + new ItemPath(NodeType.F_NODE_IDENTIFIER) + )); + SEARCHABLE_OBJECTS.put(ReportType.class, Arrays.asList( + new ItemPath(ReportType.F_PARENT) + )); + SEARCHABLE_OBJECTS.put(ShadowType.class, Arrays.asList( + new ItemPath(ShadowType.F_OBJECT_CLASS), + new ItemPath(ShadowType.F_DEAD), + new ItemPath(ShadowType.F_INTENT), + new ItemPath(ShadowType.F_EXISTS) + )); + SEARCHABLE_OBJECTS.put(TaskType.class, Arrays.asList( + new ItemPath(TaskType.F_TASK_IDENTIFIER), + new ItemPath(TaskType.F_NODE), + new ItemPath(TaskType.F_CATEGORY), + new ItemPath(TaskType.F_RESULT_STATUS) + )); + } - //todo add other object types and properties which can be used in search + public static Search createSearch(Class type, PrismContext ctx) { + return createSearch(type, ctx, true); } - public static Search createSearch(Class type, PrismContext ctx, boolean useDefsFromSuperclass) { + public static Search createSearch(Class type, PrismContext ctx, + boolean useDefsFromSuperclass) { Map availableDefs = getAvailableDefinitions(type, ctx, useDefsFromSuperclass); Search search = new Search(type, availableDefs); @@ -80,7 +121,7 @@ private static Map getAvailable if (pathList != null) { map.putAll(createAvailableDefinitions(typeClass, ctx, pathList)); } - if (!useDefsFromSuperclass){ + if (!useDefsFromSuperclass) { break; } typeClass = (Class) typeClass.getSuperclass(); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPanel.java index 458e835ca4a..092bb4b2320 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/search/SearchPanel.java @@ -110,6 +110,14 @@ public void onClick(AjaxRequestTarget target) { togglePopover(target, button, popover, 14); } }; + more.add(new VisibleEnableBehaviour() { + + @Override + public boolean isVisible() { + Search search = getModelObject(); + return !search.getAvailableDefinitions().isEmpty(); + } + }); more.setOutputMarkupId(true); form.add(more); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminFocus.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminFocus.java index 4250ebac3a1..f4fecf50291 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminFocus.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminFocus.java @@ -203,7 +203,9 @@ public void finishProcessing(AjaxRequestTarget target, OperationResult result) { } goBackPage(); } else { - showResult(result); + getProgressReporter().showBackButton(target); + getProgressReporter().hideAbortButton(target); + showResult(result); target.add(getFeedbackPanel()); // if we only stayed on the page because of displaying results, hide diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminObjectDetails.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminObjectDetails.java index 6da0095a54e..4adf9a76da4 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminObjectDetails.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/PageAdminObjectDetails.java @@ -808,7 +808,7 @@ public void goBackPage() { } } - protected abstract PageBase getDefaultBackPage(); + public abstract PageBase getDefaultBackPage(); public List getObjectFormTypes() { Task task = createSimpleTask(OPERATION_LOAD_GUI_CONFIGURATION); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertCampaigns.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertCampaigns.html index 040e6acdc79..d3a1a501aec 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertCampaigns.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertCampaigns.html @@ -20,12 +20,6 @@ -
-
-
-
-
-
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertCampaigns.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertCampaigns.java index 94cbe766b47..0d298e5612b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertCampaigns.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertCampaigns.java @@ -50,6 +50,7 @@ import com.evolveum.midpoint.web.component.data.column.LinkColumn; import com.evolveum.midpoint.web.component.data.column.SingleButtonColumn; import com.evolveum.midpoint.web.component.dialog.ConfirmationDialog; +import com.evolveum.midpoint.web.component.dialog.ConfirmationPanel; import com.evolveum.midpoint.web.component.menu.cog.InlineMenuItem; import com.evolveum.midpoint.web.component.util.Selectable; import com.evolveum.midpoint.web.page.admin.certification.dto.CertCampaignListItemDto; @@ -120,11 +121,6 @@ public class PageCertCampaigns extends PageAdminCertification { public static final String OP_CLOSE_STAGE = "PageCertCampaigns.button.closeStage"; public static final String OP_OPEN_NEXT_STAGE = "PageCertCampaigns.button.openNextStage"; public static final String OP_START_REMEDIATION = "PageCertCampaigns.button.startRemediation"; - private static final String DIALOG_CONFIRM_CLOSE_STAGE = "confirmCloseStagePopup"; - private static final String DIALOG_CONFIRM_DELETE_CAMPAIGN ="confirmDeleteCampaignPopup"; - private static final String DIALOG_CONFIRM_DELETE_MULTIPLE_CAMPAIGNS = "confirmDeleteMultipleCampaignsPopup"; - private static final String DIALOG_CONFIRM_CLOSE_CAMPAIGN ="confirmCloseCampaignPopup"; - private static final String DIALOG_CONFIRM_CLOSE_MULTIPLE_CAMPAIGNS ="confirmCloseMultipleCampaignsPopup"; // campaign on which close-stage/close-campaign/delete has to be executed (if chosen directly from row menu) private CertCampaignListItemDto relevantCampaign; @@ -213,66 +209,6 @@ private void initLayout() { Form mainForm = new Form(ID_MAIN_FORM); add(mainForm); - add(new ConfirmationDialog( - DIALOG_CONFIRM_CLOSE_STAGE, - createStringResource("PageCertCampaigns.dialog.title.confirmCloseStage"), - createCloseStageConfirmString()) { - - @Override - public void yesPerformed(AjaxRequestTarget target) { - close(target); - closeStageConfirmedPerformed(target, relevantCampaign); - } - }); - - add(new ConfirmationDialog( - DIALOG_CONFIRM_CLOSE_CAMPAIGN, - createStringResource("PageCertCampaigns.dialog.title.confirmCloseCampaign"), - createCloseCampaignConfirmString()) { - - @Override - public void yesPerformed(AjaxRequestTarget target) { - close(target); - closeCampaignConfirmedPerformed(target, relevantCampaign); - } - }); - - add(new ConfirmationDialog( - DIALOG_CONFIRM_CLOSE_MULTIPLE_CAMPAIGNS, - createStringResource("PageCertCampaigns.dialog.title.confirmCloseCampaign"), - createCloseSelectedCampaignsConfirmString()) { - - @Override - public void yesPerformed(AjaxRequestTarget target) { - close(target); - closeSelectedCampaignsConfirmedPerformed(target); - } - }); - - add(new ConfirmationDialog( - DIALOG_CONFIRM_DELETE_CAMPAIGN, - createStringResource("PageCertCampaigns.dialog.title.confirmDeleteCampaign"), - createDeleteCampaignConfirmString()) { - - @Override - public void yesPerformed(AjaxRequestTarget target) { - close(target); - deleteCampaignConfirmedPerformed(target); - } - }); - - add(new ConfirmationDialog( - DIALOG_CONFIRM_DELETE_MULTIPLE_CAMPAIGNS, - createStringResource("PageCertCampaigns.dialog.title.confirmDeleteCampaign"), - createDeleteSelectedCampaignsConfirmString()) { - - @Override - public void yesPerformed(AjaxRequestTarget target) { - close(target); - deleteSelectedCampaignsConfirmedPerformed(target); - } - }); - CertCampaignListItemDtoProvider provider = createProvider(); int itemsPerPage = (int) getItemsPerPage(UserProfileStorage.TableId.PAGE_CERT_CAMPAIGNS_PANEL); BoxedTablePanel table = new BoxedTablePanel<>( @@ -574,20 +510,48 @@ private void closeSelectedCampaignsConfirmation(AjaxRequestTarget target) { if (!ensureSomethingIsSelected(target)) { return; } - ModalWindow dialog = (ModalWindow) get(DIALOG_CONFIRM_CLOSE_MULTIPLE_CAMPAIGNS); - dialog.show(target); - } - - private void deleteSelectedCampaignsConfirmation(AjaxRequestTarget target) { + showMainPopup(getCloseSelectedCampaignsConfirmationPanel(), createStringResource("PageCertCampaigns.dialog.title.confirmCloseCampaign"), + target); + } + + private Component getCloseSelectedCampaignsConfirmationPanel() { + return new ConfirmationPanel(getMainPopupBodyId(), + createCloseSelectedCampaignsConfirmString()) { + @Override + public void yesPerformed(AjaxRequestTarget target) { + ModalWindow modalWindow = findParent(ModalWindow.class); + if (modalWindow != null) { + modalWindow.close(target); + closeSelectedCampaignsConfirmedPerformed(target); + } + } + }; + } + + private void deleteSelectedCampaignsConfirmation(AjaxRequestTarget target) { this.relevantCampaign = null; if (!ensureSomethingIsSelected(target)) { return; } - ModalWindow dialog = (ModalWindow) get(DIALOG_CONFIRM_DELETE_MULTIPLE_CAMPAIGNS); - dialog.show(target); - } - - private boolean ensureSomethingIsSelected(AjaxRequestTarget target) { + showMainPopup(getDeleteSelectedCampaignsConfirmationPanel(), createStringResource("PageCertCampaigns.dialog.title.confirmDeleteCampaign"), + target); + } + + private Component getDeleteSelectedCampaignsConfirmationPanel() { + return new ConfirmationPanel(getMainPopupBodyId(), + createDeleteSelectedCampaignsConfirmString()) { + @Override + public void yesPerformed(AjaxRequestTarget target) { + ModalWindow modalWindow = findParent(ModalWindow.class); + if (modalWindow != null) { + modalWindow.close(target); + deleteSelectedCampaignsConfirmedPerformed(target); + } + } + }; + } + + private boolean ensureSomethingIsSelected(AjaxRequestTarget target) { if (relevantCampaign != null) { return true; } else if (!WebComponentUtil.getSelectedData(getTable()).isEmpty()) { @@ -603,23 +567,65 @@ private boolean ensureSomethingIsSelected(AjaxRequestTarget target) { private void closeStageConfirmation(AjaxRequestTarget target, CertCampaignListItemDto campaignDto) { this.relevantCampaign = campaignDto; - ModalWindow dialog = (ModalWindow) get(DIALOG_CONFIRM_CLOSE_STAGE); - dialog.show(target); - } - - private void closeCampaignConfirmation(AjaxRequestTarget target, CertCampaignListItemDto campaignDto) { + showMainPopup(getCloseStageConfirmationPanel(), createStringResource("PageCertCampaigns.dialog.title.confirmCloseStage"), + target); + } + + private Component getCloseStageConfirmationPanel() { + return new ConfirmationPanel(getMainPopupBodyId(), + createCloseStageConfirmString()) { + @Override + public void yesPerformed(AjaxRequestTarget target) { + ModalWindow modalWindow = findParent(ModalWindow.class); + if (modalWindow != null) { + modalWindow.close(target); + closeStageConfirmedPerformed(target, relevantCampaign); + } + } + }; + } + + private void closeCampaignConfirmation(AjaxRequestTarget target, CertCampaignListItemDto campaignDto) { this.relevantCampaign = campaignDto; - ModalWindow dialog = (ModalWindow) get(DIALOG_CONFIRM_CLOSE_CAMPAIGN); - dialog.show(target); - } - - private void deleteCampaignConfirmation(AjaxRequestTarget target, CertCampaignListItemDto campaignDto) { + showMainPopup(getCloseCampaignConfirmationPanel(), createStringResource("PageCertCampaigns.dialog.title.confirmCloseCampaign"), + target); + } + + private Component getCloseCampaignConfirmationPanel() { + return new ConfirmationPanel(getMainPopupBodyId(), + createCloseCampaignConfirmString()) { + @Override + public void yesPerformed(AjaxRequestTarget target) { + ModalWindow modalWindow = findParent(ModalWindow.class); + if (modalWindow != null) { + modalWindow.close(target); + closeCampaignConfirmedPerformed(target, relevantCampaign); + } + } + }; + } + + private void deleteCampaignConfirmation(AjaxRequestTarget target, CertCampaignListItemDto campaignDto) { this.relevantCampaign = campaignDto; - ModalWindow dialog = (ModalWindow) get(DIALOG_CONFIRM_DELETE_CAMPAIGN); - dialog.show(target); - } - - // actions after confirmation (single and multiple versions mixed) + showMainPopup(getDeleteCampaignConfirmationPanel(), createStringResource("PageCertCampaigns.dialog.title.confirmDeleteCampaign"), + target); + } + + private Component getDeleteCampaignConfirmationPanel() { + return new ConfirmationPanel(getMainPopupBodyId(), + createDeleteCampaignConfirmString()) { + @Override + public void yesPerformed(AjaxRequestTarget target) { + ModalWindow modalWindow = findParent(ModalWindow.class); + if (modalWindow != null) { + modalWindow.close(target); + deleteCampaignConfirmedPerformed(target); + } + } + }; + } + + // actions after confirmation (single and multiple versions mixed) private void deleteCampaignConfirmedPerformed(AjaxRequestTarget target) { deleteCampaignsPerformed(target, Arrays.asList(relevantCampaign)); diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertDefinitions.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertDefinitions.html index e4dd15db490..2425ef844cb 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertDefinitions.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertDefinitions.html @@ -18,8 +18,6 @@ -
-
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertDefinitions.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertDefinitions.java index de76d7aac1f..75b21a85043 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertDefinitions.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/certification/PageCertDefinitions.java @@ -35,6 +35,7 @@ import com.evolveum.midpoint.web.component.data.column.LinkColumn; import com.evolveum.midpoint.web.component.data.column.MultiButtonColumn; import com.evolveum.midpoint.web.component.dialog.ConfirmationDialog; +import com.evolveum.midpoint.web.component.dialog.ConfirmationPanel; import com.evolveum.midpoint.web.component.util.SelectableBean; import com.evolveum.midpoint.web.page.admin.configuration.PageDebugView; import com.evolveum.midpoint.web.page.admin.workflow.PageAdminWorkItems; @@ -77,7 +78,6 @@ public class PageCertDefinitions extends PageAdminWorkItems { private static final String DOT_CLASS = PageCertDefinitions.class.getName() + "."; private static final String OPERATION_CREATE_CAMPAIGN = DOT_CLASS + "createCampaign"; private static final String OPERATION_DELETE_DEFINITION = DOT_CLASS + "deleteDefinition"; - private static final String DIALOG_CONFIRM_DELETE = "confirmDeletePopup"; private static final String ID_MAIN_FORM = "mainForm"; private static final String ID_DEFINITIONS_TABLE = "definitionsTable"; @@ -114,15 +114,6 @@ private void initLayout() { ObjectDataProvider provider = createProvider(); - add(new ConfirmationDialog(DIALOG_CONFIRM_DELETE, - createStringResource("PageCertDefinitions.title.confirmDelete"), createDeleteConfirmString()) { - - @Override - public void yesPerformed(AjaxRequestTarget target) { - close(target); - deleteDefinitionPerformed(target, singleDelete); - } - }); int itemsPerPage = (int) getItemsPerPage(UserProfileStorage.TableId.PAGE_CERT_DEFINITIONS_PANEL); BoxedTablePanel table = new BoxedTablePanel<>(ID_DEFINITIONS_TABLE, provider, initColumns(), UserProfileStorage.TableId.PAGE_CERT_DEFINITIONS_PANEL, itemsPerPage); @@ -244,8 +235,8 @@ private void createCampaignPerformed(AjaxRequestTarget target, AccessCertificati private void deleteConfirmation(AjaxRequestTarget target, AccessCertificationDefinitionType definition) { this.singleDelete = definition; - ModalWindow dialog = (ModalWindow) get(DIALOG_CONFIRM_DELETE); - dialog.show(target); + showMainPopup(getDeleteDefinitionConfirmationPanel(), createStringResource("PageCertDefinitions.title.confirmDelete"), + target); } private void deleteDefinitionPerformed(AjaxRequestTarget target, AccessCertificationDefinitionType definition) { @@ -288,4 +279,18 @@ private void definitionDetailsPerformed(AjaxRequestTarget target, String oid) { } //endregion + + private Component getDeleteDefinitionConfirmationPanel() { + return new ConfirmationPanel(getMainPopupBodyId(), + createDeleteConfirmString()) { + @Override + public void yesPerformed(AjaxRequestTarget target) { + ModalWindow modalWindow = findParent(ModalWindow.class); + if (modalWindow != null) { + modalWindow.close(target); + deleteDefinitionPerformed(target, singleDelete); + } + } + }; + } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugList.html b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugList.html index c3f95a560a0..c4c0d76a358 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugList.html +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugList.html @@ -18,7 +18,6 @@ -
@@ -51,7 +50,7 @@
-
+
diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugList.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugList.java index b31f56c31b2..e57c6dddaa3 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugList.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageDebugList.java @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2010-2016 Evolveum +/* Copyright (c) 2010-2016 Evolveum + * * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,10 @@ import javax.xml.namespace.QName; -import org.apache.commons.lang.StringUtils; +import com.evolveum.midpoint.web.component.dialog.ConfirmationPanel; +import com.evolveum.midpoint.web.component.search.Search; +import com.evolveum.midpoint.web.component.search.SearchFactory; +import com.evolveum.midpoint.web.component.search.SearchPanel; import org.apache.wicket.AttributeModifier; import org.apache.wicket.Component; import org.apache.wicket.MarkupContainer; @@ -59,9 +62,7 @@ import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismProperty; import com.evolveum.midpoint.prism.PrismPropertyDefinition; -import com.evolveum.midpoint.prism.match.PolyStringNormMatchingRule; import com.evolveum.midpoint.prism.path.ItemPath; -import com.evolveum.midpoint.prism.polystring.PolyStringNormalizer; import com.evolveum.midpoint.prism.query.AndFilter; import com.evolveum.midpoint.prism.query.EqualFilter; import com.evolveum.midpoint.prism.query.InOidFilter; @@ -71,7 +72,6 @@ import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.prism.query.QueryJaxbConvertor; import com.evolveum.midpoint.prism.query.RefFilter; -import com.evolveum.midpoint.prism.query.SubstringFilter; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.ObjectTypes; @@ -89,7 +89,6 @@ import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.web.application.AuthorizationAction; import com.evolveum.midpoint.web.application.PageDescriptor; -import com.evolveum.midpoint.web.component.BasicSearchPanel; import com.evolveum.midpoint.web.component.data.BoxedTablePanel; import com.evolveum.midpoint.web.component.data.RepositoryObjectDataProvider; import com.evolveum.midpoint.web.component.data.Table; @@ -98,7 +97,6 @@ import com.evolveum.midpoint.web.component.data.column.InlineMenuable; import com.evolveum.midpoint.web.component.data.column.LinkColumn; import com.evolveum.midpoint.web.component.data.column.TwoValueLinkPanel; -import com.evolveum.midpoint.web.component.dialog.ConfirmationDialog; import com.evolveum.midpoint.web.component.dialog.DeleteAllDialog; import com.evolveum.midpoint.web.component.dialog.DeleteAllDto; import com.evolveum.midpoint.web.component.input.ChoiceableChoiceRenderer; @@ -123,38 +121,6 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import com.evolveum.prism.xml.ns._public.query_3.QueryType; -import org.apache.commons.lang.StringUtils; -import org.apache.wicket.AttributeModifier; -import org.apache.wicket.Component; -import org.apache.wicket.MarkupContainer; -import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; -import org.apache.wicket.ajax.form.OnChangeAjaxBehavior; -import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox; -import org.apache.wicket.behavior.Behavior; -import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; -import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; -import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn; -import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable; -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.markup.html.WebMarkupContainer; -import org.apache.wicket.markup.html.basic.Label; -import org.apache.wicket.markup.html.form.DropDownChoice; -import org.apache.wicket.markup.html.form.Form; -import org.apache.wicket.markup.html.form.IChoiceRenderer; -import org.apache.wicket.markup.html.list.ListItem; -import org.apache.wicket.markup.html.list.PropertyListView; -import org.apache.wicket.markup.html.panel.Fragment; -import org.apache.wicket.markup.repeater.Item; -import org.apache.wicket.model.*; -import org.apache.wicket.model.util.ListModel; -import org.apache.wicket.request.mapper.parameter.PageParameters; - -import javax.swing.text.html.ListView; -import javax.xml.namespace.QName; - -import java.util.*; /** * @author lazyman @@ -173,7 +139,6 @@ public class PageDebugList extends PageAdminConfiguration { private static final String OPERATION_LOAD_RESOURCES = DOT_CLASS + "loadResources"; private static final String OPERATION_DELETE_SHADOWS = DOT_CLASS + "deleteShadows"; - private static final String ID_CONFIRM_DELETE_POPUP = "confirmDeletePopup"; private static final String ID_MAIN_FORM = "mainForm"; private static final String ID_ZIP_CHECK = "zipCheck"; private static final String ID_TABLE = "table"; @@ -181,10 +146,10 @@ public class PageDebugList extends PageAdminConfiguration { private static final String ID_EXPORT = "export"; private static final String ID_EXPORT_ALL = "exportAll"; private static final String ID_SEARCH_FORM = "searchForm"; - private static final String ID_BASIC_SEARCH = "basicSearch"; private static final String ID_DELETE_ALL_DIALOG = "confirmDeleteAll"; private static final String ID_RESOURCE = "resource"; private static final String ID_TABLE_HEADER = "tableHeader"; + private static final String ID_SEARCH = "search"; private static final Integer DELETE_LOG_INTERVAL = 50; @@ -204,7 +169,11 @@ public PageDebugList(boolean clearPagingInSession) { @Override protected DebugSearchDto load() { ConfigurationStorage storage = getSessionStorage().getConfiguration(); - return storage.getDebugSearchDto(); + + DebugSearchDto dto = storage.getDebugSearchDto(); + setupSearchDto(dto); + + return dto; } }; @@ -268,35 +237,6 @@ public void yesPerformed(AjaxRequestTarget target) { }; add(deleteAllDialog); - ConfirmationDialog deleteConfirm = new ConfirmationDialog(ID_CONFIRM_DELETE_POPUP, - createStringResource("pageDebugList.dialog.title.confirmDelete"), - createDeleteConfirmString()) { - - @Override - public void yesPerformed(AjaxRequestTarget target) { - close(target); - - DebugConfDialogDto dto = confDialogModel.getObject(); - switch (dto.getOperation()) { - case DELETE_ALL_TYPE: - deleteAllTypeConfirmed(target); - break; - case DELETE_SELECTED: - deleteSelectedConfirmed(target, dto.getObjects()); - break; - case DELETE_RESOURCE_SHADOWS: - deleteAllShadowsOnResourceConfirmed(target); - break; - } - } - - @Override - public boolean getLabelEscapeModelStrings() { - return false; - } - }; - add(deleteConfirm); - Form main = new Form(ID_MAIN_FORM); add(main); @@ -327,7 +267,6 @@ private void initDownload(AjaxRequestTarget target, Class } private void addOrReplaceTable(RepositoryObjectDataProvider provider) { - provider.setQuery(createQuery()); Form mainForm = (Form) get(ID_MAIN_FORM); BoxedTablePanel table = new BoxedTablePanel(ID_TABLE, provider, initColumns(provider.getType()), @@ -382,7 +321,7 @@ public void onClick(AjaxRequestTarget target) { columns.add(column); columns.add(new PropertyColumn(createStringResource("pageDebugList.description"), - DebugObjectItem.F_DESCRIPTION)); + DebugObjectItem.F_DESCRIPTION)); if (ShadowType.class.isAssignableFrom(type)) { columns.add(new PropertyColumn(createStringResource("pageDebugList.resourceName"), @@ -445,15 +384,33 @@ public void onSubmit(AjaxRequestTarget target, Form form) { headerMenuItems .add(new InlineMenuItem(createStringResource("pageDebugList.menu.exportAllSelectedType"), - true, new HeaderMenuAction(this) { + true, new HeaderMenuAction(this) { + + @Override + public void onSubmit(AjaxRequestTarget target, Form form) { + exportAllType(target); + } + })); + + headerMenuItems + .add(new InlineMenuItem(createStringResource("pageDebugList.menu.exportShadowsOnResource"), + new Model(true), new AbstractReadOnlyModel() { - @Override - public void onSubmit(AjaxRequestTarget target, Form form) { - exportAllType(target); - } - })); + @Override + public Boolean getObject() { + DebugSearchDto dto = searchModel.getObject(); + return ObjectTypes.SHADOW.equals(dto.getType()); + } - headerMenuItems.add(new InlineMenuItem(createStringResource("pageDebugList.menu.exportAll"), true, + }, false, new HeaderMenuAction(this) { + + @Override + public void onClick(AjaxRequestTarget target) { + exportAllShadowsOnResource(target); + } + })); + + headerMenuItems.add(new InlineMenuItem(createStringResource("pageDebugList.menu.exportAll"), true, new HeaderMenuAction(this) { @Override @@ -484,21 +441,21 @@ public void onSubmit(AjaxRequestTarget target, Form form) { headerMenuItems .add(new InlineMenuItem(createStringResource("pageDebugList.menu.deleteShadowsOnResource"), - new Model(true), new AbstractReadOnlyModel() { + new Model(true), new AbstractReadOnlyModel() { - @Override - public Boolean getObject() { - DebugSearchDto dto = searchModel.getObject(); - return ObjectTypes.SHADOW.equals(dto.getType()); - } + @Override + public Boolean getObject() { + DebugSearchDto dto = searchModel.getObject(); + return ObjectTypes.SHADOW.equals(dto.getType()); + } - }, false, new HeaderMenuAction(this) { + }, false, new HeaderMenuAction(this) { - @Override - public void onClick(AjaxRequestTarget target) { - deleteAllShadowsOnResource(target); - } - })); + @Override + public void onClick(AjaxRequestTarget target) { + deleteAllShadowsOnResource(target); + } + })); headerMenuItems.add(new InlineMenuItem()); @@ -526,16 +483,35 @@ private Table getListTable() { return (Table) get(createComponentPath(ID_MAIN_FORM, ID_TABLE)); } + /** + * called when object type is changed, search panel will be refreshed + */ private void listObjectsPerformed(AjaxRequestTarget target) { + DebugSearchDto dto = searchModel.getObject(); + setupSearchDto(dto); + + Search search = dto.getSearch(); + ObjectQuery query = search.createObjectQuery(getPrismContext()); + + listObjectsPerformed(query, target); + } + + private void setupSearchDto(DebugSearchDto dto) { + ObjectTypes type = dto.getType(); + Search search = SearchFactory.createSearch(type.getClassDefinition(), getPrismContext(), true); + dto.setSearch(search); + } + + private void listObjectsPerformed(ObjectQuery query, AjaxRequestTarget target) { DebugSearchDto dto = searchModel.getObject(); ObjectTypes selected = dto.getType(); RepositoryObjectDataProvider provider = getTableDataProvider(); - provider.setQuery(createQuery()); + provider.setQuery(createQuery(query)); if (selected != null) { provider.setType(selected.getClassDefinition()); - addOrReplaceTable(provider); +// addOrReplaceTable(provider); } // save object type category to session storage, used by back button @@ -546,7 +522,7 @@ private void listObjectsPerformed(AjaxRequestTarget target) { target.add((Component) table); } - private ObjectQuery createQuery() { + private ObjectQuery createQuery(ObjectQuery searchQuery) { DebugSearchDto dto = searchModel.getObject(); List filters = new ArrayList<>(); @@ -557,14 +533,8 @@ private ObjectQuery createQuery() { filters.add(ref); } - if (StringUtils.isNotEmpty(dto.getText())) { - String nameText = dto.getText(); - PolyStringNormalizer normalizer = getPrismContext().getDefaultPolyStringNormalizer(); - String normalizedString = normalizer.normalize(nameText); - - ObjectFilter substring = SubstringFilter.createSubstring(ObjectType.F_NAME, ObjectType.class, - getPrismContext(), PolyStringNormMatchingRule.NAME, normalizedString); - filters.add(substring); + if (searchQuery != null && searchQuery.getFilter() != null) { + filters.add(searchQuery.getFilter()); } if (filters.isEmpty()) { @@ -668,7 +638,7 @@ private void deleteAllShadowsConfirmed(OperationResult result, boolean deleteAcc throws ObjectAlreadyExistsException, ObjectNotFoundException, SchemaException { ObjectFilter kind = EqualFilter.createEqual(ShadowType.F_KIND, ShadowType.class, getPrismContext(), - null, ShadowKindType.ACCOUNT); + null, ShadowKindType.ACCOUNT); String taskName; ObjectQuery query; @@ -715,8 +685,8 @@ private void deleteAllType(AjaxRequestTarget target) { searchDto.getType().getClassDefinition()); confDialogModel.setObject(dto); - ModalWindow dialog = (ModalWindow) get(ID_CONFIRM_DELETE_POPUP); - dialog.show(target); + showMainPopup(getDeleteConfirmationPanel(), createStringResource("pageDebugList.dialog.title.confirmDelete"), + target); } private List getSelectedData(AjaxRequestTarget target, DebugObjectItem item) { @@ -747,8 +717,8 @@ private void deleteSelected(AjaxRequestTarget target, DebugObjectItem item) { selected, searchDto.getType().getClassDefinition()); confDialogModel.setObject(dto); - ModalWindow dialog = (ModalWindow) get(ID_CONFIRM_DELETE_POPUP); - dialog.show(target); + showMainPopup(getDeleteConfirmationPanel(), createStringResource("pageDebugList.dialog.title.confirmDelete"), + target); } private void deleteAllIdentities(AjaxRequestTarget target) { @@ -802,13 +772,6 @@ private void deleteSelectedConfirmed(AjaxRequestTarget target, List> resourcesModel) { final IModel model = (IModel) getDefaultModel(); - BasicSearchPanel basicSearch = new BasicSearchPanel( - ID_BASIC_SEARCH, model) { - - @Override - protected IModel createSearchTextModel() { - return new PropertyModel<>(model, DebugSearchDto.F_TEXT); - } - - @Override - protected void searchPerformed(AjaxRequestTarget target) { - PageDebugList page = (PageDebugList) getPage(); - page.listObjectsPerformed(target); - } - - @Override - protected void clearSearchPerformed(AjaxRequestTarget target) { - PageDebugList page = (PageDebugList) getPage(); - page.clearSearchPerformed(target); - } - }; - searchForm.add(basicSearch); - EnumChoiceRenderer renderer = new EnumChoiceRenderer() { protected String resourceKey(ObjectTypes object) { @@ -957,24 +944,32 @@ protected void onUpdate(AjaxRequestTarget target) { }); DropDownChoice resource = new DropDownChoice(ID_RESOURCE, - new PropertyModel(model, DebugSearchDto.F_RESOURCE_OID), resourcesModel, + new PropertyModel(model, DebugSearchDto.F_RESOURCE), resourcesModel, createResourceRenderer()); resource.setNullValid(true); resource.add(new AjaxFormComponentUpdatingBehavior("blur") { - @Override - protected void onUpdate(AjaxRequestTarget target) { - // nothing to do, it's here just to update model - } - }); + @Override + protected void onUpdate(AjaxRequestTarget target) { + // nothing to do, it's here just to update model + } + }); + resource.add(new OnChangeAjaxBehavior() { + + @Override + protected void onUpdate(AjaxRequestTarget target) { + PageDebugList page = (PageDebugList) getPage(); + page.listObjectsPerformed(target); + } + }); resource.add(new VisibleEnableBehaviour() { - @Override - public boolean isVisible() { - DebugSearchDto dto = model.getObject(); - return ObjectTypes.SHADOW.equals(dto.getType()); - } - }); + @Override + public boolean isVisible() { + DebugSearchDto dto = model.getObject(); + return ObjectTypes.SHADOW.equals(dto.getType()); + } + }); searchForm.add(resource); AjaxCheckBox zipCheck = new AjaxCheckBox(ID_ZIP_CHECK, new Model<>(false)) { @@ -984,6 +979,17 @@ protected void onUpdate(AjaxRequestTarget target) { } }; add(zipCheck); + + SearchPanel search = new SearchPanel(ID_SEARCH, + new PropertyModel(model, DebugSearchDto.F_SEARCH)) { + + @Override + public void searchPerformed(ObjectQuery query, AjaxRequestTarget target) { + PageDebugList page = (PageDebugList) getPage(); + page.listObjectsPerformed(query, target); + } + }; + searchForm.add(search); } public AjaxCheckBox getZipCheck() { diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageImportObject.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageImportObject.java index e80bf3d2ca3..e51c401fc9b 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageImportObject.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/PageImportObject.java @@ -52,245 +52,250 @@ import org.apache.wicket.util.file.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; /** * @author lazyman * @author mserbak */ @PageDescriptor(url = "/admin/config/import", action = { - @AuthorizationAction(actionUri = PageAdminConfiguration.AUTH_CONFIGURATION_ALL, - label = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_LABEL, description = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_DESCRIPTION), - @AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_CONFIGURATION_IMPORT_URL, - label = "PageImportObject.auth.configImport.label", description = "PageImportObject.auth.configImport.description")}) + @AuthorizationAction(actionUri = PageAdminConfiguration.AUTH_CONFIGURATION_ALL, label = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_LABEL, description = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_DESCRIPTION), + @AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_CONFIGURATION_IMPORT_URL, label = "PageImportObject.auth.configImport.label", description = "PageImportObject.auth.configImport.description") }) public class PageImportObject extends PageAdminConfiguration { - private static final Trace LOGGER = TraceManager.getTrace(PageImportObject.class); - private static final String DOT_CLASS = PageImportObject.class.getName() + "."; - private static final String OPERATION_IMPORT_FILE = DOT_CLASS + "importFile"; - private static final String OPERATION_IMPORT_XML = DOT_CLASS + "importXml"; - - private static final String ID_MAIN_FORM = "mainForm"; - private static final String ID_BUTTON_BAR = "buttonBar"; - private static final String ID_IMPORT_OPTIONS = "importOptions"; - private static final String ID_IMPORT_RADIO_GROUP = "importRadioGroup"; - private static final String ID_FILE_RADIO = "fileRadio"; - private static final String ID_XML_RADIO = "xmlRadio"; - private static final String ID_IMPORT_FILE_BUTTON = "importFileButton"; - private static final String ID_IMPORT_XML_BUTTON = "importXmlButton"; - private static final String ID_INPUT = "input"; - private static final String ID_INPUT_ACE = "inputAce"; - private static final String ID_ACE_EDITOR = "aceEditor"; - private static final String ID_INPUT_FILE_LABEL = "inputFileLabel"; - private static final String ID_INPUT_FILE = "inputFile"; - private static final String ID_FILE_INPUT = "fileInput"; - - private static final Integer INPUT_FILE = 1; - private static final Integer INPUT_XML = 2; - - private LoadableModel model; - private IModel xmlEditorModel; - - public PageImportObject() { - model = new LoadableModel(false) { - - @Override - protected ImportOptionsType load() { - return MiscSchemaUtil.getDefaultImportOptions(); - } - }; - xmlEditorModel = new Model(null); - - initLayout(); - } - - private void initLayout() { - Form mainForm = new Form(ID_MAIN_FORM); - add(mainForm); - - ImportOptionsPanel importOptions = new ImportOptionsPanel(ID_IMPORT_OPTIONS, model); - mainForm.add(importOptions); - - final WebMarkupContainer input = new WebMarkupContainer(ID_INPUT); - input.setOutputMarkupId(true); - mainForm.add(input); - - final WebMarkupContainer buttonBar = new WebMarkupContainer(ID_BUTTON_BAR); - buttonBar.setOutputMarkupId(true); - mainForm.add(buttonBar); - - final IModel groupModel = new Model(INPUT_FILE); - RadioGroup importRadioGroup = new RadioGroup(ID_IMPORT_RADIO_GROUP, groupModel); - importRadioGroup.add(new AjaxFormChoiceComponentUpdatingBehavior() { - - @Override - protected void onUpdate(AjaxRequestTarget target) { - target.add(input); - target.add(buttonBar); - } - }); - mainForm.add(importRadioGroup); - - Radio fileRadio = new Radio(ID_FILE_RADIO, new Model(INPUT_FILE), importRadioGroup); - importRadioGroup.add(fileRadio); - - Radio xmlRadio = new Radio(ID_XML_RADIO, new Model(INPUT_XML), importRadioGroup); - importRadioGroup.add(xmlRadio); - - WebMarkupContainer inputAce = new WebMarkupContainer(ID_INPUT_ACE); - addVisibileForInputType(inputAce, INPUT_XML, groupModel); - input.add(inputAce); - - AceEditor aceEditor = new AceEditor(ID_ACE_EDITOR, xmlEditorModel); - aceEditor.setOutputMarkupId(true); - inputAce.add(aceEditor); - - WebMarkupContainer inputFileLabel = new WebMarkupContainer(ID_INPUT_FILE_LABEL); - addVisibileForInputType(inputFileLabel, INPUT_FILE, groupModel); - input.add(inputFileLabel); - - WebMarkupContainer inputFile = new WebMarkupContainer(ID_INPUT_FILE); - addVisibileForInputType(inputFile, INPUT_FILE, groupModel); - input.add(inputFile); - - FileUploadField fileInput = new FileUploadField(ID_FILE_INPUT); - inputFile.add(fileInput); - - initButtons(buttonBar, groupModel); - } - - private void addVisibileForInputType(Component comp, final Integer type, final IModel groupModel) { - comp.add(new VisibleEnableBehaviour() { - - @Override - public boolean isVisible() { - return type.equals(groupModel.getObject()); - } - - }); - } - - private void initButtons(WebMarkupContainer buttonBar, IModel inputType) { - AjaxSubmitButton saveFileButton = new AjaxSubmitButton(ID_IMPORT_FILE_BUTTON, - createStringResource("PageImportObject.button.import")) { - - @Override - protected void onSubmit(AjaxRequestTarget target, Form form) { - saveFilePerformed(target); - } - - @Override - protected void onError(AjaxRequestTarget target, Form form) { - target.add(getFeedbackPanel()); - } - }; - addVisibileForInputType(saveFileButton, INPUT_FILE, inputType); - buttonBar.add(saveFileButton); - - AjaxSubmitButton saveXmlButton = new AjaxSubmitButton(ID_IMPORT_XML_BUTTON, - createStringResource("PageImportObject.button.import")) { - - @Override - protected void onSubmit(AjaxRequestTarget target, Form form) { - saveXmlPerformed(target); - } - - @Override - protected void onError(AjaxRequestTarget target, Form form) { - target.add(getFeedbackPanel()); - } - }; - addVisibileForInputType(saveXmlButton, INPUT_XML, inputType); - buttonBar.add(saveXmlButton); - } - - private void saveFilePerformed(AjaxRequestTarget target) { - OperationResult result = new OperationResult(OPERATION_IMPORT_FILE); - - FileUploadField file = (FileUploadField) get(createComponentPath(ID_MAIN_FORM, ID_INPUT, ID_INPUT_FILE, ID_FILE_INPUT)); - final FileUpload uploadedFile = file.getFileUpload(); - if (uploadedFile == null) { - error(getString("pageImportObject.message.nullFile")); - target.add(getFeedbackPanel()); - - return; - } - - InputStream stream = null; - File newFile = null; - try { - // Create new file - MidPointApplication application = getMidpointApplication(); - WebApplicationConfiguration config = application.getWebApplicationConfiguration(); - File folder = new File(config.getImportFolder()); - if (!folder.exists() || !folder.isDirectory()) { - folder.mkdir(); - } - - newFile = new File(folder, uploadedFile.getClientFileName()); - // Check new file, delete if it already exists - if (newFile.exists()) { - newFile.delete(); - } - // Save file - Task task = createSimpleTask(OPERATION_IMPORT_FILE); - newFile.createNewFile(); - uploadedFile.writeTo(newFile); - - InputStreamReader reader = new InputStreamReader(new FileInputStream(newFile), "utf-8"); - stream = new ReaderInputStream(reader, reader.getEncoding()); - getModelService().importObjectsFromStream(stream, model.getObject(), task, result); - - result.recomputeStatus(); - } catch (Exception ex) { - result.recordFatalError("Couldn't import file.", ex); - LoggingUtils.logException(LOGGER, "Couldn't import file", ex); - } finally { - if (stream != null) { - IOUtils.closeQuietly(stream); - } - if (newFile != null) { - FileUtils.deleteQuietly(newFile); - } - } - - showResult(result); - target.add(getFeedbackPanel()); - } - - private void saveXmlPerformed(AjaxRequestTarget target) { - String xml = xmlEditorModel.getObject(); - if (StringUtils.isEmpty(xml)) { - error(getString("pageImportObject.message.emptyXml")); - target.add(getFeedbackPanel()); - - return; - } - - OperationResult result = new OperationResult(OPERATION_IMPORT_XML); - InputStream stream = null; - try { - Task task = createSimpleTask(OPERATION_IMPORT_XML); - - stream = IOUtils.toInputStream(xml, "utf-8"); - getModelService().importObjectsFromStream(stream, model.getObject(), task, result); - - result.recomputeStatus(); - } catch (Exception ex) { - result.recordFatalError("Couldn't import object.", ex); - LoggingUtils.logException(LOGGER, "Error occured during xml import", ex); - } finally { - if (stream != null) { - IOUtils.closeQuietly(stream); - } - } - - if (result.isSuccess()) { - xmlEditorModel.setObject(null); - } - - showResult(result); - target.add(getFeedbackPanel()); - } + private static final Trace LOGGER = TraceManager.getTrace(PageImportObject.class); + private static final String DOT_CLASS = PageImportObject.class.getName() + "."; + private static final String OPERATION_IMPORT_FILE = DOT_CLASS + "importFile"; + private static final String OPERATION_IMPORT_XML = DOT_CLASS + "importXml"; + + private static final String ID_MAIN_FORM = "mainForm"; + private static final String ID_BUTTON_BAR = "buttonBar"; + private static final String ID_IMPORT_OPTIONS = "importOptions"; + private static final String ID_IMPORT_RADIO_GROUP = "importRadioGroup"; + private static final String ID_FILE_RADIO = "fileRadio"; + private static final String ID_XML_RADIO = "xmlRadio"; + private static final String ID_IMPORT_FILE_BUTTON = "importFileButton"; + private static final String ID_IMPORT_XML_BUTTON = "importXmlButton"; + private static final String ID_INPUT = "input"; + private static final String ID_INPUT_ACE = "inputAce"; + private static final String ID_ACE_EDITOR = "aceEditor"; + private static final String ID_INPUT_FILE_LABEL = "inputFileLabel"; + private static final String ID_INPUT_FILE = "inputFile"; + private static final String ID_FILE_INPUT = "fileInput"; + + private static final Integer INPUT_FILE = 1; + private static final Integer INPUT_XML = 2; + + private LoadableModel model; + private IModel xmlEditorModel; + + public PageImportObject() { + model = new LoadableModel(false) { + + @Override + protected ImportOptionsType load() { + return MiscSchemaUtil.getDefaultImportOptions(); + } + }; + xmlEditorModel = new Model(null); + + initLayout(); + } + + private void initLayout() { + Form mainForm = new Form(ID_MAIN_FORM); + add(mainForm); + + ImportOptionsPanel importOptions = new ImportOptionsPanel(ID_IMPORT_OPTIONS, model); + mainForm.add(importOptions); + + final WebMarkupContainer input = new WebMarkupContainer(ID_INPUT); + input.setOutputMarkupId(true); + mainForm.add(input); + + final WebMarkupContainer buttonBar = new WebMarkupContainer(ID_BUTTON_BAR); + buttonBar.setOutputMarkupId(true); + mainForm.add(buttonBar); + + final IModel groupModel = new Model(INPUT_FILE); + RadioGroup importRadioGroup = new RadioGroup(ID_IMPORT_RADIO_GROUP, groupModel); + importRadioGroup.add(new AjaxFormChoiceComponentUpdatingBehavior() { + + @Override + protected void onUpdate(AjaxRequestTarget target) { + target.add(input); + target.add(buttonBar); + } + }); + mainForm.add(importRadioGroup); + + Radio fileRadio = new Radio(ID_FILE_RADIO, new Model(INPUT_FILE), importRadioGroup); + importRadioGroup.add(fileRadio); + + Radio xmlRadio = new Radio(ID_XML_RADIO, new Model(INPUT_XML), importRadioGroup); + importRadioGroup.add(xmlRadio); + + WebMarkupContainer inputAce = new WebMarkupContainer(ID_INPUT_ACE); + addVisibileForInputType(inputAce, INPUT_XML, groupModel); + input.add(inputAce); + + AceEditor aceEditor = new AceEditor(ID_ACE_EDITOR, xmlEditorModel); + aceEditor.setOutputMarkupId(true); + inputAce.add(aceEditor); + + WebMarkupContainer inputFileLabel = new WebMarkupContainer(ID_INPUT_FILE_LABEL); + addVisibileForInputType(inputFileLabel, INPUT_FILE, groupModel); + input.add(inputFileLabel); + + WebMarkupContainer inputFile = new WebMarkupContainer(ID_INPUT_FILE); + addVisibileForInputType(inputFile, INPUT_FILE, groupModel); + input.add(inputFile); + + FileUploadField fileInput = new FileUploadField(ID_FILE_INPUT); + inputFile.add(fileInput); + + initButtons(buttonBar, groupModel); + } + + private void addVisibileForInputType(Component comp, final Integer type, + final IModel groupModel) { + comp.add(new VisibleEnableBehaviour() { + + @Override + public boolean isVisible() { + return type.equals(groupModel.getObject()); + } + + }); + } + + private void initButtons(WebMarkupContainer buttonBar, IModel inputType) { + AjaxSubmitButton saveFileButton = new AjaxSubmitButton(ID_IMPORT_FILE_BUTTON, + createStringResource("PageImportObject.button.import")) { + + @Override + protected void onSubmit(AjaxRequestTarget target, Form form) { + savePerformed(false, OPERATION_IMPORT_FILE, target); + } + + @Override + protected void onError(AjaxRequestTarget target, Form form) { + target.add(getFeedbackPanel()); + } + }; + addVisibileForInputType(saveFileButton, INPUT_FILE, inputType); + buttonBar.add(saveFileButton); + + AjaxSubmitButton saveXmlButton = new AjaxSubmitButton(ID_IMPORT_XML_BUTTON, + createStringResource("PageImportObject.button.import")) { + + @Override + protected void onSubmit(AjaxRequestTarget target, Form form) { + savePerformed(true, OPERATION_IMPORT_XML, target); + } + + @Override + protected void onError(AjaxRequestTarget target, Form form) { + target.add(getFeedbackPanel()); + } + }; + addVisibileForInputType(saveXmlButton, INPUT_XML, inputType); + buttonBar.add(saveXmlButton); + } + + private FileUpload getUploadedFile() { + FileUploadField file = (FileUploadField) get( + createComponentPath(ID_MAIN_FORM, ID_INPUT, ID_INPUT_FILE, ID_FILE_INPUT)); + return file.getFileUpload(); + } + + private boolean validateInput(boolean raw) { + if (raw) { + return StringUtils.isNotEmpty(xmlEditorModel.getObject()); + } + return getUploadedFile() != null; + + } + + private InputStream getInputStream(boolean raw) throws Exception { + if (raw) { + return IOUtils.toInputStream(xmlEditorModel.getObject(), "utf-8"); + } + File newFile = null; + try { + // Create new file + MidPointApplication application = getMidpointApplication(); + WebApplicationConfiguration config = application.getWebApplicationConfiguration(); + File folder = new File(config.getImportFolder()); + if (!folder.exists() || !folder.isDirectory()) { + folder.mkdir(); + } + + FileUpload uploadedFile = getUploadedFile(); + newFile = new File(folder, uploadedFile.getClientFileName()); + // Check new file, delete if it already exists + if (newFile.exists()) { + newFile.delete(); + } + // Save file + + newFile.createNewFile(); + uploadedFile.writeTo(newFile); + + InputStreamReader reader = new InputStreamReader(new FileInputStream(newFile), "utf-8"); + return new ReaderInputStream(reader, reader.getEncoding()); + } finally { + if (newFile != null) { + FileUtils.deleteQuietly(newFile); + } + } + } + + private void clearOldFeedback(){ + getSession().getFeedbackMessages().clear(); + getFeedbackMessages().clear(); + } + + private void savePerformed(boolean raw, String operationName, AjaxRequestTarget target) { + clearOldFeedback(); + + OperationResult result = new OperationResult(operationName); + + if (!validateInput(raw)) { + error(getString("pageImportObject.message.nullFile")); + target.add(getFeedbackPanel()); + + return; + } + InputStream stream = null; + + try { + Task task = createSimpleTask(operationName); + stream = getInputStream(raw); + getModelService().importObjectsFromStream(stream, model.getObject(), task, result); + + result.recomputeStatus(); + } catch (Exception ex) { + result.recordFatalError("Couldn't import file.", ex); + LoggingUtils.logException(LOGGER, "Couldn't import file", ex); + } finally { + if (stream != null) { + IOUtils.closeQuietly(stream); + } + + } + + if (result.isSuccess()) { + xmlEditorModel.setObject(null); + } + + showResult(result); + target.add(getFeedbackPanel()); + } + + } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/dto/DebugSearchDto.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/dto/DebugSearchDto.java index de7b27dbdf6..e4372218e9f 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/dto/DebugSearchDto.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/configuration/dto/DebugSearchDto.java @@ -17,6 +17,7 @@ package com.evolveum.midpoint.web.page.admin.configuration.dto; import com.evolveum.midpoint.schema.constants.ObjectTypes; +import com.evolveum.midpoint.web.component.search.Search; import com.evolveum.midpoint.web.page.admin.dto.ObjectViewDto; import java.io.Serializable; @@ -26,25 +27,17 @@ */ public class DebugSearchDto implements Serializable { - public static final String F_TEXT = "text"; public static final String F_TYPE = "type"; - public static final String F_RESOURCE_OID = "resource"; + public static final String F_RESOURCE = "resource"; + public static final String F_SEARCH = "search"; - private String text; private ObjectTypes type; private ObjectViewDto resource; - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } + private Search search; public ObjectTypes getType() { if (type == null) { - return ObjectTypes.SYSTEM_CONFIGURATION; + type = ObjectTypes.SYSTEM_CONFIGURATION; } return type; } @@ -60,4 +53,12 @@ public ObjectViewDto getResource() { public void setResource(ObjectViewDto resource) { this.resource = resource; } + + public Search getSearch() { + return search; + } + + public void setSearch(Search search) { + this.search = search; + } } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/PageRole.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/PageRole.java index 35ef0dc37f0..04dfb8bc38d 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/PageRole.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/roles/PageRole.java @@ -196,7 +196,7 @@ protected AbstractObjectMainPanel createMainPanel(String id) { } @Override - protected PageBase getDefaultBackPage() { + public PageBase getDefaultBackPage() { return new PageRoles(false, ""); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageOrgUnit.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageOrgUnit.java index 57c699aab37..abfd877ee36 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageOrgUnit.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageOrgUnit.java @@ -165,7 +165,7 @@ protected AbstractObjectMainPanel createMainPanel(String id) { } @Override - protected PageBase getDefaultBackPage() { + public PageBase getDefaultBackPage() { return new PageOrgTree(); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUser.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUser.java index 1bf38b9a7d4..e78f79a6017 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUser.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUser.java @@ -129,7 +129,7 @@ protected AbstractObjectMainPanel createMainPanel(String id) { } @Override - protected PageBase getDefaultBackPage() { + public PageBase getDefaultBackPage() { return new PageUsers(); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUsers.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUsers.java index 1350b6ae5da..209f0120793 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUsers.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/admin/users/PageUsers.java @@ -126,11 +126,7 @@ public PageUsers() { public PageUsers(boolean clearPagingInSession) { this(clearPagingInSession, null, null); } - @Override - protected void onBeforeRender() { - // TODO Auto-generated method stub - super.onBeforeRender(); - } + public PageUsers(boolean clearPagingInSession, final UsersDto.SearchType type, final String text) { searchModel = new LoadableModel(false) { @@ -156,7 +152,6 @@ protected ExecuteChangeOptionsDto load() { }; getSessionStorage().clearPagingInSession(clearPagingInSession); - add(getFeedbackPanel()); initLayout(); } diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageSelfProfile.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageSelfProfile.java index d4720e7638e..284a06ff57e 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageSelfProfile.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/page/self/PageSelfProfile.java @@ -54,7 +54,7 @@ protected String getObjectOidParameter() { } @Override - protected PageBase getDefaultBackPage() { + public PageBase getDefaultBackPage() { return new PageSelfProfile(); } // diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/session/ConfigurationStorage.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/session/ConfigurationStorage.java index fa668470c87..1bcfdf2b4ab 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/session/ConfigurationStorage.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/session/ConfigurationStorage.java @@ -18,8 +18,11 @@ import com.evolveum.midpoint.prism.query.ObjectPaging; import com.evolveum.midpoint.schema.constants.ObjectTypes; +import com.evolveum.midpoint.web.component.search.Search; +import com.evolveum.midpoint.web.component.search.SearchFactory; import com.evolveum.midpoint.web.page.admin.configuration.dto.AccountDetailsSearchDto; import com.evolveum.midpoint.web.page.admin.configuration.dto.DebugSearchDto; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; /** * @author lazyman diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint.properties b/gui/admin-gui/src/main/resources/localization/Midpoint.properties index 8848a93f132..c93de44d3f7 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint.properties @@ -1520,6 +1520,7 @@ pageDebugList.menu.deleteAllIdentities=Delete all identities pageDebugList.menu.deleteAllType=Delete all of selected type pageDebugList.menu.deleteSelected=Delete selected pageDebugList.menu.deleteShadowsOnResource=Delete all shadows on resource +pageDebugList.menu.exportShadowsOnResource=Export all shadows on resource pageDebugList.menu.exportAll=Export all objects pageDebugList.menu.exportAllSelectedType=Export all of selected type pageDebugList.menu.exportSelected=Export selected @@ -1536,7 +1537,7 @@ pageDebugList.message.singleOrgDeleteProblem=Couldn't delete org. unit pageDebugList.message.singleShadowDeleteProblem=Couldn't delete shadow pageDebugList.message.singleUserDeleteProblem=Couldn't delete user pageDebugList.messsage.deleteAllOfType=Deleting objects of type {0}. -pageDebugList.messsage.deleteAllResourceShadows=Do your really want to delete all shadows on resource {0}? +pageDebugList.messsage.deleteAllResourceShadows=Do you really want to delete all shadows on resource {0}? pageDebugList.messsage.deleteAllShadowsStarted=Task which deletes all shadows on resource {0} was started. pageDebugList.name=Name pageDebugList.oid=Oid diff --git a/gui/admin-gui/src/main/resources/localization/Midpoint_en_US.properties b/gui/admin-gui/src/main/resources/localization/Midpoint_en_US.properties index dc1d0ba87b9..811933d94c0 100644 --- a/gui/admin-gui/src/main/resources/localization/Midpoint_en_US.properties +++ b/gui/admin-gui/src/main/resources/localization/Midpoint_en_US.properties @@ -1505,7 +1505,7 @@ pageDebugList.message.singleOrgDeleteProblem=Couldn't delete org. unit pageDebugList.message.singleShadowDeleteProblem=Couldn't delete shadow pageDebugList.message.singleUserDeleteProblem=Couldn't delete user pageDebugList.messsage.deleteAllOfType=Deleting objects of type {0}. -pageDebugList.messsage.deleteAllResourceShadows=Do your really want to delete all shadows on resource {0}? +pageDebugList.messsage.deleteAllResourceShadows=Do you really want to delete all shadows on resource {0}? pageDebugList.messsage.deleteAllShadowsStarted=Task which deletes all shadows on resource {0} was started. pageDebugList.name=Name pageDebugList.oid=Oid diff --git a/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/PageLoginTest.java b/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/PageLoginTest.java new file mode 100644 index 00000000000..e0806c4d2fc --- /dev/null +++ b/gui/admin-gui/src/test/java/com/evolveum/midpoint/web/PageLoginTest.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2010-2016 Evolveum + * + * Licensed 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 com.evolveum.midpoint.web; + +import com.evolveum.midpoint.web.page.admin.users.PageUser; +import com.evolveum.midpoint.web.page.login.PageLogin; +import org.apache.wicket.util.tester.WicketTester; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; +import org.testng.annotations.Test; + +/** + * Created by honchar + */ +@ContextConfiguration(locations = {"classpath:ctx-admin-gui-test-main.xml"}) +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) +public class PageLoginTest extends AbstractInitializedGuiIntegrationTest { + + @Test + public void test001BasicRender() { + WicketTester tester = new WicketTester(); + PageLogin page = tester.startPage(PageLogin.class); + tester.assertRenderedPage(PageUser.class); + } + + + +} diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinition.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinition.java index abff0d7b383..bdd9fb71c8e 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinition.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/CompositeRefinedObjectClassDefinition.java @@ -25,6 +25,7 @@ import com.evolveum.midpoint.prism.ItemDefinition; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObjectDefinition; +import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition; import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition; import com.evolveum.midpoint.schema.util.SchemaDebugUtil; import com.evolveum.midpoint.util.DebugUtil; @@ -225,6 +226,10 @@ public PrismObjectDefinition getObjectDefinition() { return structuralObjectClassDefinition.getObjectDefinition(); } + public ObjectClassComplexTypeDefinition getObjectClassDefinition() { + return structuralObjectClassDefinition.getObjectClassDefinition(); + } + public ResourceObjectReferenceType getBaseContext() { return structuralObjectClassDefinition.getBaseContext(); } diff --git a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java index b1276baff3c..fd9fe395871 100644 --- a/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java +++ b/infra/common/src/main/java/com/evolveum/midpoint/common/refinery/RefinedObjectClassDefinition.java @@ -114,7 +114,7 @@ public LayerRefinedObjectClassDefinition forLayer(LayerType layerType) { @Override public ResourceAttributeDefinition getDescriptionAttribute() { - return objectClassDefinition.getDescriptionAttribute(); + return getObjectClassDefinition().getDescriptionAttribute(); } @Override @@ -124,17 +124,17 @@ public void setDescriptionAttribute(ResourceAttributeDefinition descriptionAt @Override public RefinedAttributeDefinition getNamingAttribute() { - return substituteRefinedAttributeDefinition(objectClassDefinition.getNamingAttribute()); + return substituteRefinedAttributeDefinition(getObjectClassDefinition().getNamingAttribute()); } @Override public QName getTypeName() { - return objectClassDefinition.getTypeName(); + return getObjectClassDefinition().getTypeName(); } @Override public String getNativeObjectClass() { - return objectClassDefinition.getNativeObjectClass(); + return getObjectClassDefinition().getNativeObjectClass(); } @Override @@ -173,7 +173,7 @@ public void setKind(ShadowKindType kind) { @Override public RefinedAttributeDefinition getDisplayNameAttribute() { if (displayNameAttributeDefinition == null) { - ResourceAttributeDefinition displayNameAttribute = objectClassDefinition.getDisplayNameAttribute(); + ResourceAttributeDefinition displayNameAttribute = getObjectClassDefinition().getDisplayNameAttribute(); if (displayNameAttribute == null) { return null; } @@ -296,7 +296,7 @@ public Collection getProtectedObjectPatterns() { } public PrismContext getPrismContext() { - return resourceType.asPrismObject().getPrismContext(); + return getResourceType().asPrismObject().getPrismContext(); } @Override @@ -361,7 +361,7 @@ public RefinedAttributeDefinition findAttributeDefinition(String elementL } protected String getResourceNamespace() { - return ResourceTypeUtil.getResourceNamespace(resourceType); + return ResourceTypeUtil.getResourceNamespace(getResourceType()); } @Override @@ -440,7 +440,7 @@ private void constructObjectDefinition() { } public RefinedAttributeDefinition getAttributeDefinition(QName attributeName) { - for (RefinedAttributeDefinition attrDef : attributeDefinitions) { + for (RefinedAttributeDefinition attrDef : getAttributeDefinitions()) { if (QNameUtil.match(attrDef.getName(), attributeName)) { return attrDef; } @@ -450,7 +450,7 @@ public RefinedAttributeDefinition getAttributeDefinition(QName attributeName) public void add(RefinedAttributeDefinition refinedAttributeDefinition) { - attributeDefinitions.add(refinedAttributeDefinition); + ((Collection)getAttributeDefinitions()).add(refinedAttributeDefinition); } public boolean containsAttributeDefinition(ItemPathType pathType) { @@ -459,7 +459,7 @@ public boolean containsAttributeDefinition(ItemPathType pathType) { } public boolean containsAttributeDefinition(QName attributeName) { - for (RefinedAttributeDefinition rAttributeDef : attributeDefinitions) { + for (RefinedAttributeDefinition rAttributeDef : getAttributeDefinitions()) { if (QNameUtil.match(rAttributeDef.getName(), attributeName)) { return true; } @@ -654,7 +654,7 @@ public void parseAttributes(RefinedResourceSchema rSchema, String contextDescrip return; } - parseAttributesFrom(rSchema, objectClassDefinition, false, contextDescription); + parseAttributesFrom(rSchema, getObjectClassDefinition(), false, contextDescription); if (auxiliaryObjectClassDefinitions != null) { for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition: auxiliaryObjectClassDefinitions) { parseAttributesFrom(rSchema, auxiliaryObjectClassDefinition, true, contextDescription); @@ -759,8 +759,8 @@ public PrismObject createBlankShadow() { accountShadowType.setIntent(getIntent()); accountShadowType.setKind(getKind()); - accountShadowType.setObjectClass(objectClassDefinition.getTypeName()); - accountShadowType.setResourceRef(ObjectTypeUtil.createObjectRef(resourceType)); + accountShadowType.setObjectClass(getObjectClassDefinition().getTypeName()); + accountShadowType.setResourceRef(ObjectTypeUtil.createObjectRef(getResourceType())); // Setup definition PrismObjectDefinition newDefinition = accountShadow.getDefinition().cloneWithReplacedDefinition( @@ -771,7 +771,7 @@ public PrismObject createBlankShadow() { } public ResourceShadowDiscriminator getShadowDiscriminator() { - return new ResourceShadowDiscriminator(resourceType.getOid(), getKind(), getIntent()); + return new ResourceShadowDiscriminator(getResourceType().getOid(), getKind(), getIntent()); } public Collection getNamesOfAttributesWithOutboundExpressions() { @@ -892,7 +892,7 @@ public AttributeFetchStrategyType getActivationFetchStrategy(QName propertyName) } public T getEffectiveCapability(Class capabilityClass) { - return ResourceTypeUtil.getEffectiveCapability(resourceType, schemaHandlingObjectTypeDefinitionType, capabilityClass); + return ResourceTypeUtil.getEffectiveCapability(getResourceType(), schemaHandlingObjectTypeDefinitionType, capabilityClass); } public PagedSearchCapabilityType getPagedSearches() { @@ -910,14 +910,14 @@ public boolean isObjectCountingEnabled() { public boolean isAuxiliary() { - return objectClassDefinition.isAuxiliary(); + return getObjectClassDefinition().isAuxiliary(); } public boolean matches(ShadowType shadowType) { if (shadowType == null) { return false; } - if (!QNameUtil.match(objectClassDefinition.getTypeName(), shadowType.getObjectClass())) { + if (!QNameUtil.match(getObjectClassDefinition().getTypeName(), shadowType.getObjectClass())) { return false; } if (shadowType.getKind() == null) { diff --git a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismProperty.java b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismProperty.java index 2fc3e1c1f66..4c5fd97ee07 100644 --- a/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismProperty.java +++ b/infra/prism/src/main/java/com/evolveum/midpoint/prism/PrismProperty.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -396,6 +396,16 @@ public PropertyDelta diff(PrismProperty other, boolean ignoreMetadata, boo } return (PropertyDelta)deltas.get(0); } + + public static PropertyDelta diff(PrismProperty a, PrismProperty b) { + if (a == null) { + PropertyDelta delta = b.createDelta(); + delta.addValuesToAdd(PrismValue.cloneCollection(b.getValues())); + return delta; + } else { + return a.diff(b); + } + } @Override protected void checkDefinition(PrismPropertyDefinition def) { diff --git a/infra/prism/src/test/java/com/evolveum/midpoint/prism/TestDiff.java b/infra/prism/src/test/java/com/evolveum/midpoint/prism/TestDiff.java index 8567962ff86..b2352b98b65 100644 --- a/infra/prism/src/test/java/com/evolveum/midpoint/prism/TestDiff.java +++ b/infra/prism/src/test/java/com/evolveum/midpoint/prism/TestDiff.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ */ package com.evolveum.midpoint.prism; +import static org.testng.AssertJUnit.assertNull; import static com.evolveum.midpoint.prism.PrismInternalTestUtil.*; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; @@ -28,12 +29,14 @@ import com.evolveum.midpoint.prism.delta.ItemDelta; import com.evolveum.midpoint.prism.delta.ObjectDelta; +import com.evolveum.midpoint.prism.delta.PropertyDelta; import com.evolveum.midpoint.prism.foo.AssignmentType; import com.evolveum.midpoint.prism.foo.UserType; import com.evolveum.midpoint.prism.path.IdItemPathSegment; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.path.ItemPathSegment; import com.evolveum.midpoint.prism.path.NameItemPathSegment; +import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.prism.util.PrismTestUtil; import com.evolveum.midpoint.util.DebugUtil; @@ -75,6 +78,52 @@ public void testUserSimplePropertyDiffNoChange() throws Exception { assertEquals("Wrong OID", USER_JACK_OID, delta.getOid()); delta.checkConsistence(); } + + @Test + public void testPropertySimplePropertyDiffNoChange() throws Exception { + System.out.println("\n\n===[ testPropertySimplePropertyDiffNoChange ]===\n"); + // GIVEN + PrismObjectDefinition userDef = getUserTypeDefinition(); + + PrismObject user1 = userDef.instantiate(); + user1.setOid(USER_JACK_OID); + user1.setPropertyRealValue(UserType.F_NAME, PrismTestUtil.createPolyString("test name")); + PrismProperty user1NameProp = user1.findProperty(UserType.F_NAME); + + PrismObject user2 = userDef.instantiate(); + user2.setOid(USER_JACK_OID); + user2.setPropertyRealValue(UserType.F_NAME, PrismTestUtil.createPolyString("test name")); + PrismProperty user2NameProp = user2.findProperty(UserType.F_NAME); + + // WHEN + PropertyDelta delta = user1NameProp.diff(user2NameProp); + + // THEN + assertNull(delta); + } + + @Test + public void testPropertySimplePropertyDiffNoChangeStatic() throws Exception { + System.out.println("\n\n===[ testPropertySimplePropertyDiffNoChangeStatic ]===\n"); + // GIVEN + PrismObjectDefinition userDef = getUserTypeDefinition(); + + PrismObject user1 = userDef.instantiate(); + user1.setOid(USER_JACK_OID); + user1.setPropertyRealValue(UserType.F_NAME, PrismTestUtil.createPolyString("test name")); + PrismProperty user1NameProp = user1.findProperty(UserType.F_NAME); + + PrismObject user2 = userDef.instantiate(); + user2.setOid(USER_JACK_OID); + user2.setPropertyRealValue(UserType.F_NAME, PrismTestUtil.createPolyString("test name")); + PrismProperty user2NameProp = user2.findProperty(UserType.F_NAME); + + // WHEN + PropertyDelta delta = PrismProperty.diff(user1NameProp, user2NameProp); + + // THEN + assertNull(delta); + } @Test public void testUserSimplePropertyDiffReplace() throws Exception { @@ -102,6 +151,58 @@ public void testUserSimplePropertyDiffReplace() throws Exception { delta.checkConsistence(); } + @Test + public void testPropertyUserSimplePropertyDiffReplace() throws Exception { + System.out.println("\n\n===[ testPropertyUserSimplePropertyDiffReplace ]===\n"); + // GIVEN + PrismObjectDefinition userDef = getUserTypeDefinition(); + + PrismObject user1 = userDef.instantiate(); + user1.setOid(USER_JACK_OID); + user1.setPropertyRealValue(UserType.F_NAME, PrismTestUtil.createPolyString("test name")); + PrismProperty user1NameProp = user1.findProperty(UserType.F_NAME); + + PrismObject user2 = userDef.instantiate(); + user2.setOid(USER_JACK_OID); + user2.setPropertyRealValue(UserType.F_NAME, PrismTestUtil.createPolyString("other name")); + PrismProperty user2NameProp = user2.findProperty(UserType.F_NAME); + + // WHEN + PropertyDelta delta = user1NameProp.diff(user2NameProp); + + // THEN + assertNotNull(delta); + System.out.println(delta.debugDump()); + PrismAsserts.assertReplace(delta, PrismTestUtil.createPolyString("other name")); + delta.checkConsistence(); + } + + @Test + public void testPropertyUserSimplePropertyDiffReplaceStatic() throws Exception { + System.out.println("\n\n===[ testPropertyUserSimplePropertyDiffReplaceStatic ]===\n"); + // GIVEN + PrismObjectDefinition userDef = getUserTypeDefinition(); + + PrismObject user1 = userDef.instantiate(); + user1.setOid(USER_JACK_OID); + user1.setPropertyRealValue(UserType.F_NAME, PrismTestUtil.createPolyString("test name")); + PrismProperty user1NameProp = user1.findProperty(UserType.F_NAME); + + PrismObject user2 = userDef.instantiate(); + user2.setOid(USER_JACK_OID); + user2.setPropertyRealValue(UserType.F_NAME, PrismTestUtil.createPolyString("other name")); + PrismProperty user2NameProp = user2.findProperty(UserType.F_NAME); + + // WHEN + PropertyDelta delta = PrismProperty.diff(user1NameProp, user2NameProp); + + // THEN + assertNotNull(delta); + System.out.println(delta.debugDump()); + PrismAsserts.assertReplace(delta, PrismTestUtil.createPolyString("other name")); + delta.checkConsistence(); + } + @Test public void testUserSimpleDiffMultiNoChange() throws Exception { System.out.println("\n\n===[ testUserSimpleDiffMultiNoChange ]===\n"); @@ -130,6 +231,58 @@ public void testUserSimpleDiffMultiNoChange() throws Exception { assertEquals("Wrong OID", USER_JACK_OID, delta.getOid()); delta.checkConsistence(); } + + @Test + public void testPropertyUserSimpleDiffMultiNoChange() throws Exception { + System.out.println("\n\n===[ testPropertyUserSimpleDiffMultiNoChange ]===\n"); + + // GIVEN + PrismObjectDefinition userDef = getUserTypeDefinition(); + + PrismObject user1 = userDef.instantiate(); + user1.setOid(USER_JACK_OID); + PrismProperty additionalNamesProp1 = user1.findOrCreateProperty(UserType.F_ADDITIONAL_NAMES); + additionalNamesProp1.addRealValue("foo"); + additionalNamesProp1.addRealValue("bar"); + + PrismObject user2 = userDef.instantiate(); + user2.setOid(USER_JACK_OID); + PrismProperty additionalNamesProp2 = user2.findOrCreateProperty(UserType.F_ADDITIONAL_NAMES); + additionalNamesProp2.addRealValue("foo"); + additionalNamesProp2.addRealValue("bar"); + + // WHEN + PropertyDelta delta = additionalNamesProp1.diff(additionalNamesProp2); + + // THEN + assertNull(delta); + } + + @Test + public void testPropertyUserSimpleDiffMultiNoChangeStatic() throws Exception { + System.out.println("\n\n===[ testPropertyUserSimpleDiffMultiNoChangeStatic ]===\n"); + + // GIVEN + PrismObjectDefinition userDef = getUserTypeDefinition(); + + PrismObject user1 = userDef.instantiate(); + user1.setOid(USER_JACK_OID); + PrismProperty additionalNamesProp1 = user1.findOrCreateProperty(UserType.F_ADDITIONAL_NAMES); + additionalNamesProp1.addRealValue("foo"); + additionalNamesProp1.addRealValue("bar"); + + PrismObject user2 = userDef.instantiate(); + user2.setOid(USER_JACK_OID); + PrismProperty additionalNamesProp2 = user2.findOrCreateProperty(UserType.F_ADDITIONAL_NAMES); + additionalNamesProp2.addRealValue("foo"); + additionalNamesProp2.addRealValue("bar"); + + // WHEN + PropertyDelta delta = PrismProperty.diff(additionalNamesProp1, additionalNamesProp2); + + // THEN + assertNull(delta); + } @Test public void testUserSimpleDiffMultiAdd() throws Exception { @@ -162,6 +315,112 @@ public void testUserSimpleDiffMultiAdd() throws Exception { assertEquals("Wrong OID", USER_JACK_OID, delta.getOid()); delta.checkConsistence(); } + + @Test + public void testPropertyUserSimpleDiffMultiAdd() throws Exception { + System.out.println("\n\n===[ testPropertyUserSimpleDiffMultiAdd ]===\n"); + + // GIVEN + PrismObjectDefinition userDef = getUserTypeDefinition(); + + PrismObject user1 = userDef.instantiate(); + user1.setOid(USER_JACK_OID); + PrismProperty additionalNamesProp1 = user1.findOrCreateProperty(UserType.F_ADDITIONAL_NAMES); + additionalNamesProp1.addRealValue("foo"); + additionalNamesProp1.addRealValue("bar"); + + PrismObject user2 = userDef.instantiate(); + user2.setOid(USER_JACK_OID); + PrismProperty additionalNamesProp2 = user2.findOrCreateProperty(UserType.F_ADDITIONAL_NAMES); + additionalNamesProp2.addRealValue("foo"); + additionalNamesProp2.addRealValue("bar"); + additionalNamesProp2.addRealValue("baz"); + + // WHEN + PropertyDelta delta = additionalNamesProp1.diff(additionalNamesProp2); + + // THEN + assertNotNull(delta); + System.out.println(delta.debugDump()); + PrismAsserts.assertAdd(delta, "baz"); + delta.checkConsistence(); + } + + @Test + public void testPropertyUserSimpleDiffMultiAddStatic() throws Exception { + System.out.println("\n\n===[ testPropertyUserSimpleDiffMultiAddStatic ]===\n"); + + // GIVEN + PrismObjectDefinition userDef = getUserTypeDefinition(); + + PrismObject user1 = userDef.instantiate(); + user1.setOid(USER_JACK_OID); + PrismProperty additionalNamesProp1 = user1.findOrCreateProperty(UserType.F_ADDITIONAL_NAMES); + additionalNamesProp1.addRealValue("foo"); + additionalNamesProp1.addRealValue("bar"); + + PrismObject user2 = userDef.instantiate(); + user2.setOid(USER_JACK_OID); + PrismProperty additionalNamesProp2 = user2.findOrCreateProperty(UserType.F_ADDITIONAL_NAMES); + additionalNamesProp2.addRealValue("foo"); + additionalNamesProp2.addRealValue("bar"); + additionalNamesProp2.addRealValue("baz"); + + // WHEN + PropertyDelta delta = PrismProperty.diff(additionalNamesProp1, additionalNamesProp2); + + // THEN + assertNotNull(delta); + System.out.println(delta.debugDump()); + PrismAsserts.assertAdd(delta, "baz"); + delta.checkConsistence(); + } + + @Test + public void testPropertyUserSimpleDiffMultiAddStaticNull1() throws Exception { + System.out.println("\n\n===[ testPropertyUserSimpleDiffMultiAddStaticNull1 ]===\n"); + + // GIVEN + PrismObjectDefinition userDef = getUserTypeDefinition(); + + PrismObject user2 = userDef.instantiate(); + user2.setOid(USER_JACK_OID); + PrismProperty additionalNamesProp2 = user2.findOrCreateProperty(UserType.F_ADDITIONAL_NAMES); + additionalNamesProp2.addRealValue("foo"); + additionalNamesProp2.addRealValue("bar"); + + // WHEN + PropertyDelta delta = PrismProperty.diff(null, additionalNamesProp2); + + // THEN + assertNotNull(delta); + System.out.println(delta.debugDump()); + PrismAsserts.assertAdd(delta, "foo", "bar"); + delta.checkConsistence(); + } + + @Test + public void testPropertyUserSimpleDiffMultiAddStaticNull2() throws Exception { + System.out.println("\n\n===[ testPropertyUserSimpleDiffMultiAddStaticNull2 ]===\n"); + + // GIVEN + PrismObjectDefinition userDef = getUserTypeDefinition(); + + PrismObject user2 = userDef.instantiate(); + user2.setOid(USER_JACK_OID); + PrismProperty additionalNamesProp1 = user2.findOrCreateProperty(UserType.F_ADDITIONAL_NAMES); + additionalNamesProp1.addRealValue("bar"); + additionalNamesProp1.addRealValue("baz"); + + // WHEN + PropertyDelta delta = PrismProperty.diff(additionalNamesProp1, null); + + // THEN + assertNotNull(delta); + System.out.println(delta.debugDump()); + PrismAsserts.assertDelete(delta, "bar", "baz"); + delta.checkConsistence(); + } @Test public void testContainerSimpleDiffNoChange() throws Exception { diff --git a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestUtil.java b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestUtil.java index 3bd93ab0c3e..87a9c8d9f04 100644 --- a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestUtil.java +++ b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -590,4 +590,9 @@ public static int getJavaMajorVersion() { } } + + public static void assertMessageContains(String message, String expectedSubstring) { + assertTrue("Expected that message will contain substring '"+expectedSubstring+"', but it did not. Message: "+message, + message.contains(expectedSubstring)); + } } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java index e546bb4ae22..5c6831abdac 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/controller/ModelInteractionServiceImpl.java @@ -30,6 +30,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; +import com.evolveum.midpoint.common.refinery.CompositeRefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.LayerRefinedAttributeDefinition; import com.evolveum.midpoint.common.refinery.LayerRefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; @@ -270,21 +271,7 @@ public RefinedObjectClassDefinition getEditObjectClassDefinition(PrismObject resolveTarget(AssignmentType assignmentType, ObjectType s } PrismObject target = null; - target = repository.getObject(clazz, oid, null, result); + try { + target = repository.getObject(clazz, oid, null, result); + } catch (SchemaException e) { + throw new SchemaException(e.getMessage() + " in " + sourceDescription, e); + } if (target == null) { throw new IllegalArgumentException("Got null target from repository, oid:"+oid+", class:"+clazz+" (should not happen, probably a bug) in "+sourceDescription); } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java index 45b85d07b51..ed23cf89cc4 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,6 +39,7 @@ import org.jvnet.jaxb2_commons.lang.Validate; import com.evolveum.midpoint.common.crypto.CryptoUtil; +import com.evolveum.midpoint.common.refinery.CompositeRefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition; import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition; import com.evolveum.midpoint.common.refinery.RefinedResourceSchema; @@ -167,6 +168,7 @@ public class LensProjectionContext extends LensElementContext implem private transient RefinedObjectClassDefinition structuralObjectClassDefinition; private transient Collection auxiliaryObjectClassDefinitions; + private transient CompositeRefinedObjectClassDefinition compositeObjectClassDefinition; private ValuePolicyType accountPasswordPolicy; @@ -372,7 +374,7 @@ public void setResource(ResourceType resource) { public PrismObjectDefinition getObjectDefinition() { if (shadowDefinition == null) { try { - shadowDefinition = ShadowUtil.applyObjectClass(super.getObjectDefinition(), getStructuralObjectClassDefinition()); + shadowDefinition = ShadowUtil.applyObjectClass(super.getObjectDefinition(), getCompositeObjectClassDefinition()); } catch (SchemaException e) { // This should not happen throw new SystemException(e.getMessage(), e); @@ -587,6 +589,17 @@ public Collection getAuxiliaryObjectClassDefinitio } return auxiliaryObjectClassDefinitions; } + + public CompositeRefinedObjectClassDefinition getCompositeObjectClassDefinition() throws SchemaException { + if (compositeObjectClassDefinition == null) { + RefinedObjectClassDefinition structuralObjectClassDefinition = getStructuralObjectClassDefinition(); + if (structuralObjectClassDefinition != null) { + compositeObjectClassDefinition = new CompositeRefinedObjectClassDefinition( + structuralObjectClassDefinition, getAuxiliaryObjectClassDefinitions()); + } + } + return compositeObjectClassDefinition; + } private void addAuxiliaryObjectClassNames(List auxiliaryObjectClassQNames, PrismObject shadow) { @@ -722,7 +735,7 @@ public void recompute() throws SchemaException { } if (base == null && accDelta.isModify()) { - RefinedObjectClassDefinition rAccountDef = getStructuralObjectClassDefinition(); + RefinedObjectClassDefinition rAccountDef = getCompositeObjectClassDefinition(); if (rAccountDef != null) { base = (PrismObject) rAccountDef.createBlankShadow(); } @@ -811,13 +824,13 @@ public ObjectDelta getExecutableDelta() throws SchemaException { // We need to convert modify delta to ADD ObjectDelta addDelta = new ObjectDelta(getObjectTypeClass(), ChangeType.ADD, getPrismContext()); - RefinedObjectClassDefinition rAccount = getStructuralObjectClassDefinition(); + RefinedObjectClassDefinition rObjectClassDef = getCompositeObjectClassDefinition(); - if (rAccount == null) { + if (rObjectClassDef == null) { throw new IllegalStateException("Definition for account type " + getResourceShadowDiscriminator() + " not found in the context, but it should be there"); } - PrismObject newAccount = (PrismObject) rAccount.createBlankShadow(); + PrismObject newAccount = (PrismObject) rObjectClassDef.createBlankShadow(); addDelta.setObjectToAdd(newAccount); if (origDelta != null) { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConsolidationProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConsolidationProcessor.java index 8e32651a3b7..e19aa8f5e6f 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConsolidationProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ConsolidationProcessor.java @@ -230,7 +230,7 @@ public boolean isAuthoritative() { ObjectDelta objectDelta = new ObjectDelta(ShadowType.class, ChangeType.MODIFY, prismContext); objectDelta.setOid(projCtx.getOid()); - RefinedObjectClassDefinition rOcDef = projCtx.getStructuralObjectClassDefinition(); + RefinedObjectClassDefinition rOcDef = projCtx.getCompositeObjectClassDefinition(); if (rOcDef == null) { LOGGER.error("Definition for account type {} not found in the context, but it should be there, dumping context:\n{}", discr, context.debugDump()); throw new IllegalStateException("Definition for account type " + discr + " not found in the context, but it should be there"); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ContextLoader.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ContextLoader.java index e2ceb8169e6..18f9ffc6667 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ContextLoader.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ContextLoader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/CredentialsProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/CredentialsProcessor.java index 9d3a583eca9..097bcfb8d07 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/CredentialsProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/CredentialsProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/InboundProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/InboundProcessor.java index 00999acc264..ce4285cc163 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/InboundProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/InboundProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -161,15 +161,15 @@ void processInboundFocal(LensContext context, Task task continue; } - RefinedObjectClassDefinition accountDefinition = projectionContext.getStructuralObjectClassDefinition(); - if (accountDefinition == null) { - LOGGER.error("Definition for account type {} not found in the context, but it " + + RefinedObjectClassDefinition rOcDef = projectionContext.getCompositeObjectClassDefinition(); + if (rOcDef == null) { + LOGGER.error("Definition for projection type {} not found in the context, but it " + "should be there, dumping context:\n{}", rat, context.debugDump()); - throw new IllegalStateException("Definition for account type " + rat + throw new IllegalStateException("Definition for projection type " + rat + " not found in the context, but it should be there"); } - processInboundExpressionsForProjection(context, projectionContext, accountDefinition, aPrioriDelta, task, now, result); + processInboundExpressionsForProjection(context, projectionContext, rOcDef, aPrioriDelta, task, now, result); } } finally { diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java index a2132735025..4ec65df2c19 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/OutboundProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -104,7 +104,7 @@ public void processOutbound(LensContext context, LensPr LOGGER.trace("Processing outbound expressions for {} starting", discr); - RefinedObjectClassDefinition rOcDef = projCtx.getStructuralObjectClassDefinition(); + RefinedObjectClassDefinition rOcDef = projCtx.getCompositeObjectClassDefinition(); if (rOcDef == null) { LOGGER.error("Definition for {} not found in the context, but it should be there, dumping context:\n{}", discr, context.debugDump()); throw new IllegalStateException("Definition for " + discr + " not found in the context, but it should be there"); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ProjectionValuesProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ProjectionValuesProcessor.java index b6641b74469..a71da90064b 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ProjectionValuesProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ProjectionValuesProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -459,7 +459,7 @@ private boolean willResetIterationCounter(LensProjectionContext projectionContex if (accountDelta == null) { return false; } - RefinedObjectClassDefinition oOcDef = projectionContext.getStructuralObjectClassDefinition(); + RefinedObjectClassDefinition oOcDef = projectionContext.getCompositeObjectClassDefinition(); for (RefinedAttributeDefinition identifierDef: oOcDef.getIdentifiers()) { ItemPath identifierPath = new ItemPath(ShadowType.F_ATTRIBUTES, identifierDef.getName()); if (accountDelta.findPropertyDelta(identifierPath) != null) { @@ -552,7 +552,7 @@ public void checkSchemaAndPolicies(LensContext context return; } - RefinedObjectClassDefinition rAccountDef = accountContext.getStructuralObjectClassDefinition(); + RefinedObjectClassDefinition rAccountDef = accountContext.getCompositeObjectClassDefinition(); if (rAccountDef == null) { throw new SchemaException("No definition for account type '" +accountContext.getResourceShadowDiscriminator()+"' in "+accountContext.getResource()); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java index bbf0448afa6..68604bff7ca 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ReconciliationProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -171,7 +171,7 @@ void processReconciliationFocus(LensContext context, LOGGER.trace("Starting reconciliation of {}", projCtx.getHumanReadableName()); } - RefinedObjectClassDefinition rOcDef = projCtx.getStructuralObjectClassDefinition(); + RefinedObjectClassDefinition rOcDef = projCtx.getCompositeObjectClassDefinition(); Map,PrismPropertyDefinition>>> squeezedAttributes = projCtx .getSqueezedAttributes(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ShadowConstraintsChecker.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ShadowConstraintsChecker.java index 7be23721bd9..174ab579696 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ShadowConstraintsChecker.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ShadowConstraintsChecker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -106,7 +106,7 @@ public PrismObject getConflictingShadow() { public void check(Task task, OperationResult result) throws SchemaException, ObjectAlreadyExistsException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException { - RefinedObjectClassDefinition projDef = projectionContext.getStructuralObjectClassDefinition(); + RefinedObjectClassDefinition projOcDef = projectionContext.getCompositeObjectClassDefinition(); PrismObject projectionNew = projectionContext.getObjectNew(); if (projectionNew == null) { // This must be delete @@ -140,7 +140,7 @@ public boolean confirmViolation(String oid) { } }; - constraintsCheckingResult = provisioningService.checkConstraints(projDef, projectionNew, + constraintsCheckingResult = provisioningService.checkConstraints(projOcDef, projectionNew, projectionContext.getResource(), projectionContext.getOid(), projectionContext.getResourceShadowDiscriminator(), confirmer, task, result); diff --git a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/AbstractInternalModelIntegrationTest.java b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/AbstractInternalModelIntegrationTest.java index 9ec3b9d5aed..039c4da8621 100644 --- a/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/AbstractInternalModelIntegrationTest.java +++ b/model/model-impl/src/test/java/com/evolveum/midpoint/model/impl/AbstractInternalModelIntegrationTest.java @@ -407,7 +407,7 @@ protected ObjectDelta createAccountDelta(LensProjectionContext a ResourceType resourceType = accCtx.getResource(); QName attrQName = new QName(ResourceTypeUtil.getResourceNamespace(resourceType), attributeLocalName); ItemPath attrPath = new ItemPath(ShadowType.F_ATTRIBUTES, attrQName); - RefinedObjectClassDefinition refinedAccountDefinition = accCtx.getStructuralObjectClassDefinition(); + RefinedObjectClassDefinition refinedAccountDefinition = accCtx.getCompositeObjectClassDefinition(); RefinedAttributeDefinition attrDef = refinedAccountDefinition.findAttributeDefinition(attrQName); assertNotNull("No definition of attribute "+attrQName+" in account def "+refinedAccountDefinition, attrDef); ObjectDelta accountDelta = ObjectDelta.createEmptyModifyDelta(ShadowType.class, accountOid, prismContext); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestStrangeCases.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestStrangeCases.java index 2a5eb9582f9..e7fa879327c 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestStrangeCases.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestStrangeCases.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum + * Copyright (c) 2010-2016 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -104,6 +104,15 @@ public class TestStrangeCases extends AbstractInitializedModelIntegrationTest { private static final File ROLE_STUPID_FILE = new File(TEST_DIR, "role-stupid.xml"); private static final String ROLE_STUPID_OID = "12345678-d34d-b33f-f00d-555555550002"; + + private static final File ROLE_BAD_CONSTRUCTION_RESOURCE_REF_FILE = new File(TEST_DIR, "role-bad-construction-resource-ref.xml"); + private static final String ROLE_BAD_CONSTRUCTION_RESOURCE_REF_OID = "54084f2c-eba0-11e5-8278-03ea5d7058d9"; + + private static final File ROLE_META_BAD_CONSTRUCTION_RESOURCE_REF_FILE = new File(TEST_DIR, "role-meta-bad-construction-resource-ref.xml"); + private static final String ROLE_META_BAD_CONSTRUCTION_RESOURCE_REF_OID = "90b931ae-eba8-11e5-977a-b73ba58cf18b"; + + private static final File ROLE_TARGET_BAD_CONSTRUCTION_RESOURCE_REF_FILE = new File(TEST_DIR, "role-target-bad-construction-resource-ref.xml"); + private static final String ROLE_TARGET_BAD_CONSTRUCTION_RESOURCE_REF_OID = "e69b791a-eba8-11e5-80f5-33732b18f10a"; private static final File ROLE_RECURSION_FILE = new File(TEST_DIR, "role-recursion.xml"); private static final String ROLE_RECURSION_OID = "12345678-d34d-b33f-f00d-555555550003"; @@ -140,6 +149,8 @@ public void initSystem(Task initTask, OperationResult initResult) addObject(ROLE_IDIOT_FILE, initTask, initResult); addObject(ROLE_STUPID_FILE, initTask, initResult); addObject(ROLE_RECURSION_FILE, initTask, initResult); + addObject(ROLE_BAD_CONSTRUCTION_RESOURCE_REF_FILE, initTask, initResult); + addObject(ROLE_META_BAD_CONSTRUCTION_RESOURCE_REF_FILE, initTask, initResult); DebugUtil.setDetailedDebugDump(true); } @@ -637,6 +648,88 @@ public void test349UnAssignDeGhoulashConstructionNonExistentResource() throws Ex assertUser(userDeGhoulash, USER_DEGHOULASH_OID, "deghoulash", "Charles DeGhoulash", "Charles", "DeGhoulash"); assertAssignments(userDeGhoulash, 0); } + + @Test + public void test350AssignDeGhoulashRoleBadConstructionResourceRef() throws Exception { + final String TEST_NAME = "test350AssignDeGhoulashRoleBadConstructionResourceRef"; + TestUtil.displayTestTile(this, TEST_NAME); + + // GIVEN + Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); + dummyAuditService.clear(); + + // WHEN + assignRole(USER_DEGHOULASH_OID, ROLE_BAD_CONSTRUCTION_RESOURCE_REF_OID, task, result); + + // THEN + result.computeStatus(); + display("result", result); + TestUtil.assertPartialError(result); + String message = result.getMessage(); + TestUtil.assertMessageContains(message, "role:"+ROLE_BAD_CONSTRUCTION_RESOURCE_REF_OID); + TestUtil.assertMessageContains(message, "Bad resourceRef in construction"); + TestUtil.assertMessageContains(message, "this-oid-does-not-exist"); + + PrismObject userDeGhoulash = getUser(USER_DEGHOULASH_OID); + display("User after change execution", userDeGhoulash); + assertUser(userDeGhoulash, USER_DEGHOULASH_OID, "deghoulash", "Charles DeGhoulash", "Charles", "DeGhoulash"); + assertAssignedRole(userDeGhoulash, ROLE_BAD_CONSTRUCTION_RESOURCE_REF_OID); + } + + @Test + public void test351UnAssignDeGhoulashRoleBadConstructionResourceRef() throws Exception { + final String TEST_NAME = "test351UnAssignDeGhoulashRoleBadConstructionResourceRef"; + TestUtil.displayTestTile(this, TEST_NAME); + + // GIVEN + Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); + dummyAuditService.clear(); + + // WHEN + unassignRole(USER_DEGHOULASH_OID, ROLE_BAD_CONSTRUCTION_RESOURCE_REF_OID, task, result); + + // THEN + result.computeStatus(); + display("result", result); + TestUtil.assertPartialError(result); + String message = result.getMessage(); + TestUtil.assertMessageContains(message, "role:"+ROLE_BAD_CONSTRUCTION_RESOURCE_REF_OID); + TestUtil.assertMessageContains(message, "Bad resourceRef in construction"); + TestUtil.assertMessageContains(message, "this-oid-does-not-exist"); + + PrismObject userDeGhoulash = getUser(USER_DEGHOULASH_OID); + display("User after change execution", userDeGhoulash); + assertUser(userDeGhoulash, USER_DEGHOULASH_OID, "deghoulash", "Charles DeGhoulash", "Charles", "DeGhoulash"); + assertAssignedNoRole(userDeGhoulash); + } + + @Test + public void test360AddRoleTargetBadConstructionResourceRef() throws Exception { + final String TEST_NAME = "test360AddRoleTargetBadConstructionResourceRef"; + TestUtil.displayTestTile(this, TEST_NAME); + + // GIVEN + Task task = taskManager.createTaskInstance(TestModelServiceContract.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL); + dummyAuditService.clear(); + + // WHEN + addObject(ROLE_TARGET_BAD_CONSTRUCTION_RESOURCE_REF_FILE, task, result); + + // THEN + result.computeStatus(); + display("result", result); + TestUtil.assertPartialError(result); + String message = result.getMessage(); + TestUtil.assertMessageContains(message, "role:"+ROLE_META_BAD_CONSTRUCTION_RESOURCE_REF_OID); + TestUtil.assertMessageContains(message, "Bad resourceRef in construction metarole"); + TestUtil.assertMessageContains(message, "this-oid-does-not-exist"); + } @Test public void test400ImportJackMockTask() throws Exception { diff --git a/model/model-intest/src/test/resources/strange/role-bad-construction-resource-ref.xml b/model/model-intest/src/test/resources/strange/role-bad-construction-resource-ref.xml new file mode 100644 index 00000000000..66caedebb08 --- /dev/null +++ b/model/model-intest/src/test/resources/strange/role-bad-construction-resource-ref.xml @@ -0,0 +1,27 @@ + + + Bad resourceRef in construction + + + + account + default + + + diff --git a/model/model-intest/src/test/resources/strange/role-meta-bad-construction-resource-ref.xml b/model/model-intest/src/test/resources/strange/role-meta-bad-construction-resource-ref.xml new file mode 100644 index 00000000000..df623e7529b --- /dev/null +++ b/model/model-intest/src/test/resources/strange/role-meta-bad-construction-resource-ref.xml @@ -0,0 +1,27 @@ + + + Bad resourceRef in construction metarole + + + + generic + whatever + + + diff --git a/model/model-intest/src/test/resources/strange/role-target-bad-construction-resource-ref.xml b/model/model-intest/src/test/resources/strange/role-target-bad-construction-resource-ref.xml new file mode 100644 index 00000000000..d589d64fa6a --- /dev/null +++ b/model/model-intest/src/test/resources/strange/role-target-bad-construction-resource-ref.xml @@ -0,0 +1,23 @@ + + + Bad resourceRef in construction target role + + + + diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java index ac4ab619909..87abf967547 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowCache.java @@ -265,6 +265,9 @@ public PrismObject getShadow(String oid, PrismObject rep resourceShadow = resouceObjectConverter.getResourceObject(ctx, identifiers, true, parentResult); + // Resource shadow may have different auxiliary object classes than the original repo shadow. Make sure we have + // the definition that applies to resource shadow. We will fix repo shadow later. + ProvisioningContext shadowCtx = ctx.spawn(resourceShadow); resourceManager.modifyResourceAvailabilityStatus(resource.asPrismObject(), AvailabilityStatusType.UP, parentResult); //try to apply changes to the account only if the resource if UP @@ -280,9 +283,9 @@ public PrismObject getShadow(String oid, PrismObject rep LOGGER.trace("Resource object fetched from resource:\n{}", resourceShadow.debugDump()); } - forceRenameIfNeeded(ctx, resourceShadow.asObjectable(), repositoryShadow.asObjectable(), parentResult); + shadowManager.updateRepoShadow(shadowCtx, resourceShadow.asObjectable(), repositoryShadow.asObjectable(), parentResult); // Complete the shadow by adding attributes from the resource object - PrismObject resultShadow = completeShadow(ctx, resourceShadow, repositoryShadow, parentResult); + PrismObject resultShadow = completeShadow(shadowCtx, resourceShadow, repositoryShadow, parentResult); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Shadow when assembled:\n{}", resultShadow.debugDump()); @@ -731,7 +734,7 @@ public boolean handle(PrismObject resourceShadow) { // This determines the definitions exactly. How the repo shadow should have proper kind/intent ProvisioningContext shadowCtx = applyAttributesDefinition(ctx, repoShadow); - forceRenameIfNeeded(shadowCtx, resourceShadow.asObjectable(), repoShadow.asObjectable(), parentResult); + shadowManager.updateRepoShadow(shadowCtx, resourceShadow.asObjectable(), repoShadow.asObjectable(), parentResult); resultShadow = completeShadow(shadowCtx, resourceShadow, repoShadow, parentResult); @@ -1346,7 +1349,7 @@ void processChange(ProvisioningContext ctx, Change change, PrismObje oldShadow, parentResult); change.setCurrentShadow(currentShadow); ShadowType currentShadowType = currentShadow.asObjectable(); - forceRenameIfNeeded(ctx, currentShadowType, oldShadowType, parentResult); + shadowManager.updateRepoShadow(ctx, currentShadowType, oldShadowType, parentResult); } // FIXME: hack. the object delta must have oid specified. @@ -1364,57 +1367,6 @@ void processChange(ProvisioningContext ctx, Change change, PrismObje } - // TODO: better move this to shadowManager? - private void forceRenameIfNeeded(ProvisioningContext ctx, ShadowType currentShadowType, ShadowType oldShadowType, OperationResult parentResult) throws SchemaException, ObjectNotFoundException, ObjectAlreadyExistsException, ConfigurationException, CommunicationException { - Collection> oldSecondaryIdentifiers = ShadowUtil.getSecondaryIdentifiers(oldShadowType); - if (oldSecondaryIdentifiers.isEmpty()){ - return; - } - ResourceAttributeContainer newSecondaryIdentifiers = ShadowUtil.getAttributesContainer(currentShadowType); - - //remember name before normalizing attributes - PolyString currentShadowName = ShadowUtil.determineShadowName(currentShadowType); - currentShadowType.setName(new PolyStringType(currentShadowName)); - - Iterator> oldSecondaryIterator = oldSecondaryIdentifiers.iterator(); - Collection renameDeltas = new ArrayList(); - while (oldSecondaryIterator.hasNext()){ - ResourceAttribute oldSecondaryIdentifier = oldSecondaryIterator.next(); - ResourceAttribute newSecondaryIdentifier = newSecondaryIdentifiers.findAttribute(oldSecondaryIdentifier.getElementName()); - Collection newValue = newSecondaryIdentifier.getRealValues(); - - if (!shadowManager.compareAttribute(ctx.getObjectClassDefinition(), newSecondaryIdentifier, oldSecondaryIdentifier)){ - PropertyDelta propertyDelta = PropertyDelta.createDelta(new ItemPath(ShadowType.F_ATTRIBUTES, oldSecondaryIdentifier.getElementName()), oldShadowType.asPrismObject().getDefinition()); - propertyDelta.addValuesToDelete(PrismPropertyValue.cloneCollection((Collection)oldSecondaryIdentifier.getValues())); - propertyDelta.addValuesToAdd(PrismPropertyValue.cloneCollection((Collection)newSecondaryIdentifier.getValues())); - renameDeltas.add(propertyDelta); - } - - } - - if (!renameDeltas.isEmpty()){ - - PropertyDelta shadowNameDelta = PropertyDelta.createModificationReplaceProperty(ShadowType.F_NAME, - oldShadowType.asPrismObject().getDefinition(),currentShadowName); - renameDeltas.add(shadowNameDelta); - } else { - - if (!oldShadowType.getName().getOrig().equals(currentShadowType.getName().getOrig())){ - PropertyDelta shadowNameDelta = PropertyDelta.createModificationReplaceProperty(ShadowType.F_NAME, - oldShadowType.asPrismObject().getDefinition(), currentShadowName); - renameDeltas.add(shadowNameDelta); - - } - } - if (!renameDeltas.isEmpty()){ - shadowManager.normalizeDeltas((Collection)renameDeltas, ctx.getObjectClassDefinition()); - ConstraintsChecker.onShadowModifyOperation(renameDeltas); - repositoryService.modifyObject(ShadowType.class, oldShadowType.getOid(), renameDeltas, parentResult); - oldShadowType.setName(new PolyStringType(currentShadowName)); - } - - } - public PrismProperty fetchCurrentToken(ResourceShadowDiscriminator shadowCoordinates, OperationResult parentResult) throws ObjectNotFoundException, CommunicationException, SchemaException, ConfigurationException { Validate.notNull(parentResult, "Operation result must not be null."); @@ -1436,18 +1388,7 @@ public PrismProperty fetchCurrentToken(ResourceShadowDiscriminator shadowCoor parentResult.recordSuccess(); return lastToken; } - - - ////////////////////////////////////////////////////////////////////////////////////// - - -// public ObjectClassComplexTypeDefinition applyAttributesDefinition(ProvisioningContext ctx, ObjectDelta delta, -// PrismObject shadow) throws SchemaException, ConfigurationException { -// RefinedResourceSchema refinedSchema = ProvisioningUtil.getRefinedSchema(resource); -// ObjectClassComplexTypeDefinition objectClassDefinition = refinedSchema.determineCompositeObjectClassDefinition(shadow); -// return applyAttributesDefinition(delta, objectClassDefinition, resource, refinedSchema); -// } - + private void applyAttributesDefinition(ProvisioningContext ctx, ObjectDelta delta) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException { if (delta.isAdd()) { applyAttributesDefinition(ctx, delta.getObjectToAdd()); @@ -1588,11 +1529,9 @@ private PrismObject completeShadow(ProvisioningContext ctx, PrismObj throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException, SecurityViolationException, GenericConnectorException { PrismObject resultShadow = repoShadow.clone(); - boolean resultIsResourceShadowClone = false; - if (resultShadow == null) { // todo how could this happen (see above)? [mederly] - resultShadow = resourceShadow.clone(); - resultIsResourceShadowClone = true; - } + + // The real definition may be different than that of repo shadow (e.g. different auxiliary object classes). + resultShadow.applyDefinition(ctx.getObjectClassDefinition().getObjectDefinition(), true); assert resultShadow.getPrismContext() != null : "No prism context in resultShadow"; @@ -1603,6 +1542,15 @@ private PrismObject completeShadow(ProvisioningContext ctx, PrismObj ShadowType repoShadowType = repoShadow.asObjectable(); ShadowType resourceShadowType = resourceShadow.asObjectable(); + // Always take auxiliary object classes from the resource. Unlike structural object classes + // the auxiliary object classes may change. + resultShadow.removeProperty(ShadowType.F_AUXILIARY_OBJECT_CLASS); + PrismProperty resourceAuxOcProp = resourceShadow.findProperty(ShadowType.F_AUXILIARY_OBJECT_CLASS); + if (resourceAuxOcProp != null) { + PrismProperty resultAuxOcProp = resultShadow.findOrCreateProperty(ShadowType.F_AUXILIARY_OBJECT_CLASS); + resultAuxOcProp.addAll(PrismPropertyValue.cloneCollection(resourceAuxOcProp.getValues())); + } + if (resultShadowType.getObjectClass() == null) { resultShadowType.setObjectClass(resourceAttributesContainer.getDefinition().getTypeName()); } @@ -1614,28 +1562,23 @@ private PrismObject completeShadow(ProvisioningContext ctx, PrismObj } - // If the shadows are the same then no copy is needed. This was already copied by clone. - if (!resultIsResourceShadowClone) { - // Attributes - resultShadow.removeContainer(ShadowType.F_ATTRIBUTES); - ResourceAttributeContainer resultAttibutes = resourceAttributesContainer.clone(); - accessChecker.filterGetAttributes(resultAttibutes, ctx.getObjectClassDefinition(), parentResult); - resultShadow.add(resultAttibutes); - -// resultShadowType.setProtectedObject(resourceShadowType.isProtectedObject()); - resultShadowType.setIgnored(resourceShadowType.isIgnored()); + // Attributes + resultShadow.removeContainer(ShadowType.F_ATTRIBUTES); + ResourceAttributeContainer resultAttibutes = resourceAttributesContainer.clone(); + accessChecker.filterGetAttributes(resultAttibutes, ctx.getObjectClassDefinition(), parentResult); + resultShadow.add(resultAttibutes); + + resultShadowType.setIgnored(resourceShadowType.isIgnored()); - resultShadowType.setActivation(resourceShadowType.getActivation()); - - // Credentials - ShadowType resultAccountShadow = resultShadow.asObjectable(); - ShadowType resourceAccountShadow = resourceShadow.asObjectable(); - resultAccountShadow.setCredentials(resourceAccountShadow.getCredentials()); - } + resultShadowType.setActivation(resourceShadowType.getActivation()); + + // Credentials + ShadowType resultAccountShadow = resultShadow.asObjectable(); + ShadowType resourceAccountShadow = resourceShadow.asObjectable(); + resultAccountShadow.setCredentials(resourceAccountShadow.getCredentials()); //protected resouceObjectConverter.setProtectedFlag(ctx, resultShadow); -// resultShadowType.setProtectedObject(); // Activation ActivationType resultActivationType = resultShadowType.getActivation(); diff --git a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java index 4b02065fb3a..df845a87db4 100644 --- a/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java +++ b/provisioning/provisioning-impl/src/main/java/com/evolveum/midpoint/provisioning/impl/ShadowManager.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Iterator; import java.util.List; import javax.xml.namespace.QName; @@ -50,6 +51,7 @@ import com.evolveum.midpoint.prism.match.MatchingRule; import com.evolveum.midpoint.prism.match.MatchingRuleRegistry; import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.query.AndFilter; import com.evolveum.midpoint.prism.query.EqualFilter; import com.evolveum.midpoint.prism.query.ObjectFilter; @@ -809,7 +811,70 @@ public Collection updateShadow(ProvisioningContext ctx, PrismObject> oldSecondaryIdentifiers = ShadowUtil.getSecondaryIdentifiers(oldShadowType); + if (oldSecondaryIdentifiers.isEmpty()){ + return; + } + ResourceAttributeContainer newSecondaryIdentifiers = ShadowUtil.getAttributesContainer(currentShadowType); + + //remember name before normalizing attributes + PolyString currentShadowName = ShadowUtil.determineShadowName(currentShadowType); + currentShadowType.setName(new PolyStringType(currentShadowName)); + + Iterator> oldSecondaryIterator = oldSecondaryIdentifiers.iterator(); + Collection repoShadowDeltas = new ArrayList(); + while (oldSecondaryIterator.hasNext()){ + ResourceAttribute oldSecondaryIdentifier = oldSecondaryIterator.next(); + ResourceAttribute newSecondaryIdentifier = newSecondaryIdentifiers.findAttribute(oldSecondaryIdentifier.getElementName()); + Collection newValue = newSecondaryIdentifier.getRealValues(); + + if (!compareAttribute(ctx.getObjectClassDefinition(), newSecondaryIdentifier, oldSecondaryIdentifier)){ + PropertyDelta propertyDelta = PropertyDelta.createDelta(new ItemPath(ShadowType.F_ATTRIBUTES, oldSecondaryIdentifier.getElementName()), oldShadowType.asPrismObject().getDefinition()); + propertyDelta.addValuesToDelete(PrismPropertyValue.cloneCollection((Collection)oldSecondaryIdentifier.getValues())); + propertyDelta.addValuesToAdd(PrismPropertyValue.cloneCollection((Collection)newSecondaryIdentifier.getValues())); + repoShadowDeltas.add(propertyDelta); + } + + } + + if (!repoShadowDeltas.isEmpty()){ + + PropertyDelta shadowNameDelta = PropertyDelta.createModificationReplaceProperty(ShadowType.F_NAME, + oldShadowType.asPrismObject().getDefinition(),currentShadowName); + repoShadowDeltas.add(shadowNameDelta); + } else { + + if (!oldShadowType.getName().getOrig().equals(currentShadowType.getName().getOrig())){ + PropertyDelta shadowNameDelta = PropertyDelta.createModificationReplaceProperty(ShadowType.F_NAME, + oldShadowType.asPrismObject().getDefinition(), currentShadowName); + repoShadowDeltas.add(shadowNameDelta); + + } + } + + PropertyDelta auxOcDelta = PrismProperty.diff( + oldShadowType.asPrismObject().findProperty(ShadowType.F_AUXILIARY_OBJECT_CLASS), + currentShadowType.asPrismObject().findProperty(ShadowType.F_AUXILIARY_OBJECT_CLASS)); + if (auxOcDelta != null) { + repoShadowDeltas.add(auxOcDelta); + } + + if (!repoShadowDeltas.isEmpty()){ + normalizeDeltas((Collection)repoShadowDeltas, ctx.getObjectClassDefinition()); + ConstraintsChecker.onShadowModifyOperation(repoShadowDeltas); + LOGGER.trace("Modifying repository shadow {}:\n{}", oldShadowType, DebugUtil.debugDump(repoShadowDeltas)); + repositoryService.modifyObject(ShadowType.class, oldShadowType.getOid(), repoShadowDeltas, parentResult); + oldShadowType.setName(new PolyStringType(currentShadowName)); + } + + } /** * Re-reads the shadow, re-evaluates the identifiers and stored values, updates them if necessary. Returns diff --git a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/TestOpenDJ.java b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/TestOpenDJ.java index 187fa88565b..3a1f003adb2 100644 --- a/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/TestOpenDJ.java +++ b/provisioning/provisioning-impl/src/test/java/com/evolveum/midpoint/provisioning/test/impl/TestOpenDJ.java @@ -72,8 +72,10 @@ import com.evolveum.midpoint.prism.match.UuidMatchingRule; import com.evolveum.midpoint.prism.match.XmlMatchingRule; import com.evolveum.midpoint.prism.path.ItemPath; +import com.evolveum.midpoint.prism.query.ObjectOrdering; import com.evolveum.midpoint.prism.query.ObjectPaging; import com.evolveum.midpoint.prism.query.ObjectQuery; +import com.evolveum.midpoint.prism.query.OrderDirection; import com.evolveum.midpoint.prism.query.QueryJaxbConvertor; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.prism.util.PrismTestUtil; @@ -1046,6 +1048,62 @@ public void test145ModifyAccountJackJpegPhoto() throws Exception { assertShadows(3); } + + /** + * Make a duplicate modification. Add a givenName value that is already there. + * Normal LDAP should fail. So check that connector and midPoitn handles that. + */ + @Test + public void test147ModifyAccountJackGivenNameDuplicit() throws Exception { + final String TEST_NAME = "test147ModifyAccountJackGivenNameDuplicit"; + TestUtil.displayTestTile(TEST_NAME); + + OperationResult result = new OperationResult(TestOpenDJ.class.getName() + + "." + TEST_NAME); + + PropertyDelta givenNameDelta = new PropertyDelta<>( + new ItemPath(ShadowType.F_ATTRIBUTES, new QName(RESOURCE_OPENDJ_NS, "givenName")), + null , prismContext); + givenNameDelta.addValueToAdd(new PrismPropertyValue("Jack")); + + // Also make an ordinary non-conflicting modification. We need to make sure that + // the operation was not ignored as a whole + PropertyDelta titleDelta = new PropertyDelta<>( + new ItemPath(ShadowType.F_ATTRIBUTES, new QName(RESOURCE_OPENDJ_NS, "title")), + null , prismContext); + titleDelta.addValueToAdd(new PrismPropertyValue("Great Captain")); + + Collection modifications = MiscSchemaUtil.createCollection(givenNameDelta, titleDelta); + + display("Modifications",modifications); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + provisioningService.modifyObject(ShadowType.class, ACCOUNT_JACK_OID, + modifications, null, null, taskManager.createTaskInstance(), result); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + TestUtil.assertSuccess(result); + + Entry entry = openDJController.searchByUid("rename"); + display("LDAP Entry", entry); + OpenDJController.assertAttribute(entry, "givenName", "Jack"); + OpenDJController.assertAttribute(entry, "title", "Great Captain"); + + PrismObject shadow = provisioningService.getObject(ShadowType.class, + ACCOUNT_JACK_OID, null, taskManager.createTaskInstance(), result); + + display("Object after change",shadow); + + PrismContainer attributesContainer = shadow.findContainer(ShadowType.F_ATTRIBUTES); + PrismAsserts.assertPropertyValue(attributesContainer, new QName(RESOURCE_OPENDJ_NS, "givenName"), "Jack"); + PrismAsserts.assertPropertyValue(attributesContainer, new QName(RESOURCE_OPENDJ_NS, "title"), "Great Captain"); + + assertShadows(3); + } + @Test public void test150ChangePassword() throws Exception { @@ -1580,10 +1638,12 @@ public void test230SearchObjectsPagedNoOffset() throws Exception { rememberConnectorSimulatedPagingSearchCount(); // WHEN + TestUtil.displayWhen(TEST_NAME); List> searchResults = provisioningService.searchObjects(ShadowType.class, query, null, null, result); // THEN + TestUtil.displayThen(TEST_NAME); result.computeStatus(); assertSuccess(result); display("Search resutls", searchResults); @@ -1611,10 +1671,12 @@ public void test231SearchObjectsPagedOffsetZero() throws Exception { rememberConnectorSimulatedPagingSearchCount(); // WHEN + TestUtil.displayWhen(TEST_NAME); List> searchResults = provisioningService.searchObjects(ShadowType.class, query, null, null, result); // THEN + TestUtil.displayThen(TEST_NAME); result.computeStatus(); assertSuccess(result); display("Search resutls", searchResults); @@ -1642,9 +1704,11 @@ public void test232SearchObjectsPagedOffset() throws Exception { rememberConnectorSimulatedPagingSearchCount(); // WHEN + TestUtil.displayWhen(TEST_NAME); SearchResultList> searchResults = provisioningService.searchObjects(ShadowType.class, query, null, null, result); // THEN + TestUtil.displayThen(TEST_NAME); result.computeStatus(); assertSuccess(result); display("Search resutls", searchResults); @@ -1655,6 +1719,76 @@ public void test232SearchObjectsPagedOffset() throws Exception { assertConnectorOperationIncrement(1); assertConnectorSimulatedPagingSearchIncrement(0); } + + @Test + public void test233SearchObjectsPagedNoOffsetSortSn() throws Exception { + final String TEST_NAME = "test233SearchObjectsPagedNoOffsetSortSn"; + TestUtil.displayTestTile(TEST_NAME); + + OperationResult result = new OperationResult(TestOpenDJ.class.getName() + "." + TEST_NAME); + + QueryType queryType = PrismTestUtil.parseAtomicValue(QUERY_ALL_ACCOUNTS_FILE, QueryType.COMPLEX_TYPE); + ObjectQuery query = QueryJaxbConvertor.createObjectQuery(ShadowType.class, queryType, prismContext); + + ObjectPaging paging = ObjectPaging.createPaging(null, 4); + paging.setOrdering(ObjectOrdering.createOrdering( + new ItemPath(ShadowType.F_ATTRIBUTES, new QName(RESOURCE_NS, "sn")), OrderDirection.ASCENDING)); + query.setPaging(paging); + + rememberConnectorOperationCount(); + rememberConnectorSimulatedPagingSearchCount(); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + List> searchResults = + provisioningService.searchObjects(ShadowType.class, query, null, null, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + assertSuccess(result); + display("Search resutls", searchResults); + + assertSearchResults(searchResults, "monk", "hbarbossa", "jbeckett", "jbond" ); + + assertConnectorOperationIncrement(1); + assertConnectorSimulatedPagingSearchIncrement(0); + } + + @Test + public void test234SearchObjectsPagedOffsetSortSn() throws Exception { + final String TEST_NAME = "test234SearchObjectsPagedOffsetSortSn"; + TestUtil.displayTestTile(TEST_NAME); + + OperationResult result = new OperationResult(TestOpenDJ.class.getName() + "." + TEST_NAME); + + QueryType queryType = PrismTestUtil.parseAtomicValue(QUERY_ALL_ACCOUNTS_FILE, QueryType.COMPLEX_TYPE); + ObjectQuery query = QueryJaxbConvertor.createObjectQuery(ShadowType.class, queryType, prismContext); + + ObjectPaging paging = ObjectPaging.createPaging(2, 4); + paging.setOrdering(ObjectOrdering.createOrdering( + new ItemPath(ShadowType.F_ATTRIBUTES, new QName(RESOURCE_NS, "sn")), OrderDirection.ASCENDING)); + query.setPaging(paging); + + rememberConnectorOperationCount(); + rememberConnectorSimulatedPagingSearchCount(); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + List> searchResults = + provisioningService.searchObjects(ShadowType.class, query, null, null, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + assertSuccess(result); + display("Search resutls", searchResults); + + assertSearchResults(searchResults, "jbeckett", "jbond", "cook", "drake" ); + + assertConnectorOperationIncrement(1); + assertConnectorSimulatedPagingSearchIncrement(0); + } private void assertSearchResults(List> searchResults, String... expectedUids) { assertEquals("Unexpected number of search results", expectedUids.length, searchResults.size()); diff --git a/provisioning/provisioning-impl/src/test/resources/logback-test.xml b/provisioning/provisioning-impl/src/test/resources/logback-test.xml index 7aca100e4df..67e24e34933 100644 --- a/provisioning/provisioning-impl/src/test/resources/logback-test.xml +++ b/provisioning/provisioning-impl/src/test/resources/logback-test.xml @@ -1,6 +1,6 @@ - + diff --git a/samples/resources/csvfile/midpoint-flatfile.csv b/samples/resources/csvfile/midpoint-flatfile.csv index 5cac4cded74..1b7d0d16346 100644 --- a/samples/resources/csvfile/midpoint-flatfile.csv +++ b/samples/resources/csvfile/midpoint-flatfile.csv @@ -1,3 +1,7 @@ "id","firstname","lastname","disabled","password" "user01","Firstname","Lastname","false","secret" "user02","Test","Lastname","false","secret" +"nnnnn","fffff","lllll","false","password" +"AAAA_DEL_PROJ11","AAAA_DEL_PROJ","last","false","password" +"maxeassign11","maxeassign1","maxeassign1","false","maxeassign1" +"AAA_del_proj_user","AAA_del_proj_user","AAA_del_proj_user","false","AAA_del_proj_user" diff --git a/samples/resources/openldap/openldap-localhost-advanced-sync-modifytimestamp.xml b/samples/resources/openldap/openldap-localhost-advanced-sync-modifytimestamp.xml index 0e4245c6d2f..8640b7dbbbb 100644 --- a/samples/resources/openldap/openldap-localhost-advanced-sync-modifytimestamp.xml +++ b/samples/resources/openldap/openldap-localhost-advanced-sync-modifytimestamp.xml @@ -1,6 +1,6 @@ - - true - - + + + + connectorType + org.connid.bundles.unix.UnixConnector + + + + + + false + + + midpoint + + secret + + localhost + 22 + true + true + $ + false + true + 0 + + secret + + 10000 + + + + + + entitlement + unixGroup + UNIX Group + ri:GroupObjectClass + + icfs:name + mr:stringIgnoreCase + + + name + + + + + + + account + Normal Account + true + ri:AccountObjectClass + + icfs:name + Distinguished Name + + 0 + + true + true + true + + + + + $user/name + + + + + icfs:uid + Entry UUID + + + true + false + true + + + + + ri:comment + Comment + + + fullName + + + + + ri:homeDir + Home directory + + + name + + + + + + + + ri:uid + Unix UID + + + employeeNumber + + + + + ri:shell + Shell + + + /bin/bash + + + + + ri:unixGroup + LDAP Group Membership + entitlement + unixGroup + subjectToObject + ri:groups + icfs:name + + + midpoint + + + root + + + + + + + + + + + + + + + + + + + + + + + + 2016-01-08T10:55:09.834+01:00 + 9daad27c2782934a-6fb5c4a527e3b230 + + + + + + + + + + + false + + + + + + + + + + connector + + + + + + + ri:AccountObjectClass + account + UserType + true + + + name + + $shadow/attributes/icfs:name + + + + + linked + true + + + deleted + false + + + unlinked + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#link + + + + unmatched + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus + + + + + ri:GroupObjectClass + entitlement + unixGroup + OrgType + true + + + name + + $shadow/attributes/icfs:name + + + + + linked + true + + + deleted + false + + + unlinked + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#link + + + + + + diff --git a/samples/stories/unix-management/extension-unix.xsd b/samples/stories/unix-management/extension-unix.xsd new file mode 100644 index 00000000000..0da66e9bc63 --- /dev/null +++ b/samples/stories/unix-management/extension-unix.xsd @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + true + Group Name + + + + + + + false + Unix Permissions + + + + + + + + + + + + + + + + + + + false + Public Key + + + + + + + + diff --git a/samples/stories/unix-management/midpoint-user-example.txt b/samples/stories/unix-management/midpoint-user-example.txt new file mode 100644 index 00000000000..3b7a599a3d1 --- /dev/null +++ b/samples/stories/unix-management/midpoint-user-example.txt @@ -0,0 +1,3 @@ +Host_Alias HOST = ALL + +midpoint HOST=(ALL) NOPASSWD: /usr/sbin/useradd,/usr/sbin/usermod,/usr/sbin/userdel,/usr/sbin/groupadd,/usr/sbin/groupmod,/usr/sbin/groupdel,/bin/mv,/usr/bin/passwd,/usr/bin/getent,/bin/echo,/usr/bin/tee,/bin/chown,/bin/chmod,/bin/mkdir,/usr/bin/groups,/usr/bin/id,/usr/bin/replace,/bin/rm,/bin/cat \ No newline at end of file diff --git a/samples/stories/unix-management/resource-unix-advanced.xml b/samples/stories/unix-management/resource-unix-advanced.xml new file mode 100644 index 00000000000..449d5fbf430 --- /dev/null +++ b/samples/stories/unix-management/resource-unix-advanced.xml @@ -0,0 +1,285 @@ + + Unix Resource + + + + connectorType + org.connid.bundles.unix.UnixConnector + + + + + + false + + + midpoint + + secret + + 192.168.56.101 + 22 + true + true + $ + false + true + 0 + + secret + + 10000 + + + + + + entitlement + unixGroup + UNIX Group + ri:GroupObjectClass + + icfs:name + mr:stringIgnoreCase + + + + account + Normal Account + true + ri:AccountObjectClass + + icfs:name + Distinguished Name + + 0 + + true + true + true + + + + + name + + + + + icfs:uid + Entry UUID + + + true + false + true + + + + + ri:comment + Comment + + + fullName + + + + + ri:homeDir + Home directory + + + name + + + + + + + + ri:uid + Unix UID + + + employeeNumber + + + + + ri:publicKey + Public Key + + + publicKeys + extension/ext:publicKey + + + + + + + + ri:shell + Shell + + + /bin/bash + + + + + ri:unixGroup + LDAP Group Membership + entitlement + unixGroup + subjectToObject + ri:groups + icfs:name + + + midpoint + + + root + + + + + + + + + + + + + + + + + + + + + + + + 2016-03-14T22:45:57.550+01:00 + 1141db340df1573e-621c56a87c47c088 + + + + + + + + + + + false + + + + + + + + + + connector + + + + + + + ri:AccountObjectClass + account + UserType + true + + + name + + $shadow/attributes/icfs:name + + + + + linked + true + + + unlinked + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#link + + + + unmatched + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#addFocus + + + + + ri:GroupObjectClass + entitlement + unixGroup + OrgType + true + + + name + + $shadow/attributes/icfs:name + + + + + linked + true + + + unlinked + true + + http://midpoint.evolveum.com/xml/ns/public/model/action-3#link + + + + + \ No newline at end of file diff --git a/samples/stories/unix-management/role-assignment-inducement-metarole.xml b/samples/stories/unix-management/role-assignment-inducement-metarole.xml new file mode 100644 index 00000000000..b04d9fa7af6 --- /dev/null +++ b/samples/stories/unix-management/role-assignment-inducement-metarole.xml @@ -0,0 +1,62 @@ + + Assignemnt & Inducement UNIX Group Metarole + Create group in the unix, assign this group to the user when role with this metarole is assigned. + + + + + entitlement + unixGroup + + icfs:name + mr:stringIgnoreCase + + + groupName + extension/ext:groupName + + + + + ri:permissions + + + permissions + extension/ext:permissions + + + + + + + + + account + default + + ri:unixGroup + + strong + + + + entitlement + unixGroup + + + + + + + 2 + UserType + + \ No newline at end of file diff --git a/testing/conntest/src/test/java/com/evolveum/midpoint/testing/conntest/AbstractLdapConnTest.java b/testing/conntest/src/test/java/com/evolveum/midpoint/testing/conntest/AbstractLdapConnTest.java index 5ddcd9438ca..63598430358 100644 --- a/testing/conntest/src/test/java/com/evolveum/midpoint/testing/conntest/AbstractLdapConnTest.java +++ b/testing/conntest/src/test/java/com/evolveum/midpoint/testing/conntest/AbstractLdapConnTest.java @@ -541,8 +541,8 @@ public void test200AssignAccountToBarbossa() throws Exception { } @Test - public void test210ModifyAccountBarbossaTitle() throws Exception { - final String TEST_NAME = "test210ModifyAccountBarbossaTitle"; + public void test210ModifyAccountBarbossaReplaceTitle() throws Exception { + final String TEST_NAME = "test210ModifyAccountBarbossaReplaceTitle"; TestUtil.displayTestTile(this, TEST_NAME); // GIVEN @@ -573,6 +573,43 @@ public void test210ModifyAccountBarbossaTitle() throws Exception { assertEquals("Shadows have moved", accountBarbossaOid, shadowOid); } + /** + * Make a duplicate modification. Add a title value that is already there. + * Normal LDAP should fail. So check that connector and midPoint handles that. + */ + @Test + public void test212ModifyAccountBarbossaAddTitleDuplicate() throws Exception { + final String TEST_NAME = "test212ModifyAccountBarbossaAddTitleDuplicate"; + TestUtil.displayTestTile(this, TEST_NAME); + + // GIVEN + Task task = taskManager.createTaskInstance(this.getClass().getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + ObjectDelta delta = ObjectDelta.createEmptyModifyDelta(ShadowType.class, accountBarbossaOid, prismContext); + QName attrQName = new QName(MidPointConstants.NS_RI, "title"); + ResourceAttributeDefinition attrDef = accountObjectClassDefinition.findAttributeDefinition(attrQName); + PropertyDelta attrDelta = PropertyDelta.createModificationAddProperty( + new ItemPath(ShadowType.F_ATTRIBUTES, attrQName), attrDef, "Captain"); + delta.addModification(attrDelta); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + modelService.executeChanges(MiscSchemaUtil.createCollection(delta), null, task, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + TestUtil.assertSuccess(result); + + Entry entry = assertLdapAccount(USER_BARBOSSA_USERNAME, USER_BARBOSSA_FULL_NAME); + assertAttribute(entry, "title", "Captain"); + + PrismObject user = getUser(USER_BARBOSSA_OID); + String shadowOid = getSingleLinkOid(user); + assertEquals("Shadows have moved", accountBarbossaOid, shadowOid); + } + @Test public void test220ModifyUserBarbossaPassword() throws Exception { final String TEST_NAME = "test220ModifyUserBarbossaPassword"; diff --git a/testing/conntest/src/test/java/com/evolveum/midpoint/testing/conntest/TestOpenDj.java b/testing/conntest/src/test/java/com/evolveum/midpoint/testing/conntest/TestOpenDj.java index 5d7303c985d..54ed335d30d 100644 --- a/testing/conntest/src/test/java/com/evolveum/midpoint/testing/conntest/TestOpenDj.java +++ b/testing/conntest/src/test/java/com/evolveum/midpoint/testing/conntest/TestOpenDj.java @@ -121,7 +121,7 @@ protected String getSyncTaskOid() { @Override protected void assertStepSyncToken(String syncTaskOid, int step, long tsStart, long tsEnd) throws ObjectNotFoundException, SchemaException { - assertSyncToken(syncTaskOid, (Integer)(step+5)); + assertSyncToken(syncTaskOid, (Integer)(step + 6)); } } diff --git a/testing/conntest/src/test/resources/opendj/resource.xml b/testing/conntest/src/test/resources/opendj/resource.xml index 2839ccc3b61..82e4783e2ae 100644 --- a/testing/conntest/src/test/resources/opendj/resource.xml +++ b/testing/conntest/src/test/resources/opendj/resource.xml @@ -284,7 +284,7 @@ - true + false diff --git a/testing/conntest/src/test/resources/openldap/resource.xml b/testing/conntest/src/test/resources/openldap/resource.xml index f6923716b63..d0807f3df6a 100644 --- a/testing/conntest/src/test/resources/openldap/resource.xml +++ b/testing/conntest/src/test/resources/openldap/resource.xml @@ -48,6 +48,7 @@ dc=example,dc=com cn=idm,ou=Administrators,dc=example,dc=com secret + always auto SSHA uid @@ -275,7 +276,7 @@ - true + false diff --git a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java index e2ea33eb526..67188be756b 100644 --- a/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java +++ b/testing/story/src/test/java/com/evolveum/midpoint/testing/story/TestUnix.java @@ -82,6 +82,7 @@ import com.evolveum.midpoint.util.exception.SecurityViolationException; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentPolicyEnforcementType; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; +import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationPhaseType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType; @@ -243,6 +244,9 @@ public class TestUnix extends AbstractStoryTest { private String accountRangerOid; private String accountRangerDn; + private String accountWallyOid; + private String accountWallyDn; + private String roleMonkeyIslandOid; private String groupMonkeyIslandDn; @@ -404,6 +408,36 @@ public void test110AddUserMancombUnix() throws Exception { accountMancombDn = assertPosixAccount(shadow, 1001); } + @Test + public void test111AccountMancombEditObjectClassDefinition() throws Exception { + final String TEST_NAME = "test111AccountMancombEditObjectClassDefinition"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestUnix.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + PrismObject shadow = getShadowModel(accountMancombOid); + display("shadow", shadow); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + RefinedObjectClassDefinition editObjectClassDefinition = modelInteractionService.getEditObjectClassDefinition(shadow, resourceOpenDj, AuthorizationPhaseType.REQUEST); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + TestUtil.assertSuccess(result); + display("OC def", editObjectClassDefinition); + + PrismAsserts.assertPropertyDefinition(editObjectClassDefinition, + new QName(RESOURCE_OPENDJ_NAMESPACE, "cn"), DOMUtil.XSD_STRING, 1, -1); + PrismAsserts.assertPropertyDefinition(editObjectClassDefinition, + new QName(RESOURCE_OPENDJ_NAMESPACE, "o"), DOMUtil.XSD_STRING, 0, -1); + PrismAsserts.assertPropertyDefinition(editObjectClassDefinition, + new QName(RESOURCE_OPENDJ_NAMESPACE, "uidNumber"), DOMUtil.XSD_INT, 1, 1); + PrismAsserts.assertPropertyDefinition(editObjectClassDefinition, + new QName(RESOURCE_OPENDJ_NAMESPACE, "gidNumber"), DOMUtil.XSD_INT, 1, 1); + } + @Test public void test119DeleteUserMancombUnix() throws Exception { final String TEST_NAME = "test119DeleteUserMancombUnix"; @@ -1169,11 +1203,11 @@ public void test310AddUserWallyUnix() throws Exception { assertNotNull("No herman user", userAfter); display("User after", userAfter); assertUserPosix(userAfter, USER_WALLY_USERNAME, USER_WALLY_FIST_NAME, USER_WALLY_LAST_NAME, USER_WALLY_UID_NUMBER); - accountMancombOid = getSingleLinkOid(userAfter); + accountWallyOid = getSingleLinkOid(userAfter); - PrismObject shadow = getShadowModel(accountMancombOid); + PrismObject shadow = getShadowModel(accountWallyOid); display("Shadow (model)", shadow); - accountMancombDn = assertPosixAccount(shadow, USER_WALLY_UID_NUMBER); + accountWallyDn = assertPosixAccount(shadow, USER_WALLY_UID_NUMBER); PrismObject sequenceAfter = getObject(SequenceType.class, SEQUENCE_UIDNUMBER_OID); display("Sequence after", sequenceAfter); @@ -1181,6 +1215,107 @@ public void test310AddUserWallyUnix() throws Exception { assertTrue("Unexpected unused values in the sequence", sequenceAfter.asObjectable().getUnusedValues().isEmpty()); } + /** + * Remove posixAccount directly in LDAP server. Then try to get the account. MidPoint should survive that. + */ + @Test + public void test312AccountWallyRemovePosixObjectclassNative() throws Exception { + final String TEST_NAME = "test312AccountWallyRemovePosixObjectclassNative"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestUnix.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + openDJController.executeLdifChange("dn: "+accountWallyDn+"\n"+ + "changetype: modify\n"+ + "delete: objectclass\n"+ + "objectclass: posixAccount\n"+ + "-\n"+ + "delete: uidNumber\n"+ + "uidNumber: "+USER_WALLY_UID_NUMBER+"\n"+ + "-\n"+ + "delete: gidNumber\n"+ + "gidNumber: "+USER_WALLY_UID_NUMBER+"\n"+ + "-\n"+ + "delete: homeDirectory\n"+ + "homeDirectory: /home/wally"); + + Entry entryWallyBefore = openDJController.fetchEntry(accountWallyDn); + display("Wally LDAP account before", entryWallyBefore); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + PrismObject shadow = modelService.getObject(ShadowType.class, accountWallyOid, null, task, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + TestUtil.assertSuccess(result); + + display("Shadow (model)", shadow); + assertBasicAccount(shadow); + + PrismObject repoShadow = repositoryService.getObject(ShadowType.class, accountWallyOid, null, result); + display("Shadow (repo)", repoShadow); + PrismAsserts.assertNoItem(repoShadow, ShadowType.F_AUXILIARY_OBJECT_CLASS); +// PrismAsserts.assertPropertyValue(repoShadow, ShadowType.F_AUXILIARY_OBJECT_CLASS); + + PrismObject userAfter = findUserByUsername(USER_WALLY_USERNAME); + assertNotNull("No herman user", userAfter); + display("User after", userAfter); + assertUserPosix(userAfter, USER_WALLY_USERNAME, USER_WALLY_FIST_NAME, USER_WALLY_LAST_NAME, USER_WALLY_UID_NUMBER); + accountMancombOid = getSingleLinkOid(userAfter); + } + + /** + * Add posixAccount directly in LDAP server. Then try to get the account. MidPoint should survive that. + */ + @Test + public void test314AccountWallyAddPosixObjectclassNative() throws Exception { + final String TEST_NAME = "test314AccountWallyAddPosixObjectclassNative"; + TestUtil.displayTestTile(this, TEST_NAME); + Task task = taskManager.createTaskInstance(TestUnix.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + openDJController.executeLdifChange("dn: "+accountWallyDn+"\n"+ + "changetype: modify\n"+ + "add: objectclass\n"+ + "objectclass: posixAccount\n"+ + "-\n"+ + "add: uidNumber\n"+ + "uidNumber: "+USER_WALLY_UID_NUMBER+"\n"+ + "-\n"+ + "add: gidNumber\n"+ + "gidNumber: "+USER_WALLY_UID_NUMBER+"\n"+ + "-\n"+ + "add: homeDirectory\n"+ + "homeDirectory: /home/wally"); + + Entry entryWallyBefore = openDJController.fetchEntry(accountWallyDn); + display("Wally LDAP account before", entryWallyBefore); + + // WHEN + TestUtil.displayWhen(TEST_NAME); + PrismObject shadow = modelService.getObject(ShadowType.class, accountWallyOid, null, task, result); + + // THEN + TestUtil.displayThen(TEST_NAME); + result.computeStatus(); + TestUtil.assertSuccess(result); + + display("Shadow (model)", shadow); + assertPosixAccount(shadow, USER_WALLY_UID_NUMBER); + + PrismObject repoShadow = repositoryService.getObject(ShadowType.class, accountWallyOid, null, result); + display("Shadow (repo)", repoShadow); + PrismAsserts.assertPropertyValue(repoShadow, ShadowType.F_AUXILIARY_OBJECT_CLASS, OPENDJ_ACCOUNT_POSIX_AUXILIARY_OBJECTCLASS_NAME); + + PrismObject userAfter = findUserByUsername(USER_WALLY_USERNAME); + assertNotNull("No herman user", userAfter); + display("User after", userAfter); + assertUserPosix(userAfter, USER_WALLY_USERNAME, USER_WALLY_FIST_NAME, USER_WALLY_LAST_NAME, USER_WALLY_UID_NUMBER); + accountMancombOid = getSingleLinkOid(userAfter); + } + @Test public void test400ListAllAccountsObjectClass() throws Exception { final String TEST_NAME = "test400ListAllAccountsObjectClass";