blob: 625d2bc42378d472613fe0710e261578c630cf00 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.syncope.client.console.panels;
import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
import de.agilecoders.wicket.core.markup.html.bootstrap.tabs.AjaxBootstrapTabbedPanel;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.syncope.client.console.SyncopeWebApplication;
import org.apache.syncope.client.ui.commons.ConnIdSpecialName;
import org.apache.syncope.client.ui.commons.Constants;
import org.apache.syncope.client.console.commons.ITabComponent;
import org.apache.syncope.client.ui.commons.status.StatusUtils;
import org.apache.syncope.client.console.layout.AnyLayout;
import org.apache.syncope.client.console.layout.AnyLayoutUtils;
import org.apache.syncope.client.console.rest.AnyTypeRestClient;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
import org.apache.syncope.client.console.wizards.WizardMgtPanel;
import org.apache.syncope.client.console.wizards.any.ConnObjectPanel;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.AnyTypeTO;
import org.apache.syncope.common.lib.to.ConnObjectTO;
import org.apache.syncope.common.lib.to.EntityTO;
import org.apache.syncope.common.lib.to.PropagationStatus;
import org.apache.syncope.common.lib.to.ProvisioningResult;
import org.apache.syncope.common.lib.to.RealmTO;
import org.apache.syncope.common.lib.types.ExecStatus;
import org.apache.syncope.common.lib.types.IdRepoEntitlement;
import org.apache.wicket.Component;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.markup.html.tabs.ITab;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class Realm extends WizardMgtPanel<RealmTO> {
private static final long serialVersionUID = -1100228004207271270L;
protected static final Logger LOG = LoggerFactory.getLogger(Realm.class);
private final RealmTO realmTO;
private final List<AnyTypeTO> anyTypes;
protected final RealmWizardBuilder wizardBuilder;
public Realm(final String id, final RealmTO realmTO, final PageReference pageRef, final int selectedIndex) {
super(id, true);
this.realmTO = realmTO;
this.anyTypes = AnyTypeRestClient.listAnyTypes();
setPageRef(pageRef);
AjaxBootstrapTabbedPanel<ITab> tabbedPanel =
new AjaxBootstrapTabbedPanel<>("tabbedPanel", buildTabList(pageRef));
tabbedPanel.setSelectedTab(selectedIndex);
addInnerObject(tabbedPanel);
this.wizardBuilder = new RealmWizardBuilder(pageRef);
addNewItemPanelBuilder(this.wizardBuilder, false);
setShowResultPage(true);
modal.size(Modal.Size.Large);
setWindowClosedReloadCallback(modal);
}
public RealmTO getRealmTO() {
return realmTO;
}
private List<ITab> buildTabList(final PageReference pageRef) {
List<ITab> tabs = new ArrayList<>();
tabs.add(new ITabComponent(new Model<>("DETAILS"),
IdRepoEntitlement.REALM_CREATE, IdRepoEntitlement.REALM_UPDATE, IdRepoEntitlement.REALM_DELETE) {
private static final long serialVersionUID = -5861786415855103549L;
@Override
public Panel getPanel(final String panelId) {
final ActionsPanel<RealmTO> actionPanel = new ActionsPanel<>("actions", null);
if (StringUtils.startsWith(realmTO.getFullPath(), SyncopeConstants.ROOT_REALM)) {
actionPanel.add(new ActionLink<>(realmTO) {
private static final long serialVersionUID = 2802988981431379827L;
@Override
public void onClick(final AjaxRequestTarget target, final RealmTO ignore) {
onClickCreate(target);
}
}, ActionLink.ActionType.CREATE, IdRepoEntitlement.REALM_CREATE).hideLabel();
actionPanel.add(new ActionLink<>(realmTO) {
private static final long serialVersionUID = 2802988981431379828L;
@Override
public void onClick(final AjaxRequestTarget target, final RealmTO ignore) {
onClickEdit(target, realmTO);
}
}, ActionLink.ActionType.EDIT, IdRepoEntitlement.REALM_UPDATE).hideLabel();
actionPanel.add(new ActionLink<>(realmTO) {
private static final long serialVersionUID = 2802988981431379827L;
@Override
public void onClick(final AjaxRequestTarget target, final RealmTO ignore) {
onClickTemplate(target);
}
}, ActionLink.ActionType.TEMPLATE, IdRepoEntitlement.REALM_UPDATE).hideLabel();
actionPanel.add(new ActionLink<>(realmTO) {
private static final long serialVersionUID = 2802988981431379829L;
@Override
public void onClick(final AjaxRequestTarget target, final RealmTO ignore) {
onClickDelete(target, realmTO);
}
}, ActionLink.ActionType.DELETE, IdRepoEntitlement.REALM_DELETE, true).hideLabel();
}
RealmDetails panel = new RealmDetails(panelId, realmTO, actionPanel, false);
panel.setContentEnabled(false);
actionPanel.setEnabled(true);
return panel;
}
@Override
public boolean isVisible() {
return SyncopeWebApplication.get().getSecuritySettings().getAuthorizationStrategy().
isActionAuthorized(this, RENDER);
}
});
AnyLayout anyLayout = AnyLayoutUtils.fetch(
anyTypes.stream().map(EntityTO::getKey).collect(Collectors.toList()));
for (AnyTypeTO anyType : anyTypes) {
tabs.add(new ITabComponent(new Model<>(anyType.getKey()), String.format("%s_SEARCH", anyType.getKey())) {
private static final long serialVersionUID = 1169585538404171118L;
@Override
public WebMarkupContainer getPanel(final String panelId) {
return AnyLayoutUtils.newAnyPanel(
anyLayout.getAnyPanelClass(), panelId, anyType, realmTO, anyLayout, true, pageRef);
}
@Override
public boolean isVisible() {
return SyncopeWebApplication.get().getSecuritySettings().getAuthorizationStrategy().
isActionAuthorized(this, RENDER);
}
});
}
return tabs;
}
@Override
@SuppressWarnings("unchecked")
protected Panel customResultBody(final String panelId, final RealmTO item, final Serializable result) {
if (!(result instanceof ProvisioningResult)) {
throw new IllegalStateException("Unsupported result type");
}
final MultilevelPanel mlp = new MultilevelPanel(panelId);
add(mlp);
final PropagationStatus syncope = new PropagationStatus();
syncope.setStatus(ExecStatus.SUCCESS);
syncope.setResource(Constants.SYNCOPE);
List<PropagationStatus> propagations = new ArrayList<>();
propagations.add(syncope);
propagations.addAll(((ProvisioningResult) result).getPropagationStatuses());
ListViewPanel.Builder<PropagationStatus> builder = new ListViewPanel.Builder<>(
PropagationStatus.class, pageRef) {
private static final long serialVersionUID = -6809736686861678498L;
@Override
protected Component getValueComponent(final String key, final PropagationStatus bean) {
if ("afterObj".equalsIgnoreCase(key)) {
ConnObjectTO afterObj = bean.getAfterObj();
String remoteId = afterObj == null
|| afterObj.getAttrs().isEmpty()
|| afterObj.getAttr(ConnIdSpecialName.NAME).isEmpty()
|| afterObj.getAttr(ConnIdSpecialName.NAME).get().getValues() == null
|| afterObj.getAttr(ConnIdSpecialName.NAME).get().getValues().isEmpty()
? StringUtils.EMPTY
: afterObj.getAttr(ConnIdSpecialName.NAME).get().getValues().get(0);
return new Label("field", remoteId);
} else if ("status".equalsIgnoreCase(key)) {
return StatusUtils.getStatusImagePanel("field", bean.getStatus());
} else {
return super.getValueComponent(key, bean);
}
}
};
builder.setItems(propagations);
builder.includes("resource", "afterObj", "status");
builder.withChecks(ListViewPanel.CheckAvailability.NONE);
builder.setReuseItem(false);
ActionLink<PropagationStatus> connObjectLink = new ActionLink<>() {
private static final long serialVersionUID = -3722207913631435501L;
@Override
protected boolean statusCondition(final PropagationStatus bean) {
return !Constants.SYNCOPE.equals(bean.getResource())
&& (ExecStatus.CREATED == bean.getStatus()
|| ExecStatus.SUCCESS == bean.getStatus());
}
@Override
public void onClick(final AjaxRequestTarget target, final PropagationStatus status) {
mlp.next(status.getResource(), new RemoteRealmPanel(status), target);
}
};
SyncopeWebApplication.get().getStatusProvider().addConnObjectLink(builder, connObjectLink);
builder.addAction(new ActionLink<>() {
private static final long serialVersionUID = -3722207913631435501L;
@Override
protected boolean statusCondition(final PropagationStatus status) {
return StringUtils.isNotBlank(status.getFailureReason());
}
@Override
public void onClick(final AjaxRequestTarget target, final PropagationStatus status) {
mlp.next(status.getResource(), new PropagationErrorPanel(status.getFailureReason()), target);
}
}, ActionLink.ActionType.PROPAGATION_TASKS, StringUtils.EMPTY);
mlp.setFirstLevel(builder.build(MultilevelPanel.FIRST_LEVEL_ID));
return mlp;
}
protected abstract void onClickTemplate(AjaxRequestTarget target);
protected abstract void onClickCreate(AjaxRequestTarget target);
protected abstract void onClickEdit(AjaxRequestTarget target, RealmTO realmTO);
protected abstract void onClickDelete(AjaxRequestTarget target, RealmTO realmTO);
static class RemoteRealmPanel extends RemoteObjectPanel {
private static final long serialVersionUID = 4303365227411467563L;
private final PropagationStatus bean;
RemoteRealmPanel(final PropagationStatus bean) {
this.bean = bean;
add(new ConnObjectPanel(
REMOTE_OBJECT_PANEL_ID,
Pair.<IModel<?>, IModel<?>>of(new ResourceModel("before"), new ResourceModel("after")),
getConnObjectTOs(),
false));
}
@Override
protected final Pair<ConnObjectTO, ConnObjectTO> getConnObjectTOs() {
return Pair.of(bean.getBeforeObj(), bean.getAfterObj());
}
}
}