/* (c) 2014 - 2016 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.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.util.logging.Level; import java.util.logging.Logger; import javax.naming.Context; import javax.naming.InitialContext; import javax.sql.DataSource; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox; import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.FormComponent; import org.apache.wicket.markup.html.form.FormComponentPanel; import org.apache.wicket.markup.html.form.PasswordTextField; import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.StringResourceModel; import org.geoserver.security.jdbc.config.JDBCSecurityServiceConfig; import org.geotools.util.logging.Logging; /** * Reusable form component for jdbc connect configurations * * @author Chrisitian Mueller * @author Justin Deoliveira, OpenGeo * */ public class JDBCConnectionPanel<T extends JDBCSecurityServiceConfig> extends FormComponentPanel<T> { private static final long serialVersionUID = 1L; static Logger LOGGER = Logging.getLogger("org.geoserver.security"); FeedbackPanel feedbackPanel; public JDBCConnectionPanel(String id, IModel<T> model) { super(id, new Model()); add(new AjaxCheckBox("jndi") { @Override protected void onUpdate(AjaxRequestTarget target) { WebMarkupContainer c = (WebMarkupContainer) JDBCConnectionPanel.this.get("cxPanelContainer"); //reset any values that were set ((ConnectionPanel)c.get("cxPanel")).resetModel(); //replace old panel c.addOrReplace(createCxPanel("cxPanel", getModelObject())); target.add(c); } }); boolean useJNDI = model.getObject().isJndi(); add(new WebMarkupContainer("cxPanelContainer") .add(createCxPanel("cxPanel", useJNDI)).setOutputMarkupId(true)); add(new AjaxSubmitLink("cxTest") { @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { try { ((ConnectionPanel)JDBCConnectionPanel.this.get("cxPanelContainer:cxPanel")).test(); info(new StringResourceModel("connectionSuccessful",JDBCConnectionPanel.this, null).getObject()); } catch(Exception e) { error(e); LOGGER.log(Level.WARNING, "Connection error", e); } finally { target.add(feedbackPanel); } } }.setDefaultFormProcessing(false)); add(feedbackPanel = new FeedbackPanel("feedback")); feedbackPanel.setOutputMarkupId(true); } ConnectionPanel createCxPanel(String id, boolean useJNDI) { return useJNDI ? new JNDIConnectionPanel(id) : new BasicConnectionPanel(id); } abstract class ConnectionPanel extends FormComponentPanel { public ConnectionPanel(String id) { super(id, new Model()); } public abstract void resetModel(); public abstract void test() throws Exception; } class BasicConnectionPanel extends ConnectionPanel { public BasicConnectionPanel(String id) { super(id); add(new JDBCDriverChoice("driverClassName").setRequired(true)); add(new TextField("connectURL").setRequired(true)); add(new TextField("userName").setRequired(true)); PasswordTextField pwdField = new PasswordTextField("password"); pwdField.setRequired(false); // avoid reseting the password which results in an //empty password on saving a modified configuration pwdField.setResetPassword(false); add(pwdField); } @Override public void resetModel() { //get("userGroupServiceName").setDefaultModelObject(null); } @Override public void test() throws Exception { //since this wasn't a regular form submission, we need to manually update component // models ((FormComponent)get("driverClassName")).processInput(); ((FormComponent)get("connectURL")).processInput(); ((FormComponent)get("userName")).processInput(); ((FormComponent)get("password")).processInput(); //do the test Class.forName(get("driverClassName").getDefaultModelObjectAsString()); Connection cx = DriverManager.getConnection( get("connectURL").getDefaultModelObjectAsString(), get("userName").getDefaultModelObjectAsString(), get("password").getDefaultModelObjectAsString()); cx.close(); } } class JNDIConnectionPanel extends ConnectionPanel { public JNDIConnectionPanel(String id) { super(id); add(new TextField("jndiName").setRequired(true)); } @Override public void resetModel() { //get("groupSearchBase").setDefaultModelObject(null); //get("groupSearchFilter").setDefaultModelObject(null); } @Override public void test() throws Exception { //since this wasn't a regular form submission, we need to manually update component // models ((FormComponent)get("jndiName")).processInput(); Context initialContext = new InitialContext(); try { DataSource datasource = (DataSource) initialContext.lookup(get("jndiName").getDefaultModelObjectAsString()); Connection con = datasource.getConnection(); con.close(); } finally { initialContext.close(); } } } }