/******************************************************************************* * Copyright (c) 2011, 2016 Eurotech and/or its affiliates * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Eurotech *******************************************************************************/ package org.eclipse.kura.web.client.firewall; import java.util.ArrayList; import java.util.List; import org.eclipse.kura.web.client.messages.Messages; import org.eclipse.kura.web.client.resources.Resources; import org.eclipse.kura.web.client.util.FailureHandler; import org.eclipse.kura.web.client.util.SwappableListStore; import org.eclipse.kura.web.shared.model.GwtFirewallOpenPortEntry; import org.eclipse.kura.web.shared.model.GwtSession; import org.eclipse.kura.web.shared.model.GwtXSRFToken; import org.eclipse.kura.web.shared.service.GwtNetworkService; import org.eclipse.kura.web.shared.service.GwtNetworkServiceAsync; import org.eclipse.kura.web.shared.service.GwtSecurityTokenService; import org.eclipse.kura.web.shared.service.GwtSecurityTokenServiceAsync; import com.allen_sauer.gwt.log.client.Log; import com.extjs.gxt.ui.client.Style.HorizontalAlignment; import com.extjs.gxt.ui.client.Style.LayoutRegion; import com.extjs.gxt.ui.client.Style.Scroll; import com.extjs.gxt.ui.client.Style.SelectionMode; import com.extjs.gxt.ui.client.Style.SortDir; import com.extjs.gxt.ui.client.data.BaseListLoader; import com.extjs.gxt.ui.client.data.ListLoadResult; import com.extjs.gxt.ui.client.data.LoadEvent; import com.extjs.gxt.ui.client.data.ModelKeyProvider; import com.extjs.gxt.ui.client.data.RpcProxy; import com.extjs.gxt.ui.client.event.ButtonEvent; import com.extjs.gxt.ui.client.event.ComponentEvent; import com.extjs.gxt.ui.client.event.Events; import com.extjs.gxt.ui.client.event.Listener; import com.extjs.gxt.ui.client.event.LoadListener; import com.extjs.gxt.ui.client.event.MessageBoxEvent; import com.extjs.gxt.ui.client.event.SelectionChangedEvent; import com.extjs.gxt.ui.client.event.SelectionChangedListener; import com.extjs.gxt.ui.client.event.SelectionListener; import com.extjs.gxt.ui.client.store.ListStore; import com.extjs.gxt.ui.client.util.Margins; import com.extjs.gxt.ui.client.widget.ContentPanel; import com.extjs.gxt.ui.client.widget.LayoutContainer; import com.extjs.gxt.ui.client.widget.MessageBox; import com.extjs.gxt.ui.client.widget.button.Button; import com.extjs.gxt.ui.client.widget.grid.ColumnConfig; import com.extjs.gxt.ui.client.widget.grid.ColumnModel; import com.extjs.gxt.ui.client.widget.grid.Grid; import com.extjs.gxt.ui.client.widget.grid.GridSelectionModel; import com.extjs.gxt.ui.client.widget.layout.BorderLayout; import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData; import com.extjs.gxt.ui.client.widget.layout.FitLayout; import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem; import com.extjs.gxt.ui.client.widget.toolbar.ToolBar; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.AbstractImagePrototype; public class OpenPortsConfigTab extends LayoutContainer { private static final Messages MSGS = GWT.create(Messages.class); private final GwtSecurityTokenServiceAsync gwtXSRFService = GWT.create(GwtSecurityTokenService.class); private final GwtNetworkServiceAsync gwtNetworkService = GWT.create(GwtNetworkService.class); private GwtSession m_currentSession; private Grid<GwtFirewallOpenPortEntry> m_grid; private BaseListLoader<ListLoadResult<GwtFirewallOpenPortEntry>> m_openPortsLoader; private GwtFirewallOpenPortEntry m_selectedEntry; private boolean m_dirty; private ToolBar m_openPortsToolBar; private Button m_newButton; private Button m_editButton; private Button m_deleteButton; private Button m_applyButton; public OpenPortsConfigTab(GwtSession currentSession) { m_currentSession = currentSession; } protected void onRender(final Element parent, int index) { super.onRender(parent, index); m_dirty = false; // // Borderlayout that expands to the whole screen setLayout(new FitLayout()); setBorders(false); setId("firewall-open-ports"); LayoutContainer mf = new LayoutContainer(); mf.setLayout(new BorderLayout()); // // Center Panel: Open Ports Table BorderLayoutData centerData = new BorderLayoutData(LayoutRegion.CENTER, 1F); centerData.setMargins(new Margins(0, 0, 0, 0)); centerData.setSplit(true); centerData.setMinSize(0); ContentPanel openPortsTablePanel = new ContentPanel(); openPortsTablePanel.setBorders(false); openPortsTablePanel.setBodyBorder(false); openPortsTablePanel.setHeaderVisible(false); openPortsTablePanel.setScrollMode(Scroll.AUTO); openPortsTablePanel.setLayout(new FitLayout()); initOpenPortsToolBar(); initOpenPortsGrid(); openPortsTablePanel.setTopComponent(m_openPortsToolBar); openPortsTablePanel.add(m_grid); mf.add(openPortsTablePanel, centerData); add(mf); refresh(); } public void refresh() { m_openPortsLoader.load(); } public List<GwtFirewallOpenPortEntry> getCurrentConfigurations() { if(m_grid != null) { ListStore<GwtFirewallOpenPortEntry> store = m_grid.getStore(); return store.getModels(); } else { return null; } } public boolean isDirty() { return m_dirty; } private void initOpenPortsToolBar() { m_openPortsToolBar = new ToolBar(); m_openPortsToolBar.setId("firewall-open-ports-toolbar"); m_applyButton = new Button(MSGS.firewallApply(), AbstractImagePrototype.create(Resources.INSTANCE.accept()), new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { Log.debug("about to updateDeviceFirewallOpenPorts() and updateDeviceFirewallPortForwards()"); gwtXSRFService.generateSecurityToken(new AsyncCallback<GwtXSRFToken> () { @Override public void onFailure(Throwable ex) { FailureHandler.handle(ex); } @Override public void onSuccess(GwtXSRFToken token) { List<GwtFirewallOpenPortEntry> updatedOpenPortConf = getCurrentConfigurations(); if(updatedOpenPortConf != null) { Log.debug("got updatedOpenPortConf: " + updatedOpenPortConf.size()); mask(MSGS.applying()); gwtNetworkService.updateDeviceFirewallOpenPorts(token, updatedOpenPortConf, new AsyncCallback<Void>() { public void onSuccess(Void result) { Log.debug("updated!"); m_dirty = false; m_applyButton.disable(); unmask(); } public void onFailure(Throwable caught) { Log.debug("caught: " + caught.toString()); unmask(); FailureHandler.handle(caught); } }); } }}); } }); m_applyButton.disable(); m_openPortsToolBar.add(m_applyButton); m_openPortsToolBar.add(new SeparatorToolItem()); // // New Open Port Button m_newButton = new Button(MSGS.newButton(), AbstractImagePrototype.create(Resources.INSTANCE.add()), new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { final OpenPortForm openPortForm = new OpenPortForm(m_currentSession); openPortForm.addListener(Events.Hide, new Listener<ComponentEvent>() { public void handleEvent(ComponentEvent be) { // add the new open port entry to the grid and select it if (openPortForm.getNewOpenPortEntry() != null) { if(!duplicateEntry(openPortForm.getNewOpenPortEntry())) { m_grid.getStore().add(openPortForm.getNewOpenPortEntry()); if (!openPortForm.isCanceled()) { m_applyButton.enable(); m_dirty = true; } } else { MessageBox.alert(MSGS.firewallOpenPortFormError(), MSGS.firewallOpenPortFormDuplicate(), new Listener<MessageBoxEvent>() { public void handleEvent(MessageBoxEvent ce) { //noop } }); } } } }); openPortForm.show(); } }); m_openPortsToolBar.add(m_newButton); m_openPortsToolBar.add(new SeparatorToolItem()); // // Edit Open Port Button m_editButton = new Button(MSGS.editButton(), AbstractImagePrototype.create(Resources.INSTANCE.edit()), new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { if (m_grid != null) { final GwtFirewallOpenPortEntry openPortEntry = m_grid.getSelectionModel().getSelectedItem(); if (openPortEntry != null) { if(openPortEntry.getPortRange().equals("22")) { MessageBox.alert(MSGS.firewallOpenPortsCaution(), MSGS.firewallOpenPorts22(), new Listener<MessageBoxEvent>() { public void handleEvent(MessageBoxEvent ce) { showEditOpenPort(openPortEntry); } }); } else if(openPortEntry.getPortRange().equals("80")) { MessageBox.alert(MSGS.firewallOpenPortsCaution(), MSGS.firewallOpenPorts80(), new Listener<MessageBoxEvent>() { public void handleEvent(MessageBoxEvent ce) { showEditOpenPort(openPortEntry); } }); } else { showEditOpenPort(openPortEntry); } } } } }); m_editButton.setEnabled(false); m_openPortsToolBar.add(m_editButton); m_openPortsToolBar.add(new SeparatorToolItem()); // // Delete Open Port Entry Button m_deleteButton = new Button(MSGS.deleteButton(), AbstractImagePrototype.create(Resources.INSTANCE.delete()), new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { if (m_grid != null) { final GwtFirewallOpenPortEntry openPortEntry = m_grid.getSelectionModel().getSelectedItem(); if (openPortEntry != null) { if(openPortEntry.getPortRange().equals("22")) { // ask for confirmation MessageBox.confirm(MSGS.confirm(), MSGS.firewallOpenPortDeleteConfirmation22(openPortEntry.getPortRange()), new Listener<MessageBoxEvent>() { public void handleEvent(MessageBoxEvent ce) { Log.debug("Trying to delete: " + openPortEntry.getPortRange()); Log.debug("Button " + ce.getButtonClicked().getText()); if(ce.getButtonClicked().getText().equals("Yes")) { m_grid.getStore().remove(openPortEntry); m_applyButton.enable(); m_dirty = true; } } } ); } else if(openPortEntry.getPortRange().equals("80")) { // ask for confirmation MessageBox.confirm(MSGS.confirm(), MSGS.firewallOpenPortDeleteConfirmation80(openPortEntry.getPortRange()), new Listener<MessageBoxEvent>() { public void handleEvent(MessageBoxEvent ce) { Log.debug("Trying to delete: " + openPortEntry.getPortRange()); Log.debug("Button " + ce.getButtonClicked().getText()); if(ce.getButtonClicked().getText().equals("Yes")) { m_grid.getStore().remove(openPortEntry); m_applyButton.enable(); m_dirty = true; } } } ); } else { // ask for confirmation MessageBox.confirm(MSGS.confirm(), MSGS.firewallOpenPortDeleteConfirmation(openPortEntry.getPortRange()), new Listener<MessageBoxEvent>() { public void handleEvent(MessageBoxEvent ce) { Log.debug("Trying to delete: " + openPortEntry.getPortRange()); Log.debug("Button " + ce.getButtonClicked().getText()); if(ce.getButtonClicked().getText().equals("Yes")) { m_grid.getStore().remove(openPortEntry); m_applyButton.enable(); m_dirty = true; } } } ); } } } } }); m_deleteButton.setEnabled(false); m_openPortsToolBar.add(m_deleteButton); } private void initOpenPortsGrid() { // // Column Configuration ColumnConfig column = null; List<ColumnConfig> configs = new ArrayList<ColumnConfig>(); column = new ColumnConfig("portRange", MSGS.firewallOpenPort(), 100); column.setAlignment(HorizontalAlignment.CENTER); configs.add(column); column = new ColumnConfig("protocol", MSGS.firewallOpenPortProtocol(), 100); column.setAlignment(HorizontalAlignment.CENTER); configs.add(column); column = new ColumnConfig("permittedNetwork", MSGS.firewallOpenPortPermittedNetwork(), 130); column.setAlignment(HorizontalAlignment.CENTER); configs.add(column); column = new ColumnConfig("permittedInterfaceName", MSGS.firewallOpenPortPermittedInterfaceName(), 130); column.setAlignment(HorizontalAlignment.CENTER); configs.add(column); column = new ColumnConfig("unpermittedInterfaceName", MSGS.firewallOpenPortUnpermittedInterfaceName(), 130); column.setAlignment(HorizontalAlignment.CENTER); configs.add(column); column = new ColumnConfig("permittedMAC", MSGS.firewallOpenPortPermittedMac(), 130); column.setAlignment(HorizontalAlignment.CENTER); configs.add(column); column = new ColumnConfig("sourcePortRange", MSGS.firewallOpenPortSourcePortRange(), 130); column.setAlignment(HorizontalAlignment.CENTER); configs.add(column); // rpc data proxy RpcProxy<ListLoadResult<GwtFirewallOpenPortEntry>> proxy = new RpcProxy<ListLoadResult<GwtFirewallOpenPortEntry>>() { @Override protected void load(Object loadConfig, final AsyncCallback<ListLoadResult<GwtFirewallOpenPortEntry>> callback) { gwtXSRFService.generateSecurityToken(new AsyncCallback<GwtXSRFToken> () { @Override public void onFailure(Throwable ex) { FailureHandler.handle(ex); } @Override public void onSuccess(GwtXSRFToken token) { gwtNetworkService.findDeviceFirewallOpenPorts(token, callback); }}); } }; m_openPortsLoader = new BaseListLoader<ListLoadResult<GwtFirewallOpenPortEntry>>(proxy); m_openPortsLoader.setSortDir(SortDir.DESC); m_openPortsLoader.setSortField("port"); m_openPortsLoader.setRemoteSort(true); SwappableListStore<GwtFirewallOpenPortEntry> m_store = new SwappableListStore<GwtFirewallOpenPortEntry>(m_openPortsLoader); m_store.setKeyProvider( new ModelKeyProvider<GwtFirewallOpenPortEntry>() { public String getKey(GwtFirewallOpenPortEntry openPortEntry) { return openPortEntry.getPortRange(); } }); m_grid = new Grid<GwtFirewallOpenPortEntry>(m_store, new ColumnModel(configs)); m_grid.setBorders(false); m_grid.setStateful(false); m_grid.setLoadMask(true); m_grid.setStripeRows(true); m_grid.setAutoExpandColumn("portRange"); m_grid.getView().setAutoFill(true); //m_grid.getView().setEmptyText(MSGS.deviceTableNoDevices()); m_openPortsLoader.addLoadListener(new DataLoadListener(m_grid)); GridSelectionModel<GwtFirewallOpenPortEntry> selectionModel = new GridSelectionModel<GwtFirewallOpenPortEntry>(); selectionModel.setSelectionMode(SelectionMode.SINGLE); m_grid.setSelectionModel(selectionModel); m_grid.getSelectionModel().addSelectionChangedListener(new SelectionChangedListener<GwtFirewallOpenPortEntry>() { @Override public void selectionChanged(SelectionChangedEvent<GwtFirewallOpenPortEntry> se) { m_selectedEntry = se.getSelectedItem(); if (m_selectedEntry != null) { m_editButton.setEnabled(true); m_deleteButton.setEnabled(true); } else { m_editButton.setEnabled(false); m_deleteButton.setEnabled(false); } } }); } private class DataLoadListener extends LoadListener { private Grid<GwtFirewallOpenPortEntry> m_grid; private GwtFirewallOpenPortEntry m_selectedEntry; public DataLoadListener(Grid<GwtFirewallOpenPortEntry> grid) { m_grid = grid; m_selectedEntry = null; } public void loaderBeforeLoad(LoadEvent le) { m_selectedEntry = m_grid.getSelectionModel().getSelectedItem(); } public void loaderLoad(LoadEvent le) { if (le.exception != null) { FailureHandler.handle(le.exception); } if (m_selectedEntry != null) { ListStore<GwtFirewallOpenPortEntry> store = m_grid.getStore(); GwtFirewallOpenPortEntry modelEntry = store.findModel(m_selectedEntry.getPortRange()); if (modelEntry != null) { m_grid.getSelectionModel().select(modelEntry, false); m_grid.getView().focusRow(store.indexOf(modelEntry)); } } } } private boolean duplicateEntry(GwtFirewallOpenPortEntry openPortEntry) { List<GwtFirewallOpenPortEntry> entries = m_grid.getStore().getModels(); if (entries != null && openPortEntry != null) { for(GwtFirewallOpenPortEntry entry : entries) { if (entry.getPortRange().equals(openPortEntry.getPortRange()) && entry.getProtocol().equals(openPortEntry.getProtocol()) && entry.getPermittedNetwork().equals(openPortEntry.getPermittedNetwork())) { return true; } } } return false; } private void showEditOpenPort(final GwtFirewallOpenPortEntry openPortEntry) { final OpenPortForm openPortForm = new OpenPortForm(m_currentSession, m_grid.getSelectionModel().getSelectedItem()); openPortForm.addListener(Events.Hide, new Listener<ComponentEvent>() { public void handleEvent(ComponentEvent be) { if(!duplicateEntry(openPortForm.getNewOpenPortEntry())) { m_grid.getStore().remove(openPortEntry); m_grid.getStore().add(openPortForm.getExistingOpenPortEntry()); if (!openPortForm.isCanceled()) { m_applyButton.enable(); m_dirty = true; } } else { MessageBox.alert(MSGS.firewallOpenPortFormError(), MSGS.firewallOpenPortFormDuplicate(), new Listener<MessageBoxEvent>() { public void handleEvent(MessageBoxEvent ce) { //noop } }); } } }); openPortForm.show(); } }