mirror of
https://github.com/igniterealtime/Spark.git
synced 2026-08-18 02:56:24 +00:00
SPARK-2099: TransferGuard case-insensitive blocking by file extension
This commit is contained in:
@ -19,7 +19,8 @@ import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
@ -34,40 +35,32 @@ import org.jxmpp.jid.util.JidUtil;
|
||||
* Bean whose properties are the various preference settings for file transfer.
|
||||
*/
|
||||
public class FileTransferSettings {
|
||||
private List<String> extensions = new ArrayList<>();
|
||||
private List<EntityBareJid> JIDs = new ArrayList<>();
|
||||
private Set<String> extensions = Set.of();
|
||||
private Set<EntityBareJid> JIDs = Set.of();
|
||||
private int kb;
|
||||
private boolean checkSize = false;
|
||||
String cannedRejectionMessage;
|
||||
private boolean checkSize;
|
||||
private String cannedRejectionMessage;
|
||||
private static final File BACKING_STORE = new File(Spark.getSparkUserHome(), "/transferguard.properties");
|
||||
|
||||
/**
|
||||
* Returns a {@link List} of strings - one for each blocked file extension. Strings are in the form <tt>*.{extension}</tt>.
|
||||
* Returns a {@link Set} of strings - one for each blocked file extension. Strings are in the form <tt>*.{extension}</tt>.
|
||||
*/
|
||||
public List<String> getBlockedExtensions(){
|
||||
public Set<String> getBlockedExtensions(){
|
||||
return extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link List} of blocked file extensions.
|
||||
* @param extensions the {@link List} of blocked file extensions.
|
||||
*/
|
||||
public void setBlockedExtensions(List<String> extensions){
|
||||
public void setBlockedExtensions(Set<String> extensions){
|
||||
this.extensions = extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link List} of blocked JIDs. File transfers from users with those JIDs will be automaticlly rejected.
|
||||
* Returns a {@link Set} of blocked JIDs. File transfers from users with those JIDs will be automatically rejected.
|
||||
*/
|
||||
public List<EntityBareJid> getBlockedJIDs() {
|
||||
public Set<EntityBareJid> getBlockedJIDs() {
|
||||
return JIDs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link List} of blocked JIDs.
|
||||
* @param JIDs the {@link List} of blocked JIDs.
|
||||
*/
|
||||
public void setBlockedJIDS(List<EntityBareJid> JIDs){
|
||||
public void setBlockedJIDS(Set<EntityBareJid> JIDs){
|
||||
this.JIDs = JIDs;
|
||||
}
|
||||
|
||||
@ -79,10 +72,6 @@ public class FileTransferSettings {
|
||||
return kb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum file size in kilobytes for file transfers.
|
||||
* @param kb the maximum file size in kilobytes for file transfers.
|
||||
*/
|
||||
public void setMaxFileSize(int kb){
|
||||
this.kb = kb;
|
||||
}
|
||||
@ -94,11 +83,6 @@ public class FileTransferSettings {
|
||||
return checkSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set to true, files larger than the maximum file size as returned by {@link #getMaxFileSize}
|
||||
* will not be accepted.
|
||||
* @param checkSize true if size should be checked.
|
||||
*/
|
||||
public void setCheckFileSize(boolean checkSize){
|
||||
this.checkSize = checkSize;
|
||||
}
|
||||
@ -111,11 +95,6 @@ public class FileTransferSettings {
|
||||
return cannedRejectionMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text of a canned message sent to requestors whose file transfers were automatically rejected. If set
|
||||
* to null or an empty string, no message will be sent.
|
||||
* @param cannedRejectionMessage the canned message text.
|
||||
*/
|
||||
public void setCannedRejectionMessage(String cannedRejectionMessage) {
|
||||
this.cannedRejectionMessage = cannedRejectionMessage;
|
||||
}
|
||||
@ -138,9 +117,9 @@ public class FileTransferSettings {
|
||||
|
||||
String users = props.getProperty("jids");
|
||||
if (users != null) {
|
||||
List<String> jidStrings = convertSettingsStringToList(users);
|
||||
Set<String> jidStrings = convertSettingsStringToList(users);
|
||||
Set<EntityBareJid> jidSet = JidUtil.entityBareJidSetFrom(jidStrings);
|
||||
this.JIDs = new ArrayList<>(jidSet);
|
||||
this.JIDs = jidSet;
|
||||
}
|
||||
|
||||
String ignore = props.getProperty("checkFileSize");
|
||||
@ -170,6 +149,8 @@ public class FileTransferSettings {
|
||||
props.setProperty("maxSize", Integer.toString(kb));
|
||||
if (cannedRejectionMessage != null) {
|
||||
props.setProperty("cannedResponse", cannedRejectionMessage);
|
||||
} else {
|
||||
props.remove("cannedResponse");
|
||||
}
|
||||
props.store(new FileOutputStream(BACKING_STORE), null);
|
||||
} catch (IOException ioe) {
|
||||
@ -178,33 +159,21 @@ public class FileTransferSettings {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a list of strings to a single comma separated string
|
||||
* @param settings the {@link List} of strings.
|
||||
* Converts a list of strings to a single comma-separated string
|
||||
*/
|
||||
public static String convertSettingsListToString(List<? extends CharSequence> settings) {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
boolean first = true;
|
||||
for (CharSequence cs : settings) {
|
||||
if (!first) {
|
||||
buffer.append(',');
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
buffer.append(cs);
|
||||
}
|
||||
return buffer.toString();
|
||||
public static String convertSettingsListToString(Collection<? extends CharSequence> settings) {
|
||||
return String.join(",", settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the supplied string to a {@link List} of strings. The input is split
|
||||
* with the tokensL: ',' ':' '\n' '\t' '\r' and ' '.
|
||||
* @param settings the string to convert.
|
||||
* Converts the supplied string to a {@link List} of strings in lower case.
|
||||
* The input is split with the tokens: ',' ':' '\n' '\t' '\r' and ' '.
|
||||
*/
|
||||
public static List<String> convertSettingsStringToList(String settings) {
|
||||
List<String> list = new ArrayList<>();
|
||||
public static Set<String> convertSettingsStringToList(String settings) {
|
||||
HashSet<String> list = new HashSet<>();
|
||||
StringTokenizer tokenizer = new StringTokenizer(settings, ",;\n\t\r ");
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
list.add(tokenizer.nextToken());
|
||||
list.add(tokenizer.nextToken().toLowerCase());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@ -26,8 +26,10 @@ import org.jivesoftware.spark.plugin.Plugin;
|
||||
import org.jivesoftware.spark.preference.PreferenceManager;
|
||||
import org.jivesoftware.spark.util.log.Log;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
/**
|
||||
* Spark plugin which allows configuration of allowed file sizes, types, and senders for file transfer.
|
||||
* Spark plugin that allows configuration of allowed file sizes, types, and senders for file transfer.
|
||||
* Transfer requests which don't meet the configured preferences are automatically rejected.
|
||||
*/
|
||||
public class FileTransferSettingsPlugin implements Plugin {
|
||||
@ -46,7 +48,7 @@ public class FileTransferSettingsPlugin implements Plugin {
|
||||
request.reject();
|
||||
|
||||
String responseMessage = settings.getCannedRejectionMessage();
|
||||
if (responseMessage != null && !responseMessage.isEmpty()) {
|
||||
if (!isBlank(responseMessage)) {
|
||||
Message message = StanzaBuilder.buildMessage()
|
||||
.to(request.getRequestor())
|
||||
.setBody(responseMessage)
|
||||
@ -97,8 +99,8 @@ public class FileTransferSettingsPlugin implements Plugin {
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the extension off the supplied filename and prepends an asterisk. For example 'bad.doc' would return
|
||||
* '*.doc'.
|
||||
* Strips the extension off the supplied filename, lowercase and prepends an asterisk.
|
||||
* For example, 'bad.DOC' would return '*.doc'.
|
||||
*
|
||||
* @param filename to return the extension for.
|
||||
* @return the extension.
|
||||
@ -106,7 +108,7 @@ public class FileTransferSettingsPlugin implements Plugin {
|
||||
private String getFileExtensionFromName(String filename) {
|
||||
int dotIdx = filename.lastIndexOf(".");
|
||||
if (dotIdx > 0 && dotIdx < (filename.length() - 1)) {
|
||||
return "*" + filename.substring( dotIdx );
|
||||
return "*" + filename.substring( dotIdx ).toLowerCase();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -5,26 +5,28 @@ import java.util.ResourceBundle;
|
||||
|
||||
import org.jivesoftware.spark.util.log.Log;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
/**
|
||||
* Use for Transferguard Ressource Internationalization.
|
||||
* Use for TransferGuard Ressource Internationalization.
|
||||
*
|
||||
* @author tim.jentz
|
||||
* @author Tim Jentz
|
||||
*/
|
||||
public class TGuardRes {
|
||||
private static final PropertyResourceBundle prb = (PropertyResourceBundle) ResourceBundle.getBundle("i18n/transferguard_i18n");
|
||||
|
||||
private static ClassLoader cl = TGuardRes.class.getClassLoader();
|
||||
static final Icon TRANSFERGUARD_ICON = new ImageIcon(cl.getResource("/images/transferguard/guard.png"));
|
||||
|
||||
private TGuardRes() {
|
||||
|
||||
}
|
||||
|
||||
public static String getString(String propertyName) {
|
||||
try {
|
||||
return prb.getString(propertyName);
|
||||
} catch (Exception e) {
|
||||
Log.error(e);
|
||||
return propertyName;
|
||||
}
|
||||
static String getString(String propertyName) {
|
||||
try {
|
||||
return prb.getString(propertyName);
|
||||
} catch (Exception e) {
|
||||
Log.error(e);
|
||||
return propertyName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -19,14 +19,26 @@ import org.jivesoftware.spark.component.VerticalFlowLayout;
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.jxmpp.jid.util.JidUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.border.TitledBorder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.awt.GridBagConstraints.HORIZONTAL;
|
||||
import static java.awt.GridBagConstraints.NONE;
|
||||
import static java.awt.GridBagConstraints.WEST;
|
||||
|
||||
/**
|
||||
* UI for the file transfer preferences. It displays all the various preference settings for editing.
|
||||
*/
|
||||
@ -46,7 +58,8 @@ public class TransferSettingsPanel extends JPanel {
|
||||
|
||||
/**
|
||||
* Populates all the gui controls with values from the supplied {@link FileTransferSettings}.
|
||||
* @param settings the {@link FileTransferSettings} to populate the gui from.
|
||||
*
|
||||
* @param settings the {@link FileTransferSettings} to populate the gui from.
|
||||
*/
|
||||
public void applySettings(FileTransferSettings settings) {
|
||||
pnlTypes.setBlockedTypes(settings.getBlockedExtensions());
|
||||
@ -58,6 +71,7 @@ public class TransferSettingsPanel extends JPanel {
|
||||
|
||||
/**
|
||||
* Populates the supplied {@link FileTransferSettings} from the values in the gui controls.
|
||||
*
|
||||
* @param settings the {@link FileTransferSettings} to populate.
|
||||
*/
|
||||
public void storeSettings(FileTransferSettings settings) {
|
||||
@ -69,51 +83,52 @@ public class TransferSettingsPanel extends JPanel {
|
||||
}
|
||||
|
||||
private static class BlockedTypesPanel extends JPanel {
|
||||
private final JTextArea txtBlockedTypes = new JTextArea(2, 0);
|
||||
private final JTextArea txtBlockedTypes = new JTextArea(2, 0);
|
||||
|
||||
BlockedTypesPanel() {
|
||||
txtBlockedTypes.setBorder(UIManager.getLookAndFeelDefaults().getBorder("TextField.border"));
|
||||
|
||||
txtBlockedTypes.setToolTipText(TGuardRes.getString("guard.settings.tooltips.blockedtypes"));
|
||||
setLayout(new BorderLayout());
|
||||
setBorder(BorderFactory.createCompoundBorder(new TitledBorder(TGuardRes.getString("guard.settings.title.extensions")),
|
||||
new EmptyBorder(2,4,4,4)));
|
||||
TitledBorder outsideBorder = new TitledBorder(TGuardRes.getString("guard.settings.title.extensions"));
|
||||
setBorder(BorderFactory.createCompoundBorder(outsideBorder, new EmptyBorder(2, 4, 4, 4)));
|
||||
add(txtBlockedTypes, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
public void setBlockedTypes(List<String> types) {
|
||||
public void setBlockedTypes(Set<String> types) {
|
||||
txtBlockedTypes.setText(FileTransferSettings.convertSettingsListToString(types));
|
||||
}
|
||||
|
||||
public List<String> getBlockedTypes() {
|
||||
public Set<String> getBlockedTypes() {
|
||||
return FileTransferSettings.convertSettingsStringToList(txtBlockedTypes.getText());
|
||||
}
|
||||
}
|
||||
|
||||
private static class BlockedPeoplePanel extends JPanel {
|
||||
private final JTextArea txtBlockedPeople = new JTextArea(2, 0);
|
||||
private final JTextArea txtBlockedPeople = new JTextArea(2, 0);
|
||||
|
||||
BlockedPeoplePanel() {
|
||||
txtBlockedPeople.setBorder(UIManager.getLookAndFeelDefaults().getBorder("TextField.border"));
|
||||
txtBlockedPeople.setToolTipText(TGuardRes.getString("guard.settings.tooltips.blockedperson"));
|
||||
setLayout(new BorderLayout());
|
||||
setBorder(BorderFactory.createCompoundBorder(new TitledBorder(TGuardRes.getString("guard.settings.title.person")),
|
||||
new EmptyBorder(2,4,4,4)));
|
||||
TitledBorder outsideBorder = new TitledBorder(TGuardRes.getString("guard.settings.title.person"));
|
||||
setBorder(BorderFactory.createCompoundBorder(outsideBorder, new EmptyBorder(2, 4, 4, 4)));
|
||||
add(txtBlockedPeople, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
public void setBlockedPeople(List<EntityBareJid> people) {
|
||||
public void setBlockedPeople(Set<EntityBareJid> people) {
|
||||
txtBlockedPeople.setText(FileTransferSettings.convertSettingsListToString(people));
|
||||
}
|
||||
|
||||
public List<EntityBareJid> getBlockedPeople() {
|
||||
List<String> jidStrings = FileTransferSettings.convertSettingsStringToList(txtBlockedPeople.getText());
|
||||
public Set<EntityBareJid> getBlockedPeople() {
|
||||
Set<String> jidStrings = FileTransferSettings.convertSettingsStringToList(txtBlockedPeople.getText());
|
||||
Set<EntityBareJid> jidSet = JidUtil.entityBareJidSetFrom(jidStrings);
|
||||
return new ArrayList<>(jidSet);
|
||||
return jidSet;
|
||||
}
|
||||
}
|
||||
|
||||
private static class FileSizePanel extends JPanel {
|
||||
private final JSpinner spinMaxSize = new JSpinner();
|
||||
private final JLabel spinMaxSizeLabel = new JLabel(TGuardRes.getString(("guard.settings.label.maxsize")));
|
||||
private final JSpinner spinMaxSize = new JSpinner();
|
||||
private final JCheckBox chkMaxEnabled = new JCheckBox(TGuardRes.getString("guard.settings.limitcheck"));
|
||||
|
||||
FileSizePanel() {
|
||||
@ -122,19 +137,14 @@ public class TransferSettingsPanel extends JPanel {
|
||||
add(chkMaxEnabled);
|
||||
|
||||
JPanel pnlSpinner = new JPanel(new GridBagLayout());
|
||||
pnlSpinner.add(new JLabel(TGuardRes.getString(("guard.settings.label.maxsize"))),
|
||||
new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,0,0,2), 0, 0));
|
||||
pnlSpinner.add(spinMaxSize,
|
||||
new GridBagConstraints(1, 0, 1, 1, 0.25, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0,0,0,0), 0, 0));
|
||||
pnlSpinner.add(new JPanel(),
|
||||
new GridBagConstraints(2, 0, 1, 1, 0.75, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0,0,0,0), 0, 0));
|
||||
pnlSpinner.add(spinMaxSizeLabel, new GridBagConstraints(0, 0, 1, 1, 0, 0, WEST, NONE, new Insets(0, 0, 0, 2), 0, 0));
|
||||
pnlSpinner.add(spinMaxSize, new GridBagConstraints(1, 0, 1, 1, 0.25, 0, WEST, HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
|
||||
pnlSpinner.add(new JPanel(), new GridBagConstraints(2, 0, 1, 1, 0.75, 0, WEST, HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
|
||||
add(pnlSpinner);
|
||||
|
||||
chkMaxEnabled.addActionListener( evnt -> {
|
||||
if (spinMaxSize != null) {
|
||||
spinMaxSize.setEnabled(chkMaxEnabled.isSelected());
|
||||
}
|
||||
} );
|
||||
chkMaxEnabled.addActionListener(e -> {
|
||||
spinMaxSize.setEnabled(chkMaxEnabled.isSelected());
|
||||
});
|
||||
}
|
||||
|
||||
public void setMaxFileSize(int kb) {
|
||||
@ -155,14 +165,14 @@ public class TransferSettingsPanel extends JPanel {
|
||||
}
|
||||
|
||||
private static class CannedResponsePanel extends JPanel {
|
||||
private final JTextArea txtMessage = new JTextArea(2, 0);
|
||||
private final JTextArea txtMessage = new JTextArea(2, 0);
|
||||
|
||||
CannedResponsePanel() {
|
||||
txtMessage.setBorder(UIManager.getLookAndFeelDefaults().getBorder("TextField.border"));
|
||||
txtMessage.setToolTipText(TGuardRes.getString(("guard.settings.tooltips.textarea")));
|
||||
setLayout(new BorderLayout());
|
||||
setBorder(BorderFactory.createCompoundBorder(new TitledBorder(TGuardRes.getString(("guard.settings.title.rejectresponse"))),
|
||||
new EmptyBorder(2,4,4,4)));
|
||||
TitledBorder outsideBorder = new TitledBorder(TGuardRes.getString(("guard.settings.title.rejectresponse")));
|
||||
setBorder(BorderFactory.createCompoundBorder(outsideBorder, new EmptyBorder(2, 4, 4, 4)));
|
||||
add(txtMessage, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
|
||||
@ -18,11 +18,11 @@ package org.jivesoftware.spark.plugins.transfersettings;
|
||||
import org.jivesoftware.spark.preference.Preference;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JComponent;
|
||||
|
||||
/**
|
||||
* Preference object for file transfer settings. Used by Spark to show the associated UI and commit changes to preference settings.
|
||||
* Preference object for file transfer settings.
|
||||
* Used by Spark to show the associated UI and commit changes to preference settings.
|
||||
*/
|
||||
public class TransferSettingsPreference implements Preference {
|
||||
static final String NAMESPACE = "transferSettings";
|
||||
@ -54,7 +54,7 @@ public class TransferSettingsPreference implements Preference {
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return new ImageIcon(getClass().getResource("/images/guard.png"));
|
||||
return TGuardRes.TRANSFERGUARD_ICON;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -43,24 +43,22 @@
|
||||
<h1>
|
||||
TransferGuard Spark plug Changelog
|
||||
</h1>
|
||||
|
||||
<p><b>1.3</b> -- July 26, 2026</p>
|
||||
<ul>
|
||||
<li>SPARK-2099: TransferGuard case-insensitive blocking by file extension</li>
|
||||
</ul>
|
||||
<p><b>1.0.2</b> -- August 15th, 2013</p>
|
||||
<ul>
|
||||
<li>Updated polnish language file.</li>
|
||||
<li>Updated Polish language file.</li>
|
||||
</ul>
|
||||
|
||||
<p><b>1.0.1</b> -- September 19th, 2006</p>
|
||||
<ul>
|
||||
<li>Moving over to be Spark 2.0 compatible.</li>
|
||||
<li>Moving over to be Spark 2.0 compatible.</li>
|
||||
</ul>
|
||||
|
||||
<p><b>1.0.0</b> -- February 9th, 2006</p>
|
||||
<ul>
|
||||
<li>Initial release.</li>
|
||||
<li>Initial release.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 547 B After Width: | Height: | Size: 547 B |
Reference in New Issue
Block a user