http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/pages/ConfModalPage.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ConfModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ConfModalPage.java new file mode 100644 index 0000000..0c65ac2 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/ConfModalPage.java @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.pages; + +import java.util.Collections; +import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.client.console.commons.Constants; +import org.apache.syncope.client.console.commons.Mode; +import org.apache.syncope.client.console.panels.PlainAttrsPanel; +import org.apache.syncope.common.lib.to.AttrTO; +import org.apache.syncope.common.lib.to.ConfTO; +import org.apache.wicket.PageReference; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.form.AjaxButton; +import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy; +import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton; +import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.model.CompoundPropertyModel; +import org.apache.wicket.model.ResourceModel; + +public class ConfModalPage extends BaseModalPage { + + private static final long serialVersionUID = 3524777398688399977L; + + public ConfModalPage(final PageReference pageRef, final ModalWindow window, final WebMarkupContainer parameters) { + super(); + + MetaDataRoleAuthorizationStrategy.authorize( + parameters, ENABLE, xmlRolesReader.getEntitlement("Configuration", "list")); + final ConfTO conf = confRestClient.list(); + + final Form<ConfTO> form = new Form<>("confForm"); + form.setModel(new CompoundPropertyModel<>(conf)); + + form.add(new PlainAttrsPanel("paramAttrs", conf, form, Mode.ADMIN)); + + final AjaxButton submit = new IndicatingAjaxButton(SUBMIT, new ResourceModel(SUBMIT)) { + + private static final long serialVersionUID = -958724007591692537L; + + @Override + protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) { + final ConfTO updatedConf = (ConfTO) form.getModelObject(); + + try { + for (AttrTO attr : updatedConf.getPlainAttrs()) { + attr.getValues().removeAll(Collections.singleton(null)); + if (attr.getValues().isEmpty() + || attr.getValues().equals(Collections.singletonList(StringUtils.EMPTY))) { + + confRestClient.delete(attr.getSchema()); + } else { + confRestClient.set(attr); + } + } + + if (pageRef.getPage() instanceof BasePage) { + ((BasePage) pageRef.getPage()).setModalResult(true); + } + + window.close(target); + } catch (Exception e) { + error(getString(Constants.ERROR) + ": " + e.getMessage()); + feedbackPanel.refresh(target); + } + } + + @Override + protected void onError(final AjaxRequestTarget target, final Form<?> form) { + feedbackPanel.refresh(target); + } + }; + MetaDataRoleAuthorizationStrategy.authorize( + submit, ENABLE, xmlRolesReader.getEntitlement("Configuration", "set")); + MetaDataRoleAuthorizationStrategy.authorize( + submit, ENABLE, xmlRolesReader.getEntitlement("Configuration", "delete")); + form.add(submit); + form.setDefaultButton(submit); + + final AjaxButton cancel = new IndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL)) { + + private static final long serialVersionUID = -958724007591692537L; + + @Override + protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) { + window.close(target); + } + }; + cancel.setDefaultFormProcessing(false); + form.add(cancel); + + add(form); + } +}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/pages/Configuration.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/Configuration.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/Configuration.java new file mode 100644 index 0000000..c6774f2 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/Configuration.java @@ -0,0 +1,814 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.pages; + +import static org.apache.syncope.client.console.pages.AbstractBasePage.LOG; + +import java.io.File; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.config.LoggerConfig; +import org.apache.syncope.client.console.ExtensionPanel; +import org.apache.syncope.client.console.commons.AttrLayoutType; +import org.apache.syncope.client.console.commons.Constants; +import org.apache.syncope.client.console.commons.HttpResourceStream; +import org.apache.syncope.client.console.commons.PreferenceManager; +import org.apache.syncope.client.console.commons.SortableDataProviderComparator; +import org.apache.syncope.client.console.init.ImplementationClassNamesLoader; +import org.apache.syncope.client.console.panels.AbstractExtensionPanel; +import org.apache.syncope.client.console.panels.JQueryUITabbedPanel; +import org.apache.syncope.client.console.panels.LayoutsPanel; +import org.apache.syncope.client.console.panels.PoliciesPanel; +import org.apache.syncope.client.console.rest.LoggerRestClient; +import org.apache.syncope.client.console.rest.NotificationRestClient; +import org.apache.syncope.client.console.rest.SecurityQuestionRestClient; +import org.apache.syncope.client.console.rest.WorkflowRestClient; +import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.CollectionPropertyColumn; +import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink; +import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel; +import org.apache.syncope.client.console.wicket.markup.html.link.VeilPopupSettings; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.SyncopeConstants; +import org.apache.syncope.common.lib.to.LoggerTO; +import org.apache.syncope.common.lib.to.NotificationTO; +import org.apache.syncope.common.lib.to.SecurityQuestionTO; +import org.apache.syncope.common.lib.types.LoggerLevel; +import org.apache.syncope.common.lib.types.PolicyType; +import org.apache.wicket.Page; +import org.apache.wicket.PageReference; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; +import org.apache.wicket.ajax.markup.html.AjaxLink; +import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy; +import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink; +import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; +import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxFallbackDefaultDataTable; +import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator; +import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder; +import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn; +import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; +import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn; +import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider; +import org.apache.wicket.extensions.markup.html.tabs.AbstractTab; +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.image.Image; +import org.apache.wicket.markup.html.link.BookmarkablePageLink; +import org.apache.wicket.markup.html.link.Link; +import org.apache.wicket.markup.html.list.ListItem; +import org.apache.wicket.markup.html.list.PropertyListView; +import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.markup.repeater.Item; +import org.apache.wicket.model.AbstractReadOnlyModel; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.PropertyModel; +import org.apache.wicket.model.ResourceModel; +import org.apache.wicket.protocol.http.WebApplication; +import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler; +import org.apache.wicket.request.resource.ContentDisposition; +import org.apache.wicket.request.resource.DynamicImageResource; +import org.apache.wicket.request.resource.IResource; +import org.apache.wicket.spring.injection.annot.SpringBean; +import org.springframework.util.ClassUtils; +import org.springframework.web.context.support.WebApplicationContextUtils; + +/** + * Configurations WebPage. + */ +public class Configuration extends BasePage { + + private static final long serialVersionUID = -2838270869037702214L; + + private static final int SYNCOPECONF_WIN_HEIGHT = 300; + + private static final int SYNCOPECONF_WIN_WIDTH = 900; + + private static final int NOTIFICATION_WIN_HEIGHT = 500; + + private static final int NOTIFICATION_WIN_WIDTH = 1100; + + private static final int SECURITY_QUESTION_WIN_HEIGHT = 300; + + private static final int SECURITY_QUESTION_WIN_WIDTH = 900; + + @SpringBean + private LoggerRestClient loggerRestClient; + + @SpringBean + private NotificationRestClient notificationRestClient; + + @SpringBean + private SecurityQuestionRestClient securityQuestionRestClient; + + @SpringBean + private WorkflowRestClient wfRestClient; + + @SpringBean + private PreferenceManager prefMan; + + @SpringBean + private ImplementationClassNamesLoader implementationClassNamesLoader; + + private final ModalWindow syncopeConfWin; + + private final ModalWindow createNotificationWin; + + private final ModalWindow editNotificationWin; + + private final ModalWindow createSecurityQuestionWin; + + private final ModalWindow editSecurityQuestionWin; + + private WebMarkupContainer notificationContainer; + + private WebMarkupContainer securityQuestionContainer; + + private int notificationPaginatorRows; + + public Configuration() { + super(); + + // Layouts + add(new LayoutsPanel("adminUserLayoutPanel", AttrLayoutType.ADMIN_USER, feedbackPanel)); + add(new LayoutsPanel("selfUserLayoutPanel", AttrLayoutType.SELF_USER, feedbackPanel)); + add(new LayoutsPanel("adminRoleLayoutPanel", AttrLayoutType.ADMIN_ROLE, feedbackPanel)); + add(new LayoutsPanel("selfRoleLayoutPanel", AttrLayoutType.SELF_ROLE, feedbackPanel)); + add(new LayoutsPanel("adminMembershipLayoutPanel", AttrLayoutType.ADMIN_MEMBERSHIP, feedbackPanel)); + add(new LayoutsPanel("selfMembershipLayoutPanel", AttrLayoutType.SELF_MEMBERSHIP, feedbackPanel)); + + add(syncopeConfWin = new ModalWindow("syncopeConfWin")); + syncopeConfWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY); + syncopeConfWin.setInitialHeight(SYNCOPECONF_WIN_HEIGHT); + syncopeConfWin.setInitialWidth(SYNCOPECONF_WIN_WIDTH); + syncopeConfWin.setCookieName("syncopeconf-modal"); + setupSyncopeConf(); + + add(new PoliciesPanel("passwordPoliciesPanel", getPageReference(), PolicyType.PASSWORD)); + add(new PoliciesPanel("accountPoliciesPanel", getPageReference(), PolicyType.ACCOUNT)); + add(new PoliciesPanel("syncPoliciesPanel", getPageReference(), PolicyType.SYNC)); + + add(createNotificationWin = new ModalWindow("createNotificationWin")); + createNotificationWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY); + createNotificationWin.setInitialHeight(NOTIFICATION_WIN_HEIGHT); + createNotificationWin.setInitialWidth(NOTIFICATION_WIN_WIDTH); + createNotificationWin.setCookieName("create-notification-modal"); + add(editNotificationWin = new ModalWindow("editNotificationWin")); + editNotificationWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY); + editNotificationWin.setInitialHeight(NOTIFICATION_WIN_HEIGHT); + editNotificationWin.setInitialWidth(NOTIFICATION_WIN_WIDTH); + editNotificationWin.setCookieName("edit-notification-modal"); + setupNotification(); + + add(createSecurityQuestionWin = new ModalWindow("createSecurityQuestionWin")); + createSecurityQuestionWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY); + createSecurityQuestionWin.setInitialHeight(SECURITY_QUESTION_WIN_HEIGHT); + createSecurityQuestionWin.setInitialWidth(SECURITY_QUESTION_WIN_WIDTH); + createSecurityQuestionWin.setCookieName("create-security-question-modal"); + add(editSecurityQuestionWin = new ModalWindow("editSecurityQuestionWin")); + editSecurityQuestionWin.setCssClassName(ModalWindow.CSS_CLASS_GRAY); + editSecurityQuestionWin.setInitialHeight(SECURITY_QUESTION_WIN_HEIGHT); + editSecurityQuestionWin.setInitialWidth(SECURITY_QUESTION_WIN_WIDTH); + editSecurityQuestionWin.setCookieName("edit-security-question-modal"); + setupSecurityQuestion(); + + // Workflow definition stuff + WebMarkupContainer noActivitiEnabledForUsers = new WebMarkupContainer("noActivitiEnabledForUsers"); + noActivitiEnabledForUsers.setOutputMarkupPlaceholderTag(true); + add(noActivitiEnabledForUsers); + + WebMarkupContainer workflowDefContainer = new WebMarkupContainer("workflowDefContainer"); + workflowDefContainer.setOutputMarkupPlaceholderTag(true); + + if (wfRestClient.isActivitiEnabledForUsers()) { + noActivitiEnabledForUsers.setVisible(false); + } else { + workflowDefContainer.setVisible(false); + } + + BookmarkablePageLink<Void> activitiModeler = + new BookmarkablePageLink<>("activitiModeler", ActivitiModelerPopupPage.class); + activitiModeler.setPopupSettings(new VeilPopupSettings().setHeight(600).setWidth(800)); + MetaDataRoleAuthorizationStrategy.authorize(activitiModeler, ENABLE, + xmlRolesReader.getEntitlement("Configuration", "workflowDefRead")); + workflowDefContainer.add(activitiModeler); + // Check if Activiti Modeler directory is found + boolean activitiModelerEnabled = false; + try { + String activitiModelerDirectory = WebApplicationContextUtils.getWebApplicationContext( + WebApplication.get().getServletContext()).getBean("activitiModelerDirectory", String.class); + File baseDir = new File(activitiModelerDirectory); + activitiModelerEnabled = baseDir.exists() && baseDir.canRead() && baseDir.isDirectory(); + } catch (Exception e) { + LOG.error("Could not check for Activiti Modeler directory", e); + } + activitiModeler.setEnabled(activitiModelerEnabled); + + BookmarkablePageLink<Void> xmlEditor = new BookmarkablePageLink<>("xmlEditor", XMLEditorPopupPage.class); + xmlEditor.setPopupSettings(new VeilPopupSettings().setHeight(480).setWidth(800)); + MetaDataRoleAuthorizationStrategy.authorize(xmlEditor, ENABLE, + xmlRolesReader.getEntitlement("Configuration", "workflowDefRead")); + workflowDefContainer.add(xmlEditor); + + Image workflowDefDiagram = new Image("workflowDefDiagram", new Model()) { + + private static final long serialVersionUID = -8457850449086490660L; + + @Override + protected IResource getImageResource() { + return new DynamicImageResource() { + + private static final long serialVersionUID = 923201517955737928L; + + @Override + protected byte[] getImageData(final IResource.Attributes attributes) { + return wfRestClient.isActivitiEnabledForUsers() + ? wfRestClient.getDiagram() + : new byte[0]; + } + }; + } + }; + workflowDefContainer.add(workflowDefDiagram); + + MetaDataRoleAuthorizationStrategy.authorize(workflowDefContainer, ENABLE, + xmlRolesReader.getEntitlement("Configuration", "workflowDefRead")); + add(workflowDefContainer); + + // Logger stuff + PropertyListView<LoggerTO> coreLoggerList = + new LoggerPropertyList(null, "corelogger", loggerRestClient.listLogs()); + WebMarkupContainer coreLoggerContainer = new WebMarkupContainer("coreLoggerContainer"); + coreLoggerContainer.add(coreLoggerList); + coreLoggerContainer.setOutputMarkupId(true); + + MetaDataRoleAuthorizationStrategy.authorize(coreLoggerContainer, ENABLE, xmlRolesReader.getEntitlement( + "Configuration", "logList")); + add(coreLoggerContainer); + + ConsoleLoggerController consoleLoggerController = new ConsoleLoggerController(); + PropertyListView<LoggerTO> consoleLoggerList = + new LoggerPropertyList(consoleLoggerController, "consolelogger", consoleLoggerController.getLoggers()); + WebMarkupContainer consoleLoggerContainer = new WebMarkupContainer("consoleLoggerContainer"); + consoleLoggerContainer.add(consoleLoggerList); + consoleLoggerContainer.setOutputMarkupId(true); + + MetaDataRoleAuthorizationStrategy.authorize( + consoleLoggerContainer, ENABLE, xmlRolesReader.getEntitlement("Configuration", "logList")); + add(consoleLoggerContainer); + + // Extension panels + setupExtPanels(); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + private void setupSyncopeConf() { + final WebMarkupContainer parameters = new WebMarkupContainer("parameters"); + parameters.setOutputMarkupId(true); + add(parameters); + + setWindowClosedCallback(syncopeConfWin, parameters); + + AjaxLink<Void> confLink = new IndicatingAjaxLink<Void>("confLink") { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target) { + syncopeConfWin.setPageCreator(new ModalWindow.PageCreator() { + + private static final long serialVersionUID = -7834632442532690940L; + + @Override + public Page createPage() { + return new ConfModalPage(getPageReference(), editNotificationWin, parameters); + } + }); + + syncopeConfWin.show(target); + } + }; + parameters.add(confLink); + + Link<Void> dbExportLink = new Link<Void>("dbExportLink") { + + private static final long serialVersionUID = -4331619903296515985L; + + @Override + public void onClick() { + try { + HttpResourceStream stream = new HttpResourceStream(confRestClient.dbExport()); + + ResourceStreamRequestHandler rsrh = new ResourceStreamRequestHandler(stream); + rsrh.setFileName(stream.getFilename() == null ? "content.xml" : stream.getFilename()); + rsrh.setContentDisposition(ContentDisposition.ATTACHMENT); + + getRequestCycle().scheduleRequestHandlerAfterCurrent(rsrh); + } catch (Exception e) { + error(getString(Constants.ERROR) + ": " + e.getMessage()); + } + } + }; + MetaDataRoleAuthorizationStrategy.authorize( + dbExportLink, ENABLE, xmlRolesReader.getEntitlement("Configuration", "export")); + add(dbExportLink); + } + + private void setupNotification() { + notificationPaginatorRows = prefMan.getPaginatorRows(getRequest(), Constants.PREF_NOTIFICATION_PAGINATOR_ROWS); + + final List<IColumn<NotificationTO, String>> notificationCols = new ArrayList<>(); + notificationCols.add(new PropertyColumn<NotificationTO, String>( + new ResourceModel("key"), "key", "key")); + notificationCols.add(new CollectionPropertyColumn<NotificationTO>( + new ResourceModel("events"), "events", "events")); + notificationCols.add(new PropertyColumn<NotificationTO, String>( + new ResourceModel("subject"), "subject", "subject")); + notificationCols.add(new PropertyColumn<NotificationTO, String>( + new ResourceModel("template"), "template", "template")); + notificationCols.add(new PropertyColumn<NotificationTO, String>( + new ResourceModel("traceLevel"), "traceLevel", "traceLevel")); + notificationCols.add(new PropertyColumn<NotificationTO, String>( + new ResourceModel("active"), "active", "active")); + + notificationCols.add(new AbstractColumn<NotificationTO, String>(new ResourceModel("actions", "")) { + + private static final long serialVersionUID = 2054811145491901166L; + + @Override + public String getCssClass() { + return "action"; + } + + @Override + public void populateItem(final Item<ICellPopulator<NotificationTO>> cellItem, final String componentId, + final IModel<NotificationTO> model) { + + final NotificationTO notificationTO = model.getObject(); + + final ActionLinksPanel panel = new ActionLinksPanel(componentId, model, getPageReference()); + + panel.add(new ActionLink() { + + private static final long serialVersionUID = -3722207913631435501L; + + @Override + public void onClick(final AjaxRequestTarget target) { + editNotificationWin.setPageCreator(new ModalWindow.PageCreator() { + + private static final long serialVersionUID = -7834632442532690940L; + + @Override + public Page createPage() { + return new NotificationModalPage(Configuration.this.getPageReference(), + editNotificationWin, notificationTO, false); + } + }); + + editNotificationWin.show(target); + } + }, ActionLink.ActionType.EDIT, "Notification"); + + panel.add(new ActionLink() { + + private static final long serialVersionUID = -3722207913631435501L; + + @Override + public void onClick(final AjaxRequestTarget target) { + try { + notificationRestClient.delete(notificationTO.getKey()); + } catch (SyncopeClientException e) { + LOG.error("While deleting a notification", e); + error(e.getMessage()); + return; + } + + info(getString(Constants.OPERATION_SUCCEEDED)); + feedbackPanel.refresh(target); + target.add(notificationContainer); + } + }, ActionLink.ActionType.DELETE, "Notification"); + + cellItem.add(panel); + } + }); + + final AjaxFallbackDefaultDataTable<NotificationTO, String> notificationTable = + new AjaxFallbackDefaultDataTable<>( + "notificationTable", notificationCols, new NotificationProvider(), notificationPaginatorRows); + + notificationContainer = new WebMarkupContainer("notificationContainer"); + notificationContainer.add(notificationTable); + notificationContainer.setOutputMarkupId(true); + + add(notificationContainer); + + setWindowClosedCallback(createNotificationWin, notificationContainer); + setWindowClosedCallback(editNotificationWin, notificationContainer); + + AjaxLink<Void> createNotificationLink = new AjaxLink<Void>("createNotificationLink") { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target) { + createNotificationWin.setPageCreator(new ModalWindow.PageCreator() { + + private static final long serialVersionUID = -7834632442532690940L; + + @Override + public Page createPage() { + return new NotificationModalPage(Configuration.this.getPageReference(), createNotificationWin, + new NotificationTO(), true); + } + }); + + createNotificationWin.show(target); + } + }; + + MetaDataRoleAuthorizationStrategy.authorize(createNotificationLink, ENABLE, xmlRolesReader.getEntitlement( + "Notification", "create")); + add(createNotificationLink); + + @SuppressWarnings("rawtypes") + Form notificationPaginatorForm = new Form("notificationPaginatorForm"); + + @SuppressWarnings({ "unchecked", "rawtypes" }) + final DropDownChoice rowsChooser = new DropDownChoice("rowsChooser", new PropertyModel(this, + "notificationPaginatorRows"), prefMan.getPaginatorChoices()); + + rowsChooser.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + prefMan.set(getRequest(), getResponse(), Constants.PREF_NOTIFICATION_PAGINATOR_ROWS, String.valueOf( + notificationPaginatorRows)); + notificationTable.setItemsPerPage(notificationPaginatorRows); + + target.add(notificationContainer); + } + }); + + notificationPaginatorForm.add(rowsChooser); + add(notificationPaginatorForm); + } + + private void setupSecurityQuestion() { + final List<IColumn<SecurityQuestionTO, String>> securityQuestionCols = new ArrayList<>(); + securityQuestionCols.add(new PropertyColumn<SecurityQuestionTO, String>( + new ResourceModel("key"), "key", "key")); + securityQuestionCols.add(new PropertyColumn<SecurityQuestionTO, String>( + new ResourceModel("content"), "content", "content")); + + securityQuestionCols.add(new AbstractColumn<SecurityQuestionTO, String>(new ResourceModel("actions", "")) { + + private static final long serialVersionUID = 2054811145491901166L; + + @Override + public String getCssClass() { + return "action"; + } + + @Override + public void populateItem(final Item<ICellPopulator<SecurityQuestionTO>> cellItem, final String componentId, + final IModel<SecurityQuestionTO> model) { + + final SecurityQuestionTO securityQuestionTO = model.getObject(); + + final ActionLinksPanel panel = new ActionLinksPanel(componentId, model, getPageReference()); + + panel.add(new ActionLink() { + + private static final long serialVersionUID = -3722207913631435501L; + + @Override + public void onClick(final AjaxRequestTarget target) { + editSecurityQuestionWin.setPageCreator(new ModalWindow.PageCreator() { + + private static final long serialVersionUID = -7834632442532690940L; + + @Override + public Page createPage() { + return new SecurityQuestionModalPage(Configuration.this.getPageReference(), + editSecurityQuestionWin, securityQuestionTO, false); + } + }); + + editSecurityQuestionWin.show(target); + } + }, ActionLink.ActionType.EDIT, "SecurityQuestion"); + + panel.add(new ActionLink() { + + private static final long serialVersionUID = -3722207913631435501L; + + @Override + public void onClick(final AjaxRequestTarget target) { + try { + securityQuestionRestClient.delete(securityQuestionTO.getKey()); + } catch (SyncopeClientException e) { + LOG.error("While deleting a security question", e); + error(e.getMessage()); + return; + } + + info(getString(Constants.OPERATION_SUCCEEDED)); + feedbackPanel.refresh(target); + target.add(securityQuestionContainer); + } + }, ActionLink.ActionType.DELETE, "SecurityQuestion"); + + cellItem.add(panel); + } + }); + + final AjaxFallbackDefaultDataTable<SecurityQuestionTO, String> securityQuestionTable = + new AjaxFallbackDefaultDataTable<>("securityQuestionTable", + securityQuestionCols, new SecurityQuestionProvider(), 50); + + securityQuestionContainer = new WebMarkupContainer("securityQuestionContainer"); + securityQuestionContainer.add(securityQuestionTable); + securityQuestionContainer.setOutputMarkupId(true); + + add(securityQuestionContainer); + + setWindowClosedCallback(createSecurityQuestionWin, securityQuestionContainer); + setWindowClosedCallback(editSecurityQuestionWin, securityQuestionContainer); + + AjaxLink<Void> createSecurityQuestionLink = new AjaxLink<Void>("createSecurityQuestionLink") { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target) { + + createSecurityQuestionWin.setPageCreator(new ModalWindow.PageCreator() { + + private static final long serialVersionUID = -7834632442532690940L; + + @Override + public Page createPage() { + return new SecurityQuestionModalPage(Configuration.this.getPageReference(), + createSecurityQuestionWin, new SecurityQuestionTO(), true); + } + }); + + createSecurityQuestionWin.show(target); + } + }; + + MetaDataRoleAuthorizationStrategy.authorize( + createSecurityQuestionLink, ENABLE, xmlRolesReader.getEntitlement("SecurityQuestion", "create")); + add(createSecurityQuestionLink); + } + + private void setupExtPanels() { + List<AbstractTab> tabs = new ArrayList<>(); + int index = 0; + for (final Class<? extends AbstractExtensionPanel> clazz + : implementationClassNamesLoader.getExtPanelClasses()) { + + String title = clazz.getAnnotation(ExtensionPanel.class) == null + ? "Extension " + index + : clazz.getAnnotation(ExtensionPanel.class).value(); + tabs.add(new AbstractTab(new Model<>(title)) { + + private static final long serialVersionUID = -5861786415855103549L; + + @Override + public WebMarkupContainer getPanel(final String panelId) { + Panel panel; + + try { + panel = ClassUtils.getConstructorIfAvailable(clazz, String.class, PageReference.class). + newInstance(panelId, Configuration.this.getPageReference()); + } catch (Exception e) { + panel = new Panel(panelId) { + + private static final long serialVersionUID = 5538299138211283825L; + + }; + + LOG.error("Could not instantiate {}", clazz.getName(), e); + } + + return panel; + } + }); + + index++; + } + + JQueryUITabbedPanel<AbstractTab> extPanels = new JQueryUITabbedPanel<>("extPanels", tabs); + extPanels.setVisible(!tabs.isEmpty()); + add(extPanels); + } + + private class NotificationProvider extends SortableDataProvider<NotificationTO, String> { + + private static final long serialVersionUID = -276043813563988590L; + + private final SortableDataProviderComparator<NotificationTO> comparator; + + public NotificationProvider() { + //Default sorting + setSort("key", SortOrder.ASCENDING); + comparator = new SortableDataProviderComparator<>(this); + } + + @Override + public Iterator<NotificationTO> iterator(final long first, final long count) { + List<NotificationTO> list = notificationRestClient.getAllNotifications(); + + Collections.sort(list, comparator); + + return list.subList((int) first, (int) first + (int) count).iterator(); + } + + @Override + public long size() { + return notificationRestClient.getAllNotifications().size(); + } + + @Override + public IModel<NotificationTO> model(final NotificationTO notification) { + return new AbstractReadOnlyModel<NotificationTO>() { + + private static final long serialVersionUID = 774694801558497248L; + + @Override + public NotificationTO getObject() { + return notification; + } + }; + } + } + + private class SecurityQuestionProvider extends SortableDataProvider<SecurityQuestionTO, String> { + + private static final long serialVersionUID = -1458398823626281188L; + + private final SortableDataProviderComparator<SecurityQuestionTO> comparator; + + public SecurityQuestionProvider() { + //Default sorting + setSort("key", SortOrder.ASCENDING); + comparator = new SortableDataProviderComparator<>(this); + } + + @Override + public Iterator<SecurityQuestionTO> iterator(final long first, final long count) { + List<SecurityQuestionTO> list = securityQuestionRestClient.list(); + + Collections.sort(list, comparator); + + return list.subList((int) first, (int) first + (int) count).iterator(); + } + + @Override + public long size() { + return securityQuestionRestClient.list().size(); + } + + @Override + public IModel<SecurityQuestionTO> model(final SecurityQuestionTO securityQuestionTO) { + return new AbstractReadOnlyModel<SecurityQuestionTO>() { + + private static final long serialVersionUID = 5079291243768775704L; + + @Override + public SecurityQuestionTO getObject() { + return securityQuestionTO; + } + }; + } + } + + private class LoggerPropertyList extends PropertyListView<LoggerTO> { + + private static final long serialVersionUID = 5911412425994616111L; + + private final ConsoleLoggerController consoleLoggerController; + + public LoggerPropertyList(final ConsoleLoggerController consoleLoggerController, final String id, + final List<? extends LoggerTO> list) { + + super(id, list); + this.consoleLoggerController = consoleLoggerController; + } + + @Override + protected void populateItem(final ListItem<LoggerTO> item) { + item.add(new Label("key")); + + DropDownChoice<LoggerLevel> level = new DropDownChoice<>("level"); + level.setModel(new IModel<LoggerLevel>() { + + private static final long serialVersionUID = -2350428186089596562L; + + @Override + public LoggerLevel getObject() { + return item.getModelObject().getLevel(); + } + + @Override + public void setObject(final LoggerLevel object) { + item.getModelObject().setLevel(object); + } + + @Override + public void detach() { + } + }); + level.setChoices(Arrays.asList(LoggerLevel.values())); + level.setOutputMarkupId(true); + level.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + try { + if (getId().equals("corelogger")) { + loggerRestClient.setLogLevel(item.getModelObject().getKey(), + item.getModelObject().getLevel()); + } else { + consoleLoggerController.setLogLevel(item.getModelObject().getKey(), + item.getModelObject().getLevel()); + } + + info(getString(Constants.OPERATION_SUCCEEDED)); + } catch (SyncopeClientException e) { + info(getString(Constants.OPERATION_ERROR)); + } + + feedbackPanel.refresh(target); + } + }); + + MetaDataRoleAuthorizationStrategy.authorize(level, ENABLE, xmlRolesReader.getEntitlement( + "Configuration", "logSetLevel")); + + item.add(level); + } + } + + private static class ConsoleLoggerController implements Serializable { + + private static final long serialVersionUID = -1550459341476431714L; + + public List<LoggerTO> getLoggers() { + LoggerContext ctx = (LoggerContext) LogManager.getContext(false); + + List<LoggerTO> result = new ArrayList<>(); + for (LoggerConfig logger : ctx.getConfiguration().getLoggers().values()) { + final String loggerName = LogManager.ROOT_LOGGER_NAME.equals(logger.getName()) + ? SyncopeConstants.ROOT_LOGGER : logger.getName(); + if (logger.getLevel() != null) { + LoggerTO loggerTO = new LoggerTO(); + loggerTO.setKey(loggerName); + loggerTO.setLevel(LoggerLevel.fromLevel(logger.getLevel())); + result.add(loggerTO); + } + } + + return result; + } + + public void setLogLevel(final String name, final LoggerLevel level) { + LoggerContext ctx = (LoggerContext) LogManager.getContext(false); + LoggerConfig logConf = SyncopeConstants.ROOT_LOGGER.equals(name) + ? ctx.getConfiguration().getLoggerConfig(LogManager.ROOT_LOGGER_NAME) + : ctx.getConfiguration().getLoggerConfig(name); + logConf.setLevel(level.getLevel()); + ctx.updateLoggers(); + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/pages/ConfirmPasswordResetModalPage.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ConfirmPasswordResetModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ConfirmPasswordResetModalPage.java new file mode 100644 index 0000000..ebc041d --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/ConfirmPasswordResetModalPage.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.pages; + +import org.apache.syncope.client.console.commons.Constants; +import org.apache.syncope.client.console.commons.Mode; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPasswordFieldPanel; +import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel; +import org.apache.syncope.common.lib.to.UserTO; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.form.AjaxButton; +import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton; +import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.form.PasswordTextField; +import org.apache.wicket.markup.html.form.StatelessForm; +import org.apache.wicket.markup.html.form.validation.EqualPasswordInputValidator; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.ResourceModel; + +public class ConfirmPasswordResetModalPage extends BaseModalPage { + + private static final long serialVersionUID = -8419445804421211904L; + + public ConfirmPasswordResetModalPage(final ModalWindow window, final String token) { + super(); + setOutputMarkupId(true); + + final StatelessForm<?> form = new StatelessForm<Object>(FORM); + form.setOutputMarkupId(true); + + final FieldPanel<String> password = + new AjaxPasswordFieldPanel("password", "password", new Model<String>()).setRequired(true); + ((PasswordTextField) password.getField()).setResetPassword(true); + form.add(password); + + final FieldPanel<String> confirmPassword = + new AjaxPasswordFieldPanel("confirmPassword", "confirmPassword", new Model<String>()); + ((PasswordTextField) confirmPassword.getField()).setResetPassword(true); + form.add(confirmPassword); + + form.add(new EqualPasswordInputValidator(password.getField(), confirmPassword.getField())); + + final AjaxButton submit = new IndicatingAjaxButton(APPLY, new ResourceModel(SUBMIT, SUBMIT)) { + + private static final long serialVersionUID = -4804368561204623354L; + + @Override + protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) { + try { + userSelfRestClient.confirmPasswordReset(token, password.getModelObject()); + + setResponsePage(new ResultStatusModalPage.Builder(window, new UserTO()).mode(Mode.SELF).build()); + } catch (Exception e) { + LOG.error("While confirming password reset for {}", token, e); + error(getString(Constants.ERROR) + ": " + e.getMessage()); + feedbackPanel.refresh(target); + } + } + + @Override + protected void onError(final AjaxRequestTarget target, final Form<?> form) { + feedbackPanel.refresh(target); + } + }; + form.add(submit); + form.setDefaultButton(submit); + + final AjaxButton cancel = new IndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL)) { + + private static final long serialVersionUID = -958724007591692537L; + + @Override + protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) { + window.close(target); + } + + @Override + protected void onError(final AjaxRequestTarget target, final Form<?> form) { + } + }; + cancel.setDefaultFormProcessing(false); + form.add(cancel); + + add(form); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/pages/ConnObjectModalPage.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ConnObjectModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ConnObjectModalPage.java new file mode 100644 index 0000000..cf1c405 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/ConnObjectModalPage.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.pages; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import org.apache.syncope.common.lib.to.AttrTO; +import org.apache.syncope.common.lib.to.ConnObjectTO; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel; +import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel; +import org.apache.syncope.client.console.wicket.markup.html.list.AltListView; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.list.ListItem; +import org.apache.wicket.markup.html.list.ListView; +import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.LoadableDetachableModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.util.ListModel; + +public class ConnObjectModalPage extends BaseModalPage { + + private static final long serialVersionUID = -6469290753080058487L; + + public ConnObjectModalPage(final ConnObjectTO connObjectTO) { + super(); + + final Form<Void> form = new Form<Void>(FORM); + form.setEnabled(false); + add(form); + + IModel<List<AttrTO>> formProps = new LoadableDetachableModel<List<AttrTO>>() { + + private static final long serialVersionUID = 5275935387613157437L; + + @Override + protected List<AttrTO> load() { + List<AttrTO> attrs = connObjectTO.getPlainAttrs(); + Collections.sort(attrs, new Comparator<AttrTO>() { + + @Override + public int compare(final AttrTO attr1, final AttrTO attr2) { + if (attr1 == null || attr1.getSchema() == null) { + return -1; + } + if (attr2 == null || attr2.getSchema() == null) { + return 1; + } + return attr1.getSchema().compareTo(attr2.getSchema()); + } + }); + + return attrs; + } + }; + final ListView<AttrTO> propView = new AltListView<AttrTO>("propView", formProps) { + + private static final long serialVersionUID = 3109256773218160485L; + + @Override + protected void populateItem(final ListItem<AttrTO> item) { + final AttrTO prop = item.getModelObject(); + + Label label = new Label("key", prop.getSchema()); + item.add(label); + + Panel field; + if (prop.getValues().isEmpty()) { + field = new AjaxTextFieldPanel("value", + prop.getSchema(), new Model<String>()); + } else if (prop.getValues().size() == 1) { + field = new AjaxTextFieldPanel("value", + prop.getSchema(), new Model<String>(prop.getValues().get(0))); + } else { + field = new MultiFieldPanel<String>("value", new ListModel<String>(prop.getValues()), + new AjaxTextFieldPanel("panel", prop.getSchema(), new Model<String>())); + } + item.add(field); + } + }; + form.add(propView); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/pages/ConnectorModalPage.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/ConnectorModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/ConnectorModalPage.java new file mode 100644 index 0000000..8095591 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/ConnectorModalPage.java @@ -0,0 +1,479 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.pages; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.client.console.commons.Constants; +import org.apache.syncope.client.console.rest.ConnectorRestClient; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel; +import org.apache.syncope.client.console.wicket.markup.html.form.SpinnerFieldPanel; +import org.apache.syncope.client.console.wicket.markup.html.list.ConnConfPropertyListView; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.to.ConnBundleTO; +import org.apache.syncope.common.lib.to.ConnInstanceTO; +import org.apache.syncope.common.lib.to.ConnPoolConfTO; +import org.apache.syncope.common.lib.types.ConnConfPropSchema; +import org.apache.syncope.common.lib.types.ConnConfProperty; +import org.apache.syncope.common.lib.types.ConnectorCapability; +import org.apache.wicket.PageReference; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior; +import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; +import org.apache.wicket.ajax.markup.html.form.AjaxButton; +import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy; +import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton; +import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.form.CheckBoxMultipleChoice; +import org.apache.wicket.markup.html.form.DropDownChoice; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.list.ListView; +import org.apache.wicket.model.CompoundPropertyModel; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.LoadableDetachableModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.PropertyModel; +import org.apache.wicket.model.ResourceModel; +import org.apache.wicket.spring.injection.annot.SpringBean; +import org.apache.wicket.validation.validator.RangeValidator; + +/** + * Modal window with Connector form. + */ +public class ConnectorModalPage extends BaseModalPage { + + private static final long serialVersionUID = -2025535531121434050L; + + @SpringBean + private ConnectorRestClient restClient; + + private final Map<String, Map<String, Map<String, ConnBundleTO>>> mapConnBundleTOs; + + private final List<ConnectorCapability> selectedCapabilities; + + private ConnBundleTO bundleTO; + + private List<ConnConfProperty> properties; + + private final WebMarkupContainer propertiesContainer; + + public ConnectorModalPage(final PageReference pageRef, final ModalWindow window, + final ConnInstanceTO connInstanceTO) { + + super(); + + this.add(new Label("new", connInstanceTO.getKey() == 0 + ? new ResourceModel("new") + : new Model<>(StringUtils.EMPTY))); + this.add(new Label("key", connInstanceTO.getKey() == 0 + ? StringUtils.EMPTY + : connInstanceTO.getKey())); + + // general data setup + selectedCapabilities = new ArrayList<>(connInstanceTO.getKey() == 0 + ? EnumSet.noneOf(ConnectorCapability.class) + : connInstanceTO.getCapabilities()); + + mapConnBundleTOs = new HashMap<>(); + for (ConnBundleTO connBundleTO : restClient.getAllBundles()) { + // by location + if (!mapConnBundleTOs.containsKey(connBundleTO.getLocation())) { + mapConnBundleTOs.put(connBundleTO.getLocation(), new HashMap<String, Map<String, ConnBundleTO>>()); + } + final Map<String, Map<String, ConnBundleTO>> byLocation = mapConnBundleTOs.get(connBundleTO.getLocation()); + + // by name + if (!byLocation.containsKey(connBundleTO.getBundleName())) { + byLocation.put(connBundleTO.getBundleName(), new HashMap<String, ConnBundleTO>()); + } + final Map<String, ConnBundleTO> byName = byLocation.get(connBundleTO.getBundleName()); + + // by version + if (!byName.containsKey(connBundleTO.getVersion())) { + byName.put(connBundleTO.getVersion(), connBundleTO); + } + } + + bundleTO = getSelectedBundleTO(connInstanceTO); + properties = fillProperties(bundleTO, connInstanceTO); + + // form - first tab + final Form<ConnInstanceTO> connectorForm = new Form<>(FORM); + connectorForm.setModel(new CompoundPropertyModel<>(connInstanceTO)); + connectorForm.setOutputMarkupId(true); + add(connectorForm); + + propertiesContainer = new WebMarkupContainer("container"); + propertiesContainer.setOutputMarkupId(true); + connectorForm.add(propertiesContainer); + + final Form<ConnInstanceTO> connectorPropForm = new Form<>("connectorPropForm"); + connectorPropForm.setModel(new CompoundPropertyModel<>(connInstanceTO)); + connectorPropForm.setOutputMarkupId(true); + propertiesContainer.add(connectorPropForm); + + final AjaxTextFieldPanel displayName = new AjaxTextFieldPanel( + "displayName", "display name", new PropertyModel<String>(connInstanceTO, "displayName")); + displayName.setOutputMarkupId(true); + displayName.addRequiredLabel(); + connectorForm.add(displayName); + + final AjaxDropDownChoicePanel<String> location = + new AjaxDropDownChoicePanel<>("location", "location", + new Model<>(bundleTO == null ? null : bundleTO.getLocation())); + ((DropDownChoice<String>) location.getField()).setNullValid(true); + location.setStyleSheet("long_dynamicsize"); + location.setChoices(new ArrayList<>(mapConnBundleTOs.keySet())); + location.setRequired(true); + location.addRequiredLabel(); + location.setOutputMarkupId(true); + location.setEnabled(connInstanceTO.getKey() == 0); + location.getField().setOutputMarkupId(true); + connectorForm.add(location); + + final AjaxDropDownChoicePanel<String> connectorName = + new AjaxDropDownChoicePanel<>("connectorName", "connectorName", + new Model<>(bundleTO == null ? null : bundleTO.getBundleName())); + ((DropDownChoice<String>) connectorName.getField()).setNullValid(true); + connectorName.setStyleSheet("long_dynamicsize"); + connectorName.setChoices(bundleTO == null + ? new ArrayList<String>() + : new ArrayList<>(mapConnBundleTOs.get(connInstanceTO.getLocation()).keySet())); + connectorName.setRequired(true); + connectorName.addRequiredLabel(); + connectorName.setEnabled(connInstanceTO.getLocation() != null); + connectorName.setOutputMarkupId(true); + connectorName.setEnabled(connInstanceTO.getKey() == 0); + connectorName.getField().setOutputMarkupId(true); + connectorForm.add(connectorName); + + final AjaxDropDownChoicePanel<String> version = + new AjaxDropDownChoicePanel<>("version", "version", + new Model<>(bundleTO == null ? null : bundleTO.getVersion())); + version.setStyleSheet("long_dynamicsize"); + version.setChoices(bundleTO == null + ? new ArrayList<String>() + : new ArrayList<>(mapConnBundleTOs.get(connInstanceTO.getLocation()). + get(connInstanceTO.getBundleName()).keySet())); + version.setRequired(true); + version.addRequiredLabel(); + version.setEnabled(connInstanceTO.getBundleName() != null); + version.setOutputMarkupId(true); + version.addRequiredLabel(); + version.getField().setOutputMarkupId(true); + connectorForm.add(version); + + final SpinnerFieldPanel<Integer> connRequestTimeout = + new SpinnerFieldPanel<>("connRequestTimeout", "connRequestTimeout", Integer.class, + new PropertyModel<Integer>(connInstanceTO, "connRequestTimeout"), 0, null); + connRequestTimeout.getField().add(new RangeValidator<>(0, Integer.MAX_VALUE)); + connectorForm.add(connRequestTimeout); + + if (connInstanceTO.getPoolConf() == null) { + connInstanceTO.setPoolConf(new ConnPoolConfTO()); + } + final SpinnerFieldPanel<Integer> poolMaxObjects = + new SpinnerFieldPanel<>("poolMaxObjects", "poolMaxObjects", Integer.class, + new PropertyModel<Integer>(connInstanceTO.getPoolConf(), "maxObjects"), 0, null); + poolMaxObjects.getField().add(new RangeValidator<>(0, Integer.MAX_VALUE)); + connectorForm.add(poolMaxObjects); + final SpinnerFieldPanel<Integer> poolMinIdle = + new SpinnerFieldPanel<>("poolMinIdle", "poolMinIdle", Integer.class, + new PropertyModel<Integer>(connInstanceTO.getPoolConf(), "minIdle"), 0, null); + poolMinIdle.getField().add(new RangeValidator<>(0, Integer.MAX_VALUE)); + connectorForm.add(poolMinIdle); + final SpinnerFieldPanel<Integer> poolMaxIdle = + new SpinnerFieldPanel<>("poolMaxIdle", "poolMaxIdle", Integer.class, + new PropertyModel<Integer>(connInstanceTO.getPoolConf(), "maxIdle"), 0, null); + poolMaxIdle.getField().add(new RangeValidator<>(0, Integer.MAX_VALUE)); + connectorForm.add(poolMaxIdle); + final SpinnerFieldPanel<Long> poolMaxWait = + new SpinnerFieldPanel<>("poolMaxWait", "poolMaxWait", Long.class, + new PropertyModel<Long>(connInstanceTO.getPoolConf(), "maxWait"), 0L, null); + poolMaxWait.getField().add(new RangeValidator<>(0L, Long.MAX_VALUE)); + connectorForm.add(poolMaxWait); + final SpinnerFieldPanel<Long> poolMinEvictableIdleTime = + new SpinnerFieldPanel<>("poolMinEvictableIdleTime", "poolMinEvictableIdleTime", Long.class, + new PropertyModel<Long>(connInstanceTO.getPoolConf(), "minEvictableIdleTimeMillis"), + 0L, null); + poolMinEvictableIdleTime.getField().add(new RangeValidator<>(0L, Long.MAX_VALUE)); + connectorForm.add(poolMinEvictableIdleTime); + + // form - first tab - onchange() + location.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + ((DropDownChoice<String>) location.getField()).setNullValid(false); + connInstanceTO.setLocation(location.getModelObject()); + target.add(location); + + connectorName.setChoices(new ArrayList<>( + mapConnBundleTOs.get(location.getModelObject()).keySet())); + connectorName.setEnabled(true); + connectorName.getField().setModelValue(null); + target.add(connectorName); + + version.setChoices(new ArrayList<String>()); + version.getField().setModelValue(null); + version.setEnabled(false); + target.add(version); + + properties.clear(); + target.add(propertiesContainer); + } + }); + connectorName.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + ((DropDownChoice<String>) connectorName.getField()).setNullValid(false); + connInstanceTO.setBundleName(connectorName.getModelObject()); + target.add(connectorName); + + List<String> versions = new ArrayList<>( + mapConnBundleTOs.get(location.getModelObject()).get(connectorName.getModelObject()).keySet()); + version.setChoices(versions); + version.setEnabled(true); + if (versions.size() == 1) { + selectVersion(target, connInstanceTO, version, versions.get(0)); + version.getField().setModelObject(versions.get(0)); + } else { + version.getField().setModelValue(null); + properties.clear(); + target.add(propertiesContainer); + } + target.add(version); + } + }); + version.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + selectVersion(target, connInstanceTO, version, version.getModelObject()); + } + }); + + // form - second tab (properties) + final ListView<ConnConfProperty> connPropView = new ConnConfPropertyListView("connectorProperties", + new PropertyModel<List<ConnConfProperty>>(this, "properties"), + true, connInstanceTO.getConfiguration()); + connPropView.setOutputMarkupId(true); + connectorPropForm.add(connPropView); + + final AjaxButton check = new IndicatingAjaxButton("check", new ResourceModel("check")) { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onSubmit(final AjaxRequestTarget target, final Form<?> form) { + final ConnInstanceTO conn = (ConnInstanceTO) form.getModelObject(); + + // ensure that connector bundle information is in sync + conn.setBundleName(bundleTO.getBundleName()); + conn.setVersion(bundleTO.getVersion()); + conn.setConnectorName(bundleTO.getConnectorName()); + + if (restClient.check(conn)) { + info(getString("success_connection")); + } else { + error(getString("error_connection")); + } + + feedbackPanel.refresh(target); + } + }; + connectorPropForm.add(check); + + // form - third tab (capabilities) + final IModel<List<ConnectorCapability>> capabilities = + new LoadableDetachableModel<List<ConnectorCapability>>() { + + private static final long serialVersionUID = 5275935387613157437L; + + @Override + protected List<ConnectorCapability> load() { + return Arrays.asList(ConnectorCapability.values()); + } + }; + CheckBoxMultipleChoice<ConnectorCapability> capabilitiesPalette = + new CheckBoxMultipleChoice<>("capabilitiesPalette", + new PropertyModel<List<ConnectorCapability>>(this, "selectedCapabilities"), capabilities); + + capabilitiesPalette.add(new AjaxFormChoiceComponentUpdatingBehavior() { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(AjaxRequestTarget target) { + } + }); + + connectorForm.add(capabilitiesPalette); + + // form - submit / cancel buttons + final AjaxButton submit = new IndicatingAjaxButton(APPLY, new Model<>(getString(SUBMIT))) { + + private static final long serialVersionUID = -958724007591692537L; + + @Override + protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) { + final ConnInstanceTO conn = (ConnInstanceTO) form.getModelObject(); + + conn.setConnectorName(bundleTO.getConnectorName()); + conn.setBundleName(bundleTO.getBundleName()); + conn.setVersion(bundleTO.getVersion()); + conn.getConfiguration().clear(); + conn.getConfiguration().addAll(connPropView.getModelObject()); + + // Set the model object's capabilities to capabilitiesPalette's converted Set + conn.getCapabilities().clear(); + conn.getCapabilities().addAll(selectedCapabilities.isEmpty() + ? EnumSet.noneOf(ConnectorCapability.class) + : EnumSet.copyOf(selectedCapabilities)); + + // Reset pool configuration if all fields are null + if (conn.getPoolConf() != null + && conn.getPoolConf().getMaxIdle() == null + && conn.getPoolConf().getMaxObjects() == null + && conn.getPoolConf().getMaxWait() == null + && conn.getPoolConf().getMinEvictableIdleTimeMillis() == null + && conn.getPoolConf().getMinIdle() == null) { + + conn.setPoolConf(null); + } + + try { + if (connInstanceTO.getKey() == 0) { + restClient.create(conn); + } else { + restClient.update(conn); + } + + ((Resources) pageRef.getPage()).setModalResult(true); + window.close(target); + } catch (SyncopeClientException e) { + error(getString(Constants.ERROR) + ": " + e.getMessage()); + feedbackPanel.refresh(target); + ((Resources) pageRef.getPage()).setModalResult(false); + LOG.error("While creating or updating connector {}", conn, e); + } + } + + @Override + protected void onError(final AjaxRequestTarget target, final Form<?> form) { + feedbackPanel.refresh(target); + } + }; + String roles = connInstanceTO.getKey() == 0 + ? xmlRolesReader.getEntitlement("Connectors", "create") + : xmlRolesReader.getEntitlement("Connectors", "update"); + MetaDataRoleAuthorizationStrategy.authorize(submit, ENABLE, roles); + connectorForm.add(submit); + + final IndicatingAjaxButton cancel = new IndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL)) { + + private static final long serialVersionUID = -958724007591692537L; + + @Override + protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) { + window.close(target); + } + }; + cancel.setDefaultFormProcessing(false); + connectorForm.add(cancel); + } + + private ConnBundleTO getSelectedBundleTO(final ConnInstanceTO connInstanceTO) { + ConnBundleTO result = null; + if (connInstanceTO != null + && StringUtils.isNotBlank(connInstanceTO.getLocation()) + && StringUtils.isNotBlank(connInstanceTO.getBundleName()) + && StringUtils.isNotBlank(connInstanceTO.getVersion()) + && mapConnBundleTOs.containsKey(connInstanceTO.getLocation())) { + + Map<String, Map<String, ConnBundleTO>> byLocation = mapConnBundleTOs.get(connInstanceTO.getLocation()); + if (byLocation.containsKey(connInstanceTO.getBundleName())) { + Map<String, ConnBundleTO> byName = byLocation.get(connInstanceTO.getBundleName()); + if (byName.containsKey(connInstanceTO.getVersion())) { + result = byName.get(connInstanceTO.getVersion()); + } + } + } + return result; + } + + private List<ConnConfProperty> fillProperties(final ConnBundleTO bundleTO, final ConnInstanceTO connInstanceTO) { + final List<ConnConfProperty> props = new ArrayList<>(); + + if (bundleTO != null) { + for (ConnConfPropSchema key : bundleTO.getProperties()) { + final ConnConfProperty property = new ConnConfProperty(); + property.setSchema(key); + if (connInstanceTO.getKey() != 0 + && connInstanceTO.getConfigurationMap().containsKey(key.getName()) + && connInstanceTO.getConfigurationMap().get(key.getName()).getValues() != null) { + + property.getValues().addAll(connInstanceTO.getConfigurationMap().get(key.getName()).getValues()); + property.setOverridable(connInstanceTO.getConfigurationMap().get(key.getName()).isOverridable()); + } + + if (property.getValues().isEmpty() && !key.getDefaultValues().isEmpty()) { + property.getValues().addAll(key.getDefaultValues()); + } + + props.add(property); + } + } + + // re-order properties (implements Comparable) + Collections.sort(props); + return props; + } + + private void selectVersion(final AjaxRequestTarget target, final ConnInstanceTO connInstanceTO, + final AjaxDropDownChoicePanel<String> version, final String versionValue) { + + connInstanceTO.setVersion(versionValue); + target.add(version); + + bundleTO = getSelectedBundleTO(connInstanceTO); + properties = fillProperties(bundleTO, connInstanceTO); + target.add(propertiesContainer); + } + + public List<ConnConfProperty> getProperties() { + return properties; + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/pages/DerSchemaModalPage.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/pages/DerSchemaModalPage.java b/client/console/src/main/java/org/apache/syncope/client/console/pages/DerSchemaModalPage.java new file mode 100644 index 0000000..98f4fbb --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/pages/DerSchemaModalPage.java @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.pages; + +import org.apache.syncope.client.console.commons.Constants; +import org.apache.syncope.client.console.commons.JexlHelpUtil; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.to.DerSchemaTO; +import org.apache.syncope.common.lib.types.AttributableType; +import org.apache.wicket.PageReference; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.AjaxLink; +import org.apache.wicket.ajax.markup.html.form.AjaxButton; +import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy; +import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton; +import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.model.CompoundPropertyModel; +import org.apache.wicket.model.PropertyModel; +import org.apache.wicket.model.ResourceModel; + +/** + * Modal window with Schema form. + */ +public class DerSchemaModalPage extends AbstractSchemaModalPage<DerSchemaTO> { + + private static final long serialVersionUID = 6668789770131753386L; + + public DerSchemaModalPage(final AttributableType kind) { + super(kind); + } + + @Override + public void setSchemaModalPage(final PageReference pageRef, final ModalWindow window, + DerSchemaTO schema, final boolean createFlag) { + + if (schema == null) { + schema = new DerSchemaTO(); + } + + final Form<DerSchemaTO> schemaForm = new Form<>(FORM); + + schemaForm.setModel(new CompoundPropertyModel<>(schema)); + + final AjaxTextFieldPanel name = + new AjaxTextFieldPanel("key", getString("key"), new PropertyModel<String>(schema, "key")); + name.addRequiredLabel(); + + final AjaxTextFieldPanel expression = new AjaxTextFieldPanel("expression", getString("expression"), + new PropertyModel<String>(schema, "expression")); + expression.addRequiredLabel(); + + final WebMarkupContainer jexlHelp = JexlHelpUtil.getJexlHelpWebContainer("jexlHelp"); + + final AjaxLink<Void> questionMarkJexlHelp = JexlHelpUtil.getAjaxLink(jexlHelp, "questionMarkJexlHelp"); + schemaForm.add(questionMarkJexlHelp); + questionMarkJexlHelp.add(jexlHelp); + + name.setEnabled(createFlag); + + final AjaxButton submit = new IndicatingAjaxButton(APPLY, new ResourceModel(SUBMIT)) { + + private static final long serialVersionUID = -958724007591692537L; + + @Override + protected void onSubmit(final AjaxRequestTarget target, final Form form) { + DerSchemaTO schemaTO = (DerSchemaTO) form.getDefaultModelObject(); + + try { + if (createFlag) { + schemaRestClient.createDerSchema(kind, schemaTO); + } else { + schemaRestClient.updateDerSchema(kind, schemaTO); + } + + if (pageRef.getPage() instanceof BasePage) { + ((BasePage) pageRef.getPage()).setModalResult(true); + } + + window.close(target); + } catch (SyncopeClientException e) { + error(getString(Constants.ERROR) + ": " + e.getMessage()); + feedbackPanel.refresh(target); + } + } + + @Override + protected void onError(final AjaxRequestTarget target, final Form<?> form) { + feedbackPanel.refresh(target); + } + }; + + final AjaxButton cancel = new IndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL)) { + + private static final long serialVersionUID = -958724007591692537L; + + @Override + protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) { + window.close(target); + } + }; + + cancel.setDefaultFormProcessing( + false); + + String allowedRoles = createFlag + ? xmlRolesReader.getEntitlement("Schema", "create") + : xmlRolesReader.getEntitlement("Schema", "update"); + + MetaDataRoleAuthorizationStrategy.authorize(submit, ENABLE, allowedRoles); + + schemaForm.add(name); + + schemaForm.add(expression); + + schemaForm.add(submit); + + schemaForm.add(cancel); + + add(schemaForm); + } +}
