All Downloads are FREE. Search and download functionalities are using the official Maven repository.

pl.edu.icm.unity.saml.idp.console.EditTrustedFederationSubView Maven / Gradle / Ivy

There is a newer version: 4.0.4
Show newest version
/*
 * Copyright (c) 2019 Bixbit - Krzysztof Benedyczak. All rights reserved.
 * See LICENCE.txt file for licensing information.
 */

package pl.edu.icm.unity.saml.idp.console;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;

import com.vaadin.data.Binder;
import com.vaadin.data.ValidationResult;
import com.vaadin.data.converter.StringToIntegerConverter;
import com.vaadin.data.validator.IntegerRangeValidator;
import com.vaadin.shared.ui.Orientation;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.ProgressBar;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

import pl.edu.icm.unity.MessageSource;
import pl.edu.icm.unity.engine.api.files.FileStorageService;
import pl.edu.icm.unity.engine.api.files.URIAccessService;
import pl.edu.icm.unity.saml.idp.console.SimpleIDPMetaConverter.SAMLEntity;
import pl.edu.icm.unity.saml.metadata.srv.CachedMetadataLoader;
import pl.edu.icm.unity.webui.common.CollapsibleLayout;
import pl.edu.icm.unity.webui.common.ComponentWithToolbar;
import pl.edu.icm.unity.webui.common.FieldSizeConstans;
import pl.edu.icm.unity.webui.common.FormLayoutWithFixedCaptionWidth;
import pl.edu.icm.unity.webui.common.FormValidationException;
import pl.edu.icm.unity.webui.common.GridWithActionColumn;
import pl.edu.icm.unity.webui.common.NotificationPopup;
import pl.edu.icm.unity.webui.common.SearchField;
import pl.edu.icm.unity.webui.common.StandardButtonsHelper;
import pl.edu.icm.unity.webui.common.Toolbar;
import pl.edu.icm.unity.webui.common.grid.FilterableGridHelper;
import pl.edu.icm.unity.webui.common.validators.NoSpaceValidator;
import pl.edu.icm.unity.webui.common.webElements.SubViewSwitcher;
import pl.edu.icm.unity.webui.common.webElements.UnitySubView;
import xmlbeans.org.oasis.saml2.metadata.EntitiesDescriptorDocument;

/**
 * View for edit SAML trusted federation
 * 
 * @author P.Piernik
 *
 */
class EditTrustedFederationSubView extends CustomComponent implements UnitySubView
{
	private MessageSource msg;
	private Binder binder;
	private boolean editMode = false;
	private Set validators;
	private Set certificates;
	private Set usedNames;
	private URIAccessService uriAccessService;
	private FileStorageService fileStorageService;
	private TextField url;
	private ComboBox httpsTruststore;

	EditTrustedFederationSubView(MessageSource msg, URIAccessService uriAccessService,
			FileStorageService fileStorageService, SAMLServiceTrustedFederationConfiguration toEdit,
			SubViewSwitcher subViewSwitcher, Set usedNames, Set validators,
			Set certificates, Consumer onConfirm,
			Runnable onCancel)
	{
		this.msg = msg;
		this.uriAccessService = uriAccessService;
		this.fileStorageService = fileStorageService;
		this.validators = validators;
		this.certificates = certificates;
		this.usedNames = usedNames;

		editMode = toEdit != null;
		binder = new Binder<>(SAMLServiceTrustedFederationConfiguration.class);
		FormLayout header = buildHeaderSection();
		binder.setBean(editMode ? toEdit.clone() : new SAMLServiceTrustedFederationConfiguration());
		CollapsibleLayout fetchMeta = buildFederationFetchSection();
		VerticalLayout mainView = new VerticalLayout();
		mainView.setMargin(false);
		mainView.addComponent(header);
		mainView.addComponent(fetchMeta);

		Runnable onConfirmR = () -> {
			try
			{
				onConfirm.accept(getTrustedFederation());
			} catch (FormValidationException e)
			{
				NotificationPopup.showError(msg,
						msg.getMessage("EditTrustedFederationSubView.invalidConfiguration"), e);
			}
		};
		mainView.addComponent(editMode
				? StandardButtonsHelper.buildConfirmEditButtonsBar(msg, onConfirmR, onCancel)
				: StandardButtonsHelper.buildConfirmNewButtonsBar(msg, onConfirmR, onCancel));

		setCompositionRoot(mainView);
	}

	private FormLayout buildHeaderSection()
	{
		FormLayoutWithFixedCaptionWidth header = new FormLayoutWithFixedCaptionWidth();
		header.setMargin(true);

		TextField name = new TextField(msg.getMessage("EditTrustedFederationSubView.name"));
		binder.forField(name).asRequired(msg.getMessage("fieldRequired"))
				.withValidator(new NoSpaceValidator(msg)).withValidator((s, c) -> {
					if (usedNames.contains(s))
					{
						return ValidationResult.error(msg
								.getMessage("EditTrustedFederationSubView.nameExists"));
					} else
					{
						return ValidationResult.ok();
					}

				}).bind("name");
		header.addComponent(name);
		name.focus();

		url = new TextField(msg.getMessage("EditTrustedFederationSubView.url"));
		url.setWidth(FieldSizeConstans.LINK_FIELD_WIDTH, FieldSizeConstans.LINK_FIELD_WIDTH_UNIT);
		binder.forField(url).asRequired(msg.getMessage("fieldRequired")).bind("url");
		header.addComponent(url);

		httpsTruststore = new ComboBox<>(msg.getMessage("EditTrustedFederationSubView.httpsTruststore"));
		httpsTruststore.setItems(validators);
		binder.forField(httpsTruststore).bind("httpsTruststore");
		header.addComponent(httpsTruststore);

		CheckBox ignoreSignatureVerification = new CheckBox(
				msg.getMessage("EditTrustedFederationSubView.ignoreSignatureVerification"));
		binder.forField(ignoreSignatureVerification).bind("ignoreSignatureVerification");
		header.addComponent(ignoreSignatureVerification);

		ComboBox signatureVerificationCertificate = new ComboBox<>(
				msg.getMessage("EditTrustedFederationSubView.signatureVerificationCertificate"));
		signatureVerificationCertificate.setItems(certificates);
		header.addComponent(signatureVerificationCertificate);

		TextField refreshInterval = new TextField();
		refreshInterval.setCaption(msg.getMessage("EditTrustedFederationSubView.refreshInterval"));
		binder.forField(refreshInterval).asRequired(msg.getMessage("fieldRequired"))
				.withConverter(new StringToIntegerConverter(msg.getMessage("notAPositiveNumber")))
				.withValidator(new IntegerRangeValidator(msg.getMessage("notAPositiveNumber"), 0, null))
				.bind("refreshInterval");
		header.addComponent(refreshInterval);

		return header;
	}

	private CollapsibleLayout buildFederationFetchSection()
	{
		VerticalLayout federationListLayout = new VerticalLayout();
		federationListLayout.setMargin(false);
		ProgressBar spinner = new ProgressBar();
		spinner.setIndeterminate(true);
		spinner.setVisible(false);
		federationListLayout.addComponent(spinner);
		GridWithActionColumn samlEntities = new GridWithActionColumn<>(msg,
				Collections.emptyList());
		samlEntities.setActionColumnHidden(true);
		samlEntities.setHeightByRows(false);
		samlEntities.setHeightByRows(14);
		samlEntities.addColumn(v -> v.name, msg.getMessage("EditTrustedFederationSubView.name"), 40);
		samlEntities.addColumn(v -> v.id, msg.getMessage("EditTrustedFederationSubView.entityIdentifier"), 40);

		SearchField search = FilterableGridHelper.generateSearchField(samlEntities, msg);
		Toolbar toolbar = new Toolbar<>(Orientation.HORIZONTAL);
		toolbar.setWidth(100, Unit.PERCENTAGE);
		toolbar.addSearch(search, Alignment.MIDDLE_RIGHT);
		ComponentWithToolbar samlEntitiesListWithToolbar = new ComponentWithToolbar(samlEntities, toolbar,
				Alignment.BOTTOM_LEFT);
		samlEntitiesListWithToolbar.setSpacing(false);
		samlEntitiesListWithToolbar.setSizeFull();
		samlEntitiesListWithToolbar.setVisible(false);
		Button fetch = new Button(msg.getMessage("EditTrustedFederationSubView.fetch"));
		UI ui = UI.getCurrent();

		CachedMetadataLoader metaDownloader = new CachedMetadataLoader(uriAccessService,
			fileStorageService);
		SimpleIDPMetaConverter convert = new SimpleIDPMetaConverter(msg);

		try
		{
			Optional cached = metaDownloader.getCached(url.getValue());
			if(cached.isPresent())
			{
				List entries = convert
					.getEntries(cached.get().getEntitiesDescriptor());
				samlEntities.setItems(entries);
				samlEntitiesListWithToolbar.setVisible(true);
			}
		}
		catch (Exception e)
		{
			ui.access(() -> {
				NotificationPopup.showError(msg, "", e);
			});
		}

		fetch.addClickListener(e -> {
			ui.setPollInterval(500);
			spinner.setVisible(true);
			CompletableFuture.runAsync(() -> {

				try
				{
					EntitiesDescriptorDocument entDoc = metaDownloader.getCached(url.getValue())
							.orElse(null);
					if (entDoc == null)
					{
						entDoc = metaDownloader.getFresh(url.getValue(),
								httpsTruststore.getValue());
					}
					List entries = convert
							.getEntries(entDoc.getEntitiesDescriptor());
					samlEntities.setItems(entries);
					samlEntitiesListWithToolbar.setVisible(true);

				} catch (Exception e1)
				{
					ui.access(() -> {
						NotificationPopup.showError(msg, "", e1);
						ui.setPollInterval(-1);
						spinner.setVisible(false);
					});
					samlEntities.setItems(Collections.emptyList());
					samlEntitiesListWithToolbar.setVisible(false);
				}

				ui.access(() -> {
					ui.setPollInterval(-1);
					spinner.setVisible(false);
				});
			});

		});

		url.addValueChangeListener(e -> {
			if (e.getValue() == null || e.getValue().isEmpty())
			{
				fetch.setEnabled(false);
			} else
			{
				fetch.setEnabled(true);
			}
		});

		HorizontalLayout wrapper = new HorizontalLayout();
		wrapper.setMargin(false);
		wrapper.addComponents(fetch, spinner);

		federationListLayout.addComponent(wrapper);
		federationListLayout.addComponent(samlEntitiesListWithToolbar);
		return new CollapsibleLayout(msg.getMessage("EditTrustedFederationSubView.serviceProviders"),
				federationListLayout);
	}

	@Override
	public List getBredcrumbs()
	{
		if (editMode)
			return Arrays.asList(msg.getMessage("EditTrustedFederationSubView.trustedFederation"),
					binder.getBean().getName());
		else
			return Arrays.asList(msg.getMessage("EditTrustedFederationSubView.newTrustedFederation"));

	}

	private SAMLServiceTrustedFederationConfiguration getTrustedFederation() throws FormValidationException
	{
		if (binder.validate().hasErrors())
			throw new FormValidationException();

		return binder.getBean();
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy