/** * Copyright (C) 2016 eBusiness Information * * This file is part of OSM Contributor. * * OSM Contributor is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OSM Contributor is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OSM Contributor. If not, see <http://www.gnu.org/licenses/>. */ package io.jawg.osmcontributor.rest.security; import android.app.Activity; import android.webkit.JavascriptInterface; import android.webkit.WebView; import org.greenrobot.eventbus.EventBus; import java.util.UUID; import javax.inject.Inject; import javax.inject.Singleton; import io.jawg.osmcontributor.R; import io.jawg.osmcontributor.rest.events.GoogleAuthenticatedEvent; import io.jawg.osmcontributor.rest.utils.MapParams; import io.jawg.osmcontributor.ui.dialogs.WebViewDialogFragment; /** * @author Tommy Buonomo on 25/07/16. */ @Singleton public class GoogleOAuthManager { public static final String LOGIN_HINT_PARAM = "login_hint"; public static final String OSM_GOOGLE_AUTH_URL = "https://www.openstreetmap.org/auth/google"; public static final String OSM_MAP_URL = "https://www.openstreetmap.org/#map"; public static final String OSM_NEW_USER_URL = "https://www.openstreetmap.org/user/new"; public static final String OSM_TERMS_URL = "https://www.openstreetmap.org/user/terms#"; public static final String GOOGLE_SERVICE_LOGIN_URL = "https://accounts.google.com/ServiceLogin"; public static final String OSM_WELCOME_URL = "https://www.openstreetmap.org/welcome"; private EventBus eventBus; private boolean finish; @Inject public GoogleOAuthManager(EventBus eventBus) { this.eventBus = eventBus; } public void authenticate(final Activity activity, final String email) { finish = false; final WebViewDialogFragment dialog = WebViewDialogFragment.newInstance(OSM_GOOGLE_AUTH_URL, new MapParams<String, String>().put(LOGIN_HINT_PARAM, email).toMap()); dialog.show(activity.getFragmentManager(), WebViewDialogFragment.class.getSimpleName()); dialog.setOnPageFinishedListener(new WebViewDialogFragment.OnPageFinishedListener() { @Override public void onPageFinished(WebView webView, String url, boolean isRedirect) { webView.addJavascriptInterface(new JsInterface(activity, webView, dialog), "Android"); if (!finish && url.contains(OSM_MAP_URL) && !isRedirect) { if (dialog.isProgressing()) { dialog.stopProgressBar(); } // Get the tokens in hidden input in the html page webView.loadUrl("javascript:Android.showToken(" + "OSM.oauth_token " + "+ ' ' " + "+ OSM.oauth_token_secret" + "+ ' ' " + "+ OSM.oauth_consumer_key" + "+ ' ' " + "+ OSM.oauth_consumer_secret)"); } if (url.contains(OSM_NEW_USER_URL) && !url.equals(OSM_NEW_USER_URL)) { dialog.startProgressBar(); // Skip the inscription page webView.loadUrl("javascript:" + "document.getElementsByName('user[display_name]')[0].value = '" + email.substring(0, email.indexOf('@')) + UUID.randomUUID().toString().substring(0, 5) + "';" + "document.getElementsByName('commit')[0].click();"); } if (url.equals(OSM_NEW_USER_URL)) { dialog.showErrorText(activity.getString(R.string.login_google_error)); } if (url.contains(OSM_TERMS_URL) && !isRedirect) { dialog.stopProgressBar(); } if (url.contains(GOOGLE_SERVICE_LOGIN_URL) && !isRedirect) { // Skip the google email next page webView.loadUrl("javascript:" + "if (!document.getElementById('password-shown').hasChildNodes()) {" + " document.getElementById('next').click()" + "} else {" + " Android.stopProgressBar();" + "}"); } if (url.contains(OSM_WELCOME_URL) && !isRedirect) { webView.loadUrl(OSM_MAP_URL); } if (url.contains(OSM_WELCOME_URL) && isRedirect) { dialog.startProgressBar(); } } }); } private class JsInterface { private WebView webView; private Activity activity; private WebViewDialogFragment dialog; public JsInterface(Activity activity, WebView webView, WebViewDialogFragment dialog) { this.webView = webView; this.activity = activity; this.dialog = dialog; } @JavascriptInterface @SuppressWarnings("unused") public synchronized void showToken(String attr) { finish = true; String[] tokens = attr.split(" "); final GoogleAuthenticatedEvent event = new GoogleAuthenticatedEvent(tokens[0], tokens[1], tokens[2], tokens[3]); activity.runOnUiThread(new Runnable() { @Override public void run() { webView.stopLoading(); dialog.dismiss(); eventBus.post(event); } }); } @JavascriptInterface @SuppressWarnings("unused") public void stopProgressBar() { activity.runOnUiThread(new Runnable() { @Override public void run() { dialog.stopProgressBar(); } }); } } }