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