blob: adfbf00cd6cd84b0d0ca209507f930e6cc76e94d [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 java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.client.console.commons.RealmsUtils;
import org.apache.syncope.client.console.layout.AnyLayout;
import org.apache.syncope.client.console.layout.AnyLayoutUtils;
import org.apache.syncope.client.console.panels.search.AbstractSearchPanel;
import org.apache.syncope.client.console.panels.search.AnyObjectSearchPanel;
import org.apache.syncope.client.console.panels.search.GroupSearchPanel;
import org.apache.syncope.client.console.panels.search.SearchClause;
import org.apache.syncope.client.console.panels.search.SearchClausePanel;
import org.apache.syncope.client.console.panels.search.SearchUtils;
import org.apache.syncope.client.console.panels.search.UserSearchPanel;
import org.apache.syncope.client.console.rest.AnyTypeClassRestClient;
import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksTogglePanel;
import org.apache.syncope.client.lib.SyncopeClient;
import org.apache.syncope.client.ui.commons.Constants;
import org.apache.syncope.client.ui.commons.panels.LabelPanel;
import org.apache.syncope.client.ui.commons.panels.ModalPanel;
import org.apache.syncope.client.ui.commons.wicket.markup.html.bootstrap.tabs.Accordion;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.to.AnyObjectTO;
import org.apache.syncope.common.lib.to.AnyTypeTO;
import org.apache.syncope.common.lib.to.GroupTO;
import org.apache.syncope.common.lib.to.RealmTO;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.AnyEntitlement;
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.ajax.markup.html.AjaxLink;
import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
import org.apache.wicket.event.Broadcast;
import org.apache.wicket.event.IEvent;
import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
import org.apache.wicket.extensions.markup.html.tabs.ITab;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.model.util.ListModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AnyPanel extends Panel implements ModalPanel {
private static final long serialVersionUID = -1100228004207271270L;
protected static final Logger LOG = LoggerFactory.getLogger(AnyPanel.class);
protected static final String DIRECTORY_PANEL_ID = "searchResult";
@FunctionalInterface
public interface DirectoryPanelSupplier {
Panel supply(
String id,
AnyTypeTO anyTypeTO,
RealmTO realmTO,
AnyLayout anyLayout,
PageReference pageRef);
}
protected static final DirectoryPanelSupplier DEFAULT_DIRECTORYPANEL_SUPPLIER =
(id, anyTypeTO, realmTO, anyLayout, pageRef) -> {
Panel panel;
String fiql;
String realm;
String dynRealm;
if (StringUtils.startsWith(realmTO.getFullPath(), SyncopeConstants.ROOT_REALM)) {
realm = RealmsUtils.getFullPath(realmTO.getFullPath());
dynRealm = null;
} else {
realm = SyncopeConstants.ROOT_REALM;
dynRealm = realmTO.getKey();
}
switch (anyTypeTO.getKind()) {
case USER:
fiql = dynRealm == null
? SyncopeClient.getUserSearchConditionBuilder().
is(Constants.KEY_FIELD_NAME).notNullValue().query()
: SyncopeClient.getUserSearchConditionBuilder().
inDynRealms(dynRealm).query();
UserTO userTO = new UserTO();
userTO.setRealm(RealmsUtils.getFullPath(realmTO.getFullPath()));
panel = new UserDirectoryPanel.Builder(
AnyTypeClassRestClient.list(anyTypeTO.getClasses()),
anyTypeTO.getKey(),
pageRef).setRealm(realm).setDynRealm(dynRealm).setFiltered(true).
setFiql(fiql).setWizardInModal(true).addNewItemPanelBuilder(
AnyLayoutUtils.newLayoutInfo(
userTO, anyTypeTO.getClasses(), anyLayout.getUser(), pageRef)).
build(id);
MetaDataRoleAuthorizationStrategy.authorize(panel, WebPage.RENDER,
IdRepoEntitlement.USER_SEARCH);
break;
case GROUP:
fiql = dynRealm == null
? SyncopeClient.getGroupSearchConditionBuilder().
is(Constants.KEY_FIELD_NAME).notNullValue().query()
: SyncopeClient.getGroupSearchConditionBuilder().inDynRealms(dynRealm).query();
GroupTO groupTO = new GroupTO();
groupTO.setRealm(RealmsUtils.getFullPath(realmTO.getFullPath()));
panel = new GroupDirectoryPanel.Builder(
AnyTypeClassRestClient.list(anyTypeTO.getClasses()),
anyTypeTO.getKey(),
pageRef).setRealm(realm).setDynRealm(dynRealm).setFiltered(true).
setFiql(fiql).setWizardInModal(true).addNewItemPanelBuilder(
AnyLayoutUtils.newLayoutInfo(
groupTO, anyTypeTO.getClasses(), anyLayout.getGroup(), pageRef)).
build(id);
// list of group is available to all authenticated users
break;
case ANY_OBJECT:
fiql = dynRealm == null
? SyncopeClient.getAnyObjectSearchConditionBuilder(anyTypeTO.getKey()).
is(Constants.KEY_FIELD_NAME).notNullValue().query()
: SyncopeClient.getAnyObjectSearchConditionBuilder(anyTypeTO.getKey()).
inDynRealms(dynRealm).query();
AnyObjectTO anyObjectTO = new AnyObjectTO();
anyObjectTO.setRealm(RealmsUtils.getFullPath(realmTO.getFullPath()));
anyObjectTO.setType(anyTypeTO.getKey());
panel = new AnyObjectDirectoryPanel.Builder(
AnyTypeClassRestClient.list(anyTypeTO.getClasses()),
anyTypeTO.getKey(),
pageRef).setRealm(realm).setDynRealm(dynRealm).setFiltered(true).
setFiql(fiql).setWizardInModal(true).addNewItemPanelBuilder(
AnyLayoutUtils.newLayoutInfo(anyObjectTO, anyTypeTO.getClasses(),
anyLayout.getAnyObjects().get(anyTypeTO.getKey()), pageRef)).
build(id);
MetaDataRoleAuthorizationStrategy.authorize(
panel, WebPage.RENDER, AnyEntitlement.SEARCH.getFor(anyTypeTO.getKey()));
break;
default:
panel = new LabelPanel(id, null);
}
return panel;
};
protected final AnyTypeTO anyTypeTO;
protected final RealmTO realmTO;
protected final PageReference pageRef;
protected AbstractSearchPanel searchPanel;
protected final Panel directoryPanel;
public AnyPanel(
final String id,
final AnyTypeTO anyTypeTO,
final RealmTO realmTO,
final AnyLayout anyLayout,
final boolean enableSearch,
final PageReference pageRef) {
this(id, anyTypeTO, realmTO, anyLayout, enableSearch, DEFAULT_DIRECTORYPANEL_SUPPLIER, pageRef);
}
public AnyPanel(
final String id,
final AnyTypeTO anyTypeTO,
final RealmTO realmTO,
final AnyLayout anyLayout,
final boolean enableSearch,
final DirectoryPanelSupplier directoryPanelSupplier,
final PageReference pageRef) {
super(id);
this.anyTypeTO = anyTypeTO;
this.realmTO = realmTO;
this.pageRef = pageRef;
// ------------------------
// Accordion
// ------------------------
Model<Integer> model = Model.of(-1);
Accordion accordion = new Accordion("accordionPanel",
List.of(new AbstractTab(new ResourceModel("search.result")) {
protected static final long serialVersionUID = 1037272333056449377L;
@Override
public WebMarkupContainer getPanel(final String panelId) {
searchPanel = getSearchPanel(panelId);
return searchPanel;
}
}), model) {
protected static final long serialVersionUID = -3056452800492734900L;
@Override
protected Component newTitle(final String markupId, final ITab tab, final Accordion.State state) {
return new AjaxLink<Integer>(markupId) {
protected static final long serialVersionUID = 6250423506463465679L;
@Override
public void onClick(final AjaxRequestTarget target) {
model.setObject(model.getObject() == 0 ? -1 : 0);
}
}.setBody(tab.getTitle()).setEscapeModelStrings(false);
}
};
accordion.setOutputMarkupId(true);
add(accordion.setEnabled(enableSearch).setVisible(enableSearch));
directoryPanel = createDirectoryPanel(anyTypeTO, realmTO, anyLayout, directoryPanelSupplier);
add(directoryPanel);
// ------------------------
}
protected Panel createDirectoryPanel(
final AnyTypeTO anyTypeTO,
final RealmTO realmTO,
final AnyLayout anyLayout,
final DirectoryPanelSupplier directoryPanelSupplier) {
return directoryPanelSupplier.supply(DIRECTORY_PANEL_ID, anyTypeTO, realmTO, anyLayout, pageRef);
}
@Override
public void onEvent(final IEvent<?> event) {
if (event.getPayload() instanceof SearchClausePanel.SearchEvent) {
AjaxRequestTarget target = SearchClausePanel.SearchEvent.class.cast(event.getPayload()).getTarget();
send(AnyPanel.this.directoryPanel, Broadcast.BREADTH,
new ActionLinksTogglePanel.ActionLinkToggleCloseEventPayload(target));
String precond = realmTO.getFullPath().startsWith(SyncopeConstants.ROOT_REALM)
? StringUtils.EMPTY
: String.format("$dynRealms=~%s;", realmTO.getKey());
switch (anyTypeTO.getKind()) {
case USER:
UserDirectoryPanel.class.cast(AnyPanel.this.directoryPanel).search(
precond + SearchUtils.buildFIQL(
AnyPanel.this.searchPanel.getModel().getObject(),
SyncopeClient.getUserSearchConditionBuilder(),
AnyPanel.this.searchPanel.getAvailableSchemaTypes(),
SearchUtils.NO_CUSTOM_CONDITION),
target);
break;
case GROUP:
GroupDirectoryPanel.class.cast(AnyPanel.this.directoryPanel).search(
precond + SearchUtils.buildFIQL(
AnyPanel.this.searchPanel.getModel().getObject(),
SyncopeClient.getGroupSearchConditionBuilder(),
AnyPanel.this.searchPanel.getAvailableSchemaTypes(),
SearchUtils.NO_CUSTOM_CONDITION),
target);
break;
case ANY_OBJECT:
AnyObjectDirectoryPanel.class.cast(AnyPanel.this.directoryPanel).search(
precond + SearchUtils.buildFIQL(
AnyPanel.this.searchPanel.getModel().getObject(),
SyncopeClient.getAnyObjectSearchConditionBuilder(anyTypeTO.getKey()),
AnyPanel.this.searchPanel.getAvailableSchemaTypes(),
SearchUtils.NO_CUSTOM_CONDITION),
target);
break;
default:
}
} else {
super.onEvent(event);
}
}
protected AbstractSearchPanel getSearchPanel(final String id) {
List<SearchClause> clauses = new ArrayList<>();
SearchClause clause = new SearchClause();
clauses.add(clause);
AbstractSearchPanel panel;
switch (anyTypeTO.getKind()) {
case USER:
clause.setComparator(SearchClause.Comparator.EQUALS);
clause.setType(SearchClause.Type.ATTRIBUTE);
clause.setProperty(Constants.USERNAME_FIELD_NAME);
panel = new UserSearchPanel.Builder(
new ListModel<>(clauses), pageRef).required(true).enableSearch().build(id);
break;
case GROUP:
clause.setComparator(SearchClause.Comparator.EQUALS);
clause.setType(SearchClause.Type.ATTRIBUTE);
clause.setProperty(Constants.NAME_FIELD_NAME);
panel = new GroupSearchPanel.Builder(
new ListModel<>(clauses), pageRef).required(true).enableSearch().build(id);
break;
case ANY_OBJECT:
clause.setComparator(SearchClause.Comparator.EQUALS);
clause.setType(SearchClause.Type.ATTRIBUTE);
clause.setProperty(Constants.NAME_FIELD_NAME);
panel = new AnyObjectSearchPanel.Builder(anyTypeTO.getKey(),
new ListModel<>(clauses), pageRef).required(true).enableSearch().build(id);
break;
default:
panel = null;
}
return panel;
}
}