http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java ---------------------------------------------------------------------- diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java new file mode 100644 index 0000000..b3e63c5 --- /dev/null +++ b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourceConnConfPanel.java @@ -0,0 +1,187 @@ +/* + * 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.panels; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.syncope.client.console.pages.BaseModalPage; +import org.apache.syncope.client.console.pages.ResourceModalPage.ResourceEvent; +import org.apache.syncope.client.console.panels.ResourceDetailsPanel.DetailsModEvent; +import org.apache.syncope.client.console.rest.ConnectorRestClient; +import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel.MultiValueSelectorEvent; +import org.apache.syncope.client.console.wicket.markup.html.list.ConnConfPropertyListView; +import org.apache.syncope.common.lib.to.ResourceTO; +import org.apache.syncope.common.lib.types.ConnConfProperty; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.form.AjaxButton; +import org.apache.wicket.event.Broadcast; +import org.apache.wicket.event.IEvent; +import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.list.ListView; +import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.model.PropertyModel; +import org.apache.wicket.model.ResourceModel; +import org.apache.wicket.spring.injection.annot.SpringBean; + +public class ResourceConnConfPanel extends Panel { + + private static final long serialVersionUID = -7982691107029848579L; + + @SpringBean + private ConnectorRestClient restClient; + + private final ResourceTO resourceTO; + + private final boolean createFlag; + + private List<ConnConfProperty> connConfProperties; + + private WebMarkupContainer connConfPropContainer; + + private AjaxButton check; + + public ResourceConnConfPanel(final String id, final ResourceTO resourceTO, final boolean createFlag) { + super(id); + setOutputMarkupId(true); + + this.createFlag = createFlag; + this.resourceTO = resourceTO; + + connConfProperties = getConnConfProperties(); + + connConfPropContainer = new WebMarkupContainer("connectorPropertiesContainer"); + connConfPropContainer.setOutputMarkupId(true); + add(connConfPropContainer); + + /* + * the list of overridable connector properties + */ + final ListView<ConnConfProperty> connPropView = new ConnConfPropertyListView("connectorProperties", + new PropertyModel<List<ConnConfProperty>>(this, "connConfProperties"), + false, resourceTO.getConnConfProperties()); + connPropView.setOutputMarkupId(true); + connConfPropContainer.add(connPropView); + + check = new IndicatingAjaxButton("check", new ResourceModel("check")) { + + private static final long serialVersionUID = -4199438518229098169L; + + @Override + public void onSubmit(final AjaxRequestTarget target, final Form<?> form) { + final ResourceTO resourceTO = (ResourceTO) form.getModelObject(); + + if (restClient.check(resourceTO)) { + info(getString("success_connection")); + } else { + error(getString("error_connection")); + } + + ((BaseModalPage) getPage()).getFeedbackPanel().refresh(target); + } + }; + + check.setEnabled(!connConfProperties.isEmpty()); + connConfPropContainer.add(check); + } + + /** + * Get overridable properties. + * + * @return overridable properties. + */ + private List<ConnConfProperty> getConnConfProperties() { + final List<ConnConfProperty> props = new ArrayList<ConnConfProperty>(); + final Long connectorId = resourceTO.getConnectorId(); + if (connectorId != null && connectorId > 0) { + for (ConnConfProperty property : restClient.getConnectorProperties(connectorId)) { + if (property.isOverridable()) { + props.add(property); + } + } + } + if (createFlag || resourceTO.getConnConfProperties().isEmpty()) { + resourceTO.getConnConfProperties().clear(); + } else { + Map<String, ConnConfProperty> valuedProps = new HashMap<String, ConnConfProperty>(); + for (ConnConfProperty prop : resourceTO.getConnConfProperties()) { + valuedProps.put(prop.getSchema().getName(), prop); + } + + for (int i = 0; i < props.size(); i++) { + if (valuedProps.containsKey(props.get(i).getSchema().getName())) { + props.set(i, valuedProps.get(props.get(i).getSchema().getName())); + } + } + } + + // re-order properties + Collections.sort(props); + + return props; + } + + @Override + public void onEvent(final IEvent<?> event) { + AjaxRequestTarget target = null; + if (event.getPayload() instanceof DetailsModEvent) { + // connector change: update properties and forward event + target = ((ResourceEvent) event.getPayload()).getTarget(); + + connConfProperties = getConnConfProperties(); + check.setEnabled(!connConfProperties.isEmpty()); + + target.add(connConfPropContainer); + } else if (event.getPayload() instanceof MultiValueSelectorEvent) { + // multi value connector property change: forward event + target = ((MultiValueSelectorEvent) event.getPayload()).getTarget(); + } + + if (target != null) { + send(getPage(), Broadcast.BREADTH, new ConnConfModEvent(target, connConfProperties)); + } + } + + /** + * Connector configuration properties modification event. + */ + public static class ConnConfModEvent extends ResourceEvent { + + private List<ConnConfProperty> configuration; + + /** + * Constructor. + * + * @param target request target. + * @param configuration connector configuration properties. + */ + public ConnConfModEvent(final AjaxRequestTarget target, final List<ConnConfProperty> configuration) { + super(target); + this.configuration = configuration; + } + + public List<ConnConfProperty> getConfiguration() { + return configuration; + } + } +}
http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java ---------------------------------------------------------------------- diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java new file mode 100644 index 0000000..3bff23f --- /dev/null +++ b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourceDetailsPanel.java @@ -0,0 +1,306 @@ +/* + * 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.panels; + +import java.util.Arrays; +import java.util.List; +import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.client.console.commons.Constants; +import org.apache.syncope.client.console.pages.ResourceModalPage.ResourceEvent; +import org.apache.syncope.client.console.rest.ConnectorRestClient; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel; +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.common.lib.to.ConnInstanceTO; +import org.apache.syncope.common.lib.to.ResourceTO; +import org.apache.syncope.common.lib.types.PropagationMode; +import org.apache.syncope.common.lib.types.TraceLevel; +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.event.Broadcast; +import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.form.ChoiceRenderer; +import org.apache.wicket.markup.html.form.DropDownChoice; +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.PropertyModel; +import org.apache.wicket.model.ResourceModel; +import org.apache.wicket.spring.injection.annot.SpringBean; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ResourceDetailsPanel extends Panel { + + private static final long serialVersionUID = -7982691107029848579L; + + /** + * Logger. + */ + private static final Logger LOG = LoggerFactory.getLogger(ResourceDetailsPanel.class); + + @SpringBean + private ConnectorRestClient connRestClient; + + private ConnInstanceTO connInstanceTO; + + public ResourceDetailsPanel(final String id, final ResourceTO resourceTO, final List<String> actionClassNames, + final boolean createFlag) { + + super(id); + setOutputMarkupId(true); + + final AjaxTextFieldPanel resourceName = new AjaxTextFieldPanel("name", new ResourceModel("name", "name"). + getObject(), new PropertyModel<String>(resourceTO, "key")); + + resourceName.setEnabled(createFlag); + resourceName.addRequiredLabel(); + add(resourceName); + + final AjaxCheckBoxPanel enforceMandatoryCondition = new AjaxCheckBoxPanel("enforceMandatoryCondition", + new ResourceModel("enforceMandatoryCondition", "enforceMandatoryCondition").getObject(), + new PropertyModel<Boolean>(resourceTO, "enforceMandatoryCondition")); + add(enforceMandatoryCondition); + + final AjaxCheckBoxPanel propagationPrimary = new AjaxCheckBoxPanel("propagationPrimary", new ResourceModel( + "propagationPrimary", "propagationPrimary").getObject(), new PropertyModel<Boolean>(resourceTO, + "propagationPrimary")); + add(propagationPrimary); + + final SpinnerFieldPanel<Integer> propagationPriority = + new SpinnerFieldPanel<>("propagationPriority", "propagationPriority", Integer.class, + new PropertyModel<Integer>(resourceTO, "propagationPriority"), null, null); + add(propagationPriority); + + final AjaxDropDownChoicePanel<PropagationMode> propagationMode = new AjaxDropDownChoicePanel<>( + "propagationMode", new ResourceModel("propagationMode", "propagationMode").getObject(), + new PropertyModel<PropagationMode>(resourceTO, "propagationMode")); + propagationMode.setChoices(Arrays.asList(PropagationMode.values())); + add(propagationMode); + + final AjaxCheckBoxPanel randomPwdIfNotProvided = new AjaxCheckBoxPanel("randomPwdIfNotProvided", + new ResourceModel("randomPwdIfNotProvided", "randomPwdIfNotProvided").getObject(), + new PropertyModel<Boolean>(resourceTO, "randomPwdIfNotProvided")); + add(randomPwdIfNotProvided); + + final WebMarkupContainer propagationActionsClassNames = new WebMarkupContainer("propagationActionsClassNames"); + propagationActionsClassNames.setOutputMarkupId(true); + add(propagationActionsClassNames); + + final AjaxLink<Void> first = new IndicatingAjaxLink<Void>("first") { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target) { + resourceTO.getPropagationActionsClassNames().add(StringUtils.EMPTY); + setVisible(false); + target.add(propagationActionsClassNames); + } + }; + first.setOutputMarkupPlaceholderTag(true); + first.setVisible(resourceTO.getPropagationActionsClassNames().isEmpty()); + propagationActionsClassNames.add(first); + + final ListView<String> actionsClasses = new ListView<String>("actionsClasses", + new PropertyModel<List<String>>(resourceTO, "propagationActionsClassNames")) { + + private static final long serialVersionUID = 9101744072914090143L; + + @Override + protected void populateItem(final ListItem<String> item) { + final String className = item.getModelObject(); + + final DropDownChoice<String> actionsClass = new DropDownChoice<>( + "actionsClass", new Model<>(className), actionClassNames); + actionsClass.setNullValid(true); + actionsClass.setRequired(true); + actionsClass.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + resourceTO.getPropagationActionsClassNames(). + set(item.getIndex(), actionsClass.getModelObject()); + } + }); + actionsClass.setRequired(true); + actionsClass.setOutputMarkupId(true); + actionsClass.setRequired(true); + item.add(actionsClass); + + AjaxLink<Void> minus = new IndicatingAjaxLink<Void>("drop") { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target) { + resourceTO.getPropagationActionsClassNames().remove(className); + first.setVisible(resourceTO.getPropagationActionsClassNames().isEmpty()); + target.add(propagationActionsClassNames); + } + }; + item.add(minus); + + final AjaxLink<Void> plus = new IndicatingAjaxLink<Void>("add") { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target) { + resourceTO.getPropagationActionsClassNames().add(StringUtils.EMPTY); + target.add(propagationActionsClassNames); + } + }; + plus.setOutputMarkupPlaceholderTag(true); + plus.setVisible(item.getIndex() == resourceTO.getPropagationActionsClassNames().size() - 1); + item.add(plus); + } + }; + propagationActionsClassNames.add(actionsClasses); + + final AjaxDropDownChoicePanel<TraceLevel> createTraceLevel = new AjaxDropDownChoicePanel<>( + "createTraceLevel", new ResourceModel("createTraceLevel", "createTraceLevel").getObject(), + new PropertyModel<TraceLevel>(resourceTO, "createTraceLevel")); + createTraceLevel.setChoices(Arrays.asList(TraceLevel.values())); + add(createTraceLevel); + + final AjaxDropDownChoicePanel<TraceLevel> updateTraceLevel = new AjaxDropDownChoicePanel<>( + "updateTraceLevel", new ResourceModel("updateTraceLevel", "updateTraceLevel").getObject(), + new PropertyModel<TraceLevel>(resourceTO, "updateTraceLevel")); + updateTraceLevel.setChoices(Arrays.asList(TraceLevel.values())); + add(updateTraceLevel); + + final AjaxDropDownChoicePanel<TraceLevel> deleteTraceLevel = new AjaxDropDownChoicePanel<>( + "deleteTraceLevel", new ResourceModel("deleteTraceLevel", "deleteTraceLevel").getObject(), + new PropertyModel<TraceLevel>(resourceTO, "deleteTraceLevel")); + deleteTraceLevel.setChoices(Arrays.asList(TraceLevel.values())); + add(deleteTraceLevel); + + final AjaxDropDownChoicePanel<TraceLevel> syncTraceLevel = new AjaxDropDownChoicePanel<>( + "syncTraceLevel", new ResourceModel("syncTraceLevel", "syncTraceLevel").getObject(), + new PropertyModel<TraceLevel>(resourceTO, "syncTraceLevel")); + syncTraceLevel.setChoices(Arrays.asList(TraceLevel.values())); + add(syncTraceLevel); + + final IModel<List<ConnInstanceTO>> connectors = new LoadableDetachableModel<List<ConnInstanceTO>>() { + + private static final long serialVersionUID = 5275935387613157437L; + + @Override + protected List<ConnInstanceTO> load() { + return connRestClient.getAllConnectors(); + } + }; + + connInstanceTO = getConectorInstanceTO(connectors.getObject(), resourceTO); + + final AjaxDropDownChoicePanel<ConnInstanceTO> conn = new AjaxDropDownChoicePanel<>("connector", + new ResourceModel("connector", "connector").getObject(), + new PropertyModel<ConnInstanceTO>(this, "connInstanceTO")); + conn.setChoices(connectors.getObject()); + conn.setChoiceRenderer(new ChoiceRenderer("displayName", "key")); + + conn.getField().setModel(new IModel<ConnInstanceTO>() { + + private static final long serialVersionUID = -4202872830392400310L; + + @Override + public ConnInstanceTO getObject() { + return connInstanceTO; + } + + @Override + public void setObject(final ConnInstanceTO connector) { + resourceTO.setConnectorId(connector.getKey()); + connInstanceTO = connector; + } + + @Override + public void detach() { + } + }); + + conn.addRequiredLabel(); + conn.setEnabled(createFlag); + + conn.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + send(getPage(), Broadcast.BREADTH, new DetailsModEvent(target)); + } + }); + + add(conn); + } + + /** + * Get the connetorTO linked to the resource. + * + * @param connectorTOs list of all connectors. + * @param resourceTO resource. + * @return selected connector instance: in case of no connectors available, null; in case of new resource + * specification, the first on connector available + */ + private ConnInstanceTO getConectorInstanceTO(final List<ConnInstanceTO> connectorTOs, final ResourceTO resourceTO) { + if (connectorTOs.isEmpty()) { + resourceTO.setConnectorId(null); + return null; + } else { + // use the first element as default + ConnInstanceTO res = connectorTOs.get(0); + + for (ConnInstanceTO to : connectorTOs) { + if (Long.valueOf(to.getKey()).equals(resourceTO.getConnectorId())) { + res = to; + } + } + + // in case of no match + resourceTO.setConnectorId(res.getKey()); + + return res; + } + } + + /** + * Connector instance modification event. + */ + public static class DetailsModEvent extends ResourceEvent { + + /** + * Constructor. + * + * @param target request target. + */ + public DetailsModEvent(final AjaxRequestTarget target) { + super(target); + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java ---------------------------------------------------------------------- diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java new file mode 100644 index 0000000..406676f --- /dev/null +++ b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourceMappingPanel.java @@ -0,0 +1,644 @@ +/* + * 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.panels; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.apache.syncope.client.console.commons.Constants; +import org.apache.syncope.client.console.commons.JexlHelpUtils; +import org.apache.syncope.client.console.panels.ResourceConnConfPanel.ConnConfModEvent; +import org.apache.syncope.client.console.rest.ConnectorRestClient; +import org.apache.syncope.client.console.rest.SchemaRestClient; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDecoratedCheckbox; +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.FieldPanel; +import org.apache.syncope.client.console.wicket.markup.html.form.MappingPurposePanel; +import org.apache.syncope.common.lib.to.ConnIdObjectClassTO; +import org.apache.syncope.common.lib.to.ConnInstanceTO; +import org.apache.syncope.common.lib.to.MappingItemTO; +import org.apache.syncope.common.lib.to.MappingTO; +import org.apache.syncope.common.lib.to.ResourceTO; +import org.apache.syncope.common.lib.types.AttributableType; +import org.apache.syncope.common.lib.types.ConnConfProperty; +import org.apache.syncope.common.lib.types.IntMappingType; +import org.apache.syncope.common.lib.types.MappingPurpose; +import org.apache.wicket.Component; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.attributes.AjaxCallListener; +import org.apache.wicket.ajax.attributes.AjaxRequestAttributes; +import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; +import org.apache.wicket.ajax.markup.html.AjaxLink; +import org.apache.wicket.ajax.markup.html.form.AjaxButton; +import org.apache.wicket.event.IEvent; +import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton; +import org.apache.wicket.markup.html.WebMarkupContainer; +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.Model; +import org.apache.wicket.model.PropertyModel; +import org.apache.wicket.model.ResourceModel; +import org.apache.wicket.spring.injection.annot.SpringBean; + +/** + * Resource mapping panel. + */ +public class ResourceMappingPanel extends Panel { + + private static final long serialVersionUID = -7982691107029848579L; + + /** + * Mapping field style sheet. + */ + private static final String FIELD_STYLE = "ui-widget-content ui-corner-all short_fixedsize"; + + /** + * Mapping field style sheet. + */ + private static final String DEF_FIELD_STYLE = "ui-widget-content ui-corner-all"; + + /** + * Mapping field style sheet. + */ + private static final String SHORT_FIELD_STYLE = "ui-widget-content ui-corner-all veryshort_fixedsize"; + + /** + * Schema rest client. + */ + @SpringBean + private SchemaRestClient schemaRestClient; + + /** + * ConnInstance rest client. + */ + @SpringBean + private ConnectorRestClient connRestClient; + + /** + * Resource schema name. + */ + private final List<String> schemaNames; + + /** + * Add mapping button. + */ + private final AjaxButton addMappingBtn; + + /** + * All mappings. + */ + private final ListView<MappingItemTO> mappings; + + /** + * External resource to be updated. + */ + private final ResourceTO resourceTO; + + /** + * User / group. + */ + private final AttributableType attrType; + + /** + * Mapping container. + */ + private final WebMarkupContainer mappingContainer; + + /** + * AccountLink container. + */ + private final WebMarkupContainer accountLinkContainer; + + private final AjaxCheckBoxPanel accountLinkCheckbox; + + private MappingTO getMapping() { + MappingTO result = null; + + if (AttributableType.USER == this.attrType) { + if (this.resourceTO.getUmapping() == null) { + this.resourceTO.setUmapping(new MappingTO()); + } + result = this.resourceTO.getUmapping(); + } + if (AttributableType.GROUP == this.attrType) { + if (this.resourceTO.getGmapping() == null) { + this.resourceTO.setGmapping(new MappingTO()); + } + result = this.resourceTO.getGmapping(); + } + + return result; + } + + /** + * Attribute Mapping Panel. + * + * @param id panel id + * @param resourceTO external resource + * @param attrType USER / GROUP + */ + public ResourceMappingPanel(final String id, final ResourceTO resourceTO, final AttributableType attrType) { + super(id); + setOutputMarkupId(true); + + this.resourceTO = resourceTO; + this.attrType = attrType; + + this.mappingContainer = new WebMarkupContainer("mappingContainer"); + this.mappingContainer.setOutputMarkupId(true); + add(this.mappingContainer); + + this.accountLinkContainer = new WebMarkupContainer("accountLinkContainer"); + this.accountLinkContainer.setOutputMarkupId(true); + add(this.accountLinkContainer); + + if (this.resourceTO.getConnectorId() != null && this.resourceTO.getConnectorId() > 0) { + schemaNames = getSchemaNames(this.resourceTO.getConnectorId(), this.resourceTO.getConnConfProperties()); + + setEnabled(); + } else { + schemaNames = Collections.<String>emptyList(); + } + + final WebMarkupContainer jexlHelp = JexlHelpUtils.getJexlHelpWebContainer("jexlHelp"); + + AjaxLink<Void> questionMarkJexlHelp = JexlHelpUtils.getAjaxLink(jexlHelp, "questionMarkJexlHelp"); + mappingContainer.add(questionMarkJexlHelp); + questionMarkJexlHelp.add(jexlHelp); + + final Label passwordLabel = new Label("passwordLabel", new ResourceModel("password")); + mappingContainer.add(passwordLabel); + if (AttributableType.USER != ResourceMappingPanel.this.attrType) { + passwordLabel.setVisible(false); + } + + Collections.sort(getMapping().getItems(), new Comparator<MappingItemTO>() { + + @Override + public int compare(final MappingItemTO left, final MappingItemTO right) { + int compared; + if (left == null && right == null) { + compared = 0; + } else if (left == null) { + compared = 1; + } else if (right == null) { + compared = -1; + } else if (left.getPurpose() == MappingPurpose.BOTH && right.getPurpose() != MappingPurpose.BOTH) { + compared = -1; + } else if (left.getPurpose() != MappingPurpose.BOTH && right.getPurpose() == MappingPurpose.BOTH) { + compared = 1; + } else if (left.getPurpose() == MappingPurpose.PROPAGATION + && (right.getPurpose() == MappingPurpose.SYNCHRONIZATION || right.getPurpose() + == MappingPurpose.NONE)) { + compared = -1; + } else if (left.getPurpose() == MappingPurpose.SYNCHRONIZATION + && right.getPurpose() == MappingPurpose.PROPAGATION) { + compared = 1; + } else if (left.getPurpose() == MappingPurpose.SYNCHRONIZATION + && right.getPurpose() == MappingPurpose.NONE) { + compared = -1; + } else if (left.getPurpose() == MappingPurpose.NONE + && right.getPurpose() != MappingPurpose.NONE) { + compared = 1; + } else if (left.isAccountid()) { + compared = -1; + } else if (right.isAccountid()) { + compared = 1; + } else if (left.isPassword()) { + compared = -1; + } else if (right.isPassword()) { + compared = 1; + } else { + compared = left.getIntAttrName().compareTo(right.getIntAttrName()); + } + return compared; + } + }); + + mappings = new ListView<MappingItemTO>("mappings", getMapping().getItems()) { + + private static final long serialVersionUID = 4949588177564901031L; + + @Override + protected void populateItem(final ListItem<MappingItemTO> item) { + final MappingItemTO mapItem = item.getModelObject(); + if (mapItem.getPurpose() == null) { + mapItem.setPurpose(MappingPurpose.BOTH); + } + + AttributableType entity = null; + if (mapItem.getIntMappingType() != null) { + entity = mapItem.getIntMappingType().getAttributableType(); + } + + final List<IntMappingType> attrTypes = new ArrayList<IntMappingType>(getAttributeTypes(entity)); + + item.add(new AjaxDecoratedCheckbox("toRemove", new Model<Boolean>(Boolean.FALSE)) { + + private static final long serialVersionUID = 7170946748485726506L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + int index = -1; + for (int i = 0; i < getMapping().getItems().size() && index == -1; i++) { + if (mapItem.equals(getMapping().getItems().get(i))) { + index = i; + } + } + + if (index != -1) { + getMapping().getItems().remove(index); + item.getParent().removeAll(); + target.add(ResourceMappingPanel.this); + } + } + + @Override + protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) { + super.updateAjaxAttributes(attributes); + + final AjaxCallListener ajaxCallListener = new AjaxCallListener() { + + private static final long serialVersionUID = 7160235486520935153L; + + @Override + public CharSequence getPrecondition(final Component component) { + return "if (!confirm('" + getString("confirmDelete") + "')) return false;"; + } + }; + attributes.getAjaxCallListeners().add(ajaxCallListener); + } + }); + + final AjaxDropDownChoicePanel<String> intAttrNames = + new AjaxDropDownChoicePanel<String>("intAttrNames", getString("intAttrNames"), + new PropertyModel<String>(mapItem, "intAttrName"), false); + intAttrNames.setChoices(schemaNames); + intAttrNames.setRequired(true); + intAttrNames.setStyleSheet(FIELD_STYLE); + intAttrNames.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + } + }); + item.add(intAttrNames); + + final AjaxDropDownChoicePanel<IntMappingType> intMappingTypes = + new AjaxDropDownChoicePanel<IntMappingType>("intMappingTypes", + new ResourceModel("intMappingTypes", "intMappingTypes").getObject(), + new PropertyModel<IntMappingType>(mapItem, "intMappingType")); + intMappingTypes.setRequired(true); + intMappingTypes.setChoices(attrTypes); + intMappingTypes.setStyleSheet(FIELD_STYLE); + item.add(intMappingTypes); + + final AjaxDropDownChoicePanel<AttributableType> entitiesPanel = + new AjaxDropDownChoicePanel<AttributableType>("entities", + new ResourceModel("entities", "entities").getObject(), new Model<AttributableType>( + entity)); + entitiesPanel.setChoices(attrType == AttributableType.GROUP + ? Collections.<AttributableType>singletonList(AttributableType.GROUP) + : Arrays.asList(AttributableType.values())); + entitiesPanel.setStyleSheet(DEF_FIELD_STYLE); + entitiesPanel.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + attrTypes.clear(); + attrTypes.addAll(getAttributeTypes(entitiesPanel.getModelObject())); + intMappingTypes.setChoices(attrTypes); + + intAttrNames.setChoices(Collections.<String>emptyList()); + + target.add(intMappingTypes.getField()); + target.add(intAttrNames.getField()); + } + }); + item.add(entitiesPanel); + + final FieldPanel<String> extAttrNames = new AjaxTextFieldPanel("extAttrName", + new ResourceModel("extAttrNames", "extAttrNames").getObject(), + new PropertyModel<String>(mapItem, "extAttrName")); + ((AjaxTextFieldPanel) extAttrNames).setChoices(schemaNames); + + boolean required = false; + if (mapItem.isPassword()) { + ((AjaxTextFieldPanel) extAttrNames).setModelObject(null); + } else { + required = true; + } + extAttrNames.setRequired(required); + extAttrNames.setEnabled(required); + extAttrNames.setStyleSheet(FIELD_STYLE); + item.add(extAttrNames); + + final AjaxTextFieldPanel mandatory = new AjaxTextFieldPanel("mandatoryCondition", + new ResourceModel("mandatoryCondition", "mandatoryCondition").getObject(), + new PropertyModel<String>(mapItem, "mandatoryCondition")); + mandatory.setChoices(Arrays.asList(new String[] { "true", "false" })); + mandatory.setStyleSheet(SHORT_FIELD_STYLE); + item.add(mandatory); + + final AjaxCheckBoxPanel accountId = new AjaxCheckBoxPanel("accountId", + new ResourceModel("accountId", "accountId").getObject(), + new PropertyModel<Boolean>(mapItem, "accountid")); + accountId.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + if (accountId.getModelObject()) { + mapItem.setMandatoryCondition("true"); + mandatory.setEnabled(false); + } else { + mapItem.setMandatoryCondition("false"); + mandatory.setEnabled(true); + } + target.add(mandatory); + } + }); + item.add(accountId); + + final AjaxCheckBoxPanel password = new AjaxCheckBoxPanel("password", + new ResourceModel("password", "password").getObject(), + new PropertyModel<Boolean>(mapItem, "password")); + password.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + extAttrNames.setEnabled(!mapItem.isAccountid() && !password.getModelObject()); + extAttrNames.setModelObject(null); + extAttrNames.setRequired(!password.getModelObject()); + target.add(extAttrNames); + + setAccountId(intMappingTypes.getModelObject(), accountId, password); + target.add(accountId); + } + }); + item.add(password); + if (AttributableType.USER != ResourceMappingPanel.this.attrType) { + password.setVisible(false); + } + + final WebMarkupContainer purpose = new WebMarkupContainer("purpose"); + purpose.setOutputMarkupId(Boolean.TRUE); + + final MappingPurposePanel panel = new MappingPurposePanel("purposeActions", + new PropertyModel<MappingPurpose>(mapItem, "purpose"), purpose); + + purpose.add(panel); + + item.add(purpose); + + intMappingTypes.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + setAttrNames(intMappingTypes.getModelObject(), intAttrNames); + target.add(intAttrNames); + + setAccountId(intMappingTypes.getModelObject(), accountId, password); + target.add(accountId); + } + }); + + setAttrNames(mapItem.getIntMappingType(), intAttrNames); + setAccountId(mapItem.getIntMappingType(), accountId, password); + } + }; + + mappings.setReuseItems(true); + mappingContainer.add(mappings); + + addMappingBtn = new IndicatingAjaxButton("addMappingBtn", new ResourceModel("add")) { + + private static final long serialVersionUID = -4804368561204623354L; + + @Override + protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) { + getMapping().getItems().add(new MappingItemTO()); + target.add(ResourceMappingPanel.this); + } + }; + addMappingBtn.setDefaultFormProcessing(false); + addMappingBtn.setEnabled(this.resourceTO.getConnectorId() != null && this.resourceTO.getConnectorId() > 0); + mappingContainer.add(addMappingBtn); + + boolean accountLinkEnabled = false; + if (getMapping().getAccountLink() != null) { + accountLinkEnabled = true; + } + accountLinkCheckbox = new AjaxCheckBoxPanel("accountLinkCheckbox", + new ResourceModel("accountLinkCheckbox", "accountLinkCheckbox").getObject(), + new Model<Boolean>(Boolean.valueOf(accountLinkEnabled))); + accountLinkCheckbox.setEnabled(true); + + accountLinkContainer.add(accountLinkCheckbox); + + final AjaxTextFieldPanel accountLink = new AjaxTextFieldPanel("accountLink", + new ResourceModel("accountLink", "accountLink").getObject(), + new PropertyModel<String>(getMapping(), "accountLink")); + accountLink.setEnabled(accountLinkEnabled); + accountLinkContainer.add(accountLink); + + accountLinkCheckbox.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + if (accountLinkCheckbox.getModelObject()) { + accountLink.setEnabled(Boolean.TRUE); + accountLink.setModelObject(""); + } else { + accountLink.setEnabled(Boolean.FALSE); + accountLink.setModelObject(""); + } + + target.add(accountLink); + } + }); + } + + private List<String> getSchemaNames(final Long connectorId, final Set<ConnConfProperty> conf) { + final ConnInstanceTO connInstanceTO = new ConnInstanceTO(); + connInstanceTO.setKey(connectorId); + connInstanceTO.getConfiguration().addAll(conf); + + return connRestClient.getSchemaNames(connInstanceTO); + } + + private void setEnabled() { + final ConnInstanceTO connInstanceTO = new ConnInstanceTO(); + connInstanceTO.setKey(this.resourceTO.getConnectorId()); + connInstanceTO.getConfiguration().addAll(this.resourceTO.getConnConfProperties()); + + List<ConnIdObjectClassTO> objectClasses = connRestClient.getSupportedObjectClasses(connInstanceTO); + + boolean enabled = objectClasses.isEmpty() + || (AttributableType.USER == attrType && objectClasses.contains(ConnIdObjectClassTO.ACCOUNT)) + || (AttributableType.GROUP == attrType && objectClasses.contains(ConnIdObjectClassTO.GROUP)); + this.mappingContainer.setEnabled(enabled); + this.mappingContainer.setVisible(enabled); + this.accountLinkContainer.setEnabled(enabled); + this.accountLinkContainer.setVisible(enabled); + + if (!enabled) { + getMapping().getItems().clear(); + getMapping().setAccountLink(null); + if (this.accountLinkCheckbox != null) { + this.accountLinkCheckbox.setModelObject(null); + } + } + } + + @Override + public void onEvent(final IEvent<?> event) { + if (event.getPayload() instanceof ConnConfModEvent) { + final AjaxRequestTarget target = ((ConnConfModEvent) event.getPayload()).getTarget(); + + final List<ConnConfProperty> conf = ((ConnConfModEvent) event.getPayload()).getConfiguration(); + + mappings.removeAll(); + + addMappingBtn.setEnabled(resourceTO.getConnectorId() != null && resourceTO.getConnectorId() > 0); + + schemaNames.clear(); + schemaNames.addAll(getSchemaNames(resourceTO.getConnectorId(), new HashSet<ConnConfProperty>(conf))); + + setEnabled(); + + target.add(this); + } + } + + /** + * Set attribute names for a drop down choice list. + * + * @param type attribute type. + * @param toBeUpdated drop down choice to be updated. + */ + private void setAttrNames(final IntMappingType type, final AjaxDropDownChoicePanel<String> toBeUpdated) { + toBeUpdated.setRequired(true); + toBeUpdated.setEnabled(true); + + if (type == null || type.getAttributableType() == null) { + toBeUpdated.setChoices(Collections.<String>emptyList()); + } else { + switch (type) { + // user attribute names + case UserPlainSchema: + case GroupPlainSchema: + case MembershipPlainSchema: + toBeUpdated.setChoices(schemaRestClient.getPlainSchemaNames(type.getAttributableType())); + break; + + case UserDerivedSchema: + case GroupDerivedSchema: + case MembershipDerivedSchema: + toBeUpdated.setChoices(schemaRestClient.getDerSchemaNames(type.getAttributableType())); + break; + + case UserVirtualSchema: + case GroupVirtualSchema: + case MembershipVirtualSchema: + toBeUpdated.setChoices(schemaRestClient.getVirSchemaNames(type.getAttributableType())); + break; + + case UserId: + case Password: + case Username: + case GroupId: + case GroupName: + default: + toBeUpdated.setRequired(false); + toBeUpdated.setEnabled(false); + toBeUpdated.setChoices(Collections.<String>emptyList()); + } + } + } + + /** + * Enable/Disable accountId checkbox. + * + * @param type attribute type. + * @param accountId accountId checkbox. + * @param password password checkbox. + */ + private void setAccountId(final IntMappingType type, final AjaxCheckBoxPanel accountId, + final AjaxCheckBoxPanel password) { + + if (type != null && type.getAttributableType() != null) { + switch (type) { + case UserVirtualSchema: + case GroupVirtualSchema: + case MembershipVirtualSchema: + // Virtual accountId is not permitted + case Password: + // AccountId cannot be derived from password. + accountId.setReadOnly(true); + accountId.setModelObject(false); + break; + + default: + if (password.getModelObject()) { + accountId.setReadOnly(true); + accountId.setModelObject(false); + } else { + accountId.setReadOnly(false); + } + } + } + } + + /** + * Get all attribute types from a selected attribute type. + * + * @param entity entity. + * @return all attribute types. + */ + private List<IntMappingType> getAttributeTypes(final AttributableType entity) { + final List<IntMappingType> res = new ArrayList<IntMappingType>(); + + if (entity != null) { + res.addAll(IntMappingType.getAttributeTypes(AttributableType.valueOf(entity.name()))); + } + + return res; + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourceSecurityPanel.java ---------------------------------------------------------------------- diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourceSecurityPanel.java b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourceSecurityPanel.java new file mode 100644 index 0000000..40e031a --- /dev/null +++ b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourceSecurityPanel.java @@ -0,0 +1,189 @@ +/* + * 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.panels; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import org.apache.syncope.client.console.rest.PolicyRestClient; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel; +import org.apache.syncope.common.lib.to.AbstractPolicyTO; +import org.apache.syncope.common.lib.to.ResourceTO; +import org.apache.syncope.common.lib.types.PolicyType; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.form.ChoiceRenderer; +import org.apache.wicket.markup.html.form.DropDownChoice; +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.PropertyModel; +import org.apache.wicket.model.ResourceModel; +import org.apache.wicket.spring.injection.annot.SpringBean; + +public class ResourceSecurityPanel extends Panel { + + private static final long serialVersionUID = -7982691107029848579L; + + @SpringBean + private PolicyRestClient policyRestClient; + + private IModel<Map<Long, String>> passwordPolicies = null; + + private IModel<Map<Long, String>> accountPolicies = null; + + private IModel<Map<Long, String>> syncPolicies = null; + + public ResourceSecurityPanel(final String id, final ResourceTO resourceTO) { + + super(id); + + setOutputMarkupId(true); + + passwordPolicies = new LoadableDetachableModel<Map<Long, String>>() { + + private static final long serialVersionUID = 5275935387613157437L; + + @Override + protected Map<Long, String> load() { + Map<Long, String> res = new HashMap<>(); + for (AbstractPolicyTO policyTO : policyRestClient.getPolicies(PolicyType.PASSWORD, false)) { + res.put(policyTO.getKey(), policyTO.getDescription()); + } + return res; + } + }; + + accountPolicies = new LoadableDetachableModel<Map<Long, String>>() { + + private static final long serialVersionUID = -2012833443695917883L; + + @Override + protected Map<Long, String> load() { + Map<Long, String> res = new HashMap<>(); + for (AbstractPolicyTO policyTO : policyRestClient.getPolicies(PolicyType.ACCOUNT, false)) { + res.put(policyTO.getKey(), policyTO.getDescription()); + } + return res; + } + }; + + syncPolicies = new LoadableDetachableModel<Map<Long, String>>() { + + private static final long serialVersionUID = -2012833443695917883L; + + @Override + protected Map<Long, String> load() { + Map<Long, String> res = new HashMap<>(); + for (AbstractPolicyTO policyTO : policyRestClient.getPolicies(PolicyType.SYNC, false)) { + res.put(policyTO.getKey(), policyTO.getDescription()); + } + return res; + } + }; + + final WebMarkupContainer securityContainer = new WebMarkupContainer("security"); + + securityContainer.setOutputMarkupId(true); + add(securityContainer); + + // ------------------------------- + // Password policy specification + // ------------------------------- + final AjaxDropDownChoicePanel<Long> passwordPolicy = new AjaxDropDownChoicePanel<Long>("passwordPolicy", + new ResourceModel("passwordPolicy", "passwordPolicy").getObject(), new PropertyModel<Long>(resourceTO, + "passwordPolicy")); + + passwordPolicy.setChoiceRenderer(new PolicyRenderer(PolicyType.PASSWORD)); + + passwordPolicy.setChoices(new ArrayList<>(passwordPolicies.getObject().keySet())); + + ((DropDownChoice<?>) passwordPolicy.getField()).setNullValid(true); + + securityContainer.add(passwordPolicy); + // ------------------------------- + + // ------------------------------- + // Account policy specification + // ------------------------------- + final AjaxDropDownChoicePanel<Long> accountPolicy = new AjaxDropDownChoicePanel<Long>("accountPolicy", + new ResourceModel("accountPolicy", "accountPolicy").getObject(), new PropertyModel<Long>(resourceTO, + "accountPolicy")); + + accountPolicy.setChoiceRenderer(new PolicyRenderer(PolicyType.ACCOUNT)); + + accountPolicy.setChoices(new ArrayList<Long>(accountPolicies.getObject().keySet())); + + ((DropDownChoice<?>) accountPolicy.getField()).setNullValid(true); + + securityContainer.add(accountPolicy); + // ------------------------------- + + // ------------------------------- + // Sync policy specification + // ------------------------------- + final AjaxDropDownChoicePanel<Long> syncPolicy = new AjaxDropDownChoicePanel<Long>("syncPolicy", + new ResourceModel("syncPolicy", "syncPolicy").getObject(), new PropertyModel<Long>(resourceTO, + "syncPolicy")); + + syncPolicy.setChoiceRenderer(new PolicyRenderer(PolicyType.SYNC)); + + syncPolicy.setChoices(new ArrayList<Long>(syncPolicies.getObject().keySet())); + + ((DropDownChoice<?>) syncPolicy.getField()).setNullValid(true); + + securityContainer.add(syncPolicy); + // ------------------------------- + } + + private class PolicyRenderer extends ChoiceRenderer<Long> { + + private static final long serialVersionUID = 8060500161321947000L; + + private PolicyType type; + + public PolicyRenderer(final PolicyType type) { + super(); + this.type = type; + } + + @Override + public Object getDisplayValue(final Long object) { + switch (type) { + case GLOBAL_ACCOUNT: + case ACCOUNT: + return accountPolicies.getObject().get(object); + case GLOBAL_PASSWORD: + case PASSWORD: + return passwordPolicies.getObject().get(object); + case GLOBAL_SYNC: + case SYNC: + return syncPolicies.getObject().get(object); + default: + return ""; + } + } + + @Override + public String getIdValue(final Long object, final int index) { + return String.valueOf(object != null + ? object + : 0L); + } + }; +} http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourcesPanel.java ---------------------------------------------------------------------- diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourcesPanel.java b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourcesPanel.java new file mode 100644 index 0000000..028b3a0 --- /dev/null +++ b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/ResourcesPanel.java @@ -0,0 +1,177 @@ +/* + * 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.panels; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.apache.syncope.client.console.commons.Constants; +import org.apache.syncope.client.console.commons.GroupTreeBuilder; +import org.apache.syncope.client.console.commons.SelectChoiceRenderer; +import org.apache.syncope.client.console.commons.status.StatusUtils; +import org.apache.syncope.client.console.rest.ResourceRestClient; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel; +import org.apache.syncope.client.console.wicket.markup.html.form.NonI18nPalette; +import org.apache.syncope.common.lib.to.AbstractSubjectTO; +import org.apache.syncope.common.lib.to.MembershipTO; +import org.apache.syncope.common.lib.to.ResourceTO; +import org.apache.syncope.common.lib.to.GroupTO; +import org.apache.syncope.common.lib.to.UserTO; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; +import org.apache.wicket.extensions.markup.html.form.palette.Palette; +import org.apache.wicket.extensions.markup.html.form.palette.component.Recorder; +import org.apache.wicket.markup.html.form.IChoiceRenderer; +import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.PropertyModel; +import org.apache.wicket.model.util.ListModel; +import org.apache.wicket.spring.injection.annot.SpringBean; + +public class ResourcesPanel extends Panel { + + private static final long serialVersionUID = -8728071019777410008L; + + @SpringBean + private ResourceRestClient resourceRestClient; + + @SpringBean + private GroupTreeBuilder groupTreeBuilder; + + private final AbstractSubjectTO subjectTO; + + private final Set<String> previousResources; + + private final List<String> allResources; + + public static class Builder implements Serializable { + + private static final long serialVersionUID = 8644108944633025494L; + + private String id; + + private Object to; + + private StatusPanel statusPanel; + + public Builder(final String id) { + this.id = id; + } + + public Builder attributableTO(final Object to) { + this.to = to; + return this; + } + + public Builder statusPanel(final StatusPanel statusPanel) { + this.statusPanel = statusPanel; + return this; + } + + public ResourcesPanel build() { + return new ResourcesPanel(this); + } + } + + private ResourcesPanel(final Builder builder) { + super(builder.id); + subjectTO = (AbstractSubjectTO) builder.to; + previousResources = new HashSet<>(subjectTO.getResources()); + allResources = new ArrayList<>(); + for (ResourceTO resourceTO : resourceRestClient.getAll()) { + allResources.add(resourceTO.getKey()); + } + Collections.sort(allResources); + + AjaxPalettePanel<String> resourcesPalette = null; + + if (subjectTO instanceof UserTO) { + resourcesPalette = new AjaxRecordingPalettePanel<>("resourcesPalette", + new PropertyModel<List<String>>(subjectTO, "resources"), + new ListModel<>(allResources), builder.statusPanel); + } else if (subjectTO instanceof GroupTO) { + resourcesPalette = new AjaxPalettePanel<>("resourcesPalette", + new PropertyModel<List<String>>(subjectTO, "resources"), new ListModel<>(allResources)); + } + add(resourcesPalette); + } + + private class AjaxRecordingPalettePanel<T> extends AjaxPalettePanel<T> { + + private static final long serialVersionUID = -4215625881756021988L; + + private final StatusPanel statusPanel; + + public AjaxRecordingPalettePanel(final String id, final IModel<List<T>> model, final ListModel<T> choices, + final StatusPanel statusPanel) { + + super(id, model, choices, new SelectChoiceRenderer<T>(), false, false); + this.statusPanel = statusPanel; + } + + @Override + protected Palette<T> createPalette(final IModel<List<T>> model, final ListModel<T> choices, + final IChoiceRenderer<T> renderer, final boolean allowOrder, final boolean allowMoveAll) { + + return new NonI18nPalette<T>("paletteField", model, choices, renderer, 8, allowOrder, false) { + + private static final long serialVersionUID = -3415146226879212841L; + + @Override + protected Recorder<T> newRecorderComponent() { + Recorder<T> recorder = super.newRecorderComponent(); + recorder.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = 5538299138211283825L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + if (subjectTO instanceof UserTO) { + UserTO userTO = (UserTO) subjectTO; + + Set<String> resourcesToRemove = new HashSet<>(previousResources); + resourcesToRemove.removeAll(userTO.getResources()); + if (!resourcesToRemove.isEmpty()) { + Set<String> resourcesAssignedViaMembership = new HashSet<>(); + for (MembershipTO membTO : userTO.getMemberships()) { + GroupTO groupTO = groupTreeBuilder.findGroup(membTO.getGroupKey()); + if (groupTO != null) { + resourcesAssignedViaMembership.addAll(groupTO.getResources()); + } + } + resourcesToRemove.removeAll(resourcesAssignedViaMembership); + } + + previousResources.clear(); + previousResources.addAll(userTO.getResources()); + + StatusUtils.update( + userTO, statusPanel, target, userTO.getResources(), resourcesToRemove); + } + } + }); + return recorder; + } + }; + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/panels/SchedTasks.java ---------------------------------------------------------------------- diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/SchedTasks.java b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/SchedTasks.java new file mode 100644 index 0000000..205bfa5 --- /dev/null +++ b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/SchedTasks.java @@ -0,0 +1,286 @@ +/* + * 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.panels; + +import java.util.ArrayList; +import java.util.List; +import org.apache.syncope.client.console.commons.Constants; +import org.apache.syncope.client.console.pages.SchedTaskModalPage; +import org.apache.syncope.client.console.pages.Tasks; +import org.apache.syncope.client.console.pages.Tasks.TasksProvider; +import org.apache.syncope.client.console.wicket.ajax.markup.html.ClearIndicatingAjaxLink; +import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn; +import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn; +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.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.to.AbstractTaskTO; +import org.apache.syncope.common.lib.to.SchedTaskTO; +import org.apache.wicket.Component; +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.event.IEvent; +import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; +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.form.DropDownChoice; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.PropertyModel; +import org.apache.wicket.model.StringResourceModel; +import org.apache.wicket.request.http.WebResponse; + +public class SchedTasks extends AbstractTasks { + + private static final long serialVersionUID = 525486152284253354L; + + private int paginatorRows; + + private WebMarkupContainer container; + + private ModalWindow window; + + private AjaxDataTablePanel<AbstractTaskTO, String> table; + + public SchedTasks(final String id, final PageReference pageRef) { + super(id, pageRef); + + container = new WebMarkupContainer("container"); + container.setOutputMarkupId(true); + add(container); + + window = new ModalWindow("taskWin"); + window.setCssClassName(ModalWindow.CSS_CLASS_GRAY); + window.setInitialHeight(WIN_HEIGHT); + window.setInitialWidth(WIN_WIDTH); + window.setCookieName(VIEW_TASK_WIN_COOKIE_NAME); + add(window); + + ((Tasks) pageRef.getPage()).setWindowClosedCallback(window, container); + + paginatorRows = prefMan.getPaginatorRows(getWebRequest(), Constants.PREF_SCHED_TASKS_PAGINATOR_ROWS); + + table = Tasks.updateTaskTable( + getColumns(), + new TasksProvider<SchedTaskTO>(restClient, paginatorRows, getId(), SchedTaskTO.class), + container, + 0, + pageRef, + restClient); + + container.add(table); + + @SuppressWarnings("rawtypes") + Form paginatorForm = new Form("PaginatorForm"); + + @SuppressWarnings({ "unchecked", "rawtypes" }) + final DropDownChoice rowsChooser = new DropDownChoice("rowsChooser", new PropertyModel(this, "paginatorRows"), + prefMan.getPaginatorChoices()); + + rowsChooser.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + prefMan.set(getWebRequest(), (WebResponse) getResponse(), Constants.PREF_SCHED_TASKS_PAGINATOR_ROWS, + String.valueOf(paginatorRows)); + + table = Tasks.updateTaskTable( + getColumns(), + new TasksProvider<SchedTaskTO>(restClient, paginatorRows, getId(), SchedTaskTO.class), + container, + table == null ? 0 : (int) table.getCurrentPage(), + pageRef, + restClient); + + target.add(container); + } + }); + + paginatorForm.add(rowsChooser); + add(paginatorForm); + + AjaxLink createLink = new ClearIndicatingAjaxLink("createLink", pageRef) { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + protected void onClickInternal(final AjaxRequestTarget target) { + window.setPageCreator(new ModalWindow.PageCreator() { + + private static final long serialVersionUID = -7834632442532690940L; + + @Override + public Page createPage() { + return new SchedTaskModalPage(window, new SchedTaskTO(), pageRef); + } + }); + + window.show(target); + } + }; + + MetaDataRoleAuthorizationStrategy.authorize( + createLink, RENDER, xmlRolesReader.getEntitlement(TASKS, "create")); + + add(createLink); + } + + private List<IColumn<AbstractTaskTO, String>> getColumns() { + final List<IColumn<AbstractTaskTO, String>> columns = new ArrayList<IColumn<AbstractTaskTO, String>>(); + + columns.add(new PropertyColumn<AbstractTaskTO, String>( + new StringResourceModel("key", this, null), "key", "key")); + columns.add(new PropertyColumn<AbstractTaskTO, String>( + new StringResourceModel("name", this, null), "name", "name")); + columns.add(new PropertyColumn<AbstractTaskTO, String>( + new StringResourceModel("description", this, null), "description", "description")); + columns.add(new PropertyColumn<AbstractTaskTO, String>( + new StringResourceModel("class", this, null), "jobClassName", "jobClassName")); + columns.add(new DatePropertyColumn<AbstractTaskTO>( + new StringResourceModel("lastExec", this, null), "lastExec", "lastExec")); + columns.add(new DatePropertyColumn<AbstractTaskTO>( + new StringResourceModel("nextExec", this, null), "nextExec", "nextExec")); + columns.add(new PropertyColumn<AbstractTaskTO, String>( + new StringResourceModel("latestExecStatus", this, null), "latestExecStatus", "latestExecStatus")); + + columns.add(new ActionColumn<AbstractTaskTO, String>(new StringResourceModel("actions", this, null, "")) { + + private static final long serialVersionUID = 2054811145491901166L; + + @Override + public ActionLinksPanel getActions(final String componentId, final IModel<AbstractTaskTO> model) { + + final SchedTaskTO taskTO = (SchedTaskTO) model.getObject(); + + final ActionLinksPanel panel = new ActionLinksPanel(componentId, model, pageRef); + + panel.add(new ActionLink() { + + private static final long serialVersionUID = -3722207913631435501L; + + @Override + public void onClick(final AjaxRequestTarget target) { + window.setPageCreator(new ModalWindow.PageCreator() { + + private static final long serialVersionUID = -7834632442532690940L; + + @Override + public Page createPage() { + return new SchedTaskModalPage(window, taskTO, pageRef); + } + }); + + window.show(target); + } + }, ActionLink.ActionType.EDIT, TASKS); + + panel.add(new ActionLink() { + + private static final long serialVersionUID = -3722207913631435501L; + + @Override + public void onClick(final AjaxRequestTarget target) { + try { + restClient.startExecution(taskTO.getKey(), false); + getSession().info(getString(Constants.OPERATION_SUCCEEDED)); + } catch (SyncopeClientException scce) { + error(scce.getMessage()); + } + + ((NotificationPanel) getPage().get(Constants.FEEDBACK)).refresh(target); + target.add(container); + } + }, ActionLink.ActionType.EXECUTE, TASKS); + + panel.add(new ActionLink() { + + private static final long serialVersionUID = -3722207913631435501L; + + @Override + public void onClick(final AjaxRequestTarget target) { + try { + restClient.startExecution(taskTO.getKey(), true); + getSession().info(getString(Constants.OPERATION_SUCCEEDED)); + } catch (SyncopeClientException scce) { + error(scce.getMessage()); + } + + ((NotificationPanel) getPage().get(Constants.FEEDBACK)).refresh(target); + target.add(container); + } + }, ActionLink.ActionType.DRYRUN, TASKS); + + panel.add(new ActionLink() { + + private static final long serialVersionUID = -3722207913631435501L; + + @Override + public void onClick(final AjaxRequestTarget target) { + try { + restClient.delete(taskTO.getKey(), SchedTaskTO.class); + info(getString(Constants.OPERATION_SUCCEEDED)); + } catch (SyncopeClientException scce) { + error(scce.getMessage()); + } + target.add(container); + ((NotificationPanel) getPage().get(Constants.FEEDBACK)).refresh(target); + } + }, ActionLink.ActionType.DELETE, TASKS); + + return panel; + } + + @Override + public Component getHeader(final String componentId) { + @SuppressWarnings("rawtypes") + final ActionLinksPanel panel = new ActionLinksPanel(componentId, new Model(), pageRef); + + panel.add(new ActionLink() { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target) { + if (target != null) { + target.add(table); + } + } + }, ActionLink.ActionType.RELOAD, TASKS, "list"); + + return panel; + } + }); + return columns; + } + + @Override + public void onEvent(final IEvent<?> event) { + if (event.getPayload() instanceof AbstractSearchResultPanel.EventDataWrapper) { + ((AbstractSearchResultPanel.EventDataWrapper) event.getPayload()).getTarget().add(container); + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/39f8a069/client/old_console/src/main/java/org/apache/syncope/client/console/panels/SearchClause.java ---------------------------------------------------------------------- diff --git a/client/old_console/src/main/java/org/apache/syncope/client/console/panels/SearchClause.java b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/SearchClause.java new file mode 100644 index 0000000..488a2cf --- /dev/null +++ b/client/old_console/src/main/java/org/apache/syncope/client/console/panels/SearchClause.java @@ -0,0 +1,129 @@ +/* + * 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.panels; + +import java.io.Serializable; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ReflectionToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +public class SearchClause implements Serializable { + + private static final long serialVersionUID = 2010794463096110104L; + + public enum Operator { + + AND, + OR; + + } + + public enum Type { + + ATTRIBUTE, + MEMBERSHIP, + RESOURCE, + ENTITLEMENT; + + } + + public enum Comparator { + + IS_NULL, + IS_NOT_NULL, + EQUALS, + NOT_EQUALS, + GREATER_OR_EQUALS, + GREATER_THAN, + LESS_OR_EQUALS, + LESS_THAN; + + } + + private Operator operator; + + private Type type; + + private String property; + + private Comparator comparator; + + private String value; + + public SearchClause() { + setOperator(SearchClause.Operator.AND); + setComparator(SearchClause.Comparator.EQUALS); + } + + public Operator getOperator() { + return operator; + } + + public void setOperator(final Operator operator) { + this.operator = operator; + } + + public Type getType() { + return type; + } + + public void setType(final Type type) { + this.type = type; + } + + public String getProperty() { + return property; + } + + public void setProperty(final String property) { + this.property = property; + } + + public Comparator getComparator() { + return comparator; + } + + public void setComparator(final Comparator comparator) { + this.comparator = comparator; + } + + public String getValue() { + return value; + } + + public void setValue(final String value) { + this.value = value; + } + + @Override + public boolean equals(final Object obj) { + return EqualsBuilder.reflectionEquals(this, obj); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } + + @Override + public String toString() { + return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE); + } +}
