/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.security.web; import java.awt.Toolkit; import java.awt.datatransfer.StringSelection; import java.io.ByteArrayOutputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.extensions.markup.html.tabs.AbstractTab; import org.apache.wicket.extensions.markup.html.tabs.ITab; import org.apache.wicket.extensions.markup.html.tabs.TabbedPanel; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.SubmitLink; import org.apache.wicket.markup.html.form.TextArea; import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.CompoundPropertyModel; 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.geoserver.security.config.SecurityNamedServiceConfig; import org.geoserver.web.GeoServerApplication; /** * Edit page for specific class of named security service. * <p> * Most of the work is delegated to {@link SecurityNamedServicePanelInfo} and * {@link SecurityNamedServicePanel}. * </p> * * @author Justin Deoliveira, OpenGeo * */ public class SecurityNamedServiceEditPage<T extends SecurityNamedServiceConfig> extends SecurityNamedServicePage<T> { SecurityNamedServicePanelInfo panelInfo; public SecurityNamedServiceEditPage(IModel<T> config) { //create the specific panel panelInfo = lookupPanelInfo(config); panel = createPanel("dummy", panelInfo, config); //set page title and description from the panel title and description add(new Label("name", config.getObject().getName())); add(new Label("title", createTitleModel(panelInfo))); add(new Label("description", createDescriptionModel(panelInfo))); if (SecurityNamedServiceTabbedPanel.class.isAssignableFrom(panelInfo.getComponentClass())) { //this panel supports tabs, layout in tabbed mode add(new TabbedLayoutPanel("panel", config)); } else { //else layout in basic mode add(new BasicLayoutPanel("panel", config)); } } class ContentPanel extends Panel { public ContentPanel(String id, IModel<T> config) { super(id, new Model()); Form form = new Form("form", new CompoundPropertyModel<T>(config)); add(form); form.add(panel = createPanel("panel", panelInfo, config)); form.add(new SubmitLink("save", form) { @Override public void onSubmit() { handleSubmit(getForm()); } }.setVisible(getSecurityManager().checkAuthenticationForAdminRole())); form.add(new Link("cancel") { @Override public void onClick() { doReturn(); } }); } } /* * throws the service panel into a basic form panel */ class BasicLayoutPanel extends Panel { public BasicLayoutPanel(String id, IModel<T> config) { super(id, new Model()); add(new ContentPanel("panel", config)); } } /* * throws the service panel onto the first tab, and then delegates it to create additional * tabs. */ class TabbedLayoutPanel extends Panel { public TabbedLayoutPanel(String id, final IModel<T> config) { super(id, new Model()); List<ITab> tabs = new ArrayList<ITab>(); //add the primary panel to the first tab tabs.add(new AbstractTab(new StringResourceModel("settings", (IModel<?>)null)) { @Override public Panel getPanel(String panelId) { return new ContentPanel(panelId, config); } }); //add tabs contributed by the server tabs.addAll(((SecurityNamedServiceTabbedPanel)panel).createTabs(config)); //add the error tab that displays any exceptions currently associated with the service try { panel.doLoad(config.getObject()); } catch(final Exception e) { //add the error tab tabs.add(new AbstractTab(new StringResourceModel("error", (IModel<?>)null)) { @Override public Panel getPanel(String panelId) { return new ErrorPanel(panelId, e); } }); } add(new TabbedPanel("panel", tabs)); } } class ErrorPanel extends Panel { public ErrorPanel(String id, final Exception error) { super(id, new Model()); add(new Label("message", new PropertyModel(error, "message"))); add(new TextArea("stackTrace", new Model(handleStackTrace(error)))); add(new AjaxLink("copy") { @Override public void onClick(AjaxRequestTarget target) { copyToClipBoard(handleStackTrace(error)); } }); } public String getLabelKey() { return "error"; }; String handleStackTrace(Exception error) { ByteArrayOutputStream out = new ByteArrayOutputStream(); PrintWriter writer = new PrintWriter(out); error.printStackTrace(writer); writer.flush(); return new String(out.toByteArray()); } } void copyToClipBoard(String text) { StringSelection selection = new StringSelection(text); Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, selection); } SecurityNamedServicePanelInfo lookupPanelInfo(IModel<T> model) { T config = model.getObject(); Class serviceClass = null; try { serviceClass = Class.forName(config.getClassName()); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } List<SecurityNamedServicePanelInfo> panelInfos = new ArrayList(); for (SecurityNamedServicePanelInfo pageInfo : GeoServerApplication.get().getBeansOfType(SecurityNamedServicePanelInfo.class)) { if (pageInfo.getServiceClass().isAssignableFrom(serviceClass)) { panelInfos.add(pageInfo); } } if (panelInfos.isEmpty()) { throw new RuntimeException("Unable to find panel info for service config: " + config + ", service class: " + serviceClass); } if (panelInfos.size() > 1) { //filter by strict equals List<SecurityNamedServicePanelInfo> l = new ArrayList(panelInfos); for (Iterator<SecurityNamedServicePanelInfo> it = l.iterator(); it.hasNext();) { final SecurityNamedServicePanelInfo targetPanelInfo = it.next(); if (!targetPanelInfo.getServiceClass().equals(serviceClass)) { it.remove(); } else if (!targetPanelInfo.getServiceConfigClass().equals(config.getClass())) { it.remove(); } } if (l.size() == 1) { //filter down to one match return l.get(0); } throw new RuntimeException("Found multiple panel infos for service config: " + config + ", service class: " + serviceClass); } //found just one return panelInfos.get(0); } }