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}