Changeset 5876 in josm for trunk/src/org/openstreetmap


Ignore:
Timestamp:
2013-04-17T20:14:32+02:00 (12 years ago)
Author:
akks
Message:

Remote control: allow adding tags without confirmation for current session (add_tags), see #8612
added parsing of request headers and detecting request sender by IP and "referer" HTTP header

Location:
trunk/src/org/openstreetmap/josm/io/remotecontrol
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/io/remotecontrol/AddTagsDialog.java

    r5845 r5876  
    1111import java.awt.event.KeyEvent;
    1212import java.awt.event.MouseEvent;
     13import java.io.UnsupportedEncodingException;
     14import java.net.URLDecoder;
    1315import java.util.Collection;
    1416import java.util.HashMap;
     17import java.util.HashSet;
     18import java.util.Map;
     19import java.util.Set;
    1520import javax.swing.AbstractAction;
     21import javax.swing.JCheckBox;
    1622
    1723import javax.swing.JPanel;
    1824import javax.swing.JTable;
    1925import javax.swing.KeyStroke;
    20 import javax.swing.event.CellEditorListener;
    21 import javax.swing.event.ChangeEvent;
    2226import javax.swing.table.DefaultTableModel;
    2327import javax.swing.table.TableCellEditor;
     
    3135import org.openstreetmap.josm.data.osm.OsmPrimitive;
    3236import org.openstreetmap.josm.gui.ExtendedDialog;
     37import org.openstreetmap.josm.gui.util.GuiHelper;
    3338import org.openstreetmap.josm.gui.util.TableHelper;
    3439import org.openstreetmap.josm.tools.GBC;
     
    4651
    4752
     53    /** initially given tags  **/
     54    String[][] tags;
     55   
    4856    private final JTable propertyTable;
    4957    private Collection<? extends OsmPrimitive> sel;
    5058    int[] count;
    5159
     60    String sender;
     61    static Set<String> trustedSenders = new HashSet<String>();
     62   
    5263    /**
    5364     * Class for displaying "delete from ... objects" in the table
     
    110121    }
    111122           
    112     public AddTagsDialog(String[][] tags) {
     123    public AddTagsDialog(String[][] tags, String senderName) {
    113124        super(Main.parent, tr("Add tags to selected objects"), new String[] { tr("Add selected tags"), tr("Add all tags"),  tr("Cancel")},
    114125                false,
    115126                true);
    116127        setToolTipTexts(new String[]{tr("Add checked tags to selected objects"), tr("Shift+Enter: Add all tags to selected objects"), ""});
    117      
     128
     129        this.sender = senderName;
     130       
    118131        DataSet.addSelectionListener(this);
    119132
     
    211224        tablePanel.add(propertyTable.getTableHeader(), GBC.eol().fill(GBC.HORIZONTAL));
    212225        tablePanel.add(propertyTable, GBC.eol().fill(GBC.BOTH));
     226        if (!trustedSenders.contains(sender)) {
     227            final JCheckBox c = new JCheckBox();
     228            c.setAction(new AbstractAction(tr("Accept all tags from {0} for this session", sender) ) {
     229                @Override public void actionPerformed(ActionEvent e) {
     230                    if (c.isSelected())
     231                        trustedSenders.add(sender);
     232                    else
     233                        trustedSenders.remove(sender);
     234                }
     235            } );
     236            tablePanel.add(c , GBC.eol().insets(20,10,0,0));
     237        }
    213238        setContent(tablePanel);
    214239        setDefaultButton(2);
     
    251276                }
    252277            }
     278        }
     279        if (buttonIndex == 2) {
     280            trustedSenders.remove(sender);
    253281        }
    254282        setVisible(false);
     
    260288        findExistingTags();
    261289    }
    262 
     290   
     291     /*
     292     * parse addtags parameters Example URL (part):
     293     * addtags=wikipedia:de%3DResidenzschloss Dresden|name:en%3DDresden Castle
     294     */
     295    public static void addTags(final Map<String, String> args, final String sender) {
     296        if (args.containsKey("addtags")) {
     297            GuiHelper.executeByMainWorkerInEDT(new Runnable() {
     298
     299                public void run() {
     300                    String[] tags = null;
     301                    try {
     302                        tags = URLDecoder.decode(args.get("addtags"), "UTF-8").split("\\|");
     303                    } catch (UnsupportedEncodingException e) {
     304                        throw new RuntimeException();
     305                    }
     306                    Set<String> tagSet = new HashSet<String>();
     307                    for (String tag : tags) {
     308                        if (!tag.trim().isEmpty() && tag.contains("=")) {
     309                            tagSet.add(tag.trim());
     310                        }
     311                    }
     312                    if (!tagSet.isEmpty()) {
     313                        String[][] keyValue = new String[tagSet.size()][2];
     314                        int i = 0;
     315                        for (String tag : tagSet) {
     316                            // support a  =   b===c as "a"="b===c"
     317                            String [] pair = tag.split("\\s*=\\s*",2);
     318                            keyValue[i][0] = pair[0];
     319                            keyValue[i][1] = pair.length<2 ? "": pair[1];
     320                            i++;
     321                        }
     322                        addTagsIfNeeded(keyValue, sender);
     323                    }
     324                }
     325
     326               
     327            });
     328        }
     329    }
     330   
     331    private static void addTagsIfNeeded(String[][] keyValue, String sender) {
     332        if (trustedSenders.contains(sender)) {
     333            if (Main.main.getCurrentDataSet() != null) {
     334                Collection<OsmPrimitive> s = Main.main.getCurrentDataSet().getSelected();
     335                for (int j = 0; j < keyValue.length; j++) {
     336                    Main.main.undoRedo.add(new ChangePropertyCommand(s, keyValue[j][0], keyValue[j][1]));
     337                }
     338            }
     339        } else {
     340            new AddTagsDialog(keyValue, sender).showDialog();
     341        }
     342    }
    263343}
  • trunk/src/org/openstreetmap/josm/io/remotecontrol/RequestProcessor.java

    r5837 r5876  
    22package org.openstreetmap.josm.io.remotecontrol;
    33
    4 import java.io.BufferedInputStream;
    54import java.io.BufferedOutputStream;
     5import java.io.BufferedReader;
    66import java.io.IOException;
    77import java.io.InputStreamReader;
    88import java.io.OutputStream;
    99import java.io.OutputStreamWriter;
    10 import java.io.Reader;
    1110import java.io.Writer;
    1211import java.net.Socket;
    1312import java.util.Arrays;
    1413import java.util.Date;
     14import java.util.HashMap;
    1515import java.util.Map;
    1616import java.util.Map.Entry;
    1717import java.util.StringTokenizer;
    1818import java.util.TreeMap;
     19import java.util.regex.Matcher;
     20import java.util.regex.Pattern;
    1921
    2022import org.openstreetmap.josm.io.remotecontrol.handler.AddNodeHandler;
     
    136138                    request.getOutputStream());
    137139            out = new OutputStreamWriter(raw);
    138             Reader in = new InputStreamReader(new BufferedInputStream(
    139                     request.getInputStream()), "ASCII");
    140 
    141             StringBuffer requestLine = new StringBuffer();
    142             while (requestLine.length() < 1024 * 1024) {
    143                 int c = in.read();
    144                 if (c == -1 || c == '\r' || c == '\n')
    145                     break;
    146                 requestLine.append((char) c);
    147             }
    148 
    149             System.out.println("RemoteControl received: " + requestLine);
    150             String get = requestLine.toString();
     140            BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream(), "ASCII"));
     141           
     142            String get = in.readLine();
     143            System.out.println("RemoteControl received: " + get);
     144
    151145            StringTokenizer st = new StringTokenizer(get);
    152146            if (!st.hasMoreTokens()) {
     
    165159                return;
    166160            }
    167 
    168             String command = null;
     161           
    169162            int questionPos = url.indexOf('?');
    170             if(questionPos < 0)
    171             {
    172                 command = url;
    173             }
    174             else
    175             {
    176                 command = url.substring(0, questionPos);
    177             }
    178 
     163           
     164            String command = questionPos < 0 ? url : url.substring(0, questionPos);
     165           
     166            Map <String,String> headers = new HashMap<String, String>();
     167            int k=0, MAX_HEADERS=20;
     168            while (k<MAX_HEADERS) {
     169                get=in.readLine();
     170                if (get==null) break;
     171                k++;
     172                String h[] = get.split(": ", 2);
     173                if (h.length==2) {
     174                    headers.put(h[0], h[1]);
     175                } else break;
     176            }
     177           
     178            // Who sent the request: trying our best to detect
     179            // not from localhost => sender = IP
     180            // from localhost: sender = referer header, if exists
     181            String sender = null;
     182           
     183            if (!request.getInetAddress().isLoopbackAddress()) {
     184                sender = request.getInetAddress().getHostAddress();
     185            } else {
     186                String ref = headers.get("Referer");
     187                Pattern r = Pattern.compile("(https?://)?([^/]*)");
     188                if (ref!=null) {
     189                    Matcher m = r.matcher(ref);
     190                    if (m.find()) {
     191                        sender = m.group(2);
     192                    }
     193                }
     194                if (sender == null) {
     195                    sender = "localhost";
     196                }
     197            }
     198           
    179199            // find a handler for this command
    180200            Class<? extends RequestHandler> handlerClass = handlers.get(command);
     
    202222                    handler.setCommand(command);
    203223                    handler.setUrl(url);
     224                    handler.setSender(sender);
    204225                    handler.handle();
    205226                    sendHeader(out, "200 OK", handler.getContentType(), false);
  • trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/AddNodeHandler.java

    r5845 r5876  
    1313import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1414import org.openstreetmap.josm.gui.util.GuiHelper;
     15import org.openstreetmap.josm.io.remotecontrol.AddTagsDialog;
    1516import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
    1617import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler.RequestHandlerBadRequestException;
     
    9091        }
    9192        // parse parameter addtags=tag1=value1|tag2=vlaue2
    92         LoadAndZoomHandler.addTags(args);
     93        AddTagsDialog.addTags(args, sender);       
    9394    }
    9495
  • trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/AddWayHandler.java

    r5845 r5876  
    2020import org.openstreetmap.josm.data.osm.Way;
    2121import org.openstreetmap.josm.gui.util.GuiHelper;
     22import org.openstreetmap.josm.io.remotecontrol.AddTagsDialog;
    2223import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
    2324import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler.RequestHandlerBadRequestException;
     
    5354        });
    5455        // parse parameter addtags=tag1=value1|tag2=value2
    55         LoadAndZoomHandler.addTags(args);       
     56        AddTagsDialog.addTags(args, sender);       
    5657    }
    5758
  • trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java

    r5790 r5876  
    66import java.awt.geom.Area;
    77import java.awt.geom.Rectangle2D;
    8 import java.io.UnsupportedEncodingException;
    9 import java.net.URLDecoder;
    108import java.util.HashSet;
    11 import java.util.Map;
    129import java.util.Set;
    1310import java.util.concurrent.Future;
     
    191188        }
    192189
    193         addTags(args);
    194     }
    195 
    196     /*
    197      * parse addtags parameters Example URL (part):
    198      * addtags=wikipedia:de%3DResidenzschloss Dresden|name:en%3DDresden Castle
    199      */
    200     static void addTags(final Map<String, String> args) {
    201         if (args.containsKey("addtags")) {
    202             GuiHelper.executeByMainWorkerInEDT(new Runnable() {
    203 
    204                 public void run() {
    205                     String[] tags = null;
    206                     try {
    207                         tags = URLDecoder.decode(args.get("addtags"), "UTF-8").split("\\|");
    208                     } catch (UnsupportedEncodingException e) {
    209                         throw new RuntimeException();
    210                     }
    211                     Set<String> tagSet = new HashSet<String>();
    212                     for (String tag : tags) {
    213                         if (!tag.trim().isEmpty() && tag.contains("=")) {
    214                             tagSet.add(tag.trim());
    215                         }
    216                     }
    217                     if (!tagSet.isEmpty()) {
    218                         String[][] keyValue = new String[tagSet.size()][2];
    219                         int i = 0;
    220                         for (String tag : tagSet) {
    221                             // support a  =   b===c as "a"="b===c"
    222                             String [] pair = tag.split("\\s*=\\s*",2);
    223                             keyValue[i][0] = pair[0];
    224                             keyValue[i][1] = pair.length<2 ? "": pair[1];
    225                             i++;
    226                         }
    227    
    228                         new AddTagsDialog(keyValue).showDialog();
    229                     }
    230                 }
    231             });
    232         }
     190        AddTagsDialog.addTags(args, sender);
    233191    }
    234192
  • trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java

    r5844 r5876  
    1010import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
    1111import org.openstreetmap.josm.gui.util.GuiHelper;
     12import org.openstreetmap.josm.io.remotecontrol.AddTagsDialog;
    1213import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
    1314
     
    4849                public void run() {
    4950                    Main.main.getCurrentDataSet().setSelected(ps);
    50                     LoadAndZoomHandler.addTags(args);
     51                    AddTagsDialog.addTags(args, sender);       
    5152                    ps.clear();
    5253                }
  • trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java

    r5691 r5876  
    4343    /** will be filled with the command assigned to the subclass */
    4444    protected String myCommand;
     45   
     46    /**
     47     * who send th request?
     48     * the host from refrerer header or IP of request sender
     49     */
     50    protected String sender;
    4551
    4652    /**
     
    242248    }
    243249
     250    public void setSender(String sender) {
     251        this.sender = sender;
     252    }
     253 
    244254    public static class RequestHandlerException extends Exception {
    245255
Note: See TracChangeset for help on using the changeset viewer.