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.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties; 017 018import org.openstreetmap.josm.Main; 019import org.openstreetmap.josm.tools.I18n; 020import org.openstreetmap.josm.tools.Logging; 021 022/** 023* Listens to the OAuth port (8763) in order to get the access token and sends 024* back a simple reply. 025* 026* @author nokutu 027* 028*/ 029public class OAuthPortListener extends Thread { 030public static final int PORT = 8763; 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("Mapillary login"), 035 I18n.tr("Login successful, return to JOSM.") 036); 037private final StreetsideLoginListener callback; 038 039public OAuthPortListener(StreetsideLoginListener loginCallback) { 040 this.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 Logging.info("Successful login with Mapillary, the access token is: {0}", accessToken); 070 // Saves the access token in preferences. 071 StreetsideUser.setTokenValid(true); 072 if (Main.main != null) { 073 StreetsideProperties.ACCESS_TOKEN.put(accessToken); 074 String username = StreetsideUser.getUsername(); 075 Logging.info("The username is: {0}", username); 076 if (callback != null) { 077 callback.onLogin(username); 078 } 079 } 080 } catch (BindException e) { 081 Logging.warn(e); 082 } catch (IOException e) { 083 Logging.error(e); 084 } 085} 086 087private static void writeContent(PrintWriter out) { 088 out.println("HTTP/1.1 200 OK"); 089 out.println("Content-Length: " + RESPONSE.length()); 090 out.println("Content-Type: text/html" + "\r\n\r\n"); 091 out.println(RESPONSE); 092} 093}