package io.scal.secureshareui.login;
import info.guardianproject.netcipher.proxy.OrbotHelper;
import info.guardianproject.netcipher.web.WebkitProxy;
import timber.log.Timber;
import io.scal.secureshareui.controller.SiteController;
import io.scal.secureshareui.lib.Util;
import io.scal.secureshareuilibrary.R;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeRequestUrl;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.youtube.YouTubeScopes;
public class YoutubeLoginActivity extends LockableActivity implements Runnable {
private int mAccessResult = RESULT_CANCELED;
private String mAccessToken = null;
static final String TAG = "YoutubeLoginActivity";
private String CLIENT_ID;
private String CLIENT_SECRET;
private static final String REDIRECT_URI = "http://localhost";
private static final String YOUTUBE_USER_INFO_URL = "https://www.googleapis.com/oauth2/v2/userinfo";
private static final String YOUTUBE_EMAIL_SCOPE = "https://www.googleapis.com/auth/userinfo.email";
HttpTransport transport = new NetHttpTransport();
private final JsonFactory jsonFactory = new GsonFactory();
// FIXME security: we need to override the webviews cache, cookies, formdata cache to store only in sqlcipher/iocipher, currently it hits disk and then we clear it
private WebView mWebview;
private String mReturnedWebCode;
private GoogleTokenResponse mAuthResp;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_youtube_login);
CLIENT_ID = getString(R.string.google_client_id);
CLIENT_SECRET = getString(R.string.google_client_secret);
login();
}
@SuppressLint("SetJavaScriptEnabled")
public void login() {
// check for tor settings and set proxy
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
boolean useTor = settings.getBoolean("pusetor", false);
mWebview = new WebView(this);
if (useTor) {
Timber.d("user selected \"use tor\"");
if ((!OrbotHelper.isOrbotInstalled(this)) || (!OrbotHelper.isOrbotRunning(this))) {
Timber.e("user selected \"use tor\" but orbot is not installed or not running");
return;
} else {
try {
WebkitProxy.setProxy("android.app.Application", getApplicationContext(), mWebview, Util.ORBOT_HOST, Util.ORBOT_HTTP_PORT);
} catch (Exception e) {
Timber.e("user selected \"use tor\" but an exception was thrown while setting the proxy: " + e.getLocalizedMessage());
return;
}
}
} else {
Timber.d("user selected \"don't use tor\"");
}
mWebview.getSettings().setJavaScriptEnabled(true);
mWebview.setVisibility(View.VISIBLE);
setContentView(mWebview);
List<String> scopes = new ArrayList<String>();
scopes.add(YouTubeScopes.YOUTUBE_UPLOAD);
scopes.add(YOUTUBE_EMAIL_SCOPE);
String authUrl = new GoogleAuthorizationCodeRequestUrl(CLIENT_ID, REDIRECT_URI, scopes).build();
// WebViewClient must be set BEFORE calling loadUrl!
mWebview.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap bitmap) {
}
@Override
public void onPageFinished(WebView view, String url) {
if (url.startsWith(REDIRECT_URI)) {
if (url.indexOf("code=") != -1) {
if (mReturnedWebCode == null) {
mReturnedWebCode = extractCodeFromUrl(url);
view.setVisibility(View.INVISIBLE);
new Thread(YoutubeLoginActivity.this).start();
//must be done on the main thread
Util.clearWebviewAndCookies(mWebview, YoutubeLoginActivity.this);
}
} else if (url.indexOf("error=") != -1) {
view.setVisibility(View.INVISIBLE);
mAccessResult = RESULT_CANCELED;
}
}
}
private String extractCodeFromUrl(String url) {
return url.substring(REDIRECT_URI.length() + 7, url.length());
}
});
mWebview.loadUrl(authUrl);
}
public void run() {
try {
mAuthResp = new GoogleAuthorizationCodeTokenRequest(transport,
jsonFactory,
CLIENT_ID,
CLIENT_SECRET,
mReturnedWebCode, REDIRECT_URI).execute();
String userEmail = getUserEmail(mAuthResp.getAccessToken());
if (null != userEmail) {
mAccessResult = RESULT_OK;
mAccessToken = userEmail;
} else { // failed login
mAccessResult = RESULT_CANCELED;
}
} catch (IOException ioe) {
Timber.e("Authentication Error: " + ioe.getMessage());
}
finish();
}
public String getUserEmail(String accessToken) {
String userEmail = null;
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(YOUTUBE_USER_INFO_URL + "?access_token=" + accessToken);
try {
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpClient.execute(httpGet, responseHandler);
JSONObject responseJson = new JSONObject(responseBody);
userEmail = responseJson.getString("email");
} catch (ClientProtocolException cpe) {
Timber.e("ClientProtocolException: " + cpe.getMessage());
}
catch (IOException ioe) {
Timber.e("IOException: " + ioe.getMessage());
}
catch (JSONException jsone) {
Timber.e("JSONException: " + jsone.getMessage());
}
return userEmail;
}
@Override
public void finish() {
Timber.d("finish()");
Intent data = new Intent();
data.putExtra(SiteController.EXTRAS_KEY_CREDENTIALS, mAccessToken);
setResult(mAccessResult, data);;
super.finish();
}
}