001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.plugins.streetside.oauth; 003 004 005import java.io.IOException; 006import java.io.InputStreamReader; 007import java.io.OutputStreamWriter; 008import java.io.PrintWriter; 009import java.net.BindException; 010import java.net.ServerSocket; 011import java.net.Socket; 012import java.util.Scanner; 013import java.util.regex.Matcher; 014import java.util.regex.Pattern; 015 016import org.apache.log4j.Logger; 017import org.openstreetmap.josm.Main; 018import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties; 019import org.openstreetmap.josm.tools.I18n; 020 021/** 022* Listens to the OAuth port (8763) in order to get the access token and sends 023* back a simple reply. 024* 025* @author nokutu 026* 027*/ 028public class OAuthPortListener extends Thread { 029public static final int PORT = 8763; 030 031final static Logger logger = Logger.getLogger(OAuthPortListener.class); 032 033protected static final String RESPONSE = String.format( 034 "<!DOCTYPE html><html><head><meta charset=\"utf8\"><title>%s</title></head><body>%s</body></html>", 035 I18n.tr("Streetside login"), 036 I18n.tr("Login successful, return to JOSM.") 037); 038private final StreetsideLoginListener callback; 039 040public OAuthPortListener(StreetsideLoginListener loginCallback) { 041 callback = loginCallback; 042} 043 044@Override 045public void run() { 046 try ( 047 ServerSocket serverSocket = new ServerSocket(PORT); 048 Socket clientSocket = serverSocket.accept(); 049 PrintWriter out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream(), "UTF-8"), true); 050 Scanner in = new Scanner(new InputStreamReader(clientSocket.getInputStream(), "UTF-8")) 051 ) { 052 String s; 053 String accessToken = null; 054 while (in.hasNextLine()) { 055 s = in.nextLine(); 056 Matcher tokenMatcher = Pattern.compile("^.*&access_token=([^&]+)&.*$").matcher('&'+s+'&'); 057 if (tokenMatcher.matches()) { 058 accessToken = tokenMatcher.group(1); 059 break; 060 } else if (s.contains("keep-alive")) { 061 break; 062 } 063 } 064 065 writeContent(out); 066 out.flush(); 067 068 StreetsideUser.reset(); 069 070 logger.info(I18n.tr("Successful login with Streetside, the access token is: {0}", accessToken)); 071 // Saves the access token in preferences. 072 StreetsideUser.setTokenValid(true); 073 if (Main.main != null) { 074 StreetsideProperties.ACCESS_TOKEN.put(accessToken); 075 String username = StreetsideUser.getUsername(); 076 logger.info(I18n.tr("The username is: {0}", username)); 077 if (callback != null) { 078 callback.onLogin(username); 079 } 080 } 081 } catch (BindException e) { 082 logger.warn(e); 083 } catch (IOException e) { 084 logger.error(e); 085 } 086} 087 088private static void writeContent(PrintWriter out) { 089 out.println("HTTP/1.1 200 OK"); 090 out.println("Content-Length: " + RESPONSE.length()); 091 out.println("Content-Type: text/html" + "\r\n\r\n"); 092 out.println(RESPONSE); 093} 094}